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 package compressionFilters; 018 019 import java.io.IOException; 020 import java.io.OutputStreamWriter; 021 import java.io.PrintWriter; 022 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: 664175 $, $Date: 2008-06-06 18:43:44 -0400 (Fri, 06 Jun 2008) $ 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 // ----------------------------------------------------- Instance Variables 054 055 /** 056 * Original response 057 */ 058 059 protected HttpServletResponse origResponse = null; 060 061 /** 062 * Descriptive information about this Response implementation. 063 */ 064 065 protected static final String info = "CompressionServletResponseWrapper"; 066 067 /** 068 * The ServletOutputStream that has been returned by 069 * <code>getOutputStream()</code>, if any. 070 */ 071 072 protected ServletOutputStream stream = null; 073 074 075 /** 076 * The PrintWriter that has been returned by 077 * <code>getWriter()</code>, if any. 078 */ 079 080 protected PrintWriter writer = null; 081 082 /** 083 * The threshold number to compress 084 */ 085 protected int threshold = 0; 086 087 /** 088 * Debug level 089 */ 090 private int debug = 0; 091 092 /** 093 * Content type 094 */ 095 protected String contentType = null; 096 097 // --------------------------------------------------------- Public Methods 098 099 100 /** 101 * Set content type 102 */ 103 public void setContentType(String contentType) { 104 if (debug > 1) { 105 System.out.println("setContentType to " + contentType); 106 } 107 this.contentType = contentType; 108 origResponse.setContentType(contentType); 109 } 110 111 112 /** 113 * Set threshold number 114 */ 115 public void setCompressionThreshold(int threshold) { 116 if (debug > 1) { 117 System.out.println("setCompressionThreshold to " + threshold); 118 } 119 this.threshold = threshold; 120 } 121 122 123 /** 124 * Set debug level 125 */ 126 public void setDebugLevel(int debug) { 127 this.debug = debug; 128 } 129 130 131 /** 132 * Create and return a ServletOutputStream to write the content 133 * associated with this Response. 134 * 135 * @throws IOException if an input/output error occurs 136 */ 137 public ServletOutputStream createOutputStream() throws IOException { 138 if (debug > 1) { 139 System.out.println("createOutputStream gets called"); 140 } 141 142 CompressionResponseStream stream = new CompressionResponseStream(origResponse); 143 stream.setDebugLevel(debug); 144 stream.setBuffer(threshold); 145 146 return stream; 147 148 } 149 150 151 /** 152 * Finish a response. 153 */ 154 public void finishResponse() { 155 try { 156 if (writer != null) { 157 writer.close(); 158 } else { 159 if (stream != null) 160 stream.close(); 161 } 162 } catch (IOException e) { 163 } 164 } 165 166 // ------------------------------------------------ ServletResponse Methods 167 168 169 /** 170 * Flush the buffer and commit this response. 171 * 172 * @throws IOException if an input/output error occurs 173 */ 174 public void flushBuffer() throws IOException { 175 if (debug > 1) { 176 System.out.println("flush buffer @ CompressionServletResponseWrapper"); 177 } 178 ((CompressionResponseStream) stream).flush(); 179 180 } 181 182 /** 183 * Return the servlet output stream associated with this Response. 184 * 185 * @throws IllegalStateException if <code>getWriter</code> has 186 * already been called for this response 187 * @throws IOException if an input/output error occurs 188 */ 189 public ServletOutputStream getOutputStream() throws IOException { 190 191 if (writer != null) 192 throw new IllegalStateException("getWriter() has already been called for this response"); 193 194 if (stream == null) 195 stream = createOutputStream(); 196 if (debug > 1) { 197 System.out.println("stream is set to " + stream + " in getOutputStream"); 198 } 199 200 return (stream); 201 202 } 203 204 /** 205 * Return the writer associated with this Response. 206 * 207 * @throws IllegalStateException if <code>getOutputStream</code> has 208 * already been called for this response 209 * @throws IOException if an input/output error occurs 210 */ 211 public PrintWriter getWriter() throws IOException { 212 213 if (writer != null) 214 return (writer); 215 216 if (stream != null) 217 throw new IllegalStateException("getOutputStream() has already been called for this response"); 218 219 stream = createOutputStream(); 220 if (debug > 1) { 221 System.out.println("stream is set to " + stream + " in getWriter"); 222 } 223 //String charset = getCharsetFromContentType(contentType); 224 String charEnc = origResponse.getCharacterEncoding(); 225 if (debug > 1) { 226 System.out.println("character encoding is " + charEnc); 227 } 228 // HttpServletResponse.getCharacterEncoding() shouldn't return null 229 // according the spec, so feel free to remove that "if" 230 if (charEnc != null) { 231 writer = new PrintWriter(new OutputStreamWriter(stream, charEnc)); 232 } else { 233 writer = new PrintWriter(stream); 234 } 235 236 return (writer); 237 238 } 239 240 241 public void setContentLength(int length) { 242 } 243 244 245 /** 246 * Returns character from content type. This method was taken from tomcat. 247 * 248 * @author rajo 249 */ 250 private static String getCharsetFromContentType(String type) { 251 252 if (type == null) { 253 return null; 254 } 255 int semi = type.indexOf(";"); 256 if (semi == -1) { 257 return null; 258 } 259 String afterSemi = type.substring(semi + 1); 260 int charsetLocation = afterSemi.indexOf("charset="); 261 if (charsetLocation == -1) { 262 return null; 263 } else { 264 String afterCharset = afterSemi.substring(charsetLocation + 8); 265 String encoding = afterCharset.trim(); 266 return encoding; 267 } 268 } 269 270 }