KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jofti > cache > adapter > EhCachePre1_2Adapter


1 package com.jofti.cache.adapter;
2
3 import java.io.IOException JavaDoc;
4 import java.io.Serializable JavaDoc;
5 import java.util.Iterator JavaDoc;
6 import java.util.List JavaDoc;
7 import java.util.Map JavaDoc;
8 import java.util.Properties JavaDoc;
9
10 import net.sf.ehcache.CacheException;
11 import net.sf.ehcache.Element;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15
16 import com.jofti.api.IndexQuery;
17 import com.jofti.cache.CacheAdapter;
18 import com.jofti.cache.BaseAdaptor;
19 import com.jofti.core.INameSpaceAware;
20 import com.jofti.core.IParsedQuery;
21 import com.jofti.core.InternalIndex;
22 import com.jofti.core.QueryId;
23 import com.jofti.core.QueryType;
24 import com.jofti.exception.JoftiException;
25 import com.jofti.util.CompositeComparator;
26
27 /**
28
29  *
30  * The adapter implementation specific to EHCache.
31  *
32  * The adapter takes care of the implementation specific details for converting
33  * between the process the index expects and the behaviour of EHCache (pre-1.2 versions).
34  *
35  * The main drawback with ealier versions of EHCache is that it is not possible to find out when an
36  * entry has been expired in the cache so there is a possibility that if you do
37  * not access the cache entries the index will end up with extra keys that are
38  * not present in the cache.
39  *
40  * While not a huge problem, over time this could be an issue in an ongoing
41  * situation. It is strongly recommended that you upgrade to version 1.2 and use the Listener or
42  * wrapper adapter.</p>
43  *
44  * The start up of the adapter will also try and index any elements already in
45  * the cache.<P>
46  *
47  * @author Steve Woodcock
48  * <p>
49  * @version 1.0
50  * <p>
51  */

