/* * Copyright 2005 Bruce Snyder, Werner Guttmann, Ralf Joachim * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.castor.cache; import java.util.Collection; import java.util.Collections; import java.util.Hashtable; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.castor.core.util.AbstractProperties; import org.castor.cpa.CPAProperties; /** * Registry for {@link CacheFactory} implementations obtained from the Castor * properties file and used by the JDO mapping configuration file. * * @author <a href="mailto:ferret AT frii DOT com">Bruce Snyder</a> * @author <a href="mailto:werner DOT guttmann AT gmx DOT net">Werner Guttmann</a> * @author <a href="mailto:ralf DOT joachim AT syscon DOT eu">Ralf Joachim</a> * @version $Revision$ $Date: 2006-04-25 16:09:10 -0600 (Tue, 25 Apr 2006) $ */ public final class CacheFactoryRegistry { //-------------------------------------------------------------------------- /** The <a href="http://jakarta.apache.org/commons/logging/">Jakarta Commons * Logging </a> instance used for all logging. */ private static final Log LOG = LogFactory.getLog(CacheFactoryRegistry.class); /** Name of the proxy class. */ private static final String PROXY_CLASSNAME = DebuggingCacheProxy.class.getName(); /** Association between {@link Cache} name and factory implementation. */ private Hashtable<String, CacheFactory> _cacheFactories = new Hashtable<String, CacheFactory>(); //-------------------------------------------------------------------------- /** * Construct an instance of CacheFactoryRegistry that uses given properties * to get required configuration properties. * * @param properties The properties. */ public CacheFactoryRegistry(final AbstractProperties properties) { Object[] objects = properties.getObjectArray( CPAProperties.CACHE_FACTORIES, properties.getApplicationClassLoader()); for (int i = 0; i < objects.length; i++) { CacheFactory factory = (CacheFactory) objects[i]; _cacheFactories.put(factory.getCacheType(), factory); } } //-------------------------------------------------------------------------- /** * Returns a {@link Cache} instance with the specified properties. * <p> * The type of the returned cache is taken from the <b>type</b> property. If not * specified a <b>count-limited</b> cache will be returned. If the type of the * cache specified is unknown a CacheAcquireException will be thrown. * <p> * If the given properties contain a <b>debug</b> property set to <b>true</b> or if * debugging for the selected cache type is enabled, the returned cache will be * wrapped by a DebuggingCacheProxy. This proxy will output debug messages to the * log if logging for the Cache interface is enabled through the logging system. * * @param props Properties to initialize the cache with. * @param classLoader A ClassLoader instance. * @return A {@link Cache} instance. * @throws CacheAcquireException A cache of the type specified can not be acquired. */ public Cache getCache(final Properties props, final ClassLoader classLoader) throws CacheAcquireException { String cacheType = props.getProperty(Cache.PARAM_TYPE, Cache.DEFAULT_TYPE); CacheFactory cacheFactory = _cacheFactories.get(cacheType); if (cacheFactory == null) { LOG.error("Unknown cache type '" + cacheType + "'"); throw new CacheAcquireException("Unknown cache type '" + cacheType + "'"); } Cache cache = cacheFactory.getCache(classLoader); String prop = props.getProperty(Cache.PARAM_DEBUG, Cache.DEFAULT_DEBUG); boolean objectDebug = Boolean.valueOf(prop).booleanValue(); boolean cacheDebug = LogFactory.getLog(Cache.class).isDebugEnabled(); boolean cacheTypeDebug = LogFactory.getLog(cache.getClass()).isDebugEnabled(); if (cacheTypeDebug || (cacheDebug && objectDebug)) { try { ClassLoader loader = CacheFactoryRegistry.class.getClassLoader(); Class<?> cls = loader.loadClass(PROXY_CLASSNAME); Class<?>[] types = new Class[] {Cache.class}; Object[] params = new Object[] {cache}; cache = (Cache) cls.getConstructor(types).newInstance(params); } catch (Exception e) { String msg = "Error creating instance of: " + PROXY_CLASSNAME; LOG.error(msg, e); throw new CacheAcquireException(msg, e); } } cache.initialize(props); if (LOG.isDebugEnabled()) { LOG.debug("Successfully instantiated '" + cacheType + "' cache: " + props.get(Cache.PARAM_NAME)); } return cache; } /** * Returns a collection of the current configured cache factories. * * @return Collection of the current configured cache factories. */ public Collection<CacheFactory> getCacheFactories() { return Collections.unmodifiableCollection(_cacheFactories.values()); } /** * Returns a collection of the current configured cache factory names. * * @return Names of the configured cache factories. */ public Collection<String> getCacheNames() { return Collections.unmodifiableCollection(_cacheFactories.keySet()); } //-------------------------------------------------------------------------- }