You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tv...@apache.org on 2016/01/30 16:24:32 UTC

svn commit: r1727713 - in /commons/proper/jcs/trunk: commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/ commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/ src/changes/

Author: tv
Date: Sat Jan 30 15:24:32 2016
New Revision: 1727713

URL: http://svn.apache.org/viewvc?rev=1727713&view=rev
Log:
Attempt to fix JCS-116 : CompositeCacheManager is thread-hostile

Modified:
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java
    commons/proper/jcs/trunk/src/changes/changes.xml

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java?rev=1727713&r1=1727712&r2=1727713&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java Sat Jan 30 15:24:32 2016
@@ -19,10 +19,7 @@ package org.apache.commons.jcs.engine.co
  * under the License.
  */
 
-import java.io.FileInputStream;
-import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Enumeration;
 import java.util.List;
 import java.util.Properties;
 import java.util.StringTokenizer;
@@ -56,26 +53,26 @@ public class CompositeCacheConfigurator
     /** The logger */
     private static final Log log = LogFactory.getLog( CompositeCacheConfigurator.class );
 
-    /** default region prefix */
-    static final String DEFAULT_REGION = "jcs.default";
+    /** The prefix of relevant system properties */
+    protected static final String SYSTEM_PROPERTY_KEY_PREFIX = "jcs";
 
     /** normal region prefix */
-    static final String REGION_PREFIX = "jcs.region.";
+    protected static final String REGION_PREFIX = "jcs.region.";
 
     /** system region prefix. might not be used */
-    static final String SYSTEM_REGION_PREFIX = "jcs.system.";
+    protected static final String SYSTEM_REGION_PREFIX = "jcs.system.";
 
     /** auxiliary prefix */
-    static final String AUXILIARY_PREFIX = "jcs.auxiliary.";
+    protected static final String AUXILIARY_PREFIX = "jcs.auxiliary.";
 
     /** .attributes */
-    static final String ATTRIBUTE_PREFIX = ".attributes";
+    protected static final String ATTRIBUTE_PREFIX = ".attributes";
 
     /** .cacheattributes */
-    static final String CACHE_ATTRIBUTE_PREFIX = ".cacheattributes";
+    protected static final String CACHE_ATTRIBUTE_PREFIX = ".cacheattributes";
 
     /** .elementattributes */
-    static final String ELEMENT_ATTRIBUTE_PREFIX = ".elementattributes";
+    protected static final String ELEMENT_ATTRIBUTE_PREFIX = ".elementattributes";
 
     /**
      * jcs.auxiliary.NAME.keymatcher=CLASSNAME
@@ -84,171 +81,34 @@ public class CompositeCacheConfigurator
      */
     public static final String KEY_MATCHER_PREFIX = ".keymatcher";
 
-    /** Can't operate on the interface. */
-    private final CompositeCacheManager compositeCacheManager;
-
     /**
      * Constructor for the CompositeCacheConfigurator object
-     *<p>
-     * @param ccMgr
-     */
-    public CompositeCacheConfigurator( CompositeCacheManager ccMgr )
-    {
-        this.compositeCacheManager = ccMgr;
-    }
-
-    /**
-     * Configure cached for file name.
-     * <p>
-     * This is only used for testing. The manager handles the translation of a file into a
-     * properties object.
-     * <p>
-     * @param configFileName
-     */
-    protected void doConfigure( String configFileName )
-    {
-        Properties props = new Properties();
-        FileInputStream istream = null;
-
-        try
-        {
-            istream = new FileInputStream( configFileName );
-            props.load( istream );
-        }
-        catch ( IOException e )
-        {
-            log.error( "Could not read configuration file, ignored: " + configFileName, e );
-            return;
-        }
-        finally
-        {
-            if (istream != null)
-            {
-                try
-                {
-                    istream.close();
-                }
-                catch (IOException e)
-                {
-                    log.error( "Could not close configuration file " + configFileName, e );
-                }
-            }
-        }
-
-        // If we reach here, then the config file is all right.
-        doConfigure( props );
-    }
-
-    /**
-     * Configure cache for properties object.
-     * <p>
-     * This method proceeds in several steps:
-     * <ul>
-     * <li>Store props for use by non configured caches.
-     * <li>Set default value list
-     * <li>Set default cache attr
-     * <li>Set default element attr
-     * <li>Setup system caches to be used
-     * <li>Setup preconfigured caches
-     * </ul>
-     * @param properties
-     */
-    public void doConfigure( Properties properties )
-    {
-        long start = System.currentTimeMillis();
-
-        // store props for use by non configured caches
-        compositeCacheManager.setConfigurationProperties( properties );
-
-        // set default value list
-        setDefaultAuxValues( properties );
-
-        // set default cache attr
-        setDefaultCompositeCacheAttributes( properties );
-
-        // set default element attr
-        setDefaultElementAttributes( properties );
-
-        // set up system caches to be used by non system caches
-        // need to make sure there is no circularity of reference
-        parseSystemRegions( properties );
-
-        // setup preconfigured caches
-        parseRegions( properties );
-
-        long end = System.currentTimeMillis();
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Finished configuration in " + ( end - start ) + " ms." );
-        }
-
-    }
-
-    /**
-     * Set the default aux list for new caches.
-     * <p>
-     * @param props
      */
