View Javadoc

1   /*
2   * Copyright 2004 The Apache Software Foundation
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *     http://www.apache.org/licenses/LICENSE-2.0
9   *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16  package compressionFilters;
17  
18  import java.io.IOException;
19  import java.io.OutputStream;
20  import java.io.OutputStreamWriter;
21  import java.io.PrintWriter;
22  import java.util.Locale;
23  import javax.servlet.ServletRequest;
24  import javax.servlet.ServletResponse;
25  import javax.servlet.ServletException;
26  import javax.servlet.ServletOutputStream;
27  import javax.servlet.ServletResponse;
28  import javax.servlet.ServletResponseWrapper;
29  import javax.servlet.http.HttpServletResponse;
30  import javax.servlet.http.HttpServletResponseWrapper;
31  
32  /**
33   * Implementation of <b>HttpServletResponseWrapper</b> that works with
34   * the CompressionServletResponseStream implementation..
35   *
36   * @author Amy Roh
37   * @author Dmitri Valdin
38   * @version $Revision: 267129 $, $Date: 2004-03-18 08:40:35 -0800 (Thu, 18 Mar 2004) $
39   */
40  
41  public class CompressionServletResponseWrapper extends HttpServletResponseWrapper {
42  
43      // ----------------------------------------------------- Constructor
44  
45      /**
46       * Calls the parent constructor which creates a ServletResponse adaptor
47       * wrapping the given response object.
48       */
49  
50      public CompressionServletResponseWrapper(HttpServletResponse response) {
51          super(response);
52          origResponse = response;
53          if (debug > 1) {
54              System.out.println("CompressionServletResponseWrapper constructor gets called");
55          }
56      }
57  
58  
59      // ----------------------------------------------------- Instance Variables
60  
61      /**
62       * Original response
63       */
64  
65      protected HttpServletResponse origResponse = null;
66  
67      /**
68       * Descriptive information about this Response implementation.
69       */
70  
71      protected static final String info = "CompressionServletResponseWrapper";
72  
73      /**
74       * The ServletOutputStream that has been returned by
75       * <code>getOutputStream()</code>, if any.
76       */
77  
78      protected ServletOutputStream stream = null;
79  
80  
81      /**
82       * The PrintWriter that has been returned by
83       * <code>getWriter()</code>, if any.
84       */
85  
86      protected PrintWriter writer = null;
87  
88      /**
89       * The threshold number to compress
90       */
91      protected int threshold = 0;
92  
93      /**
94       * Debug level
95       */
96      private int debug = 0;
97  
98      /**
99       * Content type
100      */
101     protected String contentType = null;
102 
103     // --------------------------------------------------------- Public Methods
104 
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     /**
119      * Set threshold number
120      */
121     public void setCompressionThreshold(int threshold) {
122         if (debug > 1) {
123             System.out.println("setCompressionThreshold to " + threshold);
124         }
125         this.threshold = threshold;
126     }
127 
128 
129     /**
130      * Set debug level
131      */
132     public void setDebugLevel(int debug) {
133         this.debug = debug;
134     }
135 
136 
137     /**
138      * Create and return a ServletOutputStream to write the content
139      * associated with this Response.
140      *
141      * @exception IOException if an input/output error occurs
142      */
143     public ServletOutputStream createOutputStream() throws IOException {
144         if (debug > 1) {
145             System.out.println("createOutputStream gets called");
146         }
147 
148         CompressionResponseStream stream = new CompressionResponseStream(origResponse);
149         stream.setDebugLevel(debug);
150         stream.setBuffer(threshold);
151 
152         return stream;
153 
154     }
155 
156 
157     /**
158      * Finish a response.
159      */
160     public void finishResponse() {
161         try {
162             if (writer != null) {
163                 writer.close();
164             } else {
165                 if (stream != null)
166                     stream.close();
167             }
168         } catch (IOException e) {
169         }
170     }
171 
172 
173     // ------------------------------------------------ ServletResponse Methods
174 
175 
176     /**
177      * Flush the buffer and commit this response.
178      *
179      * @exception IOException if an input/output error occurs
180      */
181     public void flushBuffer() throws IOException {
182         if (debug > 1) {
183             System.out.println("flush buffer @ CompressionServletResponseWrapper");
184         }
185         ((CompressionResponseStream)stream).flush();
186 
187     }
188 
189     /**
190      * Return the servlet output stream associated with this Response.
191      *
192      * @exception IllegalStateException if <code>getWriter</code> has
193      *  already been called for this response
194      * @exception IOException if an input/output error occurs
195      */
196     public ServletOutputStream getOutputStream() throws IOException {
197 
198         if (writer != null)
199             throw new IllegalStateException("getWriter() has already been called for this response");
200 
201         if (stream == null)
202             stream = createOutputStream();
203         if (debug > 1) {
204             System.out.println("stream is set to "+stream+" in getOutputStream");
205         }
206 
207         return (stream);
208 
209     }
210 
211     /**
212      * Return the writer associated with this Response.
213      *
214      * @exception IllegalStateException if <code>getOutputStream</code> has
215      *  already been called for this response
216      * @exception IOException if an input/output error occurs
217      */
218     public PrintWriter getWriter() throws IOException {
219 
220         if (writer != null)
221             return (writer);
222 
223         if (stream != null)
224             throw new IllegalStateException("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+" in getWriter");
229         }
230         //String charset = getCharsetFromContentType(contentType);
231         String charEnc = origResponse.getCharacterEncoding();
232         if (debug > 1) {
233             System.out.println("character encoding is " + charEnc);
234         }
235         // HttpServletResponse.getCharacterEncoding() shouldn't return null
236         // according the spec, so feel free to remove that "if"
237         if (charEnc != null) {
238             writer = new PrintWriter(new OutputStreamWriter(stream, charEnc));
239         } else {
240             writer = new PrintWriter(stream);
241         }
242         
243         return (writer);
244 
245     }
246 
247 
248     public void setContentLength(int length) {
249     }
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.substring(charsetLocation + 8);
271             String encoding = afterCharset.trim();
272             return encoding;
273         }
274     }
275 
276 }