1 23 24 package org.enhydra.xml.xmlc.servlet; 25 26 import java.io.ByteArrayOutputStream ; 27 import java.io.IOException ; 28 import java.io.OutputStream ; 29 import java.io.PrintWriter ; 30 import java.io.StringWriter ; 31 import java.util.zip.GZIPOutputStream ; 32 33 import javax.servlet.ServletContext ; 34 import javax.servlet.http.HttpServlet ; 35 import javax.servlet.http.HttpServletRequest ; 36 import javax.servlet.http.HttpServletResponse ; 37 38 import org.enhydra.xml.dom.DOMStats; 39 import org.enhydra.xml.io.DOMFormatter; 40 import org.enhydra.xml.io.OutputOptions; 41 import org.enhydra.xml.io.URLRewriter; 42 import org.enhydra.xml.xmlc.XMLCFactory; 43 import org.enhydra.xml.xmlc.XMLObject; 44 45 133 public class XMLCContext { 134 138 public static final SessionURLEncodingMode URL_ENCODING_AUTO 139 = new SessionURLEncodingMode("auto"); 140 141 144 public static final SessionURLEncodingMode URL_ENCODING_ALWAYS 145 = new SessionURLEncodingMode("always"); 146 147 150 public static final SessionURLEncodingMode URL_ENCODING_NEVER 151 = new SessionURLEncodingMode("never"); 152 153 157 static public class SessionURLEncodingMode { 158 159 private final String fModeName; 160 161 162 private SessionURLEncodingMode(String modeName) { 163 fModeName = modeName; 164 } 165 166 167 public String toString() { 168 return fModeName; 169 } 170 } 171 172 176 public static final String CONTEXT_ATTRIBUTE 177 = "http://www.enhydra.org/xmlc/XMLCContext"; 178 179 182 private ServletContext fServletContext; 183 184 187 private XMLCFactory fFactory; 188 189 192 private SessionURLEncodingMode fSessionURLEncodingMode; 193 194 197 private boolean fLogStats; 198 199 202 private int fCompressionType; 203 204 207 static final int XMLC_COMPRESS_NONE = 0x00; 208 static final int XMLC_COMPRESS_GZIP = 0x01; 209 210 215 public XMLCContext(ServletContext servletContext, 216 XMLCFactory factory, 217 SessionURLEncodingMode sessionURLEncodingMode, 218 boolean logStats, 219 int compressionType) { 220 fServletContext = servletContext; 221 fFactory = factory; 222 fSessionURLEncodingMode = sessionURLEncodingMode; 223 fLogStats = logStats; 224 fCompressionType = compressionType; 225 } 226 227 230 public XMLCFactory getXMLCFactory() { 231 return fFactory; 232 } 233 234 239 public void setXMLCFactory(XMLCFactory factory) { 240 fFactory = factory; 241 } 242 243 251 public void setSessionURLEncoding(SessionURLEncodingMode mode) { 252 fSessionURLEncodingMode = mode; 253 } 254 255 261 public SessionURLEncodingMode getSessionURLEncoding() { 262 return fSessionURLEncodingMode; 263 } 264 265 268 protected boolean shouldEncodeSessionId(HttpServletRequest request) { 269 return (((fSessionURLEncodingMode == URL_ENCODING_AUTO) 274 && request.isRequestedSessionIdValid() 275 && !request.isRequestedSessionIdFromCookie()) 276 || (fSessionURLEncodingMode == URL_ENCODING_ALWAYS)); 277 } 278 279 283 protected URLRewriter setupURLRewriter(HttpServletRequest request, 284 final HttpServletResponse response) { 285 if (shouldEncodeSessionId(request)) { 286 return new URLRewriter() { 287 public String rewriteURL(String urlAttrValue) { 288 return response.encodeURL(urlAttrValue); 289 } 290 }; 291 } else { 292 return null; 293 } 294 } 295 296 300 private void setupEncoding(HttpServletResponse response, 301 XMLObject document, 302 OutputOptions options) { 303 304 if (options.getEncoding() == null) { 306 String encoding = document.getEncoding(); 308 if (encoding != null) { 309 options.setEncoding(encoding); 310 } 311 } 312 } 313 314 332 public OutputOptions createOutputOptions(HttpServletRequest request, 333 HttpServletResponse response, 334 XMLObject document) { 335 OutputOptions options = DOMFormatter.getDefaultOutputOptions(document); 336 337 setupEncoding(response, document, options); 338 339 options.setMIMEType(document.getMIMEType()); 341 342 options.setURLRewriter(setupURLRewriter(request, response)); 344 return options; 345 } 346 347 351 private void outputHeaders(HttpServletResponse response, 352 int docLength, 353 String mimeEncoding, 354 String mimeType, 355 boolean compressed) throws IOException { 356 357 response.setContentLength(docLength); 359 if (mimeType != null) { 360 if (mimeEncoding != null) { 361 response.setContentType(mimeType + "; charset=" + mimeEncoding); 362 } else { 363 response.setContentType(mimeType); 364 } 365 } 366 if (compressed) { 367 response.setHeader("Content-Encoding","gzip"); 368 } 369 370 if (response.containsHeader("Cache-Control")) { 372 response.setHeader("Cache-Control", "no-cache"); 373 } 374 if (response.containsHeader("Expires")) { 375 response.setHeader("Expires", "0"); 376 } 377 } 378 379 382 private void logDocumentStats(XMLObject document) { 383 StringWriter buf = new StringWriter (2048); 385 PrintWriter writer = new PrintWriter (buf); 386 DOMStats.printStats("Write " + document.getClass().getName(), 387 document, 0, writer); 388 writer.flush(); 389 fServletContext.log(buf.toString()); 390 } 391 392 397 private void outputDocument(HttpServletResponse response, 398 XMLObject document, 399 OutputOptions outputOptions, 400 boolean compress) throws IOException { 401 402 DOMFormatter formatter = new DOMFormatter(outputOptions); 404 byte[] docBytes = null; 405 if (compress) { 406 ByteArrayOutputStream bos = new ByteArrayOutputStream (); 407 GZIPOutputStream os = new GZIPOutputStream (bos); 408 formatter.write(document, os); 409 os.finish(); 410 docBytes = bos.toByteArray(); 411 } else { 412 docBytes = formatter.toBytes(document); 413 } 414 415 outputHeaders(response, docBytes.length, 416 outputOptions.getMIMEEncoding(), 417 outputOptions.getMIMEType(), 418 compress); 419 420 if (fLogStats) { 422 logDocumentStats(document); 423 } 424 425 OutputStream out = response.getOutputStream(); 427 out.write(docBytes); 428 out.flush(); 429 } 430 431 445 public void writeDOM(HttpServletRequest request, 446 HttpServletResponse response, 447 OutputOptions outputOptions, 448 XMLObject document) throws IOException { 449 OutputOptions options = new OutputOptions(outputOptions); 451 setupEncoding(response, document, options); 452 if (options.getMIMEType() == null) { 454 options.setMIMEType(document.getMIMEType()); 455 } 456 457 if (options.getURLRewriter() == null) { 460 options.setURLRewriter(setupURLRewriter(request, response)); 461 } 462 outputDocument(response, document, options, useCompression(request)); 463 } 464 465 468 private boolean useCompression(HttpServletRequest request) { 469 boolean compress = false; 471 if ((fCompressionType & XMLC_COMPRESS_GZIP) != 0) { 472 String enc = request.getHeader("Accept-Encoding"); 473 if (enc != null) { 474 int pos = enc.indexOf("gzip"); 475 compress = (pos > -1); 481 } 482 } 483 return compress; 484 } 485 486 498 public void writeDOM(HttpServletRequest request, 499 HttpServletResponse response, 500 XMLObject document) throws IOException { 501 OutputOptions options 502 = createOutputOptions(request, response, document); 503 outputDocument(response, document, options, useCompression(request)); 504 } 505 506 514 public static XMLCContext getContext(HttpServlet servlet) { 515 ServletContext servletContext = servlet.getServletContext(); 516 return getContext(servletContext); 517 } 518 519 526 public static XMLCContext getContext(ServletContext servletContext) { 527 XMLCContext context = (XMLCContext)servletContext.getAttribute(CONTEXT_ATTRIBUTE); 537 if (context == null) { 538 context = new XMLCContextInit().createContext(servletContext); 539 servletContext.setAttribute(CONTEXT_ATTRIBUTE, context); 540 } 541 return (XMLCContext)servletContext.getAttribute(CONTEXT_ATTRIBUTE); 542 } 543 544 545 546 protected ServletContext getServletContext() { return fServletContext; } 547 } 548 | Popular Tags |