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  
17  package compressionFilters;
18  
19  import java.io.IOException;
20  import java.io.OutputStream;
21  import java.io.OutputStreamWriter;
22  import java.io.PrintWriter;
23  import java.util.Locale;
24  import javax.servlet.ServletRequest;
25  import javax.servlet.ServletResponse;
26  import javax.servlet.ServletException;
27  import javax.servlet.ServletOutputStream;
28  import javax.servlet.ServletResponse;
29  import javax.servlet.ServletResponseWrapper;
30  import javax.servlet.http.HttpServletResponse;
31  import javax.servlet.http.HttpServletResponseWrapper;
32  
33  /**
34   * Implementation of <b>HttpServletResponseWrapper</b> that works with
35   * the CompressionServletResponseStream implementation..
36   *
37   * @author Amy Roh
38   * @author Dmitri Valdin
39   * @version $Revision: 267129 $, $Date: 2004-03-18 08:40:35 -0800 (Thu, 18 Mar 2004) $
40   */
41  
42  public class CompressionServletResponseWrapper extends HttpServletResponseWrapper {
43  
44      // ----------------------------------------------------- Constructor
45  
46      /**
47       * Calls the parent constructor which creates a ServletResponse adaptor
48       * wrapping the given response object.
49       */
50  
51      public CompressionServletResponseWrapper(HttpServletResponse response) {
52          super(response);
53          origResponse = response;
54          if (debug > 1) {
55              System.out.println("CompressionServletResponseWrapper constructor gets called");
56          }
57      }
58  
59  
60      // ----------------------------------------------------- Instance Variables
61  
62      /**
63       * Original response
64       */
65  
66      protected HttpServletResponse origResponse = null;
67  
68      /**
69       * Descriptive information about this Response implementation.
70       */
71  
72      protected static final String info = "CompressionServletResponseWrapper";
73  
74      /**
75       * The ServletOutputStream that has been returned by
76       * <code>getOutputStream()</code>, if any.
77       */
78  
79      protected ServletOutputStream stream = null;
80  
81  
82      /**
83       * The PrintWriter that has been returned by
84       * <code>getWriter()</code>, if any.
85       */
86  
87      protected PrintWriter writer = null;
88  
89      /**
90       * The threshold number to compress
91       */
92      protected int threshold = 0;
93  
94      /**
95       * Debug level
96       */
97      private int debug = 0;
98  
99      /**
100      * Content type
101      */
102     protected String contentType = null;
103 
104     // --------------------------------------------------------- Public Methods
105 
106 
107     /**
108      * Set content type
109      */
110     public void setContentType(String contentType) {
111         if (debug > 1) {
112             System.out.println("setContentType to "+contentType);
113         }
114         this.contentType = contentType;
115         origResponse.setContentType(contentType);
116     }
117 
118 
119     /**
120      * Set threshold number
121      */
122     public void setCompressionThreshold(int threshold) {
123         if (debug > 1) {
124             System.out.println("setCompressionThreshold to " + threshold);
125         }
126         this.threshold = threshold;
127     }
128 
129 
130     /**
131      * Set debug level
132      */
133     public void setDebugLevel(int debug) {
134         this.debug = debug;
135     }
136 
137 
138     /**
139      * Create and return a ServletOutputStream to write the content
140      * associated with this Response.
141      *
142      * @exception IOException if an input/output error occurs
143      */
144     public ServletOutputStream createOutputStream() throws IOException {
145         if (debug > 1) {
146             System.out.println("createOutputStream gets called");
147         }
148 
149         CompressionResponseStream stream = new CompressionResponseStream(origResponse);
150         stream.setDebugLevel(debug);
151         stream.setBuffer(threshold);
152 
153         return stream;
154 
155     }
156 
157 
158     /**
159      * Finish a response.
160      */
161     public void finishResponse() {
162         try {
163             if (writer != null) {
164                 writer.close();
165             } else {
166                 if (stream != null)
167                     stream.close();
168             }
169         } catch (IOException e) {
170         }
171     }
172 
173 
174     // ------------------------------------------------ ServletResponse Methods
175 
176 
177     /**
178      * Flush the buffer and commit this response.
179      *
180      * @exception IOException if an input/output error occurs
181      */
182     public void flushBuffer() throws IOException {
183         if (debug > 1) {
184             System.out.println("flush buffer @ CompressionServletResponseWrapper");
185         }
186         ((CompressionResponseStream)stream).flush();
187 
188     }
189 
190     /**
191      * Return the servlet output stream associated with this Response.
192      *
193      * @exception IllegalStateException if <code>getWriter</code> has
194      *  already been called for this response
195      * @exception IOException if an input/output error occurs
196      */
197     public ServletOutputStream getOutputStream() throws IOException {
198 
199         if (writer != null)
200             throw new IllegalStateException("getWriter() has already been called for this response");
201 
202         if (stream == null)
203             stream = createOutputStream();
204         if (debug > 1) {
205             System.out.println("stream is set to "+stream+" in getOutputStream");
206         }
207 
208         return (stream);
209 
210     }
211 
212     /**
213      * Return the writer associated with this Response.
214      *
215      * @exception IllegalStateException if <code>getOutputStream</code> has
216      *  already been called for this response
217      * @exception IOException if an input/output error occurs
218      */
219     public PrintWriter getWriter() throws IOException {
220 
221         if (writer != null)
222             return (writer);
223 
224         if (stream != null)
225             throw new IllegalStateException("getOutputStream() has already been called for this response");
226 
227         stream = createOutputStream();
228         if (debug > 1) {
229             System.out.println("stream is set to "+stream+" 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, charEnc));
240         } else {
241             writer = new PrintWriter(stream);
242         }
243         
244         return (writer);
245 
246     }
247 
248 
249     public void setContentLength(int length) {
250     }
251 
252 
253     /**
254      * Returns character from content type. This method was taken from tomcat.
255      * @author rajo
256      */
257     private static String getCharsetFromContentType(String type) {
258 
259         if (type == null) {
260             return null;
261         }
262         int semi = type.indexOf(";");
263         if (semi == -1) {
264             return null;
265         }
266         String afterSemi = type.substring(semi + 1);
267         int charsetLocation = afterSemi.indexOf("charset=");
268         if(charsetLocation == -1) {
269             return null;
270         } else {
271             String afterCharset = afterSemi.substring(charsetLocation + 8);
272             String encoding = afterCharset.trim();
273             return encoding;
274         }
275     }
276 
277 }