KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > rift > coad > lib > cache > CacheRegistry


1 /*
2  * CoadunationLib: The coaduntion implementation library.
3  * Copyright (C) 2006 Rift IT Contracting
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * CacheRegistry.java
20  *
21  * The cache registery is responsible for managing the cache information for
22  * the deployments. Each deployment gets its own class loader.
23  */

24
25 // package path
26
package com.rift.coad.lib.cache;
27
28 // java imports
29
import java.util.HashMap JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Set JavaDoc;
34
35 // logging import
36
import org.apache.log4j.Logger;
37
38 // coadunation imports
39
import com.rift.coad.lib.configuration.ConfigurationFactory;
40 import com.rift.coad.lib.configuration.Configuration;
41 import com.rift.coad.lib.thread.BasicThread;
42 import com.rift.coad.lib.thread.ThreadStateMonitor;
43 import com.rift.coad.lib.thread.CoadunationThreadGroup;
44
45 /**
46  * The cache registery is responsible for managing the cache information for
47  * the deployments. Each deployment gets its own class loader and own cache
48  * entry.
49  *
50  * @author Brett Chaldecott
51  */

52 public class CacheRegistry {
53     
54     /**
55      * This object is responsible for managing a list of cache entries.
56      */

57     public class CacheListManager extends BasicThread {
58         
59         // private member variables
60
private ClassLoader JavaDoc loader = null;
61         private Map JavaDoc caches = new HashMap JavaDoc();
62         private ThreadStateMonitor threadStateMonitor = null;
63         
64         
65         /**
66          * The constructor of the CacheListManager
67          *
68          * @param loader The reference to the class loader.
69          */

70         public CacheListManager(ClassLoader JavaDoc loader) throws Exception JavaDoc {
71             this.loader = loader;
72             threadStateMonitor = new ThreadStateMonitor(delay);
73         }
74         
75         
76         /**
77          * This method replaces the run method in the BasicThread.
78          *
79          * @exception Exception
80          */

81         public void process() throws Exception JavaDoc {
82             while(!threadStateMonitor.isTerminated()) {
83                 threadStateMonitor.monitor();
84                 Set JavaDoc keySet = new HashSet JavaDoc();
85                 synchronized (caches) {
86                     keySet.addAll(caches.keySet());
87                 }
88                 Iterator JavaDoc iter = keySet.iterator();
89                 while(iter.hasNext()) {
90                     Object JavaDoc key = iter.next();
91                     Cache cache = null;
92                     synchronized (caches) {
93                         cache = (Cache)caches.get(key);
94                     }
95                     try {
96                         cache.garbageCollect();
97                     } catch (Exception JavaDoc ex) {
98                         log.error("Failed to clear the garbage collect : " +
99                                 ex.getMessage(),ex);
100                     }
101                     if (threadStateMonitor.isTerminated())
102                     {
103                         break;
104                     }
105                 }
106             }
107             
108             // clean up the cache
109
Iterator JavaDoc iter = caches.keySet().iterator();
110             while(iter.hasNext()) {
111                 Object JavaDoc key = iter.next();
112                 Cache cache = (Cache)caches.get(key);
113                 try {
114                     cache.clear();
115                 } catch (Exception JavaDoc ex) {
116                     log.error("Failed to clear the cache : " +
117                             ex.getMessage(),ex);
118                 }
119             }
120         }
121         
122         
123         /**
124          * This method terminates the processing being performed by the cache
125          * list manager object.
126          */

127         public void terminate() {
128             threadStateMonitor.terminate(false);
129         }
130         
131         
132         /**
133          * This method retrieves a cache entry.
134          *
135          * @return The cache entry to return.
136          * @param cacheClass The cache class being requested.
137          * @exception CacheException
138          */

139         public Cache getCache(Class JavaDoc cacheClass) throws CacheException {
140             if (threadStateMonitor.isTerminated()) {
141                 throw new CacheException(
142                         "The cache has been closed cannot add anymore entries.");
143             }
144             // synchronize access to the caches
145
try
146             {
147                 synchronized (caches) {
148                     if (caches.containsKey(cacheClass)) {
149                         return (Cache)caches.get(cacheClass);
150                     }
151                     Cache cache = (Cache)cacheClass.newInstance();
152                     caches.put(cacheClass,cache);
153                     return cache;
154                 }
155             } catch (Exception JavaDoc ex) {
156                 
157                 throw new CacheException("Failed to retrieve the cache entry");
158             }
159         }
160     }
161     
162     // the classes constants
163
private static final String JavaDoc DELAY = "cache_process_delay";
164     private static final long DELAY_DEFAULT = 500;
165     private static final String JavaDoc USER = "cache_user";
166     
167     // the class log variable
168
protected Logger log =
169         Logger.getLogger(CacheRegistry.class.getName());
170     
171     // class member variables
172
private static CacheRegistry singleton = null;
173     private CoadunationThreadGroup threadGroup = null;
174     private String JavaDoc threadUser = null;
175     private Map JavaDoc cacheManagers = new HashMap JavaDoc();
176     private Configuration config = null;
177     private long delay = 0;
178     private ThreadStateMonitor stateMonitor = new ThreadStateMonitor();
179     
180     
181     /**
182      * Creates a new instance of CacheRegistry
183      *
184      * @param threadGroup The thread group used to greate a sub thread group.
185      * @exception CacheException
186      */

187     private CacheRegistry(CoadunationThreadGroup threadGroup) throws CacheException {
188         try {
189             this.threadGroup = threadGroup.createThreadGroup();
190             config = ConfigurationFactory.
191                     getInstance().getConfig(CacheRegistry.class);
192             delay = config.getLong(DELAY,DELAY_DEFAULT);
193             threadUser = config.getString(USER);
194         } catch (Exception JavaDoc ex) {
195             log.error("Failed to instanciate the cache registry : " +
196                     ex.getMessage(),ex);
197             throw new CacheException("Failed to instanciate the cache registry : "
198                     + ex.getMessage(),ex);
199         }
200     }
201     
202     
203     /**
204      * This method returns an instance of the cache registry object. Do not call
205      * more than once.
206      *
207      * @return The reference to the cache registry object.
208      * @param threadGroup The thread group used for initialization purposes.
209      * @exception CacheException
210      */

211     public static synchronized CacheRegistry init(CoadunationThreadGroup threadGroup) throws
212             CacheException {
213         // this method overrides the existing cache registry
214
if (singleton == null) {
215             singleton = new CacheRegistry(threadGroup);
216         }
217         return singleton;
218     }
219     
220     
221     /**
222      * This method returns an instance of the cache registry object.
223      *
224      * @return The reference to the cache registry object.
225      * @exception CacheException
226      */

227     public static synchronized CacheRegistry getInstance() throws CacheException {
228         if (singleton == null) {
229             throw new CacheException(
230                     "The cache registry has not been initialized");
231         }
232         return singleton;
233     }
234     
235     
236     /**
237      * This method inits the cache for a given class loader. This is based on
238      * the class loader that attached to the calling thread.
239      */

240     public void initCache() throws CacheException {
241         if (stateMonitor.isTerminated()) {
242             throw new CacheException("Cache is terminated");
243         }
244         ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
245         CacheListManager cacheListManager = null;
246         synchronized (cacheManagers) {
247             if (cacheManagers.containsKey(loader)) {
248                 throw new CacheException("There is already a cache entry for " +
249                         "this loader");
250             }
251             try {
252                 cacheListManager = new CacheListManager(loader);
253             } catch (Exception JavaDoc ex) {
254                 throw new CacheException (
255                         "Failed to instanciate the cace list manager : " +
256                         ex.getMessage(),ex);
257             }
258             cacheManagers.put(loader,cacheListManager);
259         }
260         try {
261             threadGroup.addThread(cacheListManager,threadUser);
262             cacheListManager.start();
263             cacheListManager.setContextClassLoader(loader);
264         } catch (Exception JavaDoc ex) {
265             // if fails to start remove cache entry
266
synchronized (cacheManagers) {
267                 cacheManagers.remove(loader);
268             }
269             log.error("Failed to start the cache list manager : " +
270                     ex.getMessage(),ex);
271             throw new CacheException("Failed to init the cache : " +
272                     ex.getMessage(),ex);
273         }
274
275     }
276     
277     
278     /**
279      * This method inits the cache for a given class loader. This is based on
280      * the class loader that attached to the calling thread.
281      *
282      * @return The reference to the requested cache class.
283      * @param cacheClass The cache class to retrieve.
284      * @exception CacheException
285      */

286     public Cache getCache(Class JavaDoc cacheClass) throws CacheException {
287         if (stateMonitor.isTerminated()) {
288             throw new CacheException("Cache is terminated");
289         }
290         ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
291         CacheListManager cacheListManager = null;
292         synchronized (cacheManagers) {
293             if (!cacheManagers.containsKey(loader)) {
294                 throw new CacheException("The is no cache list manager for " +
295                         "this loader");
296             }
297             cacheListManager = (CacheListManager)cacheManagers.get(loader);
298         }
299         return cacheListManager.getCache(cacheClass);
300     }
301     
302     
303     /**
304      * This method terminates the cache for the class loader making the request.
305      *
306      * @exception CacheException
307      */

308     public void terminateCache() throws CacheException {
309         ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
310         CacheListManager cacheListManager = null;
311         synchronized (cacheManagers) {
312             if (!cacheManagers.containsKey(loader)) {
313                 log.info("The is no cache list manager for this loader. " +
314                         "The deploy was not completed successfully");
315                 return;
316             }
317             cacheListManager = (CacheListManager)cacheManagers.get(loader);
318             cacheManagers.remove(loader);
319         }
320         cacheListManager.terminate();
321     }
322     
323     
324     /**
325      * This method shuts down the cache registry
326      *
327      * @exception CacheException
328      */

329     public void shutdown() throws CacheException {
330         stateMonitor.terminate(false);
331         try {
332             threadGroup.terminate();
333         } catch (Exception JavaDoc ex) {
334             log.error("Failed to terminate the cache thread managers : " +
335                     ex.getMessage(),ex);
336         }
337         synchronized(cacheManagers) {
338             cacheManagers.clear();
339         }
340     }
341 }
342
Popular Tags