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