KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > loader > CacheLoaderManager


1 /*
2  * JBoss, Home of Professional Open Source
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7 package org.jboss.cache.loader;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11 import org.jboss.cache.CacheListener;
12 import org.jboss.cache.CacheSPI;
13 import org.jboss.cache.Fqn;
14 import org.jboss.cache.config.CacheLoaderConfig;
15 import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
16
17 import java.util.ArrayList JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.Set JavaDoc;
20 import java.util.StringTokenizer JavaDoc;
21
22 /**
23  * Manages all cache loader functionality. This class is typically initialised with an XML DOM Element,
24  * represeting a cache loader configuration, or a {@see CacheLoaderConfig} object.
25  * <p/>
26  * Usage:
27  * <p/>
28  * <code>
29  * CacheLoaderManager manager = new CacheLoaderManager();
30  * manager.setConfig(myXmlSnippet, myTreeCache);
31  * CacheLoader loader = manager.getCacheLoader();
32  * </code>
33  * <p/>
34  * The XML configuration passed in would typically look like:
35  * <p/>
36  * <code><![CDATA[
37  * <p/>
38  * <config>
39  * <passivation>false</passivation>
40  * <preload>/</preload>
41  * <p/>
42  * <cacheloader>
43  * <class>org.jboss.cache.loader.FileCacheLoader</class>
44  * <async>true</async>
45  * <fetchPersistentState>false</fetchPersistentState>
46  * <ignoreModifications>false</ignoreModifications>
47  * <properties>
48  * location=/tmp/file
49  * </properties>
50  * </cacheloader>
51  * </config>
52  * ]]>
53  * </code>
54  *
55  * @author <a HREF="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
56  */