-    protected void setDefaultAuxValues( Properties props )
+    public CompositeCacheConfigurator()
     {
-        String value = OptionConverter.findAndSubst( DEFAULT_REGION, props );
-        compositeCacheManager.setDefaultAuxValues(value);
-
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Setting default auxiliaries to " + value );
-        }
-    }
-
-    /**
-     * Set the default CompositeCacheAttributes for new caches.
-     *<p>
-     * @param props
-     */
-    protected void setDefaultCompositeCacheAttributes( Properties props )
-    {
-        ICompositeCacheAttributes icca = parseCompositeCacheAttributes( props, "",
-                                                                        CompositeCacheConfigurator.DEFAULT_REGION );
-        compositeCacheManager.setDefaultCacheAttributes( icca );
-
-        log.info( "setting defaultCompositeCacheAttributes to " + icca );
-    }
-
-    /**
-     * Set the default ElementAttributes for new caches.
-     *<p>
-     * @param props
-     */
-    protected void setDefaultElementAttributes( Properties props )
-    {
-        IElementAttributes iea = parseElementAttributes( props, "", CompositeCacheConfigurator.DEFAULT_REGION );
-        compositeCacheManager.setDefaultElementAttributes( iea );
-
-        log.info( "setting defaultElementAttributes to " + iea );
+        // empty
     }
 
     /**
      * Create caches used internally. System status gives them creation priority.
      *<p>
-     * @param props
+     * @param props Configuration properties
+     * @param ccm Cache hub
      */
-    protected void parseSystemRegions( Properties props )
+    protected void parseSystemRegions( Properties props, CompositeCacheManager ccm )
     {
-        Enumeration<?> en = props.propertyNames();
-        while ( en.hasMoreElements() )
+        for (String key : props.stringPropertyNames() )
         {
-            String key = (String) en.nextElement();
             if ( key.startsWith( SYSTEM_REGION_PREFIX ) && key.indexOf( "attributes" ) == -1 )
             {
                 String regionName = key.substring( SYSTEM_REGION_PREFIX.length() );
-                String value = OptionConverter.findAndSubst( key, props );
+                String auxiliaries = OptionConverter.findAndSubst( key, props );
                 ICache<?, ?> cache;
                 synchronized ( regionName )
                 {
-                    cache = parseRegion( props, regionName, value, null, SYSTEM_REGION_PREFIX );
+                    cache = parseRegion( props, ccm, regionName, auxiliaries, null, SYSTEM_REGION_PREFIX );
                 }
-
-                compositeCacheManager.addCache( regionName, cache );
+                ccm.addCache( regionName, cache );
             }
         }
     }
@@ -256,29 +116,26 @@ public class CompositeCacheConfigurator
     /**
      * Parse region elements.
      *<p>
-     * @param props
+     * @param props Configuration properties
+     * @param ccm Cache hub
      */
