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 024 import javax.servlet.ServletOutputStream; 025 import javax.servlet.http.HttpServletResponse; 026 import javax.servlet.http.HttpServletResponseWrapper; 027 028 /** 029 * Implementation of <b>HttpServletResponseWrapper</b> that works with 030 * the CompressionServletResponseStream implementation.. 031 * 032 * @author Amy Roh 033 * @author Dmitri Valdin 034 * @version $Revision: 664175 $, $Date: 2008-06-06 18:43:44 -0400 (Fri, 06 Jun 2008) $ 035 */ 036 037 public class CompressionServletResponseWrapper extends HttpServletResponseWrapper { 038 039 // ----------------------------------------------------- Constructor 040 041 /** 042 * Calls the parent constructor which creates a ServletResponse adaptor 043 * wrapping the given response object. 044 */ 045 046 public CompressionServletResponseWrapper(HttpServletResponse response) { 047 super(response); 048 origResponse = response; 049 if (debug > 1) { 050 System.out.println("CompressionServletResponseWrapper constructor gets called"); 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 * @throws 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 // ------------------------------------------------ ServletResponse Methods 168 169 170 /** 171 * Flush the buffer and commit this response. 172 * 173 * @throws IOException if an input/output error occurs 174 */ 175 public void flushBuffer() throws IOException { 176 if (debug > 1) { 177 System.out.println("flush buffer @ CompressionServletResponseWrapper"); 178 } 179 ((CompressionResponseStream) stream).flush(); 180 181 } 182 183 /** 184 * Return the servlet output stream associated with this Response. 185 * 186 * @throws IllegalStateException if <code>getWriter</code> has 187 * already been called for this response 188 * @throws IOException if an input/output error occurs 189 */ 190 public ServletOutputStream getOutputStream() throws IOException { 191 192 if (writer != null) 193 throw new IllegalStateException("getWriter() has already been called for this response"); 194 195 if (stream == null) 196 stream = createOutputStream(); 197 if (debug > 1) { 198 System.out.println("stream is set to " + stream + " in getOutputStream"); 199 } 200 201 return (stream); 202 203 } 204 205 /** 206 * Return the writer associated with this Response. 207 * 208 * @throws IllegalStateException if <code>getOutputStream</code> has 209 * already been called for this response 210 * @throws IOException if an input/output error occurs 211 */ 212 public PrintWriter getWriter() throws IOException { 213 214 if (writer != null) 215 return (writer); 216 217 if (stream != null) 218 throw new IllegalStateException("getOutputStream() has already been called for this response"); 219 220 stream = createOutputStream(); 221 if (debug > 1) { 222 System.out.println("stream is set to " + stream + " in getWriter"); 223 } 224 //String charset = getCharsetFromContentType(contentType); 225 String charEnc = origResponse.getCharacterEncoding(); 226 if (debug > 1) { 227 System.out.println("character encoding is " + charEnc); 228 } 229 // HttpServletResponse.getCharacterEncoding() shouldn't return null 230 // according the spec, so feel free to remove that "if" 231 if (charEnc != null) { 232 writer = new PrintWriter(new OutputStreamWriter(stream, charEnc)); 233 } else { 234 writer = new PrintWriter(stream); 235 } 236 237 return (writer); 238 239 } 240 241 242 public void setContentLength(int length) { 243 } 244 245 246 /** 247 * Returns character from content type. This method was taken from tomcat. 248 * 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 }