001: /**
002: * Copyright 2003-2007 Luck Consulting Pty Ltd
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */package net.sf.ehcache.config;
016:
017: import net.sf.ehcache.Cache;
018: import net.sf.ehcache.CacheException;
019: import net.sf.ehcache.CacheManager;
020: import net.sf.ehcache.Ehcache;
021: import net.sf.ehcache.loader.CacheLoader;
022: import net.sf.ehcache.loader.CacheLoaderFactory;
023: import net.sf.ehcache.exceptionhandler.CacheExceptionHandler;
024: import net.sf.ehcache.exceptionhandler.CacheExceptionHandlerFactory;
025: import net.sf.ehcache.exceptionhandler.ExceptionHandlingDynamicCacheProxy;
026: import net.sf.ehcache.extension.CacheExtension;
027: import net.sf.ehcache.extension.CacheExtensionFactory;
028: import net.sf.ehcache.bootstrap.BootstrapCacheLoader;
029: import net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory;
030: import net.sf.ehcache.distribution.CacheManagerPeerListener;
031: import net.sf.ehcache.distribution.CacheManagerPeerListenerFactory;
032: import net.sf.ehcache.distribution.CacheManagerPeerProvider;
033: import net.sf.ehcache.distribution.CacheManagerPeerProviderFactory;
034: import net.sf.ehcache.event.CacheEventListener;
035: import net.sf.ehcache.event.CacheEventListenerFactory;
036: import net.sf.ehcache.event.CacheManagerEventListener;
037: import net.sf.ehcache.event.CacheManagerEventListenerFactory;
038: import net.sf.ehcache.event.RegisteredEventListeners;
039: import net.sf.ehcache.util.ClassLoaderUtil;
040: import net.sf.ehcache.util.PropertyUtil;
041: import org.apache.commons.logging.Log;
042: import org.apache.commons.logging.LogFactory;
043:
044: import java.util.HashSet;
045: import java.util.Iterator;
046: import java.util.List;
047: import java.util.Map;
048: import java.util.Properties;
049: import java.util.Set;
050:
051: /**
052: * The configuration for ehcache.
053: * <p/>
054: * This class can be populated through:
055: * <ul>
056: * <li>introspection by {@link ConfigurationFactory} or
057: * <li>programmatically
058: * </ul>
059: *
060: * @author Greg Luck
061: * @version $Id: ConfigurationHelper.java 568 2007-12-18 10:39:07Z gregluck $
062: */
063: public final class ConfigurationHelper {
064:
065: private static final Log LOG = LogFactory
066: .getLog(ConfigurationHelper.class.getName());
067:
068: private Configuration configuration;
069: private CacheManager cacheManager;
070:
071: /**
072: * Only Constructor
073: *
074: * @param cacheManager
075: * @param configuration
076: */
077: public ConfigurationHelper(CacheManager cacheManager,
078: Configuration configuration) {
079: if (cacheManager == null || configuration == null) {
080: throw new IllegalArgumentException(
081: "Cannot have null parameters");
082: }
083: this .cacheManager = cacheManager;
084: this .configuration = configuration;
085: }
086:
087: /**
088: * A factory method to create a RegisteredEventListeners
089: */
090: protected static void registerCacheListeners(
091: CacheConfiguration cacheConfiguration,
092: RegisteredEventListeners registeredEventListeners) {
093: List cacheEventListenerConfigurations = cacheConfiguration
094: .getCacheEventListenerConfigurations();
095: for (int i = 0; i < cacheEventListenerConfigurations.size(); i++) {
096: CacheConfiguration.CacheEventListenerFactoryConfiguration factoryConfiguration = (CacheConfiguration.CacheEventListenerFactoryConfiguration) cacheEventListenerConfigurations
097: .get(i);
098: CacheEventListener cacheEventListener = createCacheEventListener(factoryConfiguration);
099: registeredEventListeners
100: .registerListener(cacheEventListener);
101: }
102: }
103:
104: /**
105: * A factory method to register cache extensions
106: */
107: protected static void registerCacheExtensions(
108: CacheConfiguration cacheConfiguration, Ehcache cache) {
109:
110: List cacheExtensionConfigurations = cacheConfiguration
111: .getCacheExtensionConfigurations();
112:
113: for (int i = 0; i < cacheExtensionConfigurations.size(); i++) {
114: CacheConfiguration.CacheExtensionFactoryConfiguration factoryConfiguration = (CacheConfiguration.CacheExtensionFactoryConfiguration) cacheExtensionConfigurations
115: .get(i);
116: CacheExtension cacheExtension = createCacheExtension(
117: factoryConfiguration, cache);
118: cache.registerCacheExtension(cacheExtension);
119: }
120: }
121:
122: /**
123: * Tries to load the class specified otherwise defaults to null.
124: *
125: * @param factoryConfiguration
126: */
127: private static CacheEventListener createCacheEventListener(
128: CacheConfiguration.CacheEventListenerFactoryConfiguration factoryConfiguration) {
129: String className = null;
130: CacheEventListener cacheEventListener = null;
131: if (factoryConfiguration != null) {
132: className = factoryConfiguration
133: .getFullyQualifiedClassPath();
134: }
135: if (className == null) {
136: LOG
137: .debug("CacheEventListener factory not configured. Skipping...");
138: } else {
139: CacheEventListenerFactory factory = (CacheEventListenerFactory) ClassLoaderUtil
140: .createNewInstance(className);
141: Properties properties =
142:
143: PropertyUtil.parseProperties(factoryConfiguration
144: .getProperties(), factoryConfiguration
145: .getPropertySeparator());
146: cacheEventListener = factory
147: .createCacheEventListener(properties);
148: }
149: return cacheEventListener;
150: }
151:
152: /**
153: * Tries to load the class specified otherwise defaults to null.
154: *
155: * @param factoryConfiguration
156: */
157: private static CacheExtension createCacheExtension(
158: CacheConfiguration.CacheExtensionFactoryConfiguration factoryConfiguration,
159: Ehcache cache) {
160: String className = null;
161: CacheExtension cacheExtension = null;
162: if (factoryConfiguration != null) {
163: className = factoryConfiguration
164: .getFullyQualifiedClassPath();
165: }
166: if (className == null) {
167: LOG
168: .debug("CacheExtension factory not configured. Skipping...");
169: } else {
170: CacheExtensionFactory factory = (CacheExtensionFactory) ClassLoaderUtil
171: .createNewInstance(className);
172: Properties properties = PropertyUtil.parseProperties(
173: factoryConfiguration.getProperties(),
174: factoryConfiguration.getPropertySeparator());
175: cacheExtension = factory.createCacheExtension(cache,
176: properties);
177: }
178: return cacheExtension;
179: }
180:
181: /**
182: * Tries to load a BootstrapCacheLoader from the class specified.
183: *
184: * @return If there is none returns null.
185: */
186: public final BootstrapCacheLoader createBootstrapCacheLoader(
187: CacheConfiguration.BootstrapCacheLoaderFactoryConfiguration factoryConfiguration)
188: throws CacheException {
189: String className = null;
190: BootstrapCacheLoader bootstrapCacheLoader = null;
191: if (factoryConfiguration != null) {
192: className = factoryConfiguration
193: .getFullyQualifiedClassPath();
194: }
195: if (className == null || className.length() == 0) {
196: LOG
197: .debug("No BootstrapCacheLoaderFactory class specified. Skipping...");
198: } else {
199: BootstrapCacheLoaderFactory factory = (BootstrapCacheLoaderFactory) ClassLoaderUtil
200: .createNewInstance(className);
201: Properties properties = PropertyUtil.parseProperties(
202: factoryConfiguration.getProperties(),
203: factoryConfiguration.getPropertySeparator());
204: return factory.createBootstrapCacheLoader(properties);
205: }
206: return bootstrapCacheLoader;
207: }
208:
209: /**
210: * Tries to create a CacheLoader from the configuration using the factory
211: * specified.
212: *
213: * @return The CacheLoader, or null if it could not be found.
214: */
215: public final CacheLoader createCacheLoader(
216: CacheConfiguration.CacheLoaderFactoryConfiguration factoryConfiguration)
217: throws CacheException {
218: String className = null;
219: CacheLoader cacheLoader = null;
220: if (factoryConfiguration != null) {
221: className = factoryConfiguration
222: .getFullyQualifiedClassPath();
223: }
224: if (className == null || className.length() == 0) {
225: LOG
226: .debug("No CacheLoaderFactory class specified. Skipping...");
227: } else {
228: CacheLoaderFactory factory = (CacheLoaderFactory) ClassLoaderUtil
229: .createNewInstance(className);
230: Properties properties = PropertyUtil.parseProperties(
231: factoryConfiguration.getProperties(),
232: factoryConfiguration.getPropertySeparator());
233: return factory.createCacheLoader(properties);
234: }
235: return cacheLoader;
236: }
237:
238: /**
239: * Tries to create a CacheLoader from the configuration using the factory
240: * specified.
241: *
242: * @return The CacheExceptionHandler, or null if it could not be found.
243: */
244: public final CacheExceptionHandler createCacheExceptionHandler(
245: CacheConfiguration.CacheExceptionHandlerFactoryConfiguration factoryConfiguration)
246: throws CacheException {
247: String className = null;
248: CacheExceptionHandler cacheExceptionHandler = null;
249: if (factoryConfiguration != null) {
250: className = factoryConfiguration
251: .getFullyQualifiedClassPath();
252: }
253: if (className == null || className.length() == 0) {
254: LOG
255: .debug("No CacheExceptionHandlerFactory class specified. Skipping...");
256: } else {
257: CacheExceptionHandlerFactory factory = (CacheExceptionHandlerFactory) ClassLoaderUtil
258: .createNewInstance(className);
259: Properties properties = PropertyUtil.parseProperties(
260: factoryConfiguration.getProperties(),
261: factoryConfiguration.getPropertySeparator());
262: return factory.createExceptionHandler(properties);
263: }
264: return cacheExceptionHandler;
265: }
266:
267: /**
268: * Tries to load the class specified otherwise defaults to null
269: */
270: public final CacheManagerPeerProvider createCachePeerProvider() {
271: String className = null;
272: FactoryConfiguration cachePeerProviderFactoryConfiguration = configuration
273: .getCacheManagerPeerProviderFactoryConfiguration();
274: if (cachePeerProviderFactoryConfiguration != null) {
275: className = cachePeerProviderFactoryConfiguration
276: .getFullyQualifiedClassPath();
277: }
278: if (className == null) {
279: LOG
280: .debug("No CachePeerProviderFactoryConfiguration specified. Not configuring a CacheManagerPeerProvider.");
281: return null;
282: } else {
283: CacheManagerPeerProviderFactory cacheManagerPeerProviderFactory = (CacheManagerPeerProviderFactory) ClassLoaderUtil
284: .createNewInstance(className);
285: Properties properties = PropertyUtil.parseProperties(
286: cachePeerProviderFactoryConfiguration
287: .getProperties(),
288: cachePeerProviderFactoryConfiguration
289: .getPropertySeparator());
290: return cacheManagerPeerProviderFactory
291: .createCachePeerProvider(cacheManager, properties);
292: }
293: }
294:
295: /**
296: * Tries to load the class specified otherwise defaults to null
297: */
298: public final CacheManagerPeerListener createCachePeerListener() {
299: String className = null;
300: FactoryConfiguration cachePeerListenerFactoryConfiguration = configuration
301: .getCacheManagerPeerListenerFactoryConfiguration();
302: if (cachePeerListenerFactoryConfiguration != null) {
303: className = cachePeerListenerFactoryConfiguration
304: .getFullyQualifiedClassPath();
305: }
306: if (className == null) {
307: LOG
308: .debug("No CachePeerListenerFactoryConfiguration specified. Not configuring a CacheManagerPeerListener.");
309: return null;
310: } else {
311: CacheManagerPeerListenerFactory cacheManagerPeerListenerFactory = (CacheManagerPeerListenerFactory) ClassLoaderUtil
312: .createNewInstance(className);
313: Properties properties = PropertyUtil.parseProperties(
314: cachePeerListenerFactoryConfiguration
315: .getProperties(),
316: cachePeerListenerFactoryConfiguration
317: .getPropertySeparator());
318: return cacheManagerPeerListenerFactory
319: .createCachePeerListener(cacheManager, properties);
320: }
321: }
322:
323: /**
324: * Tries to load the class specified.
325: *
326: * @return If there is none returns null.
327: */
328: public final CacheManagerEventListener createCacheManagerEventListener()
329: throws CacheException {
330: String className = null;
331: FactoryConfiguration cacheManagerEventListenerFactoryConfiguration = configuration
332: .getCacheManagerEventListenerFactoryConfiguration();
333: if (cacheManagerEventListenerFactoryConfiguration != null) {
334: className = cacheManagerEventListenerFactoryConfiguration
335: .getFullyQualifiedClassPath();
336: }
337: if (className == null || className.length() == 0) {
338: LOG
339: .debug("No CacheManagerEventListenerFactory class specified. Skipping...");
340: return null;
341: } else {
342: CacheManagerEventListenerFactory factory = (CacheManagerEventListenerFactory) ClassLoaderUtil
343: .createNewInstance(className);
344: Properties properties = PropertyUtil
345: .parseProperties(
346: cacheManagerEventListenerFactoryConfiguration.properties,
347: cacheManagerEventListenerFactoryConfiguration
348: .getPropertySeparator());
349: return factory.createCacheManagerEventListener(properties);
350: }
351: }
352:
353: /**
354: * @return the disk store path, or null if not set.
355: */
356: public final String getDiskStorePath() {
357: DiskStoreConfiguration diskStoreConfiguration = configuration
358: .getDiskStoreConfiguration();
359: if (diskStoreConfiguration == null) {
360: return null;
361: } else {
362: return diskStoreConfiguration.getPath();
363: }
364: }
365:
366: /**
367: * @return the Default Cache
368: * @throws net.sf.ehcache.CacheException if there is no default cache
369: */
370: public final Ehcache createDefaultCache() throws CacheException {
371: CacheConfiguration cacheConfiguration = configuration
372: .getDefaultCacheConfiguration();
373: if (cacheConfiguration == null) {
374: throw new CacheException(
375: "Illegal configuration. No default cache is configured.");
376: } else {
377: cacheConfiguration.name = Cache.DEFAULT_CACHE_NAME;
378: return createCache(cacheConfiguration);
379: }
380: }
381:
382: /**
383: * Creates unitialised caches for each cache configuration found
384: *
385: * @return an empty set if there are none,
386: */
387: public final Set createCaches() {
388: Set caches = new HashSet();
389: Set cacheConfigurations = configuration
390: .getCacheConfigurations().entrySet();
391: for (Iterator iterator = cacheConfigurations.iterator(); iterator
392: .hasNext();) {
393: Map.Entry entry = (Map.Entry) iterator.next();
394: CacheConfiguration cacheConfiguration = (CacheConfiguration) entry
395: .getValue();
396: Ehcache cache = createCache(cacheConfiguration);
397: caches.add(cache);
398: }
399: return caches;
400: }
401:
402: /**
403: * Calculates the number of caches in the configuration that overflow to disk
404: */
405: public final Integer numberOfCachesThatOverflowToDisk() {
406: int count = 0;
407: Set cacheConfigurations = configuration
408: .getCacheConfigurations().entrySet();
409: for (Iterator iterator = cacheConfigurations.iterator(); iterator
410: .hasNext();) {
411: Map.Entry entry = (Map.Entry) iterator.next();
412: CacheConfiguration cacheConfiguration = (CacheConfiguration) entry
413: .getValue();
414: if (cacheConfiguration.overflowToDisk) {
415: count++;
416: }
417: }
418: return new Integer(count);
419: }
420:
421: /**
422: * Creates a cache from configuration where the configuration cache name matches the given name
423: *
424: * @return the cache, or null if there is no match
425: */
426: final Ehcache createCacheFromName(String name) {
427: CacheConfiguration cacheConfiguration = null;
428: Set cacheConfigurations = configuration
429: .getCacheConfigurations().entrySet();
430: for (Iterator iterator = cacheConfigurations.iterator(); iterator
431: .hasNext();) {
432: Map.Entry entry = (Map.Entry) iterator.next();
433: CacheConfiguration cacheConfigurationCandidate = (CacheConfiguration) entry
434: .getValue();
435: if (cacheConfigurationCandidate.name.equals(name)) {
436: cacheConfiguration = cacheConfigurationCandidate;
437: break;
438: }
439: }
440: if (cacheConfiguration == null) {
441: return null;
442: } else {
443: return createCache(cacheConfiguration);
444: }
445: }
446:
447: /**
448: * Create a cache given a cache configuration
449: *
450: * @param cacheConfiguration
451: */
452: final Ehcache createCache(CacheConfiguration cacheConfiguration) {
453: Ehcache cache = new Cache(cacheConfiguration.name,
454: cacheConfiguration.maxElementsInMemory,
455: cacheConfiguration.memoryStoreEvictionPolicy,
456: cacheConfiguration.overflowToDisk, getDiskStorePath(),
457: cacheConfiguration.eternal,
458: cacheConfiguration.timeToLiveSeconds,
459: cacheConfiguration.timeToIdleSeconds,
460: cacheConfiguration.diskPersistent,
461: cacheConfiguration.diskExpiryThreadIntervalSeconds,
462: null, null, cacheConfiguration.maxElementsOnDisk,
463: cacheConfiguration.diskSpoolBufferSizeMB);
464: RegisteredEventListeners listeners = cache
465: .getCacheEventNotificationService();
466: registerCacheListeners(cacheConfiguration, listeners);
467: registerCacheExtensions(cacheConfiguration, cache);
468: BootstrapCacheLoader bootstrapCacheLoader = createBootstrapCacheLoader(cacheConfiguration
469: .getBootstrapCacheLoaderFactoryConfiguration());
470: cache.setBootstrapCacheLoader(bootstrapCacheLoader);
471: CacheLoader cacheLoader = createCacheLoader(cacheConfiguration
472: .getCacheLoaderFactoryConfiguration());
473: cache.setCacheLoader(cacheLoader);
474: cache = applyCacheExceptionHandler(cacheConfiguration, cache);
475: return cache;
476: }
477:
478: private Ehcache applyCacheExceptionHandler(
479: CacheConfiguration cacheConfiguration, Ehcache cache) {
480: CacheExceptionHandler cacheExceptionHandler = createCacheExceptionHandler(cacheConfiguration
481: .getCacheExceptionHandlerFactoryConfiguration());
482: cache.setCacheExceptionHandler(cacheExceptionHandler);
483:
484: if (cache.getCacheExceptionHandler() != null) {
485: return ExceptionHandlingDynamicCacheProxy
486: .createProxy(cache);
487: }
488: return cache;
489: }
490:
491: /**
492: * @return the Configuration used
493: */
494: public final Configuration getConfigurationBean() {
495: return configuration;
496: }
497: }
|