-    protected void parseRegions( Properties props )
+    protected void parseRegions( Properties props, CompositeCacheManager ccm )
     {
         List<String> regionNames = new ArrayList<String>();
 
-        Enumeration<?> en = props.propertyNames();
-        while ( en.hasMoreElements() )
+        for (String key : props.stringPropertyNames() )
         {
-            String key = (String) en.nextElement();
             if ( key.startsWith( REGION_PREFIX ) && key.indexOf( "attributes" ) == -1 )
             {
                 String regionName = key.substring( REGION_PREFIX.length() );
-
                 regionNames.add( regionName );
-
-                String auxiliaryList = OptionConverter.findAndSubst( key, props );
+                String auxiliaries = OptionConverter.findAndSubst( key, props );
                 ICache<?, ?> cache;
                 synchronized ( regionName )
                 {
-                    cache = parseRegion( props, regionName, auxiliaryList );
+                    cache = parseRegion( props, ccm, regionName, auxiliaries );
                 }
-                compositeCacheManager.addCache( regionName, cache );
+                ccm.addCache( regionName, cache );
             }
         }
 
@@ -291,15 +148,17 @@ public class CompositeCacheConfigurator
     /**
      * Create cache region.
      *<p>
-     * @param props
-     * @param regName
-     * @param value
+     * @param props Configuration properties
+     * @param ccm Cache hub
+     * @param regName Name of the cache region
+     * @param auxiliaries Comma separated list of auxiliaries
+     *
      * @return CompositeCache
      */
     protected <K, V> CompositeCache<K, V> parseRegion(
-            Properties props, String regName, String value )
+            Properties props, CompositeCacheManager ccm, String regName, String auxiliaries )
     {
-        return parseRegion( props, regName, value, null, REGION_PREFIX );
+        return parseRegion( props, ccm, regName, auxiliaries, null, REGION_PREFIX );
     }
 
     /**
@@ -307,69 +166,76 @@ public class CompositeCacheConfigurator
      * <p>
      * This method tells the other parse method the name of the region prefix.
      *<p>
-     * @param props
-     * @param regName
-     * @param value
-     * @param cca
+     * @param props Configuration properties
+     * @param ccm Cache hub
+     * @param regName Name of the cache region
+     * @param auxiliaries Comma separated list of auxiliaries
+     * @param cca Cache configuration
+     *
      * @return CompositeCache
      */
     protected <K, V> CompositeCache<K, V> parseRegion(
-            Properties props, String regName, String value, ICompositeCacheAttributes cca )
+            Properties props, CompositeCacheManager ccm, String regName, String auxiliaries,
+            ICompositeCacheAttributes cca )
     {
-        return parseRegion( props, regName, value, cca, REGION_PREFIX );
+        return parseRegion( props, ccm, regName, auxiliaries, cca, REGION_PREFIX );
     }
 
     /**
      * Get all the properties for a region and configure its cache.
      *<p>
-     * @param props
-     * @param regName
-     * @param value
-     * @param cca
-     * @param regionPrefix
+     * @param props Configuration properties
+     * @param ccm Cache hub
+     * @param regName Name of the cache region
+     * @param auxiliaries Comma separated list of auxiliaries
+     * @param cca Cache configuration
+     * @param regionPrefix Prefix for the region
+     *
      * @return CompositeCache
      */
     protected <K, V> CompositeCache<K, V> parseRegion(
-            Properties props, String regName, String value,
+            Properties props, CompositeCacheManager ccm, String regName, String auxiliaries,
             ICompositeCacheAttributes cca, String regionPrefix )
     {
         // First, create or get the cache and element attributes, and create
         // the cache.
-        IElementAttributes ea = parseElementAttributes( props, regName, regionPrefix );
+        IElementAttributes ea = parseElementAttributes( props, regName,
+                ccm.getDefaultElementAttributes(), regionPrefix );
 
         CompositeCache<K, V> cache = ( cca == null )
-            ? new CompositeCache<K, V>( parseCompositeCacheAttributes( props, regName, regionPrefix ), ea )
+            ? new CompositeCache<K, V>( parseCompositeCacheAttributes( props, regName,
+                    ccm.getDefaultCacheAttributes(), regionPrefix ), ea )
             : new CompositeCache<K, V>( cca, ea );
 
         // Inject scheduler service
-        cache.setScheduledExecutorService(compositeCacheManager.getScheduledExecutorService());
+        cache.setScheduledExecutorService(ccm.getScheduledExecutorService());
 
         // Inject element event queue
-        cache.setElementEventQueue(compositeCacheManager.getElementEventQueue());
+        cache.setElementEventQueue(ccm.getElementEventQueue());
 
         if (cache.getMemoryCache() instanceof IRequireScheduler)
         {
             ((IRequireScheduler)cache.getMemoryCache()).setScheduledExecutorService(
-                    compositeCacheManager.getScheduledExecutorService());
+                    ccm.getScheduledExecutorService());
         }
 
