KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sape > carbon > services > cache > total > ReadOnlyCache


1 /*
2  * The contents of this file are subject to the Sapient Public License
3  * Version 1.0 (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  * http://carbon.sf.net/License.html.
6  *
7  * Software distributed under the License is distributed on an "AS IS" basis,
8  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9  * the specific language governing rights and limitations under the License.
10  *
11  * The Original Code is The Carbon Component Framework.
12  *
13  * The Initial Developer of the Original Code is Sapient Corporation
14  *
15  * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
16  */

17
18 package org.sape.carbon.services.cache.total;
19
20 import java.util.Collection JavaDoc;
21 import java.util.Collections JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Set JavaDoc;
25 import java.util.Comparator JavaDoc;
26 import java.lang.reflect.Constructor JavaDoc;
27 import java.lang.reflect.InvocationTargetException JavaDoc;
28
29 import org.sape.carbon.core.component.ComponentConfiguration;
30 import org.sape.carbon.core.component.lifecycle.Configurable;
31 import org.sape.carbon.services.cache.CacheLoadException;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36 /**
37  * <p>This Total Cache implementation is intended for fast
38  * reading of data which expires periodically as a whole. This implementation
39  * is optimized for read operations. All operations on the Map interface
40  * that could modify the cache are not supported and throw
41  * <code>UnsupportedOperationException</code>.</p>
42  *
43  * <p>Two hashmaps are used during the operation of the cache.
44  * The activeMap is the active map which is used to
45  * service all get requests for the cache. The holdingMap is used to
46  * reinitialize the cache. A call to initializeHoldingCache() creates a new
47  * holding map. The new map is then filled with all the information from
48  * the data loader. Then activateHoldingCache() atomically replaces the
49  * activeMap with the holdingMap and dereferences the old activeMap for garbage
50  * collection.</p>
51  *
52  * Copyright 2003 Sapient
53  * @since carbon 1.0
54  * @author Douglas Voet, March 2002
55  * @version $Revision: 1.13 $($Author: ghinkl $ / $Date: 2003/09/30 02:43:48 $)
56  */

57 public class ReadOnlyCache
58     extends AbstractTotalCache
59     implements Configurable {
60
61     /** The handle to Apache-commons logger */
62     private Log log = LogFactory.getLog(this.getClass());
63
64     /**
65      * The active map the cache queries against.
66      */

67     private Map JavaDoc activeMap;
68
69     /**
70      * A background map used for reloading the cache to minimize
71      * synchronization time.
72      */

73     private Map JavaDoc holdingMap;
74
75     /** Holds the dataloader for this cache. */
76     private TotalCacheDataLoader dataLoader;
77
78     /**
79      * Refresh the contents of the cache. First, initialize a holding cache.
80      * Then load the holding cache with new data from the data loader. Finally,
81      * activate the holding cache.
82      *
83      * @throws CacheLoadException when its data loader has failed to load data
84      */

85     public synchronized void refreshAll() throws CacheLoadException {
86
87         if (log.isTraceEnabled()) {
88             log.trace("Refreshing Cache");
89         }
90
91         this.initializeHoldingCache();
92         this.holdingMap.putAll(this.dataLoader.loadAllData());
93         this.activateHoldingCache();
94     }
95
96     /**
97      * @see Configurable#configure(ComponentConfiguration)
98      */

99     public void configure(ComponentConfiguration configuration) {
100
101         TotalCacheConfiguration config =
102             (TotalCacheConfiguration) configuration;
103         this.dataLoader = config.getDataLoader();
104     }
105
106     /**
107      * @see Map#entrySet()
108      *
109      * @return an unmodifiable set, this is a read-only cache
110      */

111     public Set JavaDoc entrySet() {
112         return Collections.unmodifiableSet(super.entrySet());
113     }
114
115     /**
116      * @see Map#keySet()
117      *
118      * @return an unmodifiable set, this is a read-only cache
119      */

120     public Set JavaDoc keySet() {
121         return Collections.unmodifiableSet(super.keySet());
122     }
123
124     /**
125      * @see Map#values()
126      *
127      * @return an unmodifiable collection, this is a read-only cache
128      */

129     public Collection JavaDoc values() {
130         return Collections.unmodifiableCollection(super.values());
131     }
132
133     /**
134      * @see Map#clear()
135      *
136      * @throws UnsupportedOperationException this is a read-only cache,
137      * modification methods are not supported
138      */

139     public void clear() {
140         throw new UnsupportedOperationException JavaDoc(
141             "Read-only cache does not support clear operation");
142     }
143
144     /**
145      * @see Map#put(Object, Object)
146      *
147      * @param key the key to add to the map
148      * @param value the value to add for the key
149      * @return the old value at the given key
150      * @throws UnsupportedOperationException this is a read-only cache,
151      * modification methods are not supported
152      */

153     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
154         throw new UnsupportedOperationException JavaDoc(
155             "Read-only cache does not support put operation");
156     }
157
158     /**
159      * @see Map#putAll(Map)
160      *
161      * @param t the map to place into the cache
162      * @throws UnsupportedOperationException this is a read-only cache,
163      * modification methods are not supported
164      */

165     public void putAll(Map JavaDoc t) {
166         throw new UnsupportedOperationException JavaDoc(
167             "Read-only cache does not support putAll operation");
168     }
169
170     /**
171      * @see Map#remove(Object)
172      *
173      * @param key the key to remove from this map
174      * @return the value stored at the given key or null
175      * @throws UnsupportedOperationException this is a read-only cache,
176      * modification methods are not supported
177      */

178     public Object JavaDoc remove(Object JavaDoc key) {
179         throw new UnsupportedOperationException JavaDoc(
180             "Read-only cache does not support remove operation");
181     }
182
183     /**
184      * @see AbstractTotalCache#getCacheMap()
185      */

186     protected Map JavaDoc getCacheMap() {
187         return this.activeMap;
188     }
189
190     /**
191      * <p>Replace the activeMap with the holdingMap</p>
192      */

193     private void activateHoldingCache() {
194         if (log.isTraceEnabled()) {
195             log.trace("Activating Holding Cache");
196         }
197         this.activeMap = this.holdingMap;
198         this.holdingMap = null;
199     }
200
201     /**
202      * Initialize the holdingMap
203      */

204     private void initializeHoldingCache() {
205         if (log.isTraceEnabled()) {
206             log.trace("Initializing Holding Cache");
207         }
208
209         // Checking for instance of appropriate dataloader. This will
210
// enable backward compatibility.
211
if (this.dataLoader instanceof ConfigurableMapTypeCacheDataLoader) {
212             this.holdingMap =
213                 ((ConfigurableMapTypeCacheDataLoader)this.dataLoader).
214                     getMapInstance();
215             if (log.isTraceEnabled()) {
216                 log.trace("Map instance created using "
217                     + (this.holdingMap.getClass()).getName());
218             }
219         } else {
220             if (log.isTraceEnabled()) {
221                 log.trace("Dataloader does not provide method for obtaining "
222                 + "instance of Map. Creating default instance as HashMap");
223             }
224             this.holdingMap = new HashMap JavaDoc();
225         }
226
227
228     }
229 }
Popular Tags