KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > appfuse > webapp > filter > GZIPResponseStream


1 package org.appfuse.webapp.filter;
2
3 import java.io.ByteArrayOutputStream JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.io.OutputStream JavaDoc;
6 import java.util.zip.GZIPOutputStream JavaDoc;
7
8 import javax.servlet.ServletOutputStream JavaDoc;
9 import javax.servlet.http.HttpServletResponse JavaDoc;
10
11
12 /**
13  * Wraps Response Stream for GZipFilter
14  *
15  * @author Matt Raible
16  * @version $Revision: 1.3 $ $Date: 2004-05-15 20:18:10 -0600 (Sat, 15 May 2004) $
17  */

18 public class GZIPResponseStream extends ServletOutputStream JavaDoc {
19     // abstraction of the output stream used for compression
20
protected OutputStream JavaDoc bufferedOutput = null;
21
22     // state keeping variable for if close() has been called
23
protected boolean closed = false;
24
25     // reference to original response
26
protected HttpServletResponse JavaDoc response = null;
27
28     // reference to the output stream to the client's browser
29
protected ServletOutputStream JavaDoc output = null;
30
31     // default size of the in-memory buffer
32
private int bufferSize = 50000;
33
34     public GZIPResponseStream(HttpServletResponse JavaDoc response)
35     throws IOException JavaDoc {
36         super();
37         closed = false;
38         this.response = response;
39         this.output = response.getOutputStream();
40         bufferedOutput = new ByteArrayOutputStream JavaDoc();
41     }
42
43     public void close() throws IOException JavaDoc {
44         // verify the stream is yet to be closed
45
if (closed) {
46             throw new IOException JavaDoc("This output stream has already been closed");
47         }
48
49         // if we buffered everything in memory, gzip it
50
if (bufferedOutput instanceof ByteArrayOutputStream JavaDoc) {
51             // get the content
52
ByteArrayOutputStream JavaDoc baos = (ByteArrayOutputStream JavaDoc) bufferedOutput;
53
54             // prepare a gzip stream
55
ByteArrayOutputStream JavaDoc compressedContent =
56                 new ByteArrayOutputStream JavaDoc();
57             GZIPOutputStream JavaDoc gzipstream =
58                 new GZIPOutputStream JavaDoc(compressedContent);
59             byte[] bytes = baos.toByteArray();
60             gzipstream.write(bytes);
61             gzipstream.finish();
62
63             // get the compressed content
64
byte[] compressedBytes = compressedContent.toByteArray();
65
66             // set appropriate HTTP headers
67
response.setContentLength(compressedBytes.length);
68             response.addHeader("Content-Encoding", "gzip");
69             output.write(compressedBytes);
70             output.flush();
71             output.close();
72             closed = true;
73         }
74         // if things were not buffered in memory, finish the GZIP stream and response
75
else if (bufferedOutput instanceof GZIPOutputStream JavaDoc) {
76             // cast to appropriate type
77
GZIPOutputStream JavaDoc gzipstream = (GZIPOutputStream JavaDoc) bufferedOutput;
78
79             // finish the compression
80
gzipstream.finish();
81
82             // finish the response
83
output.flush();
84             output.close();
85             closed = true;
86         }
87     }
88
89     public void flush() throws IOException JavaDoc {
90         if (closed) {
91             throw new IOException JavaDoc("Cannot flush a closed output stream");
92         }
93
94         bufferedOutput.flush();
95     }
96
97     public void write(int b) throws IOException JavaDoc {
98         if (closed) {
99             throw new IOException JavaDoc("Cannot write to a closed output stream");
100         }
101
102         // make sure we aren't over the buffer's limit
103
checkBufferSize(1);
104
105         // write the byte to the temporary output
106
bufferedOutput.write((byte) b);
107     }
108
109     private void checkBufferSize(int length) throws IOException JavaDoc {
110         // check if we are buffering too large of a file
111
if (bufferedOutput instanceof ByteArrayOutputStream JavaDoc) {
112             ByteArrayOutputStream JavaDoc baos = (ByteArrayOutputStream JavaDoc) bufferedOutput;
113
114             if ((baos.size() + length) > bufferSize) {
115                 // files too large to keep in memory are sent to the client without Content-Length specified
116
response.addHeader("Content-Encoding", "gzip");
117
118                 // get existing bytes
119
byte[] bytes = baos.toByteArray();
120
121                 // make new gzip stream using the response output stream
122
GZIPOutputStream JavaDoc gzipstream = new GZIPOutputStream JavaDoc(output);
123                 gzipstream.write(bytes);
124
125                 // we are no longer buffering, send content via gzipstream
126
bufferedOutput = gzipstream;
127             }
128         }
129     }
130
131     public void write(byte[] b) throws IOException JavaDoc {
132         write(b, 0, b.length);
133     }
134
135     public void write(byte[] b, int off, int len) throws IOException JavaDoc {
136
137         if (closed) {
138             throw new IOException JavaDoc("Cannot write to a closed output stream");
139         }
140
141         // make sure we aren't over the buffer's limit
142
checkBufferSize(len);
143
144         // write the content to the buffer
145
bufferedOutput.write(b, off, len);
146     }
147
148     public boolean closed() {
149         return (this.closed);
150     }
151
152     public void reset() {
153         //noop
154
}
155 }
156
Popular Tags