-        if (value != null)
+        if (auxiliaries != null)
         {
             // Next, create the auxiliaries for the new cache
             List<AuxiliaryCache<K, V>> auxList = new ArrayList<AuxiliaryCache<K, V>>();
 
             if ( log.isDebugEnabled() )
             {
-                log.debug( "Parsing region name '" + regName + "', value '" + value + "'" );
+                log.debug( "Parsing region name '" + regName + "', value '" + auxiliaries + "'" );
             }
 
             // We must skip over ',' but not white space
-            StringTokenizer st = new StringTokenizer( value, "," );
+            StringTokenizer st = new StringTokenizer( auxiliaries, "," );
 
             // If value is not in the form ", appender.." or "", then we should set
             // the priority of the category.
 
-            if ( !( value.startsWith( "," ) || value.equals( "" ) ) )
+            if ( !( auxiliaries.startsWith( "," ) || auxiliaries.equals( "" ) ) )
             {
                 // just to be on the safe side...
                 if ( !st.hasMoreTokens() )
@@ -389,14 +255,14 @@ public class CompositeCacheConfigurator
                 }
                 log.debug( "Parsing auxiliary named \"" + auxName + "\"." );
 
-                auxCache = parseAuxiliary( props, auxName, regName );
+                auxCache = parseAuxiliary( props, ccm, auxName, regName );
 
                 if ( auxCache != null )
                 {
                     if (auxCache instanceof IRequireScheduler)
                     {
-                        ((IRequireScheduler)auxCache).setScheduledExecutorService(
-                                compositeCacheManager.getScheduledExecutorService());
+                        ((IRequireScheduler) auxCache).setScheduledExecutorService(
+                                ccm.getScheduledExecutorService());
                     }
 
                     auxList.add( auxCache );
@@ -416,25 +282,30 @@ public class CompositeCacheConfigurator
     /**
      * Get an ICompositeCacheAttributes for the listed region.
      *<p>
-     * @param props
-     * @param regName
+     * @param props Configuration properties
+     * @param regName the region name
+     * @param defaultCCAttr the default cache attributes
+     *
      * @return ICompositeCacheAttributes
      */
-    protected ICompositeCacheAttributes parseCompositeCacheAttributes( Properties props, String regName )
+    protected ICompositeCacheAttributes parseCompositeCacheAttributes( Properties props,
+            String regName, ICompositeCacheAttributes defaultCCAttr )
     {
-        return parseCompositeCacheAttributes( props, regName, REGION_PREFIX );
+        return parseCompositeCacheAttributes( props, regName, defaultCCAttr, REGION_PREFIX );
     }
 
     /**
      * Get the main attributes for a region.
      *<p>
-     * @param props
-     * @param regName
-     * @param regionPrefix
+     * @param props Configuration properties
+     * @param regName the region name
+     * @param defaultCCAttr the default cache attributes
+     * @param regionPrefix the region prefix
+     *
      * @return ICompositeCacheAttributes
      */
-    protected ICompositeCacheAttributes parseCompositeCacheAttributes( Properties props, String regName,
-                                                                       String regionPrefix )
+    protected ICompositeCacheAttributes parseCompositeCacheAttributes( Properties props,
+            String regName, ICompositeCacheAttributes defaultCCAttr, String regionPrefix )
     {
         ICompositeCacheAttributes ccAttr;
 
@@ -452,8 +323,7 @@ public class CompositeCacheConfigurator
                     + "], using default class." );
             }
 
-            ICompositeCacheAttributes ccAttr2 = compositeCacheManager.getDefaultCacheAttributes();
-            ccAttr = ccAttr2.clone();
+            ccAttr = defaultCCAttr;
         }
 
         if ( log.isDebugEnabled() )
@@ -477,12 +347,15 @@ public class CompositeCacheConfigurator
     /**
      * Create the element attributes from the properties object for a cache region.
      *<p>
-     * @param props
-     * @param regName
-     * @param regionPrefix
+     * @param props Configuration properties
+     * @param regName the region name
+     * @param defaultEAttr the default element attributes
+     * @param regionPrefix the region prefix
+     *
      * @return IElementAttributes
      */
-    protected IElementAttributes parseElementAttributes( Properties props, String regName, String regionPrefix )
+    protected IElementAttributes parseElementAttributes( Properties props, String regName,
+            IElementAttributes defaultEAttr, String regionPrefix )
     {
         IElementAttributes eAttr;
 
@@ -498,8 +371,7 @@ public class CompositeCacheConfigurator
                 log.info( "No special ElementAttribute class defined for key [" + attrName + "], using default class." );
             }
 
-            IElementAttributes eAttr2 = compositeCacheManager.getDefaultElementAttributes();
-            eAttr = eAttr2.clone();
+            eAttr = defaultEAttr;
         }
 
         if ( log.isDebugEnabled() )
@@ -524,11 +396,13 @@ public class CompositeCacheConfigurator
      * Get an aux cache for the listed aux for a region.
      *<p>
      * @param props the configuration properties
+     * @param ccm Cache hub
      * @param auxName the name of the auxiliary cache
      * @param regName the name of the region.
      * @return AuxiliaryCache
      */
