1 10 package org.mmbase.util; 11 import java.io.*; 12 13 import javax.servlet.*; 14 import javax.servlet.http.*; 15 16 import java.util.Locale ; 17 import java.util.regex.*; 18 19 import org.mmbase.util.logging.Logger; 20 import org.mmbase.util.logging.Logging; 21 22 33 public class GenericResponseWrapper extends HttpServletResponseWrapper { 34 private static final Logger log = Logging.getLoggerInstance(GenericResponseWrapper.class); 35 36 40 private static final Pattern XMLHEADER = Pattern.compile("<\\?xml.*?(?:\\sencoding=(?:\"([^\"]+?)\"|'([^']+?)'))?\\s*\\?>.*", Pattern.DOTALL); 41 42 43 private static String UNSET_CHARSET = "iso-8859-1"; 44 public static String TEXT_XML_DEFAULT_CHARSET = "US-ASCII"; 45 46 private static String DEFAULT_CONTENTTYPE = "text/html"; 47 48 private static String [] IGNORED_HEADERS = new String []{"Last-Modified", "ETag"}; 49 50 private PrintWriter writer; 51 private StringWriter string; 53 private ServletOutputStream outputStream; private ByteArrayOutputStream bytes; 55 56 private String contentType = DEFAULT_CONTENTTYPE; 57 private String characterEncoding = UNSET_CHARSET; 58 59 private HttpServletResponse wrappedResponse; 60 61 64 public GenericResponseWrapper(HttpServletResponse resp) { 65 super(resp); 66 wrappedResponse = resp; 68 } 69 73 public GenericResponseWrapper(HttpServletResponse resp, String encoding) { 74 this(resp); 75 characterEncoding = encoding; 76 wrappedResponse = resp; } 78 79 80 85 public HttpServletResponse getHttpServletResponse() { 86 HttpServletResponse response = wrappedResponse; 88 while (response instanceof GenericResponseWrapper) { response = ((GenericResponseWrapper) response).wrappedResponse; 90 } 91 return response; 92 } 93 94 private boolean mayAddHeader(String header) { 95 for (int i=0; i<IGNORED_HEADERS.length; i++) { 96 if (IGNORED_HEADERS[i].equalsIgnoreCase(header)) { 97 return false; 98 } 99 } 100 return true; 101 } 102 103 public void sendRedirect(String location) throws IOException { 104 getHttpServletResponse().sendRedirect(location); 105 } 106 107 public void setStatus(int s) { 108 getHttpServletResponse().setStatus(s); 109 } 110 111 public void addCookie(Cookie c) { 112 getHttpServletResponse().addCookie(c); 113 } 114 115 public void setHeader(String header, String value) { 116 if (mayAddHeader(header)) { 117 getHttpServletResponse().setHeader(header,value); 118 } 119 } 120 121 124 public void addDateHeader(String arg0, long arg1) { 125 if (mayAddHeader(arg0)) { 126 getHttpServletResponse().addDateHeader(arg0, arg1); 127 } 128 } 129 130 133 public void addHeader(String arg0, String arg1) { 134 if (mayAddHeader(arg0)) { 135 getHttpServletResponse().addHeader(arg0, arg1); 136 } 137 } 138 139 142 public void addIntHeader(String arg0, int arg1) { 143 if (mayAddHeader(arg0)) { 144 getHttpServletResponse().addIntHeader(arg0, arg1); 145 } 146 } 147 150 public boolean containsHeader(String arg0) { 151 return getHttpServletResponse().containsHeader(arg0); 152 } 153 156 public String encodeRedirectURL(String arg0) { 157 return getHttpServletResponse().encodeRedirectURL(arg0); 158 } 159 162 public String encodeURL(String arg0) { 163 return getHttpServletResponse().encodeURL(arg0); 164 } 165 168 public Locale getLocale() { 169 return getHttpServletResponse().getLocale(); 170 } 171 174 public void sendError(int arg0, String arg1) throws IOException { 175 getHttpServletResponse().sendError(arg0, arg1); 176 } 177 180 public void sendError(int arg0) throws IOException { 181 getHttpServletResponse().sendError(arg0); 182 } 183 186 public void setDateHeader(String arg0, long arg1) { 187 if (mayAddHeader(arg0)) { 188 getHttpServletResponse().setDateHeader(arg0, arg1); 189 } 190 } 191 194 public void setIntHeader(String arg0, int arg1) { 195 if (mayAddHeader(arg0)) { 196 getHttpServletResponse().setIntHeader(arg0, arg1); 197 } 198 } 199 202 public void setLocale(Locale arg0) { 203 getHttpServletResponse().setLocale(arg0); 204 } 205 206 209 public ServletOutputStream getOutputStream() throws IOException { 210 if (writer != null) { 211 throw new RuntimeException ("Should use getOutputStream _or_ getWriter"); 212 } 213 if (outputStream == null) { 214 bytes = new ByteArrayOutputStream(); 215 outputStream = new MyServletOutputStream(bytes); 216 } 217 return outputStream; 218 } 219 220 223 public PrintWriter getWriter() throws IOException { 224 if (outputStream != null) { 225 throw new RuntimeException ("Should use getOutputStream _or_ getWriter"); 226 } 227 if (writer == null) { 228 string = new StringWriter(); 229 writer = new PrintWriter(string); 230 } 231 return writer; 232 } 233 234 240 public void setContentType(String ct) { 241 if (ct == null) { 242 contentType = DEFAULT_CONTENTTYPE; 243 } else { 244 contentType = ct; 245 characterEncoding = getEncoding(ct); if (characterEncoding == null) { 247 characterEncoding = getDefaultEncoding(contentType); 248 } 249 } 250 251 if (log.isDebugEnabled()) { 252 log.debug("set contenttype of include page to: '" + contentType + "' (and character encoding to '" + characterEncoding + "')"); 253 } 254 } 255 256 262 public String getCharacterEncoding() { 263 log.debug(characterEncoding); 264 269 return characterEncoding; 270 } 271 272 protected byte[] determinXMLEncoding() { 273 byte[] allBytes = bytes.toByteArray(); 274 characterEncoding = getXMLEncoding(allBytes); 275 if (characterEncoding == null) characterEncoding = "UTF-8"; return allBytes; 277 } 278 279 282 public String toString() { 283 if (writer != null) { 284 return string.toString(); 285 } else if (outputStream != null) { 286 try { 287 byte[] allBytes; 288 if (TEXT_XML_DEFAULT_CHARSET.equals(characterEncoding)) { 289 allBytes = determinXMLEncoding(); 291 } else { 292 allBytes = bytes.toByteArray(); 293 } 294 return new String (allBytes, getCharacterEncoding()); 295 } catch (Exception e) { 296 return bytes.toString(); 297 } 298 } else { 299 return ""; 300 } 301 } 302 303 310 public static final String getXMLEncoding(String xmlString) { 311 Matcher m = XMLHEADER.matcher(xmlString); 312 if (! m.matches()) { 313 return null; } else { 315 String encoding = m.group(1); 316 if (encoding == null) encoding = m.group(2); 317 if (encoding == null) encoding = "UTF-8"; return encoding; 319 } 320 } 321 322 328 public static String getXMLEncoding(byte[] allBytes) { 329 byte[] firstBytes = allBytes; 330 if (allBytes.length > 100) { 331 firstBytes = new byte[100]; 332 System.arraycopy(allBytes, 0, firstBytes, 0, 100); 333 } 334 try { 335 return getXMLEncoding(new String (firstBytes, "US-ASCII")); 336 } catch (java.io.UnsupportedEncodingException uee) { 337 } 339 return "UTF-8"; } 341 342 347 public static String getEncoding(String contentType) { 348 String contentTypeLowerCase = contentType.toLowerCase(); 349 int cs = contentTypeLowerCase.indexOf("charset="); 350 if (cs > 0) { 351 return contentType.substring(cs + 8); 352 } else { 353 return null; 354 } 355 } 356 357 363 public static String getDefaultEncoding(String contentType) { 364 if (contentType.equals("text/xml")) { 365 return TEXT_XML_DEFAULT_CHARSET; } else if ( contentType.equals("application/xml") || contentType.equals("application/xhtml+xml")) { 371 return "UTF-8"; 372 } else { 373 return "iso-8859-1"; 374 } 375 376 } 377 } 378 379 382 class MyServletOutputStream extends ServletOutputStream { 383 384 private OutputStream stream; 385 386 public MyServletOutputStream(OutputStream output) { 387 stream = output; 388 } 389 390 public void write(int b) throws IOException { 391 stream.write(b); 392 } 393 394 public void write(byte[] b) throws IOException { 395 stream.write(b); 396 } 397 398 public void write(byte[] b, int off, int len) throws IOException { 399 stream.write(b, off, len); 400 } 401 } 402 403 | Popular Tags |