001 /* 002 * Copyright 2004 The Apache Software Foundation 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package compressionFilters; 018 019 import java.io.IOException; 020 import java.io.OutputStream; 021 import java.io.OutputStreamWriter; 022 import java.io.PrintWriter; 023 import java.util.Locale; 024 import javax.servlet.ServletRequest; 025 import javax.servlet.ServletResponse; 026 import javax.servlet.ServletException; 027 import javax.servlet.ServletOutputStream; 028 import javax.servlet.ServletResponse; 029 import javax.servlet.ServletResponseWrapper; 030 import javax.servlet.http.HttpServletResponse; 031 import javax.servlet.http.HttpServletResponseWrapper; 032 033 /** 034 * Implementation of <b>HttpServletResponseWrapper</b> that works with 035 * the CompressionServletResponseStream implementation.. 036 * 037 * @author Amy Roh 038 * @author Dmitri Valdin 039 * @version $Revision: 267129 $, $Date: 2004-03-18 08:40:35 -0800 (Thu, 18 Mar 2004) $ 040 */ 041 042 public class CompressionServletResponseWrapper extends HttpServletResponseWrapper { 043 044 // ----------------------------------------------------- Constructor 045 046 /** 047 * Calls the parent constructor which creates a ServletResponse adaptor 048 * wrapping the given response object. 049 */ 050 051 public CompressionServletResponseWrapper(HttpServletResponse response) { 052 super(response); 053 origResponse = response; 054 if (debug > 1) { 055 System.out.println("CompressionServletResponseWrapper constructor gets called"); 056 } 057 } 058 059 060 // ----------------------------------------------------- Instance Variables 061 062 /** 063 * Original response 064 */ 065 066 protected HttpServletResponse origResponse = null; 067 068 /** 069 * Descriptive information about this Response implementation. 070 */ 071 072 protected static final String info = "CompressionServletResponseWrapper"; 073 074 /** 075 * The ServletOutputStream that has been returned by 076 * <code>getOutputStream()</code>, if any. 077 */ 078 079 protected ServletOutputStream stream = null; 080 081 082 /** 083 * The PrintWriter that has been returned by 084 * <code>getWriter()</code>, if any. 085 */ 086 087 protected PrintWriter writer = null; 088 089 /** 090 * The threshold number to compress 091 */ 092 protected int threshold = 0; 093 094 /** 095 * Debug level 096 */ 097 private int debug = 0; 098 099 /** 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 }