1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 }