001: /*
002: * Copyright 2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package compressionFilters;
017:
018: import java.io.IOException;
019: import java.io.OutputStream;
020: import java.io.OutputStreamWriter;
021: import java.io.PrintWriter;
022: import java.util.Locale;
023: import javax.servlet.ServletRequest;
024: import javax.servlet.ServletResponse;
025: import javax.servlet.ServletException;
026: import javax.servlet.ServletOutputStream;
027: import javax.servlet.ServletResponse;
028: import javax.servlet.ServletResponseWrapper;
029: import javax.servlet.http.HttpServletResponse;
030: import javax.servlet.http.HttpServletResponseWrapper;
031:
032: /**
033: * Implementation of <b>HttpServletResponseWrapper</b> that works with
034: * the CompressionServletResponseStream implementation..
035: *
036: * @author Amy Roh
037: * @author Dmitri Valdin
038: * @version $Revision: 1.3 $, $Date: 2004/03/18 16:40:33 $
039: */
040:
041: public class CompressionServletResponseWrapper extends
042: HttpServletResponseWrapper {
043:
044: // ----------------------------------------------------- Constructor
045:
046: /**
047: * Calls the parent constructor which creates a ServletResponse adaptor
048: * wrapping the given response object.
049: */
050:
051: public CompressionServletResponseWrapper(
052: HttpServletResponse response) {
053: super (response);
054: origResponse = response;
055: if (debug > 1) {
056: System.out
057: .println("CompressionServletResponseWrapper constructor gets called");
058: }
059: }
060:
061: // ----------------------------------------------------- Instance Variables
062:
063: /**
064: * Original response
065: */
066:
067: protected HttpServletResponse origResponse = null;
068:
069: /**
070: * Descriptive information about this Response implementation.
071: */
072:
073: protected static final String info = "CompressionServletResponseWrapper";
074:
075: /**
076: * The ServletOutputStream that has been returned by
077: * <code>getOutputStream()</code>, if any.
078: */
079:
080: protected ServletOutputStream stream = null;
081:
082: /**
083: * The PrintWriter that has been returned by
084: * <code>getWriter()</code>, if any.
085: */
086:
087: protected PrintWriter writer = null;
088:
089: /**
090: * The threshold number to compress
091: */
092: protected int threshold = 0;
093:
094: /**
095: * Debug level
096: */
097: private int debug = 0;
098:
099: /**
100: * Content type
101: */
102: protected String contentType = null;
103:
104: // --------------------------------------------------------- Public Methods
105:
106: /**
107: * Set content type
108: */
109: public void setContentType(String contentType) {
110: if (debug > 1) {
111: System.out.println("setContentType to " + contentType);
112: }
113: this .contentType = contentType;
114: origResponse.setContentType(contentType);
115: }
116:
117: /**
118: * Set threshold number
119: */
120: public void setCompressionThreshold(int threshold) {
121: if (debug > 1) {
122: System.out.println("setCompressionThreshold to "
123: + threshold);
124: }
125: this .threshold = threshold;
126: }
127:
128: /**
129: * Set debug level
130: */
131: public void setDebugLevel(int debug) {
132: this .debug = debug;
133: }
134:
135: /**
136: * Create and return a ServletOutputStream to write the content
137: * associated with this Response.
138: *
139: * @exception IOException if an input/output error occurs
140: */
141: public ServletOutputStream createOutputStream() throws IOException {
142: if (debug > 1) {
143: System.out.println("createOutputStream gets called");
144: }
145:
146: CompressionResponseStream stream = new CompressionResponseStream(
147: origResponse);
148: stream.setDebugLevel(debug);
149: stream.setBuffer(threshold);
150:
151: return stream;
152:
153: }
154:
155: /**
156: * Finish a response.
157: */
158: public void finishResponse() {
159: try {
160: if (writer != null) {
161: writer.close();
162: } else {
163: if (stream != null)
164: stream.close();
165: }
166: } catch (IOException e) {
167: }
168: }
169:
170: // ------------------------------------------------ ServletResponse Methods
171:
172: /**
173: * Flush the buffer and commit this response.
174: *
175: * @exception IOException if an input/output error occurs
176: */
177: public void flushBuffer() throws IOException {
178: if (debug > 1) {
179: System.out
180: .println("flush buffer @ CompressionServletResponseWrapper");
181: }
182: ((CompressionResponseStream) stream).flush();
183:
184: }
185:
186: /**
187: * Return the servlet output stream associated with this Response.
188: *
189: * @exception IllegalStateException if <code>getWriter</code> has
190: * already been called for this response
191: * @exception IOException if an input/output error occurs
192: */
193: public ServletOutputStream getOutputStream() throws IOException {
194:
195: if (writer != null)
196: throw new IllegalStateException(
197: "getWriter() has already been called for this response");
198:
199: if (stream == null)
200: stream = createOutputStream();
201: if (debug > 1) {
202: System.out.println("stream is set to " + stream
203: + " in getOutputStream");
204: }
205:
206: return (stream);
207:
208: }
209:
210: /**
211: * Return the writer associated with this Response.
212: *
213: * @exception IllegalStateException if <code>getOutputStream</code> has
214: * already been called for this response
215: * @exception IOException if an input/output error occurs
216: */
217: public PrintWriter getWriter() throws IOException {
218:
219: if (writer != null)
220: return (writer);
221:
222: if (stream != null)
223: throw new IllegalStateException(
224: "getOutputStream() has already been called for this response");
225:
226: stream = createOutputStream();
227: if (debug > 1) {
228: System.out.println("stream is set to " + stream
229: + " in getWriter");
230: }
231: //String charset = getCharsetFromContentType(contentType);
232: String charEnc = origResponse.getCharacterEncoding();
233: if (debug > 1) {
234: System.out.println("character encoding is " + charEnc);
235: }
236: // HttpServletResponse.getCharacterEncoding() shouldn't return null
237: // according the spec, so feel free to remove that "if"
238: if (charEnc != null) {
239: writer = new PrintWriter(new OutputStreamWriter(stream,
240: charEnc));
241: } else {
242: writer = new PrintWriter(stream);
243: }
244:
245: return (writer);
246:
247: }
248:
249: public void setContentLength(int length) {
250: }
251:
252: /**
253: * Returns character from content type. This method was taken from tomcat.
254: * @author rajo
255: */
256: private static String getCharsetFromContentType(String type) {
257:
258: if (type == null) {
259: return null;
260: }
261: int semi = type.indexOf(";");
262: if (semi == -1) {
263: return null;
264: }
265: String afterSemi = type.substring(semi + 1);
266: int charsetLocation = afterSemi.indexOf("charset=");
267: if (charsetLocation == -1) {
268: return null;
269: } else {
270: String afterCharset = afterSemi
271: .substring(charsetLocation + 8);
272: String encoding = afterCharset.trim();
273: return encoding;
274: }
275: }
276:
277: }
|