-    protected <K, V> AuxiliaryCache<K, V> parseAuxiliary( Properties props, String auxName, String regName )
+    protected <K, V> AuxiliaryCache<K, V> parseAuxiliary( Properties props, CompositeCacheManager ccm,
+            String auxName, String regName )
     {
         if ( log.isDebugEnabled() )
         {
@@ -537,12 +411,12 @@ public class CompositeCacheConfigurator
 
         // GET CACHE
         @SuppressWarnings("unchecked") // Common map for all caches
-        AuxiliaryCache<K, V> auxCache = (AuxiliaryCache<K, V>)compositeCacheManager.getAuxiliaryCache(auxName, regName);
+        AuxiliaryCache<K, V> auxCache = (AuxiliaryCache<K, V>) ccm.getAuxiliaryCache(auxName, regName);
 
         if (auxCache == null)
         {
             // GET FACTORY
-            AuxiliaryCacheFactory auxFac = compositeCacheManager.registryFacGet( auxName );
+            AuxiliaryCacheFactory auxFac = ccm.registryFacGet( auxName );
             if ( auxFac == null )
             {
                 // auxFactory was not previously initialized.
@@ -558,16 +432,15 @@ public class CompositeCacheConfigurator
 
                 if ( auxFac instanceof IRequireScheduler)
                 {
-                	((IRequireScheduler)auxFac).setScheduledExecutorService(compositeCacheManager.getScheduledExecutorService());
+                	((IRequireScheduler)auxFac).setScheduledExecutorService(ccm.getScheduledExecutorService());
                 }
 
                 auxFac.initialize();
-
-                compositeCacheManager.registryFacPut( auxFac );
+                ccm.registryFacPut( auxFac );
             }
 
             // GET ATTRIBUTES
-            AuxiliaryCacheAttributes auxAttr = compositeCacheManager.registryAttrGet( auxName );
+            AuxiliaryCacheAttributes auxAttr = ccm.registryAttrGet( auxName );
             String attrName = AUXILIARY_PREFIX + auxName + ATTRIBUTE_PREFIX;
             if ( auxAttr == null )
             {
@@ -580,7 +453,7 @@ public class CompositeCacheConfigurator
                     return null;
                 }
                 auxAttr.setName( auxName );
-                compositeCacheManager.registryAttrPut( auxAttr );
+                ccm.registryAttrPut( auxAttr );
             }
 
             auxAttr = auxAttr.clone();
@@ -604,10 +477,12 @@ public class CompositeCacheConfigurator
             String auxPrefix = AUXILIARY_PREFIX + auxName;
 
             // CONFIGURE THE EVENT LOGGER
-            ICacheEventLogger cacheEventLogger = AuxiliaryCacheConfigurator.parseCacheEventLogger( props, auxPrefix );
+            ICacheEventLogger cacheEventLogger =
+                    AuxiliaryCacheConfigurator.parseCacheEventLogger( props, auxPrefix );
 
             // CONFIGURE THE ELEMENT SERIALIZER
-            IElementSerializer elementSerializer = AuxiliaryCacheConfigurator.parseElementSerializer( props, auxPrefix );
+            IElementSerializer elementSerializer =
+                    AuxiliaryCacheConfigurator.parseElementSerializer( props, auxPrefix );
 
             // CONFIGURE THE KEYMATCHER
             //IKeyMatcher keyMatcher = parseKeyMatcher( props, auxPrefix );
@@ -619,7 +494,7 @@ public class CompositeCacheConfigurator
             // before the auxiliary is created.
             try
             {
-                auxCache = auxFac.createCache( auxAttr, compositeCacheManager, cacheEventLogger, elementSerializer );
+                auxCache = auxFac.createCache( auxAttr, ccm, cacheEventLogger, elementSerializer );
             }
             catch (Exception e)
             {
@@ -627,20 +502,42 @@ public class CompositeCacheConfigurator
                 return null;
             }
 
-            compositeCacheManager.addAuxiliaryCache(auxName, regName, auxCache);
+            ccm.addAuxiliaryCache(auxName, regName, auxCache);
         }
 
         return auxCache;
     }
 
     /**
+     * Any property values will be replaced with system property values that match the key.
+     * <p>
+     * @param props
+     */
+    protected static void overrideWithSystemProperties( Properties props )
+    {
+        // override any setting with values from the system properties.
+        Properties sysProps = System.getProperties();
+        for (String key : sysProps.stringPropertyNames())
+        {
+            if ( key.startsWith( SYSTEM_PROPERTY_KEY_PREFIX ) )
+            {
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( "Using system property [[" + key + "] [" + sysProps.getProperty( key ) + "]]" );
+                }
+                props.setProperty( key, sysProps.getProperty( key ) );
+            }
+        }
+    }
+
+    /**
      * Creates a custom key matcher if one is defined.  Else, it uses the default.
      * <p>
      * @param props
      * @param auxPrefix - ex. AUXILIARY_PREFIX + auxName
      * @return IKeyMatcher
      */
