KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > services > cache > CacheFactory


1 /*
2  * ____.
3  * __/\ ______| |__/\. _______
4  * __ .____| | \ | +----+ \
5  * _______| /--| | | - \ _ | : - \_________
6  * \\______: :---| : : | : | \________>
7  * |__\---\_____________:______: :____|____:_____\
8  * /_____|
9  *
10  * . . . i n j a h i a w e t r u s t . . .
11  *
12  *
13  *
14  * ----- BEGIN LICENSE BLOCK -----
15  * Version: JCSL 1.0
16  *
17  * The contents of this file are subject to the Jahia Community Source License
18  * 1.0 or later (the "License"); you may not use this file except in
19  * compliance with the License. You may obtain a copy of the License at
20  * http://www.jahia.org/license
21  *
22  * Software distributed under the License is distributed on an "AS IS" basis,
23  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
24  * for the rights, obligations and limitations governing use of the contents
25  * of the file. The Original and Upgraded Code is the Jahia CMS and Portal
26  * Server. The developer of the Original and Upgraded Code is JAHIA Ltd. JAHIA
27  * Ltd. owns the copyrights in the portions it created. All Rights Reserved.
28  *
29  * The Developer of the Shared Modifications is Jahia Solution Sarl.
30  * Portions created by the Initial Developer are Copyright (C) 2002 by the
31  * Initial Developer. All Rights Reserved.
32  *
33  * Contributor(s):
34  * 26-JUL-2003, Jahia Solutions Sarl, Fulco Houkes : Initial version
35  * 12-SEP-2003, Jahia Solutions Sarl, Serge Huber
36  *
37  * ----- END LICENSE BLOCK -----
38  */

39
40 package org.jahia.services.cache;
41
42 import java.util.HashMap JavaDoc;
43 import java.util.Iterator JavaDoc;
44 import java.util.Map JavaDoc;
45 import java.util.Set JavaDoc;
46
47 import org.apache.commons.collections.FastHashMap;
48 import org.apache.log4j.Logger;
49 import org.jahia.exceptions.JahiaException;
50 import org.jahia.exceptions.JahiaInitializationException;
51 import org.jahia.mbeans.JahiaMBeanServer;
52 import org.jahia.services.JahiaInitializableService;
53 import org.jahia.services.cache.simplecache.PersistenceCache;
54 import org.jahia.services.cache.simplecache.SimpleCache;
55 import org.jahia.services.cache.simplecache.SimpleHtmlCache;
56 import org.jahia.settings.SettingsBean;
57
58 /**
59  * <p>
60  * Here are the methods that should be called to create new instances of caches.
61  * </p>
62  *
63  * @author Fulco Houkes, Copyright (c) 2003 by Jahia Ltd.
64  * @version 1.0
65  * @since Jahia 4.0
66  *
67  * @see org.jahia.services.cache.Cache Cache
68  * @see org.jahia.services.cache.HtmlCache HtmlCache
69  */

