View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.jumpmind.symmetric.web.compression;
18  
19  import java.io.IOException;
20  import java.io.OutputStream;
21  import java.util.zip.GZIPOutputStream;
22  import javax.servlet.ServletOutputStream;
23  import javax.servlet.http.HttpServletResponse;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  /***
29   * Implementation of <b>ServletOutputStream</b> that works with the
30   * CompressionServletResponseWrapper implementation.
31   * 
32   * This package is derived from the Jakarta <a
33   * href="http://jakarta.apache.org/tomcat">Tomcat</a> examples compression
34   * filter and is distributed in SymmetricDS for convenience.
35   * 
36   * @author Amy Roh
37   * @author Dmitri Valdin
38   * @version $Revision: 496190 $, $Date: 2007-01-14 16:21:45 -0700 (Sun, 14 Jan
39   *          2007) $
40   */
41  
42  public class CompressionResponseStream extends ServletOutputStream {
43  
44      static final Log logger = LogFactory.getLog(CompressionResponseStream.class);
45  
46      /***
47       * The underlying gzip output stream to which we should write data.
48       */
49      protected OutputStream gzipstream = null;
50  
51      /***
52       * Has this stream been closed?
53       */
54      protected boolean closed = false;
55  
56      /***
57       * The response with which this servlet output stream is associated.
58       */
59      protected HttpServletResponse response = null;
60  
61      /***
62       * Construct a servlet output stream associated with the specified Response.
63       * 
64       * @param response
65       *                The associated response
66       */
67      public CompressionResponseStream(HttpServletResponse response) throws IOException {
68          this.closed = false;
69          this.response = response;
70          response.addHeader("Content-Encoding", "gzip");
71          gzipstream = new GZIPOutputStream(response.getOutputStream());
72      }
73  
74      /***
75       * Close this output stream, causing any buffered data to be flushed and any
76       * further output data to throw an IOException.
77       */
78      public void close() throws IOException {
79  
80          if (closed) {
81              return;
82          }
83  
84          if (gzipstream != null) {
85              gzipstream.close();
86              gzipstream = null;
87          }
88  
89          closed = true;
90  
91      }
92  
93      /***
94       * Flush any buffered data for this output stream, which also causes the
95       * response to be committed.
96       */
97      public void flush() throws IOException {
98          if (closed) {
99              return;
100         }
101 
102         if (gzipstream != null) {
103             gzipstream.flush();
104         }
105 
106     }
107 
108     /***
109      * Write the specified byte to our output stream.
110      * 
111      * @param b
112      *                The byte to be written
113      * 
114      * @exception IOException
115      *                    if an input/output error occurs
116      */
117     public void write(int b) throws IOException {
118         if (closed) {
119             return;
120         }
121 
122         write(new byte[] { (byte) b });
123 
124     }
125 
126     /***
127      * Write <code>b.length</code> bytes from the specified byte array to our
128      * output stream.
129      * 
130      * @param b
131      *                The byte array to be written
132      * 
133      * @exception IOException
134      *                    if an input/output error occurs
135      */
136     public void write(byte b[]) throws IOException {
137         write(b, 0, b.length);
138     }
139 
140     /***
141      * Write <code>len</code> bytes from the specified byte array, starting at
142      * the specified offset, to our output stream.
143      * 
144      * @param b
145      *                The byte array containing the bytes to be written
146      * @param off
147      *                Zero-relative starting offset of the bytes to be written
148      * @param len
149      *                The number of bytes to be written
150      * 
151      * @exception IOException
152      *                    if an input/output error occurs
153      */
154     public void write(byte b[], int off, int len) throws IOException {
155         if (closed || len == 0) {
156             return;
157         }
158 
159         gzipstream.write(b, off, len);
160     }
161 
162     /***
163      * Has this response stream been closed?
164      */
165     public boolean closed() {
166         return this.closed;
167     }
168 
169 }