52 public class EhCachePre1_2Adapter extends BaseAdaptor implements CacheAdapter
53 {
54
55     private net.sf.ehcache.CacheManager manager;
56
57     private static Log log = LogFactory
58                                                     .getLog(EhCachePre1_2Adapter.class);
59
60     private net.sf.ehcache.Cache cache;
61
62     private String JavaDoc name;
63
64
65     public EhCachePre1_2Adapter()
66     {
67     }
68
69     public EhCachePre1_2Adapter(Object JavaDoc cache)
70     {
71         this.cache = (net.sf.ehcache.Cache) cache;
72
73     }
74
75     public void setCacheImpl(Object JavaDoc cache)
76     {
77         this.cache = (net.sf.ehcache.Cache) cache;
78
79     }
80
81     /*
82      * (non-Javadoc)
83      *
84      * @see com.jofti.api.IndexCache#get(java.lang.Object)
85      */

86     public Object JavaDoc get(Object JavaDoc key)
87     {
88         key = decorateKey(key);
89         try {
90             if (key != null) {
91                 // do the cast early - seems to help the performance slightly -
92
// otherwise
93
// we have multiple casts in this method
94
Comparable JavaDoc tempKey = (Comparable JavaDoc) key;
95                 // get a lock for the key that we are trying to add
96
// we do not care about other parts of the cache or the index
97
synchronized (getCacheLock(key)) {
98
99                     // get the element from the cache if it exists
100
Element element = cache.get((Serializable JavaDoc) tempKey);
101                     // if it is null either it has expired or it was never there
102
if (element == null) {
103
104                         // we always do this as we can't tell if it has expired
105
// unless we have the full
106
// object - which we can't get because it has expired!
107
// this is crap - but there is little other option
108
// have raised a change request in ehcache
109
if (log.isDebugEnabled()) {
110                             log
111                                     .debug("unexpected null object retrieved for key "
112                                             + key + " removing");
113                         }
114                         // check if it exists first (might always have been
115
// null) as otherwise we have to remove anyway
116

117                         if (index.contains(tempKey)) {
118                             index.removeByKey(tempKey);
119                         }
120
121                         return null;
122                     } else {
123                         // we should not need to do this as there should be no
124
// way an entry can just appear without going through
125
// this classe
126

127                         return element.getValue();
128                     }
129                 }
130
131             } else {
132                 return null;
133             }
134         } catch (net.sf.ehcache.CacheException e) {
135             log.warn("Unable to retrieve value from cache", e);
136  
137         } catch (JoftiException e) {
138             log.warn("Unable to retrieve value from cache", e);
139         }
140         return null;
141     }
142
143     /*
144      * (non-Javadoc)
145      *
146      * @see com.jofti.api.IndexCache#put(java.lang.Object, java.lang.Object)
147      */

148     public void put(Object JavaDoc key, Object JavaDoc value) throws JoftiException
149     {
150         key = decorateKey(key);
151         acquireUpdateLock();
152         try {
153             Comparable JavaDoc tempKey = (Comparable JavaDoc) key;
154
155             synchronized (getCacheLock(key)) {
156
157                 // we have to remove a potentially expired result
158
if (index.contains(tempKey)) {
159                     if (log.isDebugEnabled()) {
160                         log.debug("Object does exist so remove " + tempKey);
161                     }
162
163                     index.removeByKey(tempKey);
164                 }
165
166                 Element element = new Element((Serializable JavaDoc) tempKey,
167                         (Serializable JavaDoc) value);
168                 cache.put(element);
169
170                 index.insert(tempKey, value);
171
172             }
173         } catch (IllegalArgumentException JavaDoc e) {
174             throw new JoftiException(e);
175         } catch (IllegalStateException JavaDoc e) {
176             throw new JoftiException(e);
177         } finally {
178             releaseUpdateLock();
179         }
180
181     }
182
183     /**
184      * Removes the element which matches the key.
185      * <p>
186      * If no element matches, nothing is removed and no Exception is thrown.
187      *
188      * @param key
189      * the key of the element to remove
190      * @throws CacheException
191      */

192     public void remove(Object JavaDoc key) throws JoftiException
193     {
194         key = decorateKey(key);
195         
196         acquireUpdateLock();
197         try {
198
199             synchronized (getCacheLock(key)) {
200                 Comparable JavaDoc tempKey = (Comparable JavaDoc) key;
201                 // remove if we need to based on the key - as it may be expired
202
// this synchronous as we have to remove these entries before
203
// we can return
204
if (index.contains(tempKey)) {
205                     index.removeByKey(tempKey);
206                 }
207
208                 cache.remove((Serializable JavaDoc) key);
209             }
210
211         } catch (ClassCastException JavaDoc e) {
212             throw new JoftiException(e);
213         } catch (IllegalStateException JavaDoc e) {
214             throw new JoftiException(e);
215         } finally {
216             releaseUpdateLock();
217         }
218     }
219
220     /**
221      * Remove all elements in the cache, but leave the cache in a useable state.
222      *
223      * @throws CacheException
224      */

225     public synchronized void removeAll() throws JoftiException
226     {
227         try {
228
229             cache.removeAll();
230             index.removeAll();
231
232         } catch (IllegalStateException JavaDoc e) {
233             throw new JoftiException(e);
234         } catch (Exception JavaDoc e) {
235             throw new JoftiException(e);
236         }
237     }
238
239     public synchronized void init(Properties JavaDoc properties) throws JoftiException
240     {
241         try {
242             String JavaDoc cacheConfigFile = null;
243             if (properties != null) {
244                 String JavaDoc key = null;
245                 for (Iterator JavaDoc it = properties.keySet().iterator(); it.hasNext();) {
246                     key = (String JavaDoc) it.next();
247                     if (MUTABLE_VALUES.equalsIgnoreCase(key)) {
248                         checkMutable = Boolean.valueOf(
249                                 properties.getProperty(key)).booleanValue();
250                         if (log.isInfoEnabled()) {
251                             log.info("Mutability checking is set to "
252                                     + checkMutable);
253                         }
254                     }
255                     if ("file".equalsIgnoreCase(key)) {
256                         cacheConfigFile = properties.getProperty(key);
257                     }
258                 }
259             }
260
261             if (manager == null) {
262                 if (cacheConfigFile != null) {
263                     manager = net.sf.ehcache.CacheManager
264                             .create(cacheConfigFile);
265                 } else {
266                     manager = net.sf.ehcache.CacheManager.create();
267                 }
268             }
269             if (cache == null) {
270                 initCache();
271             } else {
272                 // try and add it to the cache
273
if (!(manager.cacheExists(cache.getName()))) {
274                     manager.addCache(cache);
275                 } else {
276                     log
277                             .warn("IndexCache "
278                                     + cache.getName()
279                                     + "already exists in manager - not adding new cache");
280                 }
281             }
282
283         } catch (net.sf.ehcache.CacheException e) {
284             throw new JoftiException(e);
285         }
286
287     }
288
289     private void initCache() throws JoftiException
290     {
291         if (cache == null) {
292             cache = manager.getCache(name);
293             if (cache == null) {
294                 log.warn("Unable to find cache named '" + name
295                         + "' in EHCacheManager");
296                 String JavaDoc[] names = manager.getCacheNames();
297                 log.warn("Available cache names are:");
298                 for (int i = 0; i < names.length; i++) {
299                     log.warn("IndexCache:" + names[i]);
300                 }
301                 throw new JoftiException("Unable to find cache named '" + name
302                         + "' in EHCacheManager");
303             }
304         }
305     }
306
307     /* (non-Javadoc)
308      * @see com.jofti.cache.LifeCycleAdapter#start()
309      */

310     public synchronized void start() throws JoftiException
311     {
312         try {
313             loadInitialValues(cache);
314         } catch (CacheException ce) {
315             throw new JoftiException(ce);
316         }
317     }
318
319     private void loadInitialValues(net.sf.ehcache.Cache cache)
320             throws CacheException, JoftiException
321     {
322         List JavaDoc keys = cache.getKeys();
323         for (Iterator JavaDoc it = keys.iterator(); it.hasNext();) {
324             Object JavaDoc key = it.next();
325             Element element = cache.get((Serializable JavaDoc) key);
326             if (key instanceof Comparable JavaDoc) {
327                 Comparable JavaDoc tempKey = (Comparable JavaDoc) key;
328                 if (element != null && element.getValue() != null) {
329                     // then we must remove from index
330
index.insert(tempKey, element.getValue());
331                 }
332             } else {
333                 log.info("Ignoring value at key:" + key
334                         + " as key is not Comparable");
335             }
336         }
337     }
338
339     /* (non-Javadoc)
340      * @see com.jofti.cache.LifeCycleAdapter#destroy()
341      */

342     public synchronized void destroy() throws JoftiException
343     {
344         try {
345             if (manager != null) {
346                 manager.removeCache(name);
347                 manager.shutdown();
348                 index.removeAll();
349             }
350         } catch (IllegalStateException JavaDoc e) {
351             throw new JoftiException(e);
352         }
353     }
354
355     public String JavaDoc getName()
356     {
357         return name;
358     }
359
360     public void setName(String JavaDoc name)
361     {
362         this.name = name;
363     }
364
365     public String JavaDoc toString()
366     {
367         return "EHCache(" + getName() + ')';
368     }
369
370     public Object JavaDoc getCache()
371     {
372         return cache;
373     }
374
375     /*
376      * (non-Javadoc)
377      *
378      * @see com.jofti.api.IndexCache#getCacheImpl()
379      */

380     public Object JavaDoc getCacheImpl()
381     {
382         return cache;
383     }
384
385     /*
386      * (non-Javadoc)
387      *
388      * @see com.jofticache.CacheAdapter#setInternalIndex(com.jofti.core.InternalIndex)
389      */

390     public void setInternalIndex(InternalIndex index)
391     {
392         this.index = index;
393
394     }
395
396    
397     protected Object JavaDoc getCacheValue(Object JavaDoc key) {
398         return get(key);
399     }
400
401     /* (non-Javadoc)
402      * @see com.jofti.cache.CacheLocking#getIndex()
403      */

404     public InternalIndex getIndex() {
405         return index;
406     }
407     
408     public IndexQuery addQuery(String JavaDoc name, IndexQuery query)throws JoftiException {
409         
410         return index.getParserManager().addQuery(name, query);
411     }
412
413     /* (non-Javadoc)
414      * @see com.jofti.api.Index#getQuery(java.lang.String)
415      */

416     public IndexQuery getQuery(String JavaDoc name) {
417         
418         return index.getParserManager().getQuery(name);
419     }
420 }
Popular Tags