Attachment 'GzipNonCachingProcessingPipeline.java'

Download

   1 /** Creado en 12-ene-2004 */
   2 package fcc.ima.cocoon;
   3 
   4 import java.io.ByteArrayOutputStream;
   5 import java.io.IOException;
   6 import java.io.OutputStream;
   7 import java.net.SocketException;
   8 import java.util.Map;
   9 import java.util.zip.GZIPOutputStream;
  10 
  11 import org.apache.avalon.framework.logger.Logger;
  12 import org.apache.cocoon.ConnectionResetException;
  13 import org.apache.cocoon.ProcessingException;
  14 import org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline;
  15 import org.apache.cocoon.environment.Environment;
  16 import org.apache.cocoon.environment.ObjectModelHelper;
  17 import org.apache.cocoon.environment.Request;
  18 import org.apache.cocoon.environment.Response;
  19 
  20 /**Pipeline that may compress the content with gzip.
  21  * @author dperezcar */
  22 public class GzipNonCachingProcessingPipeline extends NonCachingProcessingPipeline {
  23 	static final public String USE_GZIP_KEY = "use-gzip";
  24 	static protected class StreamHandler {
  25 		protected StreamHandler(Logger log) {
  26 			this.log = log;
  27 		}
  28 		/**Get a new stream*/
  29 		protected OutputStream getStream(Environment environment, int outputBufferSize, boolean shouldSetContentLength) throws IOException {
  30 			// Copy parameters
  31 			this.environment = environment;
  32 
  33 			OutputStream result;
  34 			if (shouldSetContentLength) {
  35 				bufferStream = new ByteArrayOutputStream();
  36 				if (shouldCompress()) {
  37 					result = gs = new GZIPOutputStream(bufferStream);
  38 				} else {
  39 					result = bufferStream;
  40 				}
  41 			} else {
  42 				if (shouldCompress()) {
  43 					result = gs = new GZIPOutputStream(environment.getOutputStream(0));
  44 				} else {
  45 					result = environment.getOutputStream(outputBufferSize);
  46 				}
  47 			}
  48 			if (gs != null) {
  49 				Response resp = ObjectModelHelper.getResponse(environment.getObjectModel());
  50 				resp.addHeader("Content-Encoding", "gzip");
  51 			}
  52 			return result;
  53 		}
  54 		/**End the stream output*/
  55 		protected void end() throws IOException { 
  56 			if (gs != null) {
  57 				gs.finish();
  58 			}
  59 			if (bufferStream != null) {
  60 				byte[] data = bufferStream.toByteArray();
  61 				environment.setContentLength(data.length);
  62 				OutputStream out = environment.getOutputStream(0);
  63 				out.write(data);
  64 				out.flush();
  65 				out.close();
  66 			}
  67 		}
  68 		protected boolean shouldCompress() {
  69 			Map objModel = environment.getObjectModel();
  70 			Request req = ObjectModelHelper.getRequest(objModel);
  71 			if (req != null) {
  72 				// Compression activated in sitemap?
  73 				Object attr = req.getAttribute(USE_GZIP_KEY); 
  74 				if (attr != null && attr.equals("1")) {
  75 					// Does browser support gzip compression?
  76 					String ae = req.getHeader("accept-encoding");
  77 					if (ae != null && ae.indexOf("gzip") != -1) {
  78 						Response resp = ObjectModelHelper.getResponse(objModel);
  79 						if (resp != null && !resp.containsHeader("content-encoding")) {
  80 							log.debug("GZIP supported, compressing.");
  81 							return true;
  82 						} else {
  83 							// Nested invocation, like e.g. Xinclude transformer, don't compress again.
  84 							log.debug("Content-encoding already set.");
  85 						}
  86 					}
  87 				}
  88 			}
  89 			return false;
  90 		}
  91 		protected Environment environment;
  92 		protected ByteArrayOutputStream bufferStream;
  93 		protected GZIPOutputStream gs;
  94 		protected Logger log;
  95 	}
  96 	/** @see org.apache.cocoon.components.pipeline.AbstractProcessingPipeline#processReader(org.apache.cocoon.environment.Environment) */
  97 	protected boolean processReader(Environment environment) throws ProcessingException {
  98 		try {
  99 			getLogger().info("Ini reader");
 100 			StreamHandler sh = new StreamHandler(getLogger());
 101 			reader.setOutputStream(sh.getStream(environment, outputBufferSize, reader.shouldSetContentLength()));
 102 			reader.generate();
 103 			sh.end();
 104 			getLogger().info("End reader");
 105 		} catch ( SocketException se ) {
 106 			if (se.getMessage().indexOf("reset") > 0
 107 					|| se.getMessage().indexOf("aborted") > 0
 108 					|| se.getMessage().indexOf("connection abort") > 0) {
 109 				throw new ConnectionResetException("Connection reset by peer", se);
 110 			} else {
 111 				throw new ProcessingException("Failed to execute reader pipeline.", se);
 112 			}
 113 		} catch ( ProcessingException e ) {
 114 			throw e;
 115 		} catch ( Exception e ) {
 116 			throw new ProcessingException("Error executing reader pipeline.",e);
 117 		}
 118 		return true;
 119 	}
 120 
 121 	/** @see org.apache.cocoon.components.pipeline.AbstractProcessingPipeline#processXMLPipeline(org.apache.cocoon.environment.Environment) */
 122 	protected boolean processXMLPipeline(Environment environment) throws ProcessingException {
 123 		try {
 124 			getLogger().info("Ini XML");
 125 			if (this.serializer != this.lastConsumer) {
 126 				// internal processing
 127 				this.generator.generate();
 128 			} else {
 129 				StreamHandler sh = new StreamHandler(getLogger());
 130 				serializer.setOutputStream(sh.getStream(environment, outputBufferSize, serializer.shouldSetContentLength()));
 131 				// execute the pipeline:
 132 				generator.generate();
 133 				sh.end();
 134 			}
 135 			getLogger().info("End XML");
 136 		} catch ( ProcessingException e) {
 137 			throw e;
 138 		} catch ( Exception e ) {
 139 			throw new ProcessingException("Failed to execute pipeline.", e);
 140 		}
 141 		return true;
 142 	}
 143 }

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.