1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.portal.service.cache;
35
36 import fr.paris.lutece.portal.service.page.PageEvent;
37 import fr.paris.lutece.portal.service.page.PageEventListener;
38 import fr.paris.lutece.portal.service.page.PageService;
39
40 import net.sf.ehcache.Cache;
41 import net.sf.ehcache.CacheException;
42 import net.sf.ehcache.CacheManager;
43 import net.sf.ehcache.Ehcache;
44 import net.sf.ehcache.constructs.blocking.BlockingCache;
45 import net.sf.ehcache.constructs.blocking.LockTimeoutException;
46 import net.sf.ehcache.constructs.web.AlreadyCommittedException;
47 import net.sf.ehcache.constructs.web.AlreadyGzippedException;
48 import net.sf.ehcache.constructs.web.filter.FilterNonReentrantException;
49 import net.sf.ehcache.constructs.web.filter.SimpleCachingHeadersPageCachingFilter;
50
51 import org.apache.log4j.Logger;
52
53 import java.util.List;
54
55 import javax.servlet.FilterChain;
56 import javax.servlet.FilterConfig;
57 import javax.servlet.http.HttpServletRequest;
58 import javax.servlet.http.HttpServletResponse;
59
60
61
62
63
64
65 public class HeadersPageCachingFilter extends SimpleCachingHeadersPageCachingFilter implements CacheableService,
66 PageEventListener
67 {
68 private static final String BLOCKING_TIMEOUT_MILLIS = "blockingTimeoutMillis";
69 private static final String INIT_PARAM_CACHE_NAME = "cacheName";
70 private Cache _cache;
71 private Logger _logger = Logger.getLogger( "lutece.cache" );
72 private boolean _bInit;
73 private boolean _bEnable = true;
74 private String _strCacheName;
75
76
77
78
79 @Override
80 public void doInit( FilterConfig filterConfig ) throws CacheException
81 {
82
83
84
85 }
86
87
88
89
90 private void init( )
91 {
92
93 synchronized ( HeadersPageCachingFilter.class )
94 {
95 if ( blockingCache == null )
96 {
97 _strCacheName = filterConfig.getInitParameter( INIT_PARAM_CACHE_NAME );
98 CacheService.getInstance( ).createCache( _strCacheName );
99 _cache = CacheManager.getInstance( ).getCache( _strCacheName );
100 CacheService.registerCacheableService( this );
101 _logger.debug( "Initializing cache : " + _strCacheName );
102
103 setCacheNameIfAnyConfigured( filterConfig );
104
105 final String localCacheName = getCacheName( );
106 Ehcache cache = getCacheManager( ).getEhcache( localCacheName );
107
108 if ( cache == null )
109 {
110 throw new CacheException( "cache '" + localCacheName + "' not found in configuration" );
111 }
112
113 if ( !( cache instanceof BlockingCache ) )
114 {
115
116 BlockingCache newBlockingCache = new BlockingCache( cache );
117 getCacheManager( ).replaceCacheWithDecoratedCache( cache, newBlockingCache );
118 }
119
120 blockingCache = (BlockingCache) getCacheManager( ).getEhcache( localCacheName );
121
122 Integer blockingTimeoutMillis = parseBlockingCacheTimeoutMillis( filterConfig );
123
124 if ( ( blockingTimeoutMillis != null ) && ( blockingTimeoutMillis > 0 ) )
125 {
126 blockingCache.setTimeoutMillis( blockingTimeoutMillis );
127 }
128 }
129
130 PageService.addPageEventListener( this );
131 }
132
133 _bInit = true;
134 }
135
136
137
138
139
140
141
142
143
144 private Integer parseBlockingCacheTimeoutMillis( FilterConfig filterConfig )
145 {
146 String timeout = filterConfig.getInitParameter( BLOCKING_TIMEOUT_MILLIS );
147
148 try
149 {
150 return Integer.parseInt( timeout );
151 }
152 catch ( NumberFormatException e )
153 {
154 return null;
155 }
156 }
157
158
159
160
161 @Override
162 protected String getCacheName( )
163 {
164 return _strCacheName;
165 }
166
167
168
169
170 @Override
171 protected void doFilter( HttpServletRequest request, HttpServletResponse response, FilterChain chain )
172 throws AlreadyGzippedException, AlreadyCommittedException, FilterNonReentrantException, LockTimeoutException,
173 Exception
174 {
175 if ( !_bInit )
176 {
177 init( );
178 }
179
180 if ( _bEnable )
181 {
182 super.doFilter( request, response, chain );
183 _logger.debug( "URI served from cache : " + request.getRequestURI( ) );
184 }
185 else
186 {
187 chain.doFilter( request, response );
188 }
189 }
190
191
192
193
194
195 @Override
196 public boolean isCacheEnable( )
197 {
198 return _bEnable;
199 }
200
201
202
203
204 @Override
205 public int getCacheSize( )
206 {
207 return _cache.getSize( );
208 }
209
210
211
212
213 @Override
214 public void resetCache( )
215 {
216 _cache.removeAll( );
217 }
218
219
220
221
222 @Override
223 public String getName( )
224 {
225 return _strCacheName;
226 }
227
228
229
230
231 @Override
232 public void enableCache( boolean bEnable )
233 {
234 _bEnable = bEnable;
235
236 if ( ( !_bEnable ) && ( _cache != null ) )
237 {
238 _cache.removeAll( );
239 }
240
241 CacheService.updateCacheStatus( this );
242 }
243
244
245
246
247 @Override
248 public List<String> getKeys( )
249 {
250 return _cache.getKeys( );
251 }
252
253
254
255
256 @Override
257 public int getMaxElements( )
258 {
259 return _cache.getCacheConfiguration( ).getMaxElementsInMemory( );
260 }
261
262
263
264
265 @Override
266 public long getTimeToLive( )
267 {
268 return _cache.getCacheConfiguration( ).getTimeToLiveSeconds( );
269 }
270
271
272
273
274 @Override
275 public long getMemorySize( )
276 {
277 return _cache.calculateInMemorySize( );
278 }
279
280
281
282
283 @Override
284 public String getInfos( )
285 {
286 return CacheService.getInfos( _cache );
287 }
288
289
290
291
292 @Override
293 public void processPageEvent( PageEvent event )
294 {
295 String strPattern = "page_id=" + event.getPage( ).getId( );
296
297 for ( String strKey : (List<String>) blockingCache.getKeys( ) )
298 {
299 if ( strKey.contains( strPattern ) && ( event.getEventType( ) != PageEvent.PAGE_CREATED ) )
300 {
301 blockingCache.remove( strKey );
302 }
303 }
304 }
305 }