70 public class CacheFactory extends JahiaInitializableService {
71
72     /** class unique instance. */
73     protected static CacheFactory instance;
74
75     /** logging. */
76     private static final Logger logger = Logger.getLogger(CacheFactory.class);
77
78     /** caches table. */
79     final protected HashMap JavaDoc caches = new FastHashMap(40);
80
81     /** the JMS hub to intercept and send cache synchronization messages. */
82     private JMSHub jmsHub = null;
83
84     // hashmap containing the cache size limits specified in Jahia config.
85
private Map JavaDoc cacheLimits = null;
86
87     private boolean JMXEnabled = true;
88     
89     protected boolean keyHierarchyEnabled = false;
90
91     /**
92      * Default constructor, creates a new <code>JahiaCacheFactory</code>
93      * instance.
94      */

95     protected CacheFactory() {
96     }
97
98     /**
99      * Initializes the Cache factory.
100      *
101      * @param jSettings
102      * the jahia private settings
103      *
104      * @exception JahiaInitializationException
105      * when the Cache Factory could not be initialized
106      */

107     public void init(SettingsBean jSettings) throws JahiaInitializationException {
108         // do nothing when settings are missing
109
if (jSettings == null)
110             return;
111
112         if (jSettings.lookupBoolean(SettingsBean.JMS_CACHE_ACTIVATION)) {
113             jmsHub = new JMSHub();
114             jmsHub.init(jSettings, this);
115         }
116
117         cacheLimits = jSettings.getJahiaMaxCachedValues();
118     }
119
120     // Javadoc inherited from parent
121
public synchronized void shutdown() throws JahiaException {
122         super.shutdown();
123
124         // flush the caches
125
// we deactivated this because on a cluster we don't want to flush
126
// on all nodes.
127
// flushAllCaches();
128
caches.clear();
129
130         if (jmsHub != null) {
131             // shut down the JMS Hub, and all it's related connections and
132
// resources.
133
jmsHub.disconnect();
134         }
135     }
136
137     /**
138      * Return the unique instance of this class.
139      *
140      * @return the class' unique instance.
141      */

142     public static synchronized CacheFactory getInstance() {
143         if (instance == null) {
144             instance = new CacheFactory();
145         }
146         return instance;
147     }
148
149     /**
150      * <p>
151      * Creates a new instance of type <code>Cache</code>.
152      * </p>
153      * <p>
154      * When the region is <code>null</code> the cache creation is canceled and
155      * a <code>null</code> instance will be returned.
156      * </p>
157      *
158      * @param name
159      * the cache region
160      *
161      * @return the new cache instance
162      *
163      * @exception JahiaInitializationException
164      * when the cache could not be initialized
165      */

166     public synchronized Cache createCacheInstance(String JavaDoc name) throws JahiaInitializationException {
167         // validity check
168
if (name == null)
169             return null;
170
171         // When the cache already exists in the factory, return the instance.
172
Cache cache = getCache(name);
173         if (cache != null) {
174             return cache;
175         }
176
177         // Get the factory instance
178
CacheFactory factory = this;
179         if (factory == null) {
180             logger.warn("Could not get the CacheFactory instance! ");
181             return null;
182         }
183
184         // instanciate the new cache, can throw an JahiaInitialization exception
185
cache = new SimpleCache(name, factory.jmsHub);
186         if (factory.cacheLimits.containsKey(name)) {
187             String JavaDoc limitStr = (String JavaDoc) factory.cacheLimits.get(name);
188             cache.setCacheLimit(Integer.parseInt(limitStr));
189         }
190         logger.debug("Created cache instance [" + name + "]");
191
192         if (registerCache(cache)) {
193             return cache;
194         }
195
196         cache = null;
197         return null;
198     }
199
200     /**
201      * <p>
202      * Creates a new instance of type <code>Cache</code> or
203      * <code>PersistenceCache</code> if the persistenceCacheable parameter is
204      * non-null.
205      * </p>
206      * <p>
207      * When the name is <code>null</code> the cache creation is canceled and a
208      * <code>null</code> instance will be returned.
209      * </p>
210      *
211      * @param name
212      * the cache name
213      *
214      * @param persistenceCacheable
215      * an <code>Object</code> that implements the
216      * {@link org.jahia.services.cache.PersistenceCacheable PersistenceCacheable}
217      * interface. If this is <code>null</code>, then a regular
218      * cache will be used, otherwise a
219      * <code>PersistenceCache<code> instance will be returned,
220      * that can be used to have persistence aware gets and puts.
221      *
222      * @return the new cache instance, of class Cache is the
223      * persistenceCacheable parameter is <code>null</code>, or of
224      * class <code>PersistenceCache</code> if it is non <code>null</code>.
225      *
226      * @exception JahiaInitializationException
227      * when the cache could not be initialized
228      */

229     public synchronized PersistenceCache createCacheInstance(String JavaDoc name, PersistenceCacheable persistenceCacheable)
230             throws JahiaInitializationException {
231         // validity check
232
if (name == null)
233             return null;
234
235         // When the cache already exists in the factory, return the instance.
236
Cache cache = getCache(name);
237         if (cache != null) {
238             if (cache instanceof PersistenceCache) {
239                 return (PersistenceCache) cache;
240
241             } else {
242                 logger.error("Cannot create new cache [" + name
243                         + "] because another non PersistenceCache cache holds already this name!");
244                 return null;
245             }
246         }
247
248         // Get the factory instance
249
CacheFactory factory = this;
250         if (factory == null) {
251             logger.warn("Could not get the CacheFactory instance! ");
252             return null;
253         }
254
255         cache = new PersistenceCache(name, factory.jmsHub, persistenceCacheable);
256         if (factory.cacheLimits.containsKey(name)) {
257             Integer JavaDoc limit = (Integer JavaDoc) factory.cacheLimits.get(name);
258             cache.setCacheLimit(limit.intValue());
259         }
260         logger.debug("Created persistence cache instance [" + name + "]");
261
262         if (registerCache(cache)) {
263             return (PersistenceCache) cache;
264         }
265
266         cache = null;
267         return null;
268     }
269
270     public static synchronized Cache createCache(String JavaDoc name) throws JahiaInitializationException {
271         return CacheFactory.getInstance().createCacheInstance(name);
272     }
273
274     public static synchronized PersistenceCache createCache(String JavaDoc name, PersistenceCacheable persistenceCacheable)
275             throws JahiaInitializationException {
276         return CacheFactory.getInstance().createCacheInstance(name, persistenceCacheable);
277     }
278
279     private boolean registerCache(Cache cache) {
280         // Add the cache to the table
281
caches.put(cache.getName(), cache);
282
283         if (isJMXEnabled()) {
284             // register the cache for JMX monitoring
285
JahiaMBeanServer.getInstance().registerManagedInstance(cache, "Cache", cache.getName());
286         }
287         return true;
288     }
289
290     /**
291      * <p>
292      * Retrieves the HTML cach instance.
293      * </p>
294      *
295      * <p>
296      * When the HTML cache is not present, a new instance is created and
297      * inserted into the factory.
298      * <p>
299      *
300      * @return the HTML cache instance
301      *
302      * @exception JahiaInitializationException
303      * when the HTML cache could not be instanciated and properly
304      * initialized
305      */

306     public static HtmlCache getHtmlCache() throws JahiaInitializationException {
307        
308         // if the Html cache already exists, then return the instance
309
HtmlCache cache = (HtmlCache) getCache(CacheFactory.getInstance(), HtmlCache.HTML_CACHE);
310         if (cache != null)
311             return cache;
312
313         return CacheFactory.getInstance().createHtmlCacheInstance();
314     }
315
316     public HtmlCache createHtmlCacheInstance() throws JahiaInitializationException {
317     
318     // At this point, the HTML cache does not exist, create it
319
SimpleHtmlCache cache = new SimpleHtmlCache(this.jmsHub);
320     if (this.cacheLimits.containsKey(HtmlCache.HTML_CACHE)) {
321         String JavaDoc limitStr = (String JavaDoc) this.cacheLimits.get(HtmlCache.HTML_CACHE);
322         cache.setCacheLimit(Integer.parseInt(limitStr));
323     }
324     this.caches.put(cache.getName(), cache);
325     
326     return cache;
327     }
328     
329     public Cache getCache(String JavaDoc name) {
330         if (name == null) {
331             return null;
332         }
333         return (Cache) caches.get(name);
334     }
335
336     /**
337      * <p>
338      * Retrieves the specified <code>region</code> cache.
339      * </p>
340      *
341      * @param name
342      * the cache region name, <code>null</code> is not allowed
343      *
344      * @return the cache instance
345      */

346     public static Cache getCache(CacheFactory factory, String JavaDoc name) {
347
348         if (factory == null) {
349             logger.warn("Could not get the CacheFactory instance! ");
350             return null;
351         }
352
353         return factory.getCache(name);
354     }
355
356     /**
357      * <p>
358      * Returns an iterator of all the cache names.
359      * </p>
360      *
361      * @return an iterator of all the cache names.
362      */

363     public Set JavaDoc getNames() {
364         return caches.keySet();
365     }
366
367     /**
368      * <p>
369      * Flush all the cache entries of all the registered caches.
370      * </p>
371      *
372      * <p>
373      * Use this method with caution as it may take a lot of CPU time, because
374      * the method is synchronized and each accessed cache has to be synchronized
375      * too.
376      * </p>
377      */

378     public synchronized void flushAllCaches() {
379
380         Iterator JavaDoc cacheNames = getNames().iterator();
381         while (cacheNames.hasNext()) {
382             String JavaDoc curCacheName = (String JavaDoc) cacheNames.next();
383             Cache cache = (Cache) caches.get(curCacheName);
384
385             cache.flush();
386         }
387
388         logger.info("Flushed all caches.");
389     }
390
391     /**
392      * <p>
393      * Checks if the cache synchronization is enabled.
394      * </p>
395      *
396      * @return <code>true</code> when the cache synchronization is enabled
397      */

398     public boolean isJMSEnabled() {
399         return (jmsHub != null);
400     }
401
402     /**
403      * <p>
404      * Enables the cache synchronization by initiating a connection to the JMS
405      * Server.
406      * </p>
407      *
408      * @throws JahiaInitializationException
409      * When the cache synchronization could not be succuessfully be
410      * initialized. The most probable cause is a wrong value for a
411      * configuration parameter.
412      */

413     public void enableJMSSynchronization() throws JahiaInitializationException {
414         if (jmsHub != null)
415             jmsHub.connect();
416     }
417
418     public void syncCachesNow() {
419         if (jmsHub != null)
420             jmsHub.sendMessagesNow();
421     }
422
423     /**
424      * <p>
425      * Disables the cache synchronization by closing all existing connections to
426      * the JMS Server.
427      * </p>
428      */

429     public void disableJMSSynchronization() {
430         if (jmsHub != null)
431             jmsHub.disconnect();
432     }
433
434     public boolean isJMXEnabled() {
435         return JMXEnabled;
436     }
437
438     public void setJMXEnabled(boolean isJMXEnabled) {
439         this.JMXEnabled = isJMXEnabled;
440     }
441     
442     public boolean isKeyHierarchyEnabled() {
443         return keyHierarchyEnabled;
444     }
445 }
446
Popular Tags