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 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: 514091 $, $Date: 2007-03-03 01:26:39 -0500 (Sat, 03 Mar 2007) $ 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 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 * @exception 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 168 // ------------------------------------------------ ServletResponse Methods 169 170 171 /** 172 * Flush the buffer and commit this response. 173 * 174 * @exception IOException if an input/output error occurs 175 */ 176 public void flushBuffer() throws IOException { 177 if (debug > 1) { 178 System.out.println("flush buffer @ CompressionServletResponseWrapper"); 179 } 180 ((CompressionResponseStream)stream).flush(); 181 182 } 183 184 /** 185 * Return the servlet output stream associated with this Response. 186 * 187 * @exception IllegalStateException if <code>getWriter</code> has 188 * already been called for this response 189 * @exception IOException if an input/output error occurs 190 */ 191 public ServletOutputStream getOutputStream() throws IOException { 192 193 if (writer != null) 194 throw new IllegalStateException("getWriter() has already been called for this response"); 195 196 if (stream == null) 197 stream = createOutputStream(); 198 if (debug > 1) { 199 System.out.println("stream is set to "+stream+" in getOutputStream"); 200 } 201 202 return (stream); 203 204 } 205 206 /** 207 * Return the writer associated with this Response. 208 * 209 * @exception IllegalStateException if <code>getOutputStream</code> has 210 * already been called for this response 211 * @exception IOException if an input/output error occurs 212 */ 213 public PrintWriter getWriter() throws IOException { 214 215 if (writer != null) 216 return (writer); 217 218 if (stream != null) 219 throw new IllegalStateException("getOutputStream() has already been called for this response"); 220 221 stream = createOutputStream(); 222 if (debug > 1) { 223 System.out.println("stream is set to "+stream+" in getWriter"); 224 } 225 //String charset = getCharsetFromContentType(contentType); 226 String charEnc = origResponse.getCharacterEncoding(); 227 if (debug > 1) { 228 System.out.println("character encoding is " + charEnc); 229 } 230 // HttpServletResponse.getCharacterEncoding() shouldn't return null 231 // according the spec, so feel free to remove that "if" 232 if (charEnc != null) { 233 writer = new PrintWriter(new OutputStreamWriter(stream, charEnc)); 234 } else { 235 writer = new PrintWriter(stream); 236 } 237 238 return (writer); 239 240 } 241 242 243 public void setContentLength(int length) { 244 } 245 246 247 /** 248 * Returns character from content type. This method was taken from tomcat. 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 }