1 4 package com.opensymphony.module.sitemesh.filter; 5 6 import com.opensymphony.module.sitemesh.Factory; 7 import com.opensymphony.module.sitemesh.Page; 8 9 import javax.servlet.ServletOutputStream ; 10 import javax.servlet.http.HttpServletResponse ; 11 import javax.servlet.http.HttpServletResponseWrapper ; 12 import java.io.IOException ; 13 import java.io.PrintWriter ; 14 15 26 public final class PageResponseWrapper extends HttpServletResponseWrapper { 27 28 private final RoutablePrintWriter routablePrintWriter; 29 private final RoutableServletOutputStream routableServletOutputStream; 30 private final Factory factory; 31 32 private Buffer buffer; 33 private boolean aborted = false; 34 private boolean parseablePage = false; 35 36 public PageResponseWrapper(final HttpServletResponse response, Factory factory) { 37 super(response); 38 this.factory = factory; 39 40 routablePrintWriter = new RoutablePrintWriter(new RoutablePrintWriter.DestinationFactory() { 41 public PrintWriter activateDestination() throws IOException { 42 return response.getWriter(); 43 } 44 }); 45 routableServletOutputStream = new RoutableServletOutputStream(new RoutableServletOutputStream.DestinationFactory() { 46 public ServletOutputStream create() throws IOException { 47 return response.getOutputStream(); 48 } 49 }); 50 } 51 52 56 public void setContentType(String type) { 57 super.setContentType(type); 58 59 if (type != null) { 60 int offset = type.lastIndexOf("charset="); 62 String encoding = null; 63 if (offset != -1) 64 encoding = extractContentTypeValue(type, offset + 8); 65 String contentType = extractContentTypeValue(type, 0); 66 67 if (factory.shouldParsePage(contentType)) { 68 activateSiteMesh(contentType, encoding); 69 } 70 } 71 72 } 73 74 private void activateSiteMesh(String contentType, String encoding) { 75 if (parseablePage) { 76 return; } 78 parseablePage = true; 79 buffer = new Buffer(factory, contentType, encoding); 80 routablePrintWriter.updateDestination(new RoutablePrintWriter.DestinationFactory() { 81 public PrintWriter activateDestination() { 82 return buffer.getWriter(); 83 } 84 }); 85 routableServletOutputStream.updateDestination(new RoutableServletOutputStream.DestinationFactory() { 86 public ServletOutputStream create() { 87 return buffer.getOutputStream(); 88 } 89 }); 90 } 91 92 private String extractContentTypeValue(String type, int startIndex) { 93 if (startIndex < 0) 94 return null; 95 96 while (startIndex < type.length() && type.charAt(startIndex) == ' ') 98 startIndex++; 99 100 if (startIndex >= type.length()) 101 return null; 102 103 int endIndex = startIndex; 104 105 if (type.charAt(startIndex) == '"') { 106 startIndex++; 107 endIndex = type.indexOf('"', startIndex); 108 if (endIndex == -1) 109 endIndex = type.length(); 110 } else { 111 char ch; 115 while (endIndex < type.length() && (ch = type.charAt(endIndex)) != ' ' && ch != ';' 116 && ch != '(' && ch != ')' && ch != '[' && ch != ']' && ch != '<' && ch != '>' 117 && ch != ':' && ch != ',' && ch != '=' && ch != '?' && ch != '@' && ch!= '"' 118 && ch !='\\') 119 endIndex++; 120 } 121 return type.substring(startIndex, endIndex); 122 } 123 124 125 public void setContentLength(int contentLength) { 126 if (!parseablePage) super.setContentLength(contentLength); 127 } 128 129 130 public void setHeader(String name, String value) { 131 if (name.toLowerCase().equals("content-type")) { setContentType(value); 133 } else if (!parseablePage || !name.toLowerCase().equals("content-length")) { 134 super.setHeader(name, value); 135 } 136 } 137 138 139 public void addHeader(String name, String value) { 140 if (name.toLowerCase().equals("content-type")) { setContentType(value); 142 } else if (!parseablePage || !name.toLowerCase().equals("content-length")) { 143 super.addHeader(name, value); 144 } 145 } 146 147 151 public void setStatus(int sc) { 152 if (!parseablePage || sc != HttpServletResponse.SC_NOT_MODIFIED) { 153 super.setStatus(sc); 154 } 155 } 156 157 public ServletOutputStream getOutputStream() { 158 return routableServletOutputStream; 159 } 160 161 public PrintWriter getWriter() { 162 return routablePrintWriter; 163 } 164 165 public Page getPage() throws IOException { 166 if (aborted || !parseablePage) { 167 return null; 168 } else { 169 return buffer.parse(); 170 } 171 } 172 173 public void sendError(int sc) throws IOException { 174 aborted = true; 175 super.sendError(sc); 176 } 177 178 public void sendError(int sc, String msg) throws IOException { 179 aborted = true; 180 super.sendError(sc, msg); 181 } 182 183 public void sendRedirect(String location) throws IOException { 184 aborted = true; 185 super.sendRedirect(location); 186 } 187 188 public boolean isUsingStream() { 189 return buffer != null && buffer.isUsingStream(); 190 } 191 } | Popular Tags |