-    public static <K> IKeyMatcher<K> parseKeyMatcher( Properties props, String auxPrefix )
+    protected <K> IKeyMatcher<K> parseKeyMatcher( Properties props, String auxPrefix )
     {
 
         // auxFactory was not previously initialized.

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java?rev=1727713&r1=1727712&r2=1727713&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java Sat Jan 30 15:24:32 2016
@@ -24,14 +24,13 @@ import java.io.InputStream;
 import java.lang.management.ManagementFactory;
 import java.security.AccessControlException;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Properties;
-import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReentrantLock;
 
 import javax.management.MBeanServer;
@@ -57,6 +56,7 @@ import org.apache.commons.jcs.engine.con
 import org.apache.commons.jcs.engine.control.event.behavior.IElementEventQueue;
 import org.apache.commons.jcs.engine.stats.CacheStats;
 import org.apache.commons.jcs.engine.stats.behavior.ICacheStats;
+import org.apache.commons.jcs.utils.config.OptionConverter;
 import org.apache.commons.jcs.utils.threadpool.DaemonThreadFactory;
 import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager;
 import org.apache.commons.logging.Log;
@@ -79,15 +79,18 @@ public class CompositeCacheManager
     /** JMX object name */
     public static final String JMX_OBJECT_NAME = "org.apache.commons.jcs:type=JCSAdminBean";
 
+    /** default region prefix */
+    private static final String DEFAULT_REGION = "jcs.default";
+
     /** Caches managed by this cache manager */
     private final ConcurrentMap<String, ICache<?, ?>> caches =
         new ConcurrentHashMap<String, ICache<?, ?>>();
 
     /** Lock for initialization of caches */
-    private ReentrantLock cacheLock = new ReentrantLock();
+    private final ReentrantLock cacheLock = new ReentrantLock();
 
     /** Number of clients accessing this cache manager */
-    private int clients;
+    private final AtomicInteger clients = new AtomicInteger(0);
 
     /** Default cache attributes for this cache manager */
     private ICompositeCacheAttributes defaultCacheAttr = new CompositeCacheAttributes();
@@ -97,15 +100,15 @@ public class CompositeCacheManager
 
     /** Used to keep track of configured auxiliaries */
     private final ConcurrentMap<String, AuxiliaryCacheFactory> auxiliaryFactoryRegistry =
-        new ConcurrentHashMap<String, AuxiliaryCacheFactory>( 11 );
+        new ConcurrentHashMap<String, AuxiliaryCacheFactory>( );
 
     /** Used to keep track of attributes for auxiliaries. */
     private final ConcurrentMap<String, AuxiliaryCacheAttributes> auxiliaryAttributeRegistry =
-        new ConcurrentHashMap<String, AuxiliaryCacheAttributes>( 11 );
+        new ConcurrentHashMap<String, AuxiliaryCacheAttributes>( );
 
     /** Used to keep track of configured auxiliaries */
     private final ConcurrentMap<String, AuxiliaryCache<?, ?>> auxiliaryCaches =
-        new ConcurrentHashMap<String, AuxiliaryCache<?, ?>>( 11 );
+        new ConcurrentHashMap<String, AuxiliaryCache<?, ?>>( );
 
     /** Properties with which this manager was configured. This is exposed for other managers. */
     private Properties configurationProperties;
@@ -116,9 +119,6 @@ public class CompositeCacheManager
     /** The Singleton Instance */
     private static CompositeCacheManager instance;
 
-    /** The prefix of relevant system properties */
-    private static final String SYSTEM_PROPERTY_KEY_PREFIX = "jcs";
-
     /** Should we use system property substitutions. */
     private static final boolean DEFAULT_USE_SYSTEM_PROPERTIES = true;
 
@@ -190,7 +190,7 @@ public class CompositeCacheManager
             instance.configure( propsFilename );
         }
 
-        instance.incrementClients();
+        instance.clients.incrementAndGet();
 
         return instance;
     }
@@ -218,7 +218,7 @@ public class CompositeCacheManager
             instance.initialize();
         }
 
-        instance.incrementClients();
+        instance.clients.incrementAndGet();
 
         return instance;
     }
@@ -436,50 +436,23 @@ public class CompositeCacheManager
         }
         if ( useSystemProperties )
         {
-            overrideWithSystemProperties( props );
+            CompositeCacheConfigurator.overrideWithSystemProperties( props );
         }
         doConfigure( props );
     }
 
     /**
-     * Any property values will be replaced with system property values that match the key.
-     * <p>
-     * TODO move to a utility.
-     * <p>
-     * @param props
-     */
-    private static void overrideWithSystemProperties( Properties props )
-    {
-        // override any setting with values from the system properties.
-        Properties sysProps = System.getProperties();
-        Set<Object> keys = sysProps.keySet();
-        Iterator<Object> keyIt = keys.iterator();
-        while ( keyIt.hasNext() )
-        {
-            String key = (String) keyIt.next();
-            if ( key.startsWith( SYSTEM_PROPERTY_KEY_PREFIX ) )
-            {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Using system property [[" + key + "] [" + sysProps.getProperty( key ) + "]]" );
-                }
-                props.setProperty( key, sysProps.getProperty( key ) );
-            }
-        }
-    }
-
-    /**
      * Configure the cache using the supplied properties.
      * <p>
-     * @param props assumed not null
+     * @param properties assumed not null
      */
