KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > cms > cache > CacheFilter


1 package info.magnolia.cms.cache;
2
3 import java.io.IOException JavaDoc;
4
5 import javax.servlet.Filter JavaDoc;
6 import javax.servlet.FilterChain JavaDoc;
7 import javax.servlet.FilterConfig JavaDoc;
8 import javax.servlet.ServletException JavaDoc;
9 import javax.servlet.ServletRequest JavaDoc;
10 import javax.servlet.ServletResponse JavaDoc;
11 import javax.servlet.http.HttpServletRequest JavaDoc;
12 import javax.servlet.http.HttpServletResponse JavaDoc;
13
14 import org.apache.commons.lang.StringUtils;
15
16
17 /**
18  * @author Andreas Brenk
19  * @author Fabrizio Giustina
20  * @since 3.0
21  */

22 public class CacheFilter implements Filter JavaDoc {
23
24     public static String JavaDoc ALREADY_FILTERED = CacheFilter.class.getName();
25
26     /**
27      * the cache manager.
28      */

29     private CacheManager cacheManager;
30
31     /**
32      * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
33      */

34     public void init(FilterConfig JavaDoc filterConfig) throws ServletException JavaDoc {
35         this.cacheManager = CacheManagerFactory.getCacheManager();
36     }
37
38     /**
39      * @see javax.servlet.Filter#destroy()
40      */

41     public void destroy() {
42         this.cacheManager = null;
43     }
44
45     /**
46      * @see javax.servlet.Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
47      */

48     public void doFilter(ServletRequest JavaDoc req, ServletResponse JavaDoc res, FilterChain JavaDoc chain) throws IOException JavaDoc,
49         ServletException JavaDoc {
50
51         if (cacheManager.isEnabled() && cacheManager.isRunning()) {
52             HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) req;
53             boolean cacheable = cacheManager.isCacheable(request);
54
55             // check if the request is cachable before trying to stream from cache.
56
// if the same page has already been requested before without parameters we should not fetch it from the
57
// cache
58
// if this time there are parameters.
59
if (cacheable) {
60                 HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) res;
61
62                 CacheKey key = cacheManager.getCacheKey(request);
63                 if (!this.ifModifiedSince((HttpServletRequest JavaDoc)req, cacheManager.getCreationTime(key))) {
64                     response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
65                     return;
66                 }
67                 boolean canCompress = cacheManager.canCompress(request);
68                 boolean usedCache = cacheManager.streamFromCache(key, response, canCompress
69                     && clientAcceptsGzip(request));
70                 if (!usedCache && !isAlreadyFiltered(request) && cacheManager.isCacheable(request)) {
71
72                     // mark the request as already filtered, avoid recursion
73
request.setAttribute(ALREADY_FILTERED, Boolean.TRUE);
74
75                     CacheResponseWrapper responseWrapper = new CacheResponseWrapper(response);
76
77                     chain.doFilter(request, responseWrapper);
78
79                     // if response has status 200 go cache it
80
if (responseWrapper.getStatus() == HttpServletResponse.SC_OK) {
81                         CacheableEntry cacheableEntry = responseWrapper.getCacheableEntry();
82                         if (cacheableEntry != null) {
83                             this.cacheManager.cacheRequest(key, cacheableEntry, canCompress);
84                         }
85                     }
86                     return;
87                 }
88                 else if (usedCache) {
89                     // dont forward, response has already been commited if usedCache is true.
90
return;
91                 }
92             }
93         }
94
95         // don't cache, just go on
96
chain.doFilter(req, res);
97
98     }
99
100     /**
101      * Check if server cache is newer then the client cache
102      *
103      * @param request The servlet request we are processing
104      * @return boolean true if the server resource is newer
105      */

106     private boolean ifModifiedSince(HttpServletRequest JavaDoc request, long lastModified) {
107         try {
108             long headerValue = request.getDateHeader("If-Modified-Since");
109             if (headerValue != -1) {
110                 // If an If-None-Match header has been specified, if modified since
111
// is ignored.
112
if ((request.getHeader("If-None-Match") == null)
113                     && (lastModified <= headerValue + 1000)) {
114                     return false;
115                 }
116             }
117         } catch(IllegalArgumentException JavaDoc illegalArgument) {
118             return true;
119         }
120         return true;
121     }
122
123     private boolean clientAcceptsGzip(HttpServletRequest JavaDoc request) {
124         return StringUtils.contains(request.getHeader("Accept-Encoding"), "gzip");
125     }
126
127     protected boolean isAlreadyFiltered(HttpServletRequest JavaDoc request) {
128         return request.getAttribute(ALREADY_FILTERED) != null;
129     }
130
131 }
132
Popular Tags