57 public class CacheLoaderManager
58 {
59    private static Log log = LogFactory.getLog(CacheLoaderManager.class);
60    private CacheLoaderConfig config;
61    private CacheSPI cache;
62    private CacheLoader loader;
63    private boolean fetchPersistentState;
64
65    /**
66     * Sets a configuration object and creates a cacheloader accordingly.
67     *
68     * @param config
69     * @param cache
70     * @throws Exception
71     */

72    public void setConfig(CacheLoaderConfig config, CacheSPI cache) throws Exception JavaDoc
73    {
74       this.config = config == null ? new CacheLoaderConfig() : config;
75       this.cache = cache;
76       loader = createCacheLoader();
77    }
78
79    /**
80     * Creates the cache loader based on a cache loader config passed in.
81     *
82     * @return a configured cacheloader
83     * @throws IllegalAccessException
84     * @throws InstantiationException
85     * @throws ClassNotFoundException
86     */

87    private CacheLoader createCacheLoader() throws Exception JavaDoc
88    {
89       CacheLoader tmpLoader = null;
90       // if we only have a single cache loader configured in the chaining cacheloader then
91
// don't use a chaining cache loader at all.
92

93       ArrayList JavaDoc<IndividualCacheLoaderConfig> finalConfigs =
94               new ArrayList JavaDoc<IndividualCacheLoaderConfig>();
95
96       // also if we are using passivation then just directly use the first cache loader.
97
if (config.useChainingCacheLoader())
98       {
99          // create chaining cache loader.
100
tmpLoader = new ChainingCacheLoader();
101          ChainingCacheLoader ccl = (ChainingCacheLoader) tmpLoader;
102          Iterator JavaDoc it = config.getIndividualCacheLoaderConfigs().iterator();
103
104          // only one cache loader may have fetchPersistentState to true.
105
int numLoadersWithFetchPersistentState = 0;
106          while (it.hasNext())
107          {
108             CacheLoaderConfig.IndividualCacheLoaderConfig cfg = (CacheLoaderConfig.IndividualCacheLoaderConfig) it.next();
109             if (cfg.isFetchPersistentState())
110             {
111                numLoadersWithFetchPersistentState++;
112                fetchPersistentState = true;
113             }
114             if (numLoadersWithFetchPersistentState > 1)
115             {
116                throw new Exception JavaDoc("Invalid cache loader configuration!! Only ONE cache loader may have fetchPersistentState set to true. Cache will not start!");
117             }
118             if (cfg.isSingletonStore() && config.isShared())
119             {
120                throw new Exception JavaDoc("Invalid cache loader configuration!! If a cache loader is configured as a singleton, the cache loader cannot be shared in a cluster!");
121             }
122
123             CacheLoader l = createCacheLoader(cfg, cache);
124             cfg = l.getConfig();
125             finalConfigs.add(cfg);
126             // Only loaders that deal w/ state transfer factor into
127
// whether the overall chain supports ExtendedCacheLoader
128
ccl.addCacheLoader(l, cfg);
129
130          }
131       }
132       else
133       {
134          CacheLoaderConfig.IndividualCacheLoaderConfig cfg = config.getIndividualCacheLoaderConfigs().get(0);
135          tmpLoader = createCacheLoader(cfg, cache);
136          finalConfigs.add(tmpLoader.getConfig());
137          fetchPersistentState = cfg.isFetchPersistentState();
138       }
139
140       // Update the config with those actually used by the loaders
141
config.setIndividualCacheLoaderConfigs(finalConfigs);
142
143       return tmpLoader;
144    }
145
146    /**
147     * Creates the cache loader based on the configuration.
148     *
149     * @param cfg
150     * @param cache
151     * @return a cache loader
152     * @throws Exception
153     */

154    private CacheLoader createCacheLoader(CacheLoaderConfig.IndividualCacheLoaderConfig cfg, CacheSPI cache) throws Exception JavaDoc
155    {
156       // create loader
157
CacheLoader tmpLoader = createInstance(cfg.getClassName());
158
159       if (tmpLoader != null)
160       {
161          // async?
162
if (cfg.isAsync())
163          {
164             CacheLoader asyncDecorator;
165             asyncDecorator = new AsyncCacheLoader(tmpLoader);
166             tmpLoader = asyncDecorator;
167          }
168
169          // singleton?
170
if (cfg.isSingletonStore())
171          {
172             SingletonStoreCacheLoader singletonDecorator = new SingletonStoreCacheLoader(tmpLoader, cfg.isPushStateWhenCoordinator());
173             addCacheListener(cache, singletonDecorator.getCacheListener());
174             tmpLoader = singletonDecorator;
175          }
176
177          // load props
178
tmpLoader.setConfig(cfg);
179
180          tmpLoader.setCache(cache);
181          // we should not be creating/starting the cache loader here - this should be done in the separate
182
// startCacheLoader() method.
183
// tmpLoader.create();
184
// tmpLoader.start();
185
if (cache != null && cache.getConfiguration().isUseRegionBasedMarshalling())
186          {
187             tmpLoader.setRegionManager(cache.getRegionManager());
188          }
189       }
190       return tmpLoader;
191    }
192
193    private CacheLoader createInstance(String JavaDoc className) throws ClassNotFoundException JavaDoc, IllegalAccessException JavaDoc, InstantiationException JavaDoc
194    {
195       Class JavaDoc cl = Thread.currentThread().getContextClassLoader().loadClass(className);
196       return (CacheLoader) cl.newInstance();
197    }
198
199    /**
200     * Performs a preload on the cache based on the cache loader preload configs used when configuring the cache.
201     *
202     * @throws Exception
203     */

204    public void preloadCache() throws Exception JavaDoc
205    {
206       if (config.getPreload() == null || config.getPreload().equals("")) return;
207       if (log.isDebugEnabled()) log.debug("preloading transient state from cache loader " + loader);
208       StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(config.getPreload(), ",");
209       String JavaDoc tok;
210       Fqn fqn;
211       long start, stop, total;
212       start = System.currentTimeMillis();
213       while (st.hasMoreTokens())
214       {
215          tok = st.nextToken();
216          fqn = Fqn.fromString(tok.trim());
217          if (log.isTraceEnabled()) log.trace("preloading " + fqn);
218          preload(fqn, true, true);
219       }
220
221       stop = System.currentTimeMillis();
222       total = stop - start;
223       if (log.isDebugEnabled())
224       {
225          log.debug("preloading transient state from cache loader was successful (in " + total + " milliseconds)");
226       }
227    }
228
229    /**
230     * Preloads a specific Fqn into the cache from the configured cacheloader
231     *
232     * @param fqn fqn to preload
233     * @param preloadParents whether we preload parents
234     * @param preloadChildren whether we preload children
235     * @throws Exception
236     */

237    public void preload(Fqn fqn, boolean preloadParents, boolean preloadChildren) throws Exception JavaDoc
238    {
239
240       // 1. Load the attributes first
241
// but this will go down the entire damn chain!! :S
242
cache.get(fqn, "bla");
243
244       // 2. Then load the parents
245
if (preloadParents)
246       {
247          Fqn tmp_fqn = Fqn.ROOT;
248          for (int i = 0; i < fqn.size() - 1; i++)
249          {
250             tmp_fqn = new Fqn(tmp_fqn, fqn.get(i));
251             cache.get(tmp_fqn, "bla");
252          }
253       }
254
255       if (preloadChildren)
256       {
257          // 3. Then recursively for all child nodes, preload them as well
258
Set JavaDoc children = loader.getChildrenNames(fqn);
259          if (children != null)
260          {
261             for (Iterator JavaDoc it = children.iterator(); it.hasNext();)
262             {
263                String JavaDoc child_name = (String JavaDoc) it.next();
264                Fqn child_fqn = new Fqn(fqn, child_name);
265                preload(child_fqn, false, true);
266             }
267          }
268       }
269    }
270
271    /**
272     * Returns the configuration element of the cache loaders
273     */

274    public CacheLoaderConfig getCacheLoaderConfig()
275    {
276       return config;
277    }
278
279    /**
280     * Returns the cache loader
281     */

282    public CacheLoader getCacheLoader()
283    {
284       return loader;
285    }
286
287    /**
288     * Overrides generated cache loader with the one provided,for backward compat.
289     *
290     * @param loader
291     */

292    public void setCacheLoader(CacheLoader loader)
293    {
294       this.loader = loader;
295    }
296
297    /**
298     * Tests if we're using passivation
299     */

300    public boolean isPassivation()
301    {
302       return config.isPassivation();
303    }
304
305    /**
306     * Returns true if at least one of the configured cache loaders has set fetchPersistentState to true.
307     */

308    public boolean isFetchPersistentState()
309    {
310       return fetchPersistentState;
311    }
312
313    public void stopCacheLoader()
314    {
315       if (loader == null) throw new RuntimeException JavaDoc("Problem with configured cache loader - it has been set to null!");
316       // stop the cache loader
317
loader.stop();
318       // destroy the cache loader
319
loader.destroy();
320    }
321
322    public void startCacheLoader() throws Exception JavaDoc
323    {
324       if (loader == null) throw new RuntimeException JavaDoc("Improperly configured cache loader - cache loader is null!");
325       // create the cache loader
326
loader.create();
327       // start the cache loader
328
loader.start();
329
330       purgeLoaders(false);
331    }
332
333    public void purgeLoaders(boolean force) throws Exception JavaDoc
334    {
335       if ((loader instanceof ChainingCacheLoader) && !force)
336       {
337          ((ChainingCacheLoader) loader).purgeIfNecessary();
338       }
339       else
340       {
341          CacheLoaderConfig.IndividualCacheLoaderConfig first = getCacheLoaderConfig().getFirstCacheLoaderConfig();
342          if (force ||
343                  (first != null && first.isPurgeOnStartup()))
344          {
345             loader.remove(Fqn.ROOT);
346          }
347       }
348    }
349
350    protected void addCacheListener(CacheSPI cache, CacheListener listener)
351    {
352       cache.addCacheListener(listener);
353    }
354 }
355
Popular Tags