KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > web > util > compression > CompressionResponseStream


1 package com.genimen.djeneric.web.util.compression;
2
3 /*
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.io.IOException JavaDoc;
20 import java.util.zip.GZIPOutputStream JavaDoc;
21
22 import javax.servlet.ServletOutputStream JavaDoc;
23 import javax.servlet.http.HttpServletResponse JavaDoc;
24
25 /**
26  * Implementation of <b>ServletOutputStream</b> that works with
27  * the CompressionServletResponseWrapper implementation.
28  *
29  * @author Amy Roh
30  * @author Dmitri Valdin
31  * @version $Revision: 1.11 $, $Date: 2005/08/03 22:12:43 $
32  */

33
34 public class CompressionResponseStream extends ServletOutputStream JavaDoc
35 {
36
37   /**
38    * Construct a servlet output stream associated with the specified Response.
39    *
40    * @param response The associated response
41    */

42   public CompressionResponseStream(HttpServletResponse JavaDoc response) throws IOException JavaDoc
43   {
44
45     super();
46     closed = false;
47     this.response = response;
48     this.output = response.getOutputStream();
49
50   }
51
52   /**
53    * The threshold number which decides to compress or not.
54    * Users can configure in web.xml to set it to fit their needs.
55    */

56   protected int compressionThreshold = 0;
57
58   /**
59    * Debug level
60    */

61   private int debug = 0;
62
63   /**
64    * The buffer through which all of our output bytes are passed.
65    */

66   protected byte[] buffer = null;
67
68   /**
69    * The number of data bytes currently in the buffer.
70    */

71   protected int bufferCount = 0;
72
73   /**
74    * The underlying gzip output stream to which we should write data.
75    */

76   protected GZIPOutputStream JavaDoc gzipstream = null;
77
78   /**
79    * Has this stream been closed?
80    */

81   protected boolean closed = false;
82
83   /**
84    * The content length past which we will not write, or -1 if there is
85    * no defined content length.
86    */

87   protected int length = -1;
88
89   /**
90    * The response with which this servlet output stream is associated.
91    */

92   protected HttpServletResponse JavaDoc response = null;
93
94   /**
95    * The underlying servket output stream to which we should write data.
96    */

97   protected ServletOutputStream JavaDoc output = null;
98
99   /**
100    * Set debug level
101    */

102   public void setDebugLevel(int debug)
103   {
104     this.debug = debug;
105   }
106
107   /**
108    * Set the compressionThreshold number and create buffer for this size
109    */

110   protected void setBuffer(int threshold)
111   {
112     compressionThreshold = threshold;
113     buffer = new byte[compressionThreshold];
114     if (debug > 1)
115     {
116       System.out.println("buffer is set to " + compressionThreshold);
117     }
118   }
119
120   /**
121    * Close this output stream, causing any buffered data to be flushed and
122    * any further output data to throw an IOException.
123    */

124   public void close() throws IOException JavaDoc
125   {
126
127     if (debug > 1)
128     {
129       System.out.println("close() @ CompressionResponseStream");
130     }
131     if (closed) throw new IOException JavaDoc("This output stream has already been closed");
132
133     if (gzipstream != null)
134     {
135       flushToGZip();
136       gzipstream.close();
137       gzipstream = null;
138     }
139     else
140     {
141       if (bufferCount > 0)
142       {
143         if (debug > 2)
144         {
145           System.out.print("output.write(");
146           System.out.write(buffer, 0, bufferCount);
147           System.out.println(")");
148         }
149         output.write(buffer, 0, bufferCount);
150         bufferCount = 0;
151       }
152     }
153
154     output.close();
155     closed = true;
156
157   }
158
159   /**
160    * Flush any buffered data for this output stream, which also causes the
161    * response to be committed.
162    */

163   public void flush() throws IOException JavaDoc
164   {
165
166     if (debug > 1)
167     {
168       System.out.println("flush() @ CompressionResponseStream");
169     }
170     if (closed)
171     {
172       throw new IOException JavaDoc("Cannot flush a closed output stream");
173     }
174
175     if (gzipstream != null)
176     {
177       gzipstream.flush();
178     }
179
180   }
181
182   public void flushToGZip() throws IOException JavaDoc
183   {
184
185     if (debug > 1)
186     {
187       System.out.println("flushToGZip() @ CompressionResponseStream");
188     }
189     if (bufferCount > 0)
190     {
191       if (debug > 1)
192       {
193         System.out.println("flushing out to GZipStream, bufferCount = " + bufferCount);
194       }
195       writeToGZip(buffer, 0, bufferCount);
196       bufferCount = 0;
197     }
198
199   }
200
201   /**
202    * Write the specified byte to our output stream.
203    *
204    * @param b The byte to be written
205    *
206    * @exception IOException if an input/output error occurs
207    */

208   public void write(int b) throws IOException JavaDoc
209   {
210
211     if (debug > 1)
212     {
213       System.out.println("write " + b + " in CompressionResponseStream ");
214     }
215     if (closed) throw new IOException JavaDoc("Cannot write to a closed output stream");
216
217     if (bufferCount >= buffer.length)
218     {
219       flushToGZip();
220     }
221
222     buffer[bufferCount++] = (byte) b;
223
224   }
225
226   /**
227    * Write <code>b.length</code> bytes from the specified byte array
228    * to our output stream.
229    *
230    * @param b The byte array to be written
231    *
232    * @exception IOException if an input/output error occurs
233    */

234   public void write(byte b[]) throws IOException JavaDoc
235   {
236
237     write(b, 0, b.length);
238
239   }
240
241   /**
242    * Write <code>len</code> bytes from the specified byte array, starting
243    * at the specified offset, to our output stream.
244    *
245    * @param b The byte array containing the bytes to be written
246    * @param off Zero-relative starting offset of the bytes to be written
247    * @param len The number of bytes to be written
248    *
249    * @exception IOException if an input/output error occurs
250    */

251   public void write(byte b[], int off, int len) throws IOException JavaDoc
252   {
253
254     if (debug > 1)
255     {
256       System.out.println("write, bufferCount = " + bufferCount + " len = " + len + " off = " + off);
257     }
258     if (debug > 2)
259     {
260       System.out.print("write(");
261       System.out.write(b, off, len);
262       System.out.println(")");
263     }
264
265     if (closed) throw new IOException JavaDoc("Cannot write to a closed output stream");
266
267     if (len == 0) return;
268
269     // Can we write into buffer ?
270
if (len <= (buffer.length - bufferCount))
271     {
272       System.arraycopy(b, off, buffer, bufferCount, len);
273       bufferCount += len;
274       return;
275     }
276
277     // There is not enough space in buffer. Flush it ...
278
flushToGZip();
279
280     // ... and try again. Note, that bufferCount = 0 here !
281
if (len <= (buffer.length - bufferCount))
282     {
283       System.arraycopy(b, off, buffer, bufferCount, len);
284       bufferCount += len;
285       return;
286     }
287
288     // write direct to gzip
289
writeToGZip(b, off, len);
290   }
291
292   public void writeToGZip(byte b[], int off, int len) throws IOException JavaDoc
293   {
294
295     if (debug > 1)
296     {
297       System.out.println("writeToGZip, len = " + len);
298     }
299     if (debug > 2)
300     {
301       System.out.print("writeToGZip(");
302       System.out.write(b, off, len);
303       System.out.println(")");
304     }
305     if (gzipstream == null)
306     {
307       if (debug > 1)
308       {
309         System.out.println("new GZIPOutputStream");
310       }
311       response.addHeader("Content-Encoding", "gzip");
312       gzipstream = new GZIPOutputStream JavaDoc(output);
313     }
314     gzipstream.write(b, off, len);
315
316   }
317
318   // -------------------------------------------------------- Package Methods
319
/**
320    * Has this response stream been closed?
321    */

322   public boolean closed()
323   {
324     return (this.closed);
325   }
326 }
Popular Tags