KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > rm > factory > CacheHandler


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19 package org.openharmonise.rm.factory;
20
21
22 import java.util.*;
23 import java.util.logging.*;
24
25 import org.openharmonise.commons.cache.*;
26 import org.openharmonise.commons.dsi.AbstractDataStoreInterface;
27 import org.openharmonise.rm.resources.AbstractObject;
28
29 import EDU.oswego.cs.dl.util.concurrent.*;
30
31 /**
32  * This singleton class provides a single point of interface for the
33  * caching of the core objects within Harmonise.
34  *
35  * @author Michael Bell
36  * @version $Revision: 1.3 $
37  *
38  */

39 public class CacheHandler {
40     
41     /**
42      * The singleton instance for this class
43      */

44     private static CacheHandler m_instance = null;
45     
46     /**
47      * The default inital size of the <code>Map</code> containing all caches
48      */

49     private static final int DEFAULT_CACHESIZE = 50;
50     
51     /**
52      * The data store interface
53      */

54     private AbstractDataStoreInterface m_dsi = null;
55     
56     /**
57      * The <code>Map</code> containing all caches handled by this cache handler
58      */

59     private Map m_caches;
60     
61     /**
62      * Read-write lock to enable locking of cache map access
63      */

64     private ReadWriteLock m_lock = new WriterPreferenceReadWriteLock();
65     
66     
67     private static Logger m_logger = Logger.getLogger(CacheHandler.class.getName());
68
69     /**
70      * Constructs a new cache handler.
71      *
72      * @param dbinterf the data store interface for this object
73      */

74     private CacheHandler(AbstractDataStoreInterface dbinterf) {
75         m_dsi = dbinterf;
76         m_caches = new HashMap(DEFAULT_CACHESIZE);
77     }
78
79     /**
80      * Returns the singleton instance of <code>CacheHandler</code>.
81      *
82      * @param dbinterf the data store interface for the returned instance
83      * @return the singleton instance
84      */

85     public static synchronized CacheHandler getInstance(AbstractDataStoreInterface dbinterf) {
86         if (m_instance == null) {
87             m_instance = new CacheHandler(dbinterf);
88         }
89
90         return m_instance;
91     }
92
93     /**
94      * Returns the object for the given class name and id.
95      *
96      * @param sClassname the name of class of the object to be returned
97      * @param nId the id of object to be returned
98      * @return the object matching class and id
99      * @throws CacheException if an error occurs getting object from the cache
100      */

101     public Object JavaDoc getObject(String JavaDoc sClassname, int nId)
102                      throws CacheException {
103         Object JavaDoc cachedObject = null;
104
105         if (nId > 0) {
106             AbstractCache cache = getCache(sClassname);
107
108             cachedObject = cache.getObject(String.valueOf(nId));
109         } else {
110             cachedObject = GeneralCache.createObject(m_dsi, sClassname,
111                                                          nId);
112         }
113
114         return cachedObject;
115     }
116
117     /**
118      * Returns an object for the given class name and path.
119      *
120      * @param sClassname the name of class of the object to be returned
121      * @param sPath the path of object to be returned
122      * @return the object matching class and path
123      * @throws CacheException if an error occurs getting object from the cache
124      */

125     public Object JavaDoc getObjectFromPath(String JavaDoc sClassname, String JavaDoc sPath)
126                              throws CacheException {
127         Object JavaDoc cachedObject = null;
128
129         if ((sPath != null) && (sPath.length() > 0)) {
130             GeneralCache cache = (GeneralCache) getCache(sClassname);
131
132             cachedObject = cache.getObjectFromPath(sPath);
133         } else {
134             cachedObject = GeneralCache.createObject(m_dsi, sClassname,
135                                                          -1);
136         }
137
138         return cachedObject;
139     }
140
141     /**
142      * Returns an object for the given class and <code>String</code> cache key.
143      *
144      * @param sClassname the name of class of the object to be returned
145      * @param sKey the cache key
146      * @return the object matching class and path
147      * @throws CacheException if an error occurs getting object from the cache
148      */

149     public Object JavaDoc getObject(String JavaDoc sClassname, String JavaDoc sKey)
150                      throws CacheException {
151         Object JavaDoc cachedObject = null;
152
153         if ((sKey != null) && (sKey.length() > 0)) {
154             
155             AbstractCache cache = getCache(sClassname);
156
157             cachedObject = cache.getObject(sKey);
158         } else {
159             cachedObject = GeneralCache.createObject(m_dsi, sClassname,
160                                                          sKey);
161         }
162
163         return cachedObject;
164     }
165
166     /**
167      * Adds the given object to the relevant cache.
168      *
169      * @param xobj the object to be cached
170      * @throws CacheException if there is an error either getting the correct
171      * cache or adding the object to the cache
172      */

173     public void addToCache(AbstractObject xobj) throws CacheException {
174         Object JavaDoc cachedObject = null;
175         int nId = xobj.getId();
176
177         if (nId > 0) {
178             AbstractCache cache = getCache(xobj.getClass());
179
180             cache.addToCache(String.valueOf(nId), xobj);
181         }
182     }
183
184     /**
185      * Change object in the cache. This method notifies the appropriate cache
186      * that a change has to take place to the object referenced by
187      * <code>key</code> and possibly replaced by the new Object
188      * <code>newObj</code>, depending on the code <code>sType</code>.
189      *
190      * @param key the cache key of object in cache
191      * @param sType the type of change being made, see constants available
192      * @param newObj the new object to be placed in cache to replace object
193      * referenced by <code>key</code>, if appropriate
194      * @throws CacheException if there is an error either gettting the
195      * appropriate cache or changing the object in the cache
196      */

197     public void changeObject(String JavaDoc key, String JavaDoc sType, Object JavaDoc newObj)
198                       throws CacheException {
199         AbstractCache cache = getCache(newObj.getClass());
200
201         cache.changeObject(key, sType, newObj);
202     }
203
204     /**
205      * Change object in the cache. This method notifies the appropriate
206      * cache that a change has to take place to the object <code>oldObj</code>
207      * and possibly replaced by the new Object <code>newObj</code>,
208      * depending on the code <code>sType</code>.
209      *
210      * @param oldObj the object which is in cache
211      * @param sType The type of change being made, see constants available
212      * @param newObj the new object to be placed in cache to replace
213      * <code>oldObj</code>
214      * @throws CacheException if there is an error either gettting the
215      * appropriate cache or changing the object in the cache
216      */

217     public void changeObject(Object JavaDoc oldObj, String JavaDoc sType, Object JavaDoc newObj)
218                       throws CacheException {
219         AbstractCache cache = getCache(oldObj.getClass());
220
221         cache.changeObject(String.valueOf(((AbstractObject) oldObj).getId()), sType,
222                            newObj);
223     }
224
225     /**
226      * Returns the cache which corresponds to the specified class name.
227      *
228      * @param sClassname the class name
229      * @return the cache which corresponds to the specified class name
230      * @throws CacheException if there is an error creating the cache
231      */

232     public GeneralCache getCache(String JavaDoc sClassname)
233                              throws CacheException {
234         GeneralCache cache = null;
235
236         try {
237             m_lock.readLock().acquire();
238             cache = (GeneralCache) m_caches.get(sClassname);
239             m_lock.readLock().release();
240         } catch (InterruptedException JavaDoc e) {
241             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
242             throw new CacheException(e);
243         }
244
245         if (cache == null) {
246             try {
247                 cache = getCache(Class.forName(sClassname));
248             } catch (ClassNotFoundException JavaDoc e) {
249                 throw new CacheException(e);
250             }
251         }
252
253         return cache;
254     }
255     
256     /**
257      * Returns the appropriate cache for the specified object.
258      *
259      * @param obj the object to get cache for
260      * @return the appropriate cache for this object
261      * @throws CacheException if there is an error creating the cache
262      */

263     public GeneralCache getCache(AbstractObject obj)
264                                 throws CacheException {
265         return getCache(obj.getClass());
266     }
267     
268     /**
269      * Returns the appropriate cache for the specified <code>Class</code>.
270      *
271      * @param clss the <code>Class</code> to get cache for
272      * @return the appropriate cache for the <code>Class</code>
273      * @throws CacheException if there is an error creating the cache
274      */

275     public GeneralCache getCache(Class JavaDoc clss) throws CacheException {
276         GeneralCache cache = null;
277         String JavaDoc sClassname = clss.getName();
278
279         try {
280             m_lock.readLock().acquire();
281             cache = (GeneralCache) m_caches.get(sClassname);
282             m_lock.readLock().release();
283
284             if (cache == null) {
285                 m_lock.writeLock().acquire();
286                 //create cache for class
287
cache = new GeneralCache(this.m_dsi, sClassname);
288                 
289                 try {
290                     Object JavaDoc obj = clss.newInstance();
291                     
292                     if(CacheDependant.class.isAssignableFrom(clss)) {
293                         cache.setDependancyAware(true);
294                     }
295                     
296                     //if there's an exception creating the instance we can assume
297
// that the cache shouldn't be dependant aware
298
} catch (InstantiationException JavaDoc e) {
299                     m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
300                 } catch (IllegalAccessException JavaDoc e) {
301                     m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
302                 }
303
304                 //store cache
305
m_caches.put(sClassname, cache);
306                 m_lock.writeLock().release();
307             }
308         } catch (InterruptedException JavaDoc e) {
309             m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
310             throw new CacheException(e);
311         }
312
313         return cache;
314     }
315     
316     /**
317      * Removes the specified object from the appropriate cache.
318      *
319      * @param obj the object to remove
320      *
321      * @throws CacheException if there is an error accessing the cache or
322      * removing the object from it
323      */

324     public void removeObjectFromCache(AbstractObject obj) throws CacheException {
325         GeneralCache cache = getCache(obj);
326         
327         cache.removeObjectFromCache(String.valueOf(obj.getId()));
328     }
329     
330     /**
331      * Returns the cache pointer which will reference the specified
332      * object.
333      *
334      * @param obj the object
335      * @return the cache pointer which will reference the specified
336      * object
337      * @throws CacheException if an error occurs accessing the appropriate cache
338      */

339     public CachePointer getCachePointer(AbstractObject obj) throws CacheException {
340         CachePointer pointer = null;
341         
342         if(obj != null) {
343             GeneralCache cache = getCache(obj.getClass());
344             
345             pointer = cache.getObjectPointer(String.valueOf(obj.getId()));
346         }
347         
348         return pointer;
349     }
350
351     /**
352      * Returns a list of the name of all caches this cache handler is
353      * currently managing.
354      *
355      * @return the list of all cache names
356      */

357     public List getCacheList() {
358         try {
359             m_lock.readLock().acquire();
360         } catch (InterruptedException JavaDoc e) {
361             m_logger.log(Level.WARNING, "Couldn't aquire lock",e);
362         }
363         Set keys = m_caches.keySet();
364         ArrayList vec = new ArrayList();
365         Iterator iter = keys.iterator();
366
367         while (iter.hasNext()) {
368             vec.add(iter.next());
369         }
370         m_lock.readLock().release();
371
372         return vec;
373     }
374
375     /**
376      * Returns a list of all the caches this cache handler is
377      * currently managing.
378      *
379      * @return the list of all caches
380      */

381     public List getCaches() {
382         try {
383             m_lock.readLock().acquire();
384         } catch (InterruptedException JavaDoc e) {
385             m_logger.log(Level.WARNING, "Couldn't aquire lock",e);
386         }
387         Set keys = m_caches.keySet();
388         ArrayList vec = new ArrayList();
389         Iterator iter = keys.iterator();
390
391         while (iter.hasNext()) {
392             vec.add(this.m_caches.get(iter.next()));
393         }
394         
395         m_lock.readLock().release();
396
397         return vec;
398     }
399
400     /* (non-Javadoc)
401      * @see java.lang.Object#toString()
402      */

403     public String JavaDoc toString() {
404         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
405         List list = getCacheList();
406         buffer.append("[");
407
408         Iterator iter = list.iterator();
409         
410         while (iter.hasNext()) {
411
412             buffer.append((String JavaDoc) iter.next());
413             if (iter.hasNext()) {
414                 buffer.append(",");
415             }
416         }
417
418         buffer.append("]");
419
420         return (buffer.toString());
421     }
422 }
Popular Tags