-    private void doConfigure( Properties props )
+    private void doConfigure( Properties properties )
     {
         // We will expose this for managers that need raw properties.
-        this.configurationProperties = props;
+        this.configurationProperties = properties;
 
         // set the props value and then configure the ThreadPoolManager
-        ThreadPoolManager.setProps( props );
+        ThreadPoolManager.setProps( properties );
         ThreadPoolManager poolMgr = ThreadPoolManager.getInstance();
         if ( log.isDebugEnabled() )
         {
@@ -487,9 +460,40 @@ public class CompositeCacheManager
         }
 
         // configure the cache
-        CompositeCacheConfigurator configurator = new CompositeCacheConfigurator( this );
+        CompositeCacheConfigurator configurator = new CompositeCacheConfigurator();
+
+        long start = System.currentTimeMillis();
+
+        // set default value list
+        this.defaultAuxValues = OptionConverter.findAndSubst( CompositeCacheManager.DEFAULT_REGION,
+                properties );
+
+        log.info( "Setting default auxiliaries to " + this.defaultAuxValues );
+
+        // set default cache attr
+        this.defaultCacheAttr = configurator.parseCompositeCacheAttributes( properties, "",
+                new CompositeCacheAttributes(), DEFAULT_REGION );
+
+        log.info( "setting defaultCompositeCacheAttributes to " + this.defaultCacheAttr );
+
+        // set default element attr
+        this.defaultElementAttr = configurator.parseElementAttributes( properties, "",
+                new ElementAttributes(), DEFAULT_REGION );
+
+        log.info( "setting defaultElementAttributes to " + this.defaultElementAttr );
 
-        configurator.doConfigure( props );
+        // set up system caches to be used by non system caches
+        // need to make sure there is no circularity of reference
+        configurator.parseSystemRegions( properties, this );
+
+        // setup preconfigured caches
+        configurator.parseRegions( properties, this );
+
+        long end = System.currentTimeMillis();
+        if ( log.isInfoEnabled() )
+        {
+            log.info( "Finished configuration in " + ( end - start ) + " ms." );
+        }
 
         isConfigured = true;
     }
@@ -505,26 +509,6 @@ public class CompositeCacheManager
     }
 
     /**
-     * Sets the defaultCacheAttributes attribute of the CacheHub object
-     * <p>
-     * @param icca The new defaultCacheAttributes value
-     */
-    public void setDefaultCacheAttributes( ICompositeCacheAttributes icca )
-    {
-        this.defaultCacheAttr = icca;
-    }
-
-    /**
-     * Sets the defaultElementAttributes attribute of the CacheHub object
-     * <p>
-     * @param iea The new defaultElementAttributes value
-     */
-    public void setDefaultElementAttributes( IElementAttributes iea )
-    {
-        this.defaultElementAttr = iea;
-    }
-
-    /**
      * Gets the defaultElementAttributes attribute of the CacheHub object
      * <p>
      * @return The defaultElementAttributes value
@@ -541,7 +525,7 @@ public class CompositeCacheManager
      * @return CompositeCache -- the cache region controller
      */
     @Override
-    public <K, V> CompositeCache<K, V>  getCache( String cacheName )
+    public <K, V> CompositeCache<K, V> getCache( String cacheName )
     {
         return getCache( cacheName, this.defaultCacheAttr.clone() );
     }
@@ -622,9 +606,9 @@ public class CompositeCacheManager
                 {
                     cattr.setCacheName( cattr.getCacheName() );
 
-                    CompositeCacheConfigurator configurator = new CompositeCacheConfigurator( this );
+                    CompositeCacheConfigurator configurator = new CompositeCacheConfigurator();
 
-                    cache = configurator.parseRegion( this.getConfigurationProperties(), cattr.getCacheName(),
+                    cache = configurator.parseRegion( this.getConfigurationProperties(), this, cattr.getCacheName(),
                                                       this.defaultAuxValues, cattr );
 
                     caches.put( cattr.getCacheName(), cache );
@@ -687,6 +671,8 @@ public class CompositeCacheManager
                 {
                     observer.shutdown();
                 }
+
+                shutdownObservers.clear();
             }
 
             // Unregister JMX bean
@@ -741,12 +727,6 @@ public class CompositeCacheManager
     }
 
     /** */
