KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > rift > coad > lib > bean > BeanCache


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  * BeanCache.java
20  *
21  * This object is responsible for mantaining a cache of beans. It is used by
22  * both the RMI tie classes and the Local proxy objects when a method that
23  * contains, find|get and remove|delete is found.
24  */

25
26 // package path
27
package com.rift.coad.lib.bean;
28
29 // java imports
30
import java.util.Date JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import javax.rmi.PortableRemoteObject JavaDoc;
35
36 // logging import
37
import org.apache.log4j.Logger;
38
39 // coadunation imports
40
import com.rift.coad.lib.cache.Cache;
41 import com.rift.coad.lib.cache.CacheEntry;
42 import com.rift.coad.lib.configuration.ConfigurationFactory;
43 import com.rift.coad.lib.configuration.Configuration;
44 import com.rift.coad.lib.thread.ThreadStateMonitor;
45
46 /**
47  * This object is responsible for mantaining a cache of beans. It is used by
48  * both the RMI tie classes and the Local proxy objects when a method that
49  * contains, find|get and remove|delete is found.
50  *
51  * @author Brett Chaldecott
52  */

53 public class BeanCache implements Cache {
54     
55     // class constants
56
private final static String JavaDoc CACHE_EXPIRY_TIME = "bean_cache_expiry";
57     private final static long CACHE_EXPIRY_TIME_DEFAULT = 30 * 60 * 1000;
58     
59     // private member variables
60
protected static Logger log =
61             Logger.getLogger(BeanCache.class.getName());
62     
63     // private member variables
64
private Map JavaDoc entries = new HashMap JavaDoc();
65     private long defaultCacheExpiryTime = 0;
66     private ThreadStateMonitor status = new ThreadStateMonitor();
67     
68     /**
69      * Creates a new instance of BeanCache
70      *
71      * @exception BeanException
72      */

73     public BeanCache() throws BeanException {
74         try {
75             Configuration config = ConfigurationFactory.getInstance().
76                     getConfig(BeanCache.class);
77             defaultCacheExpiryTime = config.getLong(CACHE_EXPIRY_TIME,
78                     CACHE_EXPIRY_TIME_DEFAULT);
79         } catch (Exception JavaDoc ex) {
80             log.error("Failed to start the BeanCache object because : " +
81                     ex.getMessage(),ex);
82             throw new BeanException(
83                     "Failed to start the BeanCache object because : " +
84                     ex.getMessage(),ex);
85         }
86     }
87     
88     
89     /**
90      * This method is called to perform garbage collection on the cache entries.
91      */

92     public void garbageCollect() {
93         // copy the entries map
94
Map JavaDoc entries = new HashMap JavaDoc();
95         synchronized (this.entries) {
96             entries.putAll(this.entries);
97         }
98         
99         // loop through the entires and remove the expired ones
100
Date JavaDoc expiryDate = new Date JavaDoc();
101         for (Iterator JavaDoc iter = entries.keySet().iterator();iter.hasNext();) {
102             Object JavaDoc cacheKey = iter.next();
103             BeanCacheEntry beanCacheEntry =
104                     (BeanCacheEntry)entries.get(cacheKey);
105             if (beanCacheEntry.isExpired(expiryDate)) {
106                 synchronized (this.entries) {
107                     if (beanCacheEntry.getCacheEntry() != null)
108                     {
109                         try {
110                             PortableRemoteObject.unexportObject(
111                                     (java.rmi.Remote JavaDoc)
112                                     beanCacheEntry.getCacheEntry());
113                             // remove from cache
114
this.entries.remove(cacheKey);
115                             beanCacheEntry.cacheRelease();
116                         } catch (java.rmi.NoSuchObjectException JavaDoc ex) {
117                             log.warn("The object was never exported : " +
118                                     ex.getMessage(),ex);
119                             // remove from cache
120
this.entries.remove(cacheKey);
121                             beanCacheEntry.cacheRelease();
122                         } catch (Exception JavaDoc ex) {
123                             log.error("Failed to un-export this object : " +
124                                     ex.getMessage(),ex);
125                         }
126                     } else {
127                         // if this object has not cache entry as in no rmi tie
128
// class than just remove it.
129
this.entries.remove(cacheKey);
130                         beanCacheEntry.cacheRelease();
131                     }
132                 }
133             }
134         }
135     }
136     
137     
138     /**
139      * This method is called to forcibly remove everything from the cache.
140      */

141     public void clear() {
142         // copy the entries map
143
Map JavaDoc entries = new HashMap JavaDoc();
144         synchronized (this.entries) {
145             entries.putAll(this.entries);
146             this.entries.clear();
147             status.terminate(false);
148         }
149         
150         // loop through the entires and remove the expired ones
151
for (Iterator JavaDoc iter = entries.keySet().iterator();iter.hasNext();) {
152             Object JavaDoc cacheKey = iter.next();
153             BeanCacheEntry beanCacheEntry =
154                     (BeanCacheEntry)entries.get(cacheKey);
155             if (beanCacheEntry.getCacheEntry() != null)
156             {
157                 try {
158                     PortableRemoteObject.unexportObject(
159                             (java.rmi.Remote JavaDoc)
160                             beanCacheEntry.getCacheEntry());
161                 } catch (java.rmi.NoSuchObjectException JavaDoc ex) {
162                     log.warn("The cache object was not bound : " +
163                             ex.getMessage(),ex);
164                 } catch (Exception JavaDoc ex) {
165                     log.error("Failed to un-export the cached object : " +
166                             ex.getMessage(),ex);
167                 }
168             }
169             beanCacheEntry.cacheRelease();
170         }
171     }
172     
173     
174     /**
175      * This mehtod returns true if the cache contains the checked entry.
176      *
177      * @return TRUE if the cache contains the checked entry.
178      * @param cacheKey The entry to perform the check for.
179      */

180     public boolean contains(Object JavaDoc cacheKey) {
181         synchronized (entries) {
182             return entries.containsKey(cacheKey);
183         }
184     }
185     
186     
187     /**
188      * This method returns the bean cache entry for manipulation by the caller.
189      *
190      * @return A reference to the bean cache object.
191      * @param cacheEntry The cache entry to retrieve.
192      */

193     public BeanCacheEntry getEntry(Object JavaDoc cacheKey) throws BeanException {
194         synchronized (entries) {
195             checkStatus();
196             BeanCacheEntry beanCacheEntry =
197                     (BeanCacheEntry)entries.get(cacheKey);
198             if (beanCacheEntry != null) {
199                 beanCacheEntry.touch();
200             }
201             return beanCacheEntry;
202         }
203     }
204     
205     
206     /**
207      * This method adds the entry to the cache.
208      *
209      * @param cacheKey The key to identify this entry by.
210      * @param wrappedObject The object wrapped by the cache entry.
211      * @param entry An entry in the cache
212      */

213     public void addCacheEntry(long timeout,Object JavaDoc cacheKey, Object JavaDoc wrappedObject,
214             CacheEntry entry) throws BeanException {
215         synchronized(entries) {
216             checkStatus();
217             long cacheTimeout = timeout;
218             if (timeout == -1) {
219                 cacheTimeout = defaultCacheExpiryTime;
220             }
221             // remove the original entry if there is one.
222
BeanCacheEntry beanCacheEntry = getEntry(cacheKey);
223             if (beanCacheEntry != null) {
224                 try {
225                   PortableRemoteObject.unexportObject(
226                             (java.rmi.Remote JavaDoc)
227                             beanCacheEntry.getCacheEntry());
228                 } catch (java.rmi.NoSuchObjectException JavaDoc ex) {
229                     log.warn("The cache object was not bound : " +
230                             ex.getMessage(),ex);
231                 }
232             }
233             entries.put(cacheKey,new BeanCacheEntry(cacheTimeout,cacheKey,
234                     wrappedObject, entry));
235         }
236     }
237     
238     
239     /**
240      * This method adds a new entry to the cache.
241      *
242      * @param cacheKey The key to identify this entry by.
243      * @param wrappedObject The object wrapped by the proxy.
244      * @param proxy The proxy to add.
245      * @param handle The handler for the bean proxy object.
246      */

247     public void addCacheEntry(long timeout, Object JavaDoc cacheKey, Object JavaDoc wrappedObject,
248             Object JavaDoc proxy, CacheEntry handle) throws BeanException {
249         synchronized (entries) {
250             checkStatus();
251             long cacheTimeout = timeout;
252             if (timeout == -1) {
253                 cacheTimeout = defaultCacheExpiryTime;
254             }
255             // remove the original entry if there is one.
256
BeanCacheEntry beanCacheEntry = getEntry(cacheKey);
257             if (beanCacheEntry != null) {
258                 try {
259                   PortableRemoteObject.unexportObject(
260                             (java.rmi.Remote JavaDoc)
261                             beanCacheEntry.getCacheEntry());
262                 } catch (java.rmi.NoSuchObjectException JavaDoc ex) {
263                     log.warn("The cache object was not bound : " +
264                             ex.getMessage(),ex);
265                 }
266             }
267             entries.put(cacheKey,new BeanCacheEntry(cacheTimeout,cacheKey,
268                     wrappedObject, proxy, handle));
269         }
270     }
271     
272     
273     /**
274      * This method removes the entry from the cache based on the key passed in.
275      *
276      * @param cacheKey The key in the cache to remove.
277      */

278     public void removeCacheEntry(Object JavaDoc cacheKey) throws BeanException {
279         synchronized (entries) {
280             checkStatus();
281             entries.remove(cacheKey);
282         }
283     }
284     
285     
286     /**
287      * This method check the bean cache status.
288      */

289     private void checkStatus() throws BeanException {
290         if (status.isTerminated()) {
291             throw new BeanException("Bean cache has been terminated.");
292         }
293     }
294 }
295
Popular Tags