1 23 24 package com.sun.appserv.web.cache.filter; 25 26 import java.io.IOException ; 27 28 import java.text.MessageFormat ; 29 30 import java.util.ArrayList ; 31 import java.util.Iterator ; 32 33 import java.util.logging.Logger ; 34 import java.util.logging.Level ; 35 import java.util.ResourceBundle ; 36 37 import javax.servlet.ServletContext ; 38 import javax.servlet.ServletRequest ; 39 import javax.servlet.ServletResponse ; 40 import javax.servlet.ServletException ; 41 import javax.servlet.ServletOutputStream ; 42 import javax.servlet.Filter ; 43 import javax.servlet.FilterConfig ; 44 import javax.servlet.FilterChain ; 45 46 import javax.servlet.http.HttpServletRequest ; 47 import javax.servlet.http.HttpServletResponse ; 48 import javax.servlet.http.HttpServletResponseWrapper ; 49 import javax.servlet.http.Cookie ; 50 51 import com.sun.enterprise.web.logging.pwc.LogDomains; 52 53 import com.sun.appserv.web.cache.CacheHelper; 54 import com.sun.appserv.web.cache.DefaultCacheHelper; 55 import com.sun.appserv.web.cache.CacheManager; 56 import com.sun.appserv.web.cache.CacheManagerListener; 57 58 import com.sun.appserv.util.cache.Cache; 59 60 public class CachingFilter implements Filter , CacheManagerListener { 61 62 String filterName; 64 String servletName; 65 String urlPattern; 66 67 CacheManager manager; 69 CacheHelper helper; 70 Cache cache; 71 72 boolean isEnabled = false; 73 74 private static Logger _logger = null; 75 private static boolean _isTraceEnabled = false; 76 77 85 public void init(FilterConfig filterConfig) throws ServletException { 86 87 filterName = filterConfig.getFilterName(); 88 servletName = filterConfig.getInitParameter("servletName"); 89 urlPattern = filterConfig.getInitParameter("URLPattern"); 90 91 ServletContext context = filterConfig.getServletContext(); 92 manager = (CacheManager) 93 context.getAttribute(CacheManager.CACHE_MANAGER_ATTR_NAME); 94 95 if (manager != null && manager.isEnabled()) { 96 this.cache = manager.getDefaultCache(); 97 this.helper = manager.getCacheHelperByFilterName(filterName); 98 99 manager.addCacheManagerListener(this); 101 isEnabled = true; 102 } 103 104 if (_logger == null) { 105 _logger = LogDomains.getLogger(LogDomains.PWC_LOGGER); 106 _isTraceEnabled = _logger.isLoggable(Level.FINE); 107 } 108 109 if (_isTraceEnabled) { 110 _logger.fine("CachingFilter " + filterName + " ready; isEnabled = " + isEnabled + " manager = " + manager); 111 } 112 } 113 114 133 public void doFilter (ServletRequest srequest, ServletResponse sresponse, 134 FilterChain chain ) 135 throws IOException , ServletException { 136 String key; 137 HttpServletRequest request = (HttpServletRequest )srequest; 138 HttpServletResponse response = (HttpServletResponse )sresponse; 139 140 request.setAttribute(DefaultCacheHelper.ATTR_CACHING_FILTER_NAME, 141 filterName); 142 request.setAttribute(CacheHelper.ATTR_CACHE_MAPPED_SERVLET_NAME, 143 servletName); 144 request.setAttribute(CacheHelper.ATTR_CACHE_MAPPED_URL_PATTERN, 145 urlPattern); 146 147 if (isEnabled && helper.isCacheable((HttpServletRequest )request) && 148 (key = helper.getCacheKey(request)) != null) { 149 150 int index = cache.getIndex(key); 152 153 if (_isTraceEnabled) { 154 _logger.fine("CachingFilter " + request.getServletPath() + 155 " request is cacheable; key " + key + " index = " + index); 156 } 157 158 HttpCacheEntry entry = null; 159 boolean entryReady = false, waitForRefresh = true; 160 161 if (!helper.isRefreshNeeded(request)) { 163 do { 164 entry = (HttpCacheEntry) cache.get(key); 166 167 if (entry != null && entry.isValid()) { 168 entryReady = true; 170 break; 171 } 172 else { 173 178 waitForRefresh = cache.waitRefresh(index); 179 } 180 } while (waitForRefresh); 181 } else { 182 if (_isTraceEnabled) { 183 _logger.fine("CachingFilter " + request.getServletPath() + 184 " request needs a refresh; key " + key); 185 } 186 } 187 188 if (entryReady) { 190 if (_isTraceEnabled) { 191 _logger.fine("CachingFilter " + request.getServletPath() + 192 " serving response from the cache " + key); 193 } 194 sendCachedResponse(entry, response); 195 } else { 196 198 HttpCacheEntry oldEntry; 199 200 CachingResponseWrapper wrapper = 202 new CachingResponseWrapper(response); 203 204 try { 206 chain.doFilter(srequest, (ServletResponse )wrapper); 207 } catch (ServletException se) { 208 wrapper.clear(); 209 throw se; 210 } catch (IOException ioe) { 211 wrapper.clear(); 212 throw ioe; 213 } 214 215 if (!wrapper.isError()) { 217 219 int timeout = helper.getTimeout(request); 221 222 entry = wrapper.cacheResponse(); 224 225 if (timeout == CacheHelper.TIMEOUT_VALUE_NOT_SET) { 226 Long lval = wrapper.getExpiresDateHeader(); 228 229 if (lval == null) { 230 timeout = manager.getDefaultTimeout(); 231 entry.computeExpireTime(timeout); 232 } else { 233 long expireTime = lval.longValue(); 234 235 entry.setExpireTime(expireTime); 237 } 238 } else { 239 entry.computeExpireTime(timeout); 240 } 241 242 oldEntry = (HttpCacheEntry)cache.put(key, entry, 243 entry.getSize()); 244 cache.notifyRefresh(index); 245 246 writeBody(entry, response); 248 } else { 249 253 oldEntry = (HttpCacheEntry)cache.remove(key); 254 } 255 256 wrapper.clear(); 258 } 259 260 268 } else { 269 if (_isTraceEnabled) { 270 _logger.fine("CachingFilter " + request.getServletPath() + 271 " pass thru; isEnabled = " + isEnabled); 272 } 273 request.removeAttribute(DefaultCacheHelper.ATTR_CACHING_FILTER_NAME); 274 request.removeAttribute(CacheHelper.ATTR_CACHE_MAPPED_SERVLET_NAME); 275 request.removeAttribute(CacheHelper.ATTR_CACHE_MAPPED_URL_PATTERN); 276 277 chain.doFilter(srequest, sresponse); 279 } 280 } 281 282 288 private void sendCachedResponse(HttpCacheEntry entry, 289 HttpServletResponse response) 290 throws IOException { 291 if (entry.statusCode != HttpCacheEntry.VALUE_NOT_SET) { 293 response.setStatus(entry.statusCode); 294 } 295 296 for (Iterator iter = entry.responseHeaders.keySet().iterator(); 298 iter.hasNext(); ) { 299 String name = (String )iter.next(); 300 ArrayList values = (ArrayList )entry.responseHeaders.get(name); 301 302 for (int i = 0; i < values.size(); i++) { 303 response.addHeader(name, (String )values.get(i)); 304 } 305 } 306 307 for (Iterator iter = entry.dateHeaders.keySet().iterator(); 309 iter.hasNext(); ) { 310 String name = (String )iter.next(); 311 ArrayList values = (ArrayList )entry.dateHeaders.get(name); 312 313 for (int i = 0; i < values.size(); i++) { 314 response.addDateHeader(name, ((Long )values.get(i)).longValue()); 315 } 316 } 317 318 for (int i = 0; i < entry.cookies.size(); i++) { 320 response.addCookie((Cookie )entry.cookies.get(i)); 321 } 322 323 if (entry.contentLength != HttpCacheEntry.VALUE_NOT_SET) { 325 response.setContentLength(entry.contentLength); 326 } 327 if (entry.contentType != null) { 328 response.setContentType(entry.contentType); 329 } 330 if (entry.locale != null) { 331 response.setLocale(entry.locale); 332 } 333 334 writeBody(entry, response); 336 } 337 338 344 private void writeBody(HttpCacheEntry entry, 345 HttpServletResponse response) 346 throws IOException { 347 ServletOutputStream out = response.getOutputStream(); 348 out.write(entry.bytes); 349 } 350 351 354 public void cacheManagerEnabled() { 355 if (_isTraceEnabled) 356 _logger.fine("CachingFilter " + filterName + " received cacheManager enabled event."); 357 358 this.isEnabled = true; 359 } 360 361 364 public void cacheManagerDisabled() { 365 if (_isTraceEnabled) 366 _logger.fine("CachingFilter " + filterName + " received cacheManager disabled event."); 367 368 this.isEnabled = false; 369 } 370 371 379 public void destroy() { 380 } 381 } 382 | Popular Tags |