-    private void incrementClients()
-    {
-        clients++;
-    }
-
-    /** */
     public void release()
     {
         release( false );
@@ -760,7 +740,7 @@ public class CompositeCacheManager
         synchronized ( CompositeCacheManager.class )
         {
             // Wait until called by the last client
-            if ( --clients > 0 )
+            if ( clients.decrementAndGet() > 0 )
             {
                 if ( log.isDebugEnabled() )
                 {
@@ -804,14 +784,6 @@ public class CompositeCacheManager
     }
 
     /**
-     * @return ICompositeCacheAttributes
-     */
-    public ICompositeCacheAttributes getDefaultCattr()
-    {
-        return this.defaultCacheAttr;
-    }
-
-    /**
      * @param auxFac
      */
     public void registryFacPut( AuxiliaryCacheFactory auxFac )
@@ -886,14 +858,6 @@ public class CompositeCacheManager
     }
 
     /**
-     * @param defaultAuxValues the defaultAuxValues to set
-     */
-    public void setDefaultAuxValues(String defaultAuxValues)
-    {
-        this.defaultAuxValues = defaultAuxValues;
-    }
-
-    /**
      * Gets stats for debugging. This calls gets statistics and then puts all the results in a
      * string. This returns data for all regions.
      * <p>
@@ -974,16 +938,6 @@ public class CompositeCacheManager
     /**
      * This is exposed so other manager can get access to the props.
      * <p>
-     * @param props
-     */
-    void setConfigurationProperties( Properties props )
-    {
-        this.configurationProperties = props;
-    }
-
-    /**
-     * This is exposed so other manager can get access to the props.
-     * <p>
      * @return the configurationProperties
      */
     @Override
@@ -1008,7 +962,8 @@ public class CompositeCacheManager
         return isConfigured;
     }
 
-    public void setJmxName(final String name) {
+    public void setJmxName(final String name)
+    {
         if (isJMXRegistered)
         {
             throw new IllegalStateException("Too late, MBean registration is done");

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java?rev=1727713&r1=1727712&r2=1727713&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/CompositeCacheConfiguratorUnitTest.java Sat Jan 30 15:24:32 2016
@@ -19,7 +19,10 @@ package org.apache.commons.jcs.engine.co
  * under the License.
  */
 
+import java.util.Properties;
+
 import junit.framework.TestCase;
+
 import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheConfigurator;
 import org.apache.commons.jcs.auxiliary.MockAuxiliaryCache;
@@ -27,8 +30,6 @@ import org.apache.commons.jcs.auxiliary.
 import org.apache.commons.jcs.auxiliary.MockAuxiliaryCacheFactory;
 import org.apache.commons.jcs.engine.logging.MockCacheEventLogger;
 
-import java.util.Properties;
-
 /** Unit tests for the configurator. */
 public class CompositeCacheConfiguratorUnitTest
     extends TestCase
@@ -42,7 +43,7 @@ public class CompositeCacheConfiguratorU
         String regionName = "MyRegion";
 
         String auxName = "MockAux";
-        String auxPrefix = "jcs.auxiliary." + auxName;
+        String auxPrefix = CompositeCacheConfigurator.AUXILIARY_PREFIX + auxName;
         String auxiliaryClassName = MockAuxiliaryCacheFactory.class.getName();
         String eventLoggerClassName = MockCacheEventLogger.class.getName();
         String auxiliaryAttributeClassName = MockAuxiliaryCacheAttributes.class.getName();
@@ -55,11 +56,10 @@ public class CompositeCacheConfiguratorU
 //        System.out.print( props );
 
         CompositeCacheManager manager = CompositeCacheManager.getUnconfiguredInstance();
-
-        CompositeCacheConfigurator configurator = new CompositeCacheConfigurator( manager );
+        CompositeCacheConfigurator configurator = new CompositeCacheConfigurator();
 
         // DO WORK
-        AuxiliaryCache<String, String> aux = configurator.parseAuxiliary( props, auxName, regionName );
+        AuxiliaryCache<String, String> aux = configurator.parseAuxiliary( props, manager, auxName, regionName );
         MockAuxiliaryCache<String, String> result = (MockAuxiliaryCache<String, String>)aux;
 
         // VERIFY

Modified: commons/proper/jcs/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/src/changes/changes.xml?rev=1727713&r1=1727712&r2=1727713&view=diff
==============================================================================
--- commons/proper/jcs/trunk/src/changes/changes.xml (original)
+++ commons/proper/jcs/trunk/src/changes/changes.xml Sat Jan 30 15:24:32 2016
@@ -20,6 +20,9 @@
 	</properties>
 	<body>
         <release version="2.0" date="unreleased" description="JDK 1.6 based major release">
+            <action issue="JCS-116" dev="tv" type="fix" due-to="Sebb">
+                Fix: CompositeCacheManager is thread-hostile
+            </action>
             <action issue="JCS-158" dev="tv" type="fix" due-to="Wiktor Niesiobedzki">
                 Fix NullPointerException in IndexedDiskCache.addToRecycleBin(...)
             </action>