KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jresearch > gossip > filters > gzip > GZIPResponseStream


1 /*
2  * $$Id: GZIPResponseStream.java,v 1.3 2005/06/07 12:31:56 bel70 Exp $$
3  *
4  * ***** BEGIN LICENSE BLOCK ***** The contents of this file are subject to the
5  * Mozilla Public License Version 1.1 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of the License
7  * at http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
11  * the specific language governing rights and limitations under the License.
12  *
13  * The Original Code is JGossip forum code.
14  *
15  * The Initial Developer of the Original Code is the JResearch, Org. Portions
16  * created by the Initial Developer are Copyright (C) 2004 the Initial
17  * Developer. All Rights Reserved.
18  *
19  * Contributor(s): Dmitry Belov <bel@jresearch.org>, Jayson Falkner
20  * <jayson@jspinsider.com>
21  *
22  * ***** END LICENSE BLOCK *****
23  */

24 package org.jresearch.gossip.filters.gzip;
25
26 import java.io.ByteArrayOutputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.zip.GZIPOutputStream JavaDoc;
30
31 import javax.servlet.ServletOutputStream JavaDoc;
32 import javax.servlet.http.HttpServletResponse JavaDoc;
33
34 public class GZIPResponseStream extends ServletOutputStream JavaDoc {
35
36     // abstraction of the output stream used for compression
37
protected OutputStream JavaDoc bufferedOutput = null;
38
39     // state keeping variable for if close() has been called
40
protected boolean closed = false;
41
42     // reference to original response
43
protected HttpServletResponse JavaDoc response = null;
44
45     // reference to the output stream to the client's browser
46
protected ServletOutputStream JavaDoc output = null;
47
48     // default size of the in-memory buffer
49
private int bufferSize = 50000;
50
51     public GZIPResponseStream(HttpServletResponse JavaDoc response) throws IOException JavaDoc {
52         super();
53         closed = false;
54         this.response = response;
55         this.output = response.getOutputStream();
56         bufferedOutput = new ByteArrayOutputStream JavaDoc();
57     }
58
59     public void close() throws IOException JavaDoc {
60         // This hack shouldn't be needed, but it seems to make JBoss and Struts
61
// like the code more without hurting anything.
62
/*
63          * // verify the stream is yet to be closed if (closed) { throw new
64          * IOException("This output stream has already been closed"); }
65          */

66         // if we buffered everything in memory, gzip it
67
if (bufferedOutput instanceof ByteArrayOutputStream JavaDoc) {
68             // get the content
69
ByteArrayOutputStream JavaDoc baos = (ByteArrayOutputStream JavaDoc) bufferedOutput;
70             // prepare a gzip stream
71
ByteArrayOutputStream JavaDoc compressedContent = new ByteArrayOutputStream JavaDoc();
72             GZIPOutputStream JavaDoc gzipstream = new GZIPOutputStream JavaDoc(
73                     compressedContent);
74             byte[] bytes = baos.toByteArray();
75             gzipstream.write(bytes);
76             gzipstream.finish();
77             // get the compressed content
78
byte[] compressedBytes = compressedContent.toByteArray();
79             // set appropriate HTTP headers
80
response.setContentLength(compressedBytes.length);
81             response.addHeader("Content-Encoding", "gzip");
82             output.write(compressedBytes);
83             output.flush();
84             output.close();
85             closed = true;
86         }
87         // if things were not buffered in memory, finish the GZIP stream and
88
// response
89
else if (bufferedOutput instanceof GZIPOutputStream JavaDoc) {
90             // cast to appropriate type
91
GZIPOutputStream JavaDoc gzipstream = (GZIPOutputStream JavaDoc) bufferedOutput;
92             // finish the compression
93
gzipstream.finish();
94             // finish the response
95
output.flush();
96             output.close();
97             closed = true;
98         }
99     }
100
101     public void flush() throws IOException JavaDoc {
102         if (!closed) {
103             bufferedOutput.flush();
104         }
105     }
106
107     public void write(int b) throws IOException JavaDoc {
108         if (closed) {
109             throw new IOException JavaDoc("Cannot write to a closed output stream");
110         }
111         // make sure we aren't over the buffer's limit
112
checkBufferSize(1);
113         // write the byte to the temporary output
114
bufferedOutput.write((byte) b);
115     }
116
117     private void checkBufferSize(int length) throws IOException JavaDoc {
118         // check if we are buffering too large of a file
119
if (bufferedOutput instanceof ByteArrayOutputStream JavaDoc) {
120             ByteArrayOutputStream JavaDoc baos = (ByteArrayOutputStream JavaDoc) bufferedOutput;
121             if (baos.size() + length > bufferSize) {
122                 // files too large to keep in memory are sent to the client
123
// without Content-Length specified
124
response.addHeader("Content-Encoding", "gzip");
125                 // get existing bytes
126
byte[] bytes = baos.toByteArray();
127                 // make new gzip stream using the response output stream
128
GZIPOutputStream JavaDoc gzipstream = new GZIPOutputStream JavaDoc(output);
129                 gzipstream.write(bytes);
130                 // we are no longer buffering, send content via gzipstream
131
bufferedOutput = gzipstream;
132             }
133         }
134     }
135
136     public void write(byte b[]) throws IOException JavaDoc {
137         write(b, 0, b.length);
138     }
139
140     public void write(byte b[], int off, int len) throws IOException JavaDoc {
141         if (closed) {
142             throw new IOException JavaDoc("Cannot write to a closed output stream");
143         }
144         // make sure we aren't over the buffer's limit
145
checkBufferSize(len);
146         // write the content to the buffer
147
bufferedOutput.write(b, off, len);
148     }
149
150     public boolean closed() {
151         return (this.closed);
152     }
153
154     public void reset() {
155         // noop
156
}
157 }
Popular Tags