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 package compressionFilters; 017 018 import java.io.IOException; 019 import java.io.OutputStream; 020 import java.io.OutputStreamWriter; 021 import java.io.PrintWriter; 022 import java.util.Locale; 023 import javax.servlet.ServletRequest; 024 import javax.servlet.ServletResponse; 025 import javax.servlet.ServletException; 026 import javax.servlet.ServletOutputStream; 027 import javax.servlet.ServletResponse; 028 import javax.servlet.ServletResponseWrapper; 029 import javax.servlet.http.HttpServletResponse; 030 import javax.servlet.http.HttpServletResponseWrapper; 031 032 /** 033 * Implementation of <b>HttpServletResponseWrapper</b> that works with 034 * the CompressionServletResponseStream implementation.. 035 * 036 * @author Amy Roh 037 * @author Dmitri Valdin 038 * @version $Revision: 267129 $, $Date: 2004-03-18 08:40:35 -0800 (Thu, 18 Mar 2004) $ 039 */ 040 041 public class CompressionServletResponseWrapper extends HttpServletResponseWrapper { 042 043 // ----------------------------------------------------- Constructor 044 045 /** 046 * Calls the parent constructor which creates a ServletResponse adaptor 047 * wrapping the given response object. 048 */ 049 050 public CompressionServletResponseWrapper(HttpServletResponse response) { 051 super(response); 052 origResponse = response; 053 if (debug > 1) { 054 System.out.println("CompressionServletResponseWrapper constructor gets called"); 055 } 056 } 057 058 059 // ----------------------------------------------------- Instance Variables 060 061 /** 062 * Original response 063 */ 064 065 protected HttpServletResponse origResponse = null; 066 067 /** 068 * Descriptive information about this Response implementation. 069 */ 070 071 protected static final String info = "CompressionServletResponseWrapper"; 072 073 /** 074 * The ServletOutputStream that has been returned by 075 * <code>getOutputStream()</code>, if any. 076 */ 077 078 protected ServletOutputStream stream = null; 079 080 081 /** 082 * The PrintWriter that has been returned by 083 * <code>getWriter()</code>, if any. 084 */ 085 086 protected PrintWriter writer = null; 087 088 /** 089 * The threshold number to compress 090 */ 091 protected int threshold = 0; 092 093 /** 094 * Debug level 095 */ 096 private int debug = 0; 097 098 /** 099 * 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 }