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 2015/04/06 15:54:50 UTC

svn commit: r1671536 [1/2] - in /commons/proper/jcs/trunk/commons-jcs-core/src: main/java/org/apache/commons/jcs/auxiliary/ main/java/org/apache/commons/jcs/auxiliary/disk/ main/java/org/apache/commons/jcs/auxiliary/disk/block/ main/java/org/apache/com...

Author: tv
Date: Mon Apr  6 13:54:48 2015
New Revision: 1671536

URL: http://svn.apache.org/r1671536
Log:
FIrst part of JCS-130: Remove static managers and give factories a real life cycle.

Added:
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheFactory.java   (with props)
Removed:
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheManagerAbstractTemplate.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/util/ScheduleFormatException.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheAbstractFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheAbstractManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheRestore.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheWatchRepairable.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/ZombieLateralCacheWatch.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/behavior/ILateralCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/behavior/ILateralCacheObserver.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListenerManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheWatchRepairable.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/ZombieRemoteCacheWatch.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/behavior/IRemoteCacheObserver.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheManagerUnitTest.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheManagerUnitTest.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheManagerUnitTest.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheManagerUnitTest.java
Modified:
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheAttributes.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/util/ScheduleParser.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheRestore.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/behavior/IRemoteCacheServer.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/behavior/ICompositeCacheManager.java
    commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java
    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/auxiliary/MockAuxiliaryCacheFactory.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheHsqlBackedUnitTest.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/util/ScheduleParserUtilUnitTest.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListenerUnitTest.java
    commons/proper/jcs/trunk/commons-jcs-core/src/test/java/org/apache/commons/jcs/engine/control/MockCompositeCacheManager.java

Added: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheFactory.java?rev=1671536&view=auto
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheFactory.java (added)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheFactory.java Mon Apr  6 13:54:48 2015
@@ -0,0 +1,72 @@
+package org.apache.commons.jcs.auxiliary;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.commons.jcs.auxiliary.AuxiliaryCacheFactory;
+
+/**
+ * Base class for auxiliary cache factories.
+ */
+public abstract class AbstractAuxiliaryCacheFactory
+    implements AuxiliaryCacheFactory
+{
+    /** The auxiliary name. The composite cache manager keeps this in a map, keyed by name. */
+    private String name = this.getClass().getSimpleName();
+
+    /**
+     * Initialize this factory
+     */
+    @Override
+    public void initialize()
+    {
+        // empty
+    }
+
+    /**
+     * Dispose of this factory, clean up shared resources
+     */
+    @Override
+    public void dispose()
+    {
+        // empty
+    }
+
+    /**
+     * Gets the name attribute of the DiskCacheFactory object
+     * <p>
+     * @return The name value
+     */
+    @Override
+    public String getName()
+    {
+        return this.name;
+    }
+
+    /**
+     * Sets the name attribute of the DiskCacheFactory object
+     * <p>
+     * @param name The new name value
+     */
+    @Override
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+}

Propchange: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheAttributes.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheAttributes.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheAttributes.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheAttributes.java Mon Apr  6 13:54:48 2015
@@ -28,7 +28,7 @@ import java.io.Serializable;
  * auxiliary mangers to share a common interface.
  */
 public interface AuxiliaryCacheAttributes
-    extends Serializable
+    extends Serializable, Cloneable
 {
     /**
      * Sets the name of the cache, referenced by the appropriate manager.

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheFactory.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheFactory.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheFactory.java Mon Apr  6 13:54:48 2015
@@ -33,15 +33,27 @@ public interface AuxiliaryCacheFactory
      * <p>
      * @param attr
      * @param cacheMgr This allows auxiliaries to reference the manager without assuming that it is
-     *            a singleton. This will allow JCS to be a nonsingleton. Also, it makes it easier to
+     *            a singleton. This will allow JCS to be a non-singleton. Also, it makes it easier to
      *            test.
      * @param cacheEventLogger
      * @param elementSerializer
      * @return AuxiliaryCache
+     * @throws Exception if cache instance could not be created
      */
     <K, V> AuxiliaryCache<K, V> createCache(
             AuxiliaryCacheAttributes attr, ICompositeCacheManager cacheMgr,
-            ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer );
+            ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
+            throws Exception;
+
+    /**
+     * Initialize this factory
+     */
+    void initialize();
+
+    /**
+     * Dispose of this factory, clean up shared resources
+     */
+    void dispose();
 
     /**
      * Sets the name attribute of the AuxiliaryCacheFactory object

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java Mon Apr  6 13:54:48 2015
@@ -19,9 +19,8 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
-import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
+import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory;
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
-import org.apache.commons.jcs.auxiliary.AuxiliaryCacheFactory;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
@@ -32,32 +31,24 @@ import org.apache.commons.logging.LogFac
  * Creates disk cache instances.
  */
 public class BlockDiskCacheFactory
-    implements AuxiliaryCacheFactory
+    extends AbstractAuxiliaryCacheFactory
 {
     /** The logger */
     private static final Log log = LogFactory.getLog( BlockDiskCacheFactory.class );
 
-    /** The auxiliary name. The composite cache manager keeps this in a map, keyed by name. */
-    private String name;
-
     /**
-     * Get an instance of the BlockDiskCacheManager for the attributes and then get an
-     * IndexedDiskCache from the manager.
-     * <p>
-     * The manager is a singleton.
+     * Create an instance of the BlockDiskCache.
      * <p>
-     * One disk cache is returned per region from the manager.
-     * <p>
-     * @param iaca
+     * @param iaca the cache attributes for this cache
      * @param cacheMgr This allows auxiliaries to reference the manager without assuming that it is
      *            a singleton. This will allow JCS to be a non-singleton. Also, it makes it easier
      *            to test.
      * @param cacheEventLogger
      * @param elementSerializer
-     * @return AuxiliaryCache
+     * @return BlockDiskCache
      */
     @Override
-    public <K, V> AuxiliaryCache<K, V> createCache( AuxiliaryCacheAttributes iaca, ICompositeCacheManager cacheMgr,
+    public <K, V> BlockDiskCache<K, V> createCache( AuxiliaryCacheAttributes iaca, ICompositeCacheManager cacheMgr,
                                        ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
     {
         BlockDiskCacheAttributes idca = (BlockDiskCacheAttributes) iaca;
@@ -65,29 +56,11 @@ public class BlockDiskCacheFactory
         {
             log.debug( "Creating DiskCache for attributes = " + idca );
         }
-        BlockDiskCacheManager dcm = BlockDiskCacheManager.getInstance( idca, cacheEventLogger, elementSerializer );
-        return dcm.getCache( idca );
-    }
 
-    /**
-     * Gets the name attribute of the DiskCacheFactory object
-     * <p>
-     * @return The name value
-     */
-    @Override
-    public String getName()
-    {
-        return this.name;
-    }
+        BlockDiskCache<K, V> cache = new BlockDiskCache<K, V>( idca );
+        cache.setCacheEventLogger( cacheEventLogger );
+        cache.setElementSerializer( elementSerializer );
 
-    /**
-     * Sets the name attribute of the DiskCacheFactory object
-     * <p>
-     * @param name The new name value
-     */
-    @Override
-    public void setName( String name )
-    {
-        this.name = name;
+        return cache;
     }
 }

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java Mon Apr  6 13:54:48 2015
@@ -19,9 +19,8 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
-import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
+import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory;
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
-import org.apache.commons.jcs.auxiliary.AuxiliaryCacheFactory;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
@@ -32,32 +31,24 @@ import org.apache.commons.logging.LogFac
  * Creates disk cache instances.
  */
 public class IndexedDiskCacheFactory
-    implements AuxiliaryCacheFactory
+    extends AbstractAuxiliaryCacheFactory
 {
     /** The logger. */
     private static final Log log = LogFactory.getLog( IndexedDiskCacheFactory.class );
 
-    /** The auxiliary name. */
-    private String name;
-
     /**
-     * Get an instance of the IndexDiskCacheManager for the attributes and then get an
-     * IndexedDiskCache from the manager.
-     * <p>
-     * The manager is a singleton.
+     * Create an instance of an IndexedDiskCache.
      * <p>
-     * One disk cache is returned per region from the manager.
-     * <p>
-     * @param iaca
+     * @param iaca cache attributes of this cache instance
      * @param cacheMgr This allows auxiliaries to reference the manager without assuming that it is
      *            a singleton. This will allow JCS to be a non-singleton. Also, it makes it easier to
      *            test.
      * @param cacheEventLogger
      * @param elementSerializer
-     * @return AuxiliaryCache
+     * @return IndexedDiskCache
      */
     @Override
-    public <K, V> AuxiliaryCache<K, V> createCache( AuxiliaryCacheAttributes iaca, ICompositeCacheManager cacheMgr,
+    public <K, V> IndexedDiskCache<K, V> createCache( AuxiliaryCacheAttributes iaca, ICompositeCacheManager cacheMgr,
                                        ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
     {
         IndexedDiskCacheAttributes idca = (IndexedDiskCacheAttributes) iaca;
@@ -65,29 +56,11 @@ public class IndexedDiskCacheFactory
         {
             log.debug( "Creating DiskCache for attributes = " + idca );
         }
-        IndexedDiskCacheManager dcm = IndexedDiskCacheManager.getInstance( idca, cacheEventLogger, elementSerializer );
-        return dcm.getCache( idca );
-    }
 
-    /**
-     * Gets the name attribute of the DiskCacheFactory object
-     * <p>
-     * @return The name value
-     */
-    @Override
-    public String getName()
-    {
-        return this.name;
-    }
+        IndexedDiskCache<K, V> cache = new IndexedDiskCache<K, V>( idca );
+        cache.setCacheEventLogger( cacheEventLogger );
+        cache.setElementSerializer(elementSerializer);
 
-    /**
-     * Sets the name attribute of the DiskCacheFactory object
-     * <p>
-     * @param name The new name value
-     */
-    @Override
-    public void setName( String name )
-    {
-        this.name = name;
+        return cache;
     }
 }

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java Mon Apr  6 13:54:48 2015
@@ -19,6 +19,17 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
 import org.apache.commons.jcs.auxiliary.disk.AbstractDiskCache;
 import org.apache.commons.jcs.engine.CacheConstants;
@@ -34,18 +45,6 @@ import org.apache.commons.jcs.utils.seri
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.sql.Timestamp;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * This is the jdbc disk cache plugin.
  * <p>
@@ -191,42 +190,6 @@ public class JDBCDiskCache<K, V>
 
         try
         {
-            // TEST
-            Statement sStatement = null;
-            try
-            {
-                sStatement = con.createStatement();
-                alive = true;
-            }
-            catch ( SQLException e )
-            {
-                log.error( "Problem creating statement.", e );
-                alive = false;
-            }
-            finally
-            {
-                try
-                {
-                    if (sStatement != null)
-                    {
-                        sStatement.close();
-                    }
-                }
-                catch ( SQLException e )
-                {
-                    log.error( "Problem closing statement.", e );
-                }
-            }
-
-            if ( !alive )
-            {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Disk is not alive, aborting put." );
-                }
-                return;
-            }
-
             if ( log.isDebugEnabled() )
             {
                 log.debug( "Putting [" + ce.getKey() + "] on disk." );
@@ -345,10 +308,7 @@ public class JDBCDiskCache<K, V>
         }
         catch ( SQLException e )
         {
-            if ( e.toString().indexOf( "Violation of unique index" ) != -1
-                || e.getMessage().indexOf( "Duplicate entry" ) != -1
-                || e.getMessage().indexOf( "duplicate key" ) != -1
-                || e.getMessage().indexOf( "primary key constraint" ) != -1 )
+            if ("23000".equals(e.getSQLState()))
             {
                 exists = true;
             }
@@ -793,7 +753,7 @@ public class JDBCDiskCache<K, V>
     @Override
     protected void processRemoveAll()
     {
-        // it should never get here formt he abstract dis cache.
+        // it should never get here from the abstract disk cache.
         if ( this.jdbcDiskCacheAttributes.isAllowRemoveAll() )
         {
             try

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java Mon Apr  6 13:54:48 2015
@@ -19,12 +19,21 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
-import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory;
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
-import org.apache.commons.jcs.auxiliary.AuxiliaryCacheFactory;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.commons.jcs.utils.threadpool.DaemonThreadFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * This factory should create mysql disk caches.
@@ -32,49 +41,142 @@ import org.apache.commons.jcs.engine.log
  * @author Aaron Smuts
  */
 public class JDBCDiskCacheFactory
-    implements AuxiliaryCacheFactory
+    extends AbstractAuxiliaryCacheFactory
 {
-    /** Name of the factory */
-    private String name = "JDBCDiskCacheFactory";
+    /** The logger */
+    private static final Log log = LogFactory.getLog( JDBCDiskCacheFactory.class );
+
+    /**
+     * A map of TableState objects to table names. Each cache has a table state object, which is
+     * used to determine if any long processes such as deletes or optimizations are running.
+     */
+    private Map<String, TableState> tableStates;
+
+    /** The background scheduler, one for all regions. */
+    protected ScheduledExecutorService scheduler; // TODO this is not accessed in a threadsafe way. Perhaps use IODH idiom?
 
     /**
-     * This factory method should create an instance of the mysqlcache.
+     * A map of table name to shrinker threads. This allows each table to have a different setting.
+     * It assumes that there is only one jdbc disk cache auxiliary defined per table.
+     */
+    private Map<String, ShrinkerThread> shrinkerThreadMap;
+
+    /**
+     * This factory method should create an instance of the jdbc cache.
      * <p>
      * @param rawAttr
      * @param compositeCacheManager
      * @param cacheEventLogger
      * @param elementSerializer
-     * @return AuxiliaryCache
+     * @return JDBCDiskCache
+     * @throws SQLException if the cache instance could not be created
      */
     @Override
-    public <K, V> AuxiliaryCache<K, V> createCache( AuxiliaryCacheAttributes rawAttr, ICompositeCacheManager compositeCacheManager,
-                                       ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
+    public <K, V> JDBCDiskCache<K, V> createCache( AuxiliaryCacheAttributes rawAttr,
+            ICompositeCacheManager compositeCacheManager,
+            ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
+            throws SQLException
     {
-        JDBCDiskCacheManager diskCacheManager = JDBCDiskCacheManager.getInstance( (JDBCDiskCacheAttributes) rawAttr,
-                                                                                  compositeCacheManager,
-                                                                                  cacheEventLogger, elementSerializer );
-        return diskCacheManager.getCache( (JDBCDiskCacheAttributes) rawAttr );
+        JDBCDiskCacheAttributes cattr = (JDBCDiskCacheAttributes) rawAttr;
+        TableState tableState = getTableState( cattr.getTableName() );
+
+        JDBCDiskCache<K, V> cache = new JDBCDiskCache<K, V>( cattr, tableState, compositeCacheManager );
+        cache.setCacheEventLogger( cacheEventLogger );
+        cache.setElementSerializer( elementSerializer );
+
+        // create a shrinker if we need it.
+        createShrinkerWhenNeeded( cattr, cache );
+
+        return cache;
     }
 
     /**
-     * The name of the factory.
-     * <p>
-     * @param nameArg
+     * Initialize this factory
      */
     @Override
-    public void setName( String nameArg )
+    public void initialize()
     {
-        name = nameArg;
+        super.initialize();
+        this.tableStates = new HashMap<String, TableState>();
+        this.shrinkerThreadMap = new HashMap<String, ShrinkerThread>();
     }
 
     /**
-     * Returns the display name
-     * <p>
-     * @return String
+     * Dispose of this factory, clean up shared resources
      */
     @Override
-    public String getName()
+    public void dispose()
     {
-        return name;
+        if (this.scheduler != null)
+        {
+            this.scheduler.shutdownNow();
+            this.scheduler = null;
+        }
+        super.dispose();
+    }
+
+    /**
+     * Get a table state for a given table name
+     *
+     * @param tableName
+     * @return a cached instance of the table state
+     */
+    protected TableState getTableState(String tableName)
+    {
+        TableState tableState = tableStates.get( tableName );
+
+        if ( tableState == null )
+        {
+            tableState = new TableState( tableName );
+            tableStates.put(tableName, tableState);
+        }
+
+        return tableState;
+    }
+
+    /**
+     * Get the scheduler service (lazily loaded)
+     *
+     * @return the scheduler
+     */
+    protected ScheduledExecutorService getScheduledExecutorService()
+    {
+        if ( scheduler == null )
+        {
+            scheduler = Executors.newScheduledThreadPool(2,
+                    new DaemonThreadFactory("JCS-JDBCDiskCacheManager-", Thread.MIN_PRIORITY));
+        }
+
+        return scheduler;
+    }
+
+    /**
+     * If UseDiskShrinker is true then we will create a shrinker daemon if necessary.
+     * <p>
+     * @param cattr
+     * @param raf
+     */
+    protected void createShrinkerWhenNeeded( JDBCDiskCacheAttributes cattr, JDBCDiskCache<?, ?> raf )
+    {
+        // add cache to shrinker.
+        if ( cattr.isUseDiskShrinker() )
+        {
+            ScheduledExecutorService shrinkerService = getScheduledExecutorService();
+            ShrinkerThread shrinkerThread = shrinkerThreadMap.get( cattr.getTableName() );
+            if ( shrinkerThread == null )
+            {
+                shrinkerThread = new ShrinkerThread();
+                shrinkerThreadMap.put( cattr.getTableName(), shrinkerThread );
+
+                long intervalMillis = Math.max( 999, cattr.getShrinkerIntervalSeconds() * 1000 );
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( "Setting the shrinker to run every [" + intervalMillis + "] ms. for table ["
+                        + cattr.getTableName() + "]" );
+                }
+                shrinkerService.scheduleAtFixedRate(shrinkerThread, 0, intervalMillis, TimeUnit.MILLISECONDS);
+            }
+            shrinkerThread.addDiskCacheToShrinkList( raf );
+        }
     }
 }

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java Mon Apr  6 13:54:48 2015
@@ -19,17 +19,6 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
-import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
-import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
-import org.apache.commons.jcs.auxiliary.AuxiliaryCacheFactory;
-import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCacheAttributes;
-import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCacheManager;
-import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
-import org.apache.commons.jcs.engine.behavior.IElementSerializer;
-import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
@@ -38,86 +27,73 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
+import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCache;
+import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCacheAttributes;
+import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCacheFactory;
+import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
+import org.apache.commons.jcs.engine.behavior.IElementSerializer;
+import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 /**
- * This factory should create mysql disk caches.
+ * This factory should create hsql disk caches.
  * <p>
  * @author Aaron Smuts
  */
 public class HSQLDiskCacheFactory
-    implements AuxiliaryCacheFactory
+    extends JDBCDiskCacheFactory
 {
     /** The logger */
     private static final Log log = LogFactory.getLog( HSQLDiskCacheFactory.class );
 
-    /** Name for logging, etc. */
-    private String name = "HSQLDiskCacheFactory";
-
     /** The databases. */
-    private final Set<String> databases = Collections.synchronizedSet( new HashSet<String>() );
+    private Set<String> databases;
 
     /**
      * This factory method should create an instance of the hsqlcache.
      * <p>
      * @param rawAttr
-     * @param cacheManager
+     * @param compositeCacheManager
      * @param cacheEventLogger
      * @param elementSerializer
-     * @return AuxiliaryCache
+     * @return JDBCDiskCache
+     * @throws SQLException if the creation of the cache instance fails
      */
     @Override
-    public <K, V> AuxiliaryCache<K, V> createCache( AuxiliaryCacheAttributes rawAttr,
-    									ICompositeCacheManager cacheManager,
-    									ICacheEventLogger cacheEventLogger,
-    									IElementSerializer elementSerializer )
+    public <K, V> JDBCDiskCache<K, V> createCache( AuxiliaryCacheAttributes rawAttr,
+			ICompositeCacheManager compositeCacheManager,
+			ICacheEventLogger cacheEventLogger,
+			IElementSerializer elementSerializer )
+			throws SQLException
     {
-        JDBCDiskCacheManager mgr = JDBCDiskCacheManager.getInstance( (JDBCDiskCacheAttributes) rawAttr, cacheManager,
-                                                                     cacheEventLogger, elementSerializer );
-        try
-        {
-            setupDatabase( (JDBCDiskCacheAttributes) rawAttr );
-        }
-        catch ( Exception e )
-        {
-            // TODO we may not want to try and get the cache at this point.
-            log.error( "Problem setting up database.", e );
-        }
-        return mgr.getCache( (JDBCDiskCacheAttributes) rawAttr );
-    }
-
-    /**
-     * The name of the factory.
-     * <p>
-     * @param nameArg
-     */
-    @Override
-    public void setName( String nameArg )
-    {
-        name = nameArg;
+        setupDatabase( (JDBCDiskCacheAttributes) rawAttr );
+        return super.createCache(rawAttr, compositeCacheManager, cacheEventLogger, elementSerializer);
     }
 
     /**
-     * Returns the display name
-     * <p>
-     * @return name
+     * Initialize this factory
      */
     @Override
-    public String getName()
+    public void initialize()
     {
-        return name;
+        super.initialize();
+        this.databases = Collections.synchronizedSet( new HashSet<String>() );
     }
 
     /**
      * Creates the database if it doesn't exist, registers the driver class, etc.
      * <p>
      * @param attributes
-     * @throws Exception
+     * @throws SQLException
      */
     protected void setupDatabase( JDBCDiskCacheAttributes attributes )
-        throws Exception
+        throws SQLException
     {
         if ( attributes == null )
         {
-            throw new Exception( "The attributes are null." );
+            throw new SQLException( "The attributes are null." );
         }
 
         // url should start with "jdbc:hsqldb:"
@@ -143,25 +119,25 @@ public class HSQLDiskCacheFactory
         String password = attributes.getPassword();
 
         new org.hsqldb.jdbcDriver();
+
         try
         {
             Class.forName( driver ).newInstance();
+        }
+        catch (Exception e)
+        {
+            throw new SQLException( "Could not initialize driver " + driver, e );
+        }
 
-            Connection cConn = DriverManager.getConnection( database, user, password );
-
-            setupTABLE( cConn, attributes.getTableName() );
-
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Finished setting up database [" + database + "]" );
-            }
+        Connection cConn = DriverManager.getConnection( database, user, password );
+        setupTABLE( cConn, attributes.getTableName() );
 
-            databases.add( database );
-        }
-        catch ( Exception e )
+        if ( log.isInfoEnabled() )
         {
-            log.error( "Fatal problem setting up the database.", e );
+            log.info( "Finished setting up database [" + database + "]" );
         }
+
+        databases.add( database );
     }
 
     /**

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java Mon Apr  6 13:54:48 2015
@@ -19,12 +19,21 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
-import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
+import java.sql.SQLException;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
-import org.apache.commons.jcs.auxiliary.AuxiliaryCacheFactory;
+import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCacheFactory;
+import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCachePoolAccess;
+import org.apache.commons.jcs.auxiliary.disk.jdbc.TableState;
+import org.apache.commons.jcs.auxiliary.disk.jdbc.mysql.util.ScheduleParser;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * This factory should create mysql disk caches.
@@ -32,47 +41,153 @@ import org.apache.commons.jcs.engine.log
  * @author Aaron Smuts
  */
 public class MySQLDiskCacheFactory
-    implements AuxiliaryCacheFactory
+    extends JDBCDiskCacheFactory
 {
-    /** name of the factory */
-    private String name = "MySQLDiskCacheFactory";
+    /** The logger */
+    private static final Log log = LogFactory.getLog( MySQLDiskCacheFactory.class );
 
     /**
      * This factory method should create an instance of the mysqlcache.
      * <p>
      * @param rawAttr
-     * @param cacheManager
+     * @param compositeCacheManager
      * @param cacheEventLogger
      * @param elementSerializer
-     * @return AuxiliaryCache
+     * @return MySQLDiskCache
+     * @throws SQLException if the creation of the cache instance fails
      */
     @Override
-    public <K, V> AuxiliaryCache<K, V> createCache( AuxiliaryCacheAttributes rawAttr, ICompositeCacheManager cacheManager,
-                                       ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
+    public <K, V> MySQLDiskCache<K, V> createCache( AuxiliaryCacheAttributes rawAttr,
+            ICompositeCacheManager compositeCacheManager,
+            ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
+            throws SQLException
     {
-        MySQLDiskCacheManager mgr = MySQLDiskCacheManager.getInstance( (MySQLDiskCacheAttributes) rawAttr, cacheManager, cacheEventLogger, elementSerializer );
-        return mgr.getCache( (MySQLDiskCacheAttributes) rawAttr );
+        MySQLDiskCacheAttributes cattr = (MySQLDiskCacheAttributes) rawAttr;
+        TableState tableState = getTableState( cattr.getTableName() );
+
+        MySQLDiskCache<K, V> cache = new MySQLDiskCache<K, V>( cattr, tableState, compositeCacheManager );
+        cache.setCacheEventLogger( cacheEventLogger );
+        cache.setElementSerializer( elementSerializer );
+
+        // create a shrinker if we need it.
+        createShrinkerWhenNeeded( cattr, cache );
+        scheduleOptimizations( cattr, tableState, cache.getPoolAccess() );
+
+        return cache;
+
     }
 
     /**
-     * The name of the factory.
+     * For each time in the optimization schedule, this calls schedule Optimization.
      * <p>
-     * @param nameArg
+     * @param attributes configuration properties.
+     * @param tableState for noting optimization in progress, etc.
+     * @param poolAccess access to the pool
      */
-    @Override
-    public void setName( String nameArg )
+    protected void scheduleOptimizations( MySQLDiskCacheAttributes attributes, TableState tableState, JDBCDiskCachePoolAccess poolAccess  )
     {
-        name = nameArg;
+        if ( attributes != null )
+        {
+            if ( attributes.getOptimizationSchedule() != null )
+            {
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( "Will try to configure optimization for table [" + attributes.getTableName()
+                        + "] on schedule [" + attributes.getOptimizationSchedule() + "]" );
+                }
+
+                MySQLTableOptimizer optimizer = new MySQLTableOptimizer( attributes, tableState, poolAccess );
+
+                // loop through the dates.
+                try
+                {
+                    Date[] dates = ScheduleParser.createDatesForSchedule( attributes.getOptimizationSchedule() );
+                    if ( dates != null )
+                    {
+                        for ( int i = 0; i < dates.length; i++ )
+                        {
+                            this.scheduleOptimization( dates[i], optimizer );
+                        }
+                    }
+                }
+                catch ( ParseException e )
+                {
+                    log.warn( "Problem creating optimization schedule for table [" + attributes.getTableName() + "]", e );
+                }
+            }
+            else
+            {
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( "Optimization is not configured for table [" + attributes.getTableName() + "]" );
+                }
+            }
+        }
     }
 
     /**
-     * Returns the display name.
+     * This takes in a single time and schedules the optimizer to be called at that time every day.
      * <p>
-     * @return factory name
+     * @param startTime -- HH:MM:SS format
+     * @param optimizer
      */
-    @Override
-    public String getName()
+    protected void scheduleOptimization( Date startTime, MySQLTableOptimizer optimizer )
     {
-        return name;
+        if ( log.isInfoEnabled() )
+        {
+            log.info( "startTime [" + startTime + "] for optimizer " + optimizer );
+        }
+
+        // get the runnable from the factory
+        OptimizerTask runnable = new OptimizerTask( optimizer );
+        Date now = new Date();
+        long initialDelay = startTime.getTime() - now.getTime();
+
+        // have the daemon execute our runnable
+        getScheduledExecutorService().scheduleAtFixedRate(runnable, initialDelay, 86400000L, TimeUnit.MILLISECONDS );
+    }
+
+    /**
+     * This calls the optimizers' optimize table method. This is used by the timer.
+     * <p>
+     * @author Aaron Smuts
+     */
+    private static class OptimizerTask
+        implements Runnable
+    {
+        /** Handles optimization */
+        private MySQLTableOptimizer optimizer = null;
+
+        /**
+         * Get a handle on the optimizer.
+         * <p>
+         * @param optimizer
+         */
+        public OptimizerTask( MySQLTableOptimizer optimizer )
+        {
+            this.optimizer = optimizer;
+        }
+
+        /**
+         * This calls optimize on the optimizer.
+         * <p>
+         * @see java.lang.Runnable#run()
+         */
+        @Override
+        public void run()
+        {
+            if ( optimizer != null )
+            {
+                boolean success = optimizer.optimizeTable();
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( "Optimization success status [" + success + "]" );
+                }
+            }
+            else
+            {
+                log.warn( "OptimizerRunner: The optimizer is null.  Could not optimize table." );
+            }
+        }
     }
 }

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/util/ScheduleParser.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/util/ScheduleParser.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/util/ScheduleParser.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/util/ScheduleParser.java Mon Apr  6 13:54:48 2015
@@ -19,6 +19,8 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.StringTokenizer;
@@ -36,14 +38,14 @@ public class ScheduleParser
      * <p>
      * @param schedule
      * @return Date[]
-     * @throws ScheduleFormatException
+     * @throws ParseException
      */
     public static Date[] createDatesForSchedule( String schedule )
-        throws ScheduleFormatException
+        throws ParseException
     {
         if ( schedule == null )
         {
-            throw new ScheduleFormatException( "Cannot create schedules for a null String." );
+            throw new ParseException( "Cannot create schedules for a null String.", 0 );
         }
 
         StringTokenizer toker = new StringTokenizer( schedule, "," );
@@ -64,44 +66,27 @@ public class ScheduleParser
      * <p>
      * @param startTime
      * @return Date
-     * @throws ScheduleFormatException
+     * @throws ParseException
      */
     public static Date getDateForSchedule( String startTime )
-        throws ScheduleFormatException
+        throws ParseException
     {
         if ( startTime == null )
         {
-            throw new ScheduleFormatException( "Cannot create date for a null String." );
-        }
-
-        int firstColon = startTime.indexOf( ":" );
-        int lastColon = startTime.lastIndexOf( ":" );
-        int len = startTime.length();
-        if ( firstColon == -1 || lastColon == -1 || firstColon == lastColon || lastColon == len )
-        {
-            String message = "StartTime [" + startTime + "] is deformed.  Unable to schedule optimizaiton.";
-            throw new ScheduleFormatException( message );
+            throw new ParseException( "Cannot create date for a null String.", 0 );
         }
 
+        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+        Date date = sdf.parse(startTime);
         Calendar cal = Calendar.getInstance();
-        try
-        {
-            int hour = Integer.parseInt( startTime.substring( 0, firstColon ) );
-            cal.set( Calendar.HOUR_OF_DAY, hour );
-            int minute = Integer.parseInt( startTime.substring( firstColon + 1, lastColon ) );
-            cal.set( Calendar.MINUTE, minute );
-            int second = Integer.parseInt( startTime.substring( lastColon + 1, len ) );
-            cal.set( Calendar.SECOND, second );
-        }
-        catch ( NumberFormatException e )
-        {
-            String message = "Problem parsing start time [" + startTime + "].  It should be in HH:MM:SS format.";
-            throw new ScheduleFormatException( message );
-        }
+        // This will result in a date of 1/1/1970
+        cal.setTime(date);
+
+        Calendar now = Calendar.getInstance();
+        cal.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH));
 
         // if the date is less than now, add a day.
-        Date now = new Date();
-        if ( cal.getTime().before( now ) )
+        if ( cal.before( now ) )
         {
             cal.add( Calendar.DAY_OF_MONTH, 1 );
         }

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheMonitor.java Mon Apr  6 13:54:48 2015
@@ -19,8 +19,15 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
-import org.apache.commons.jcs.auxiliary.lateral.behavior.ILateralCacheManager;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.jcs.auxiliary.lateral.socket.tcp.LateralTCPCacheFactory;
+import org.apache.commons.jcs.auxiliary.lateral.socket.tcp.behavior.ITCPLateralCacheAttributes;
 import org.apache.commons.jcs.engine.CacheStatus;
+import org.apache.commons.jcs.engine.ZombieCacheServiceNonLocal;
+import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -31,8 +38,7 @@ import org.apache.commons.logging.LogFac
  * driven mode. That is, it attempts to recover the connections on a periodic basis. When all failed
  * connections are restored, it changes back to the failure driven mode.
  */
-public class LateralCacheMonitor
-    implements Runnable
+public class LateralCacheMonitor extends Thread
 {
     /** The logger */
     private static final Log log = LogFactory.getLog( LateralCacheMonitor.class );
@@ -43,7 +49,17 @@ public class LateralCacheMonitor
     /**
      * Must make sure LateralCacheMonitor is started before any lateral error can be detected!
      */
-    private boolean alright = true;
+    private boolean allright = true;
+
+    /**
+     * Map of caches to monitor
+     */
+    private ConcurrentHashMap<String, LateralCacheNoWait<?, ?>> caches;
+
+    /**
+     * Reference to the factory
+     */
+    private LateralTCPCacheFactory factory;
 
     /**
      * shutdown flag
@@ -56,9 +72,6 @@ public class LateralCacheMonitor
     /** The mode we are running in. Error driven */
     private static int mode = ERROR;
 
-    /** The manager */
-    private final ILateralCacheManager manager;
-
     /**
      * Configures the idle period between repairs.
      * <p>
@@ -86,12 +99,30 @@ public class LateralCacheMonitor
      * Constructor for the LateralCacheMonitor object
      * <p>
      * It's the clients responsibility to decide how many of these there will be.
-     * <p>
-     * @param manager
+     *
+     * @param factory a reference to the factory that manages the service instances
      */
-    public LateralCacheMonitor( ILateralCacheManager manager )
+    public LateralCacheMonitor(LateralTCPCacheFactory factory)
     {
-        this.manager = manager;
+        super("JCS-LateralCacheMonitor");
+        this.factory = factory;
+        this.caches = new ConcurrentHashMap<String, LateralCacheNoWait<?,?>>();
+    }
+
+    /**
+     * Add a cache to be monitored
+     *
+     * @param cache the cache
+     */
+    public void addCache(LateralCacheNoWait<?, ?> cache)
+    {
+        this.caches.put(cache.getCacheName(), cache);
+
+        // if not yet started, go ahead
+        if (this.getState() == Thread.State.NEW)
+        {
+            this.start();
+        }
     }
 
     /**
@@ -130,20 +161,20 @@ public class LateralCacheMonitor
             {
                 if ( log.isDebugEnabled() )
                 {
-                    if ( alright )
+                    if ( allright )
                     {
-                        log.debug( "ERROR DRIVEN MODE: alright = " + alright
+                        log.debug( "ERROR DRIVEN MODE: allright = " + allright
                             + ", connection monitor will wait for an error." );
                     }
                     else
                     {
-                        log.debug( "ERROR DRIVEN MODE: alright = " + alright + " connection monitor running." );
+                        log.debug( "ERROR DRIVEN MODE: allright = " + allright + " connection monitor running." );
                     }
                 }
 
                 synchronized ( this )
                 {
-                    if ( alright )
+                    if ( allright )
                     {
                         // Failure driven mode.
                         try
@@ -172,15 +203,16 @@ public class LateralCacheMonitor
                 if (shutdown)
                 {
                     log.info( "Shutting down cache monitor" );
+                    this.caches.clear();
                     return;
                 }
             }
 
-            // The "alright" flag must be false here.
+            // The "allright" flag must be false here.
             // Simply presume we can fix all the errors until proven otherwise.
             synchronized ( this )
             {
-                alright = true;
+                allright = true;
             }
 
             if ( log.isDebugEnabled() )
@@ -188,70 +220,33 @@ public class LateralCacheMonitor
                 log.debug( "Cache monitor running." );
             }
 
-            // Monitor each LateralCacheManager instance one after the other.
-            // Each LateralCacheManager corresponds to one lateral connection.
-            log.info( "LateralCacheManager.instances.size() = " + manager.getInstances().size() );
+            // Monitor each cache instance one after the other.
+            log.info( "Number of caches to monitor = " + caches.size() );
             //for
-            int cnt = 0;
-            for (ILateralCacheManager mgr : manager.getInstances().values())
+            for (Map.Entry<String, LateralCacheNoWait<?, ?>> entry : caches.entrySet())
             {
-                cnt++;
-                try
+                String cacheName = entry.getKey();
+
+                @SuppressWarnings("unchecked") // Downcast to match service
+                LateralCacheNoWait<Serializable, Serializable> c =
+                        (LateralCacheNoWait<Serializable, Serializable>) entry.getValue();
+                if ( c.getStatus() == CacheStatus.ERROR )
                 {
-                    // If any cache is in error, it strongly suggests all caches
-                    // managed by the
-                    // same LateralCacheManager instance are in error. So we fix
-                    // them once and for all.
-                    //for
-                    //log.info( "\n " + cnt + "- mgr.lca.getTcpServer() = " + mgr.lca.getTcpServer() + " mgr = " + mgr );
-                    log.info( "\n " + cnt + "- mgr.getCaches().size() = " + mgr.getCaches().size() );
+                    log.info( "Found LateralCacheNoWait in error, " + cacheName );
 
-                    if ( mgr.getCaches().size() == 0 )
-                    {
-                        // there is probably a problem.
-                        // monitor may be running when we just started up and
-                        // there
-                        // is not a cache yet.
-                        // if this is error driven mode, mark as bad,
-                        // otherwise we will come back around again.
-                        if ( mode == ERROR )
-                        {
-                            bad();
-                        }
-                    }
+                    ITCPLateralCacheAttributes lca = (ITCPLateralCacheAttributes)c.getAuxiliaryCacheAttributes();
 
-                    for (LateralCacheNoWait<?, ?> c : mgr.getCaches().values())
-                    {
-                        if ( c.getStatus() == CacheStatus.ERROR )
-                        {
-                            log.info( "found LateralCacheNoWait in error, " + c.toString() );
+                    // Get service instance
+                    ICacheServiceNonLocal<Serializable, Serializable> cacheService = factory.getCSNLInstance(lca);
 
-                            LateralCacheRestore repairer = new LateralCacheRestore( mgr );
-                            // If we can't fix them, just skip and re-try in the
-                            // next round.
-                            if ( repairer.canFix() )
-                            {
-                                repairer.fix();
-                            }
-                            else
-                            {
-                                bad();
-                            }
-                            //break;
-                        }
-                        else
-                        {
-                            log.info( "Lateral Cache No Wait not in error" );
-                        }
+                    // If we can't fix them, just skip and re-try in the
+                    // next round.
+                    if (cacheService instanceof ZombieCacheServiceNonLocal)
+                    {
+                        continue;
                     }
-                }
-                catch ( Exception ex )
-                {
-                    bad();
-                    // Problem encountered in fixing the caches managed by a
-                    // LateralCacheManager instance.
-                    // Soldier on to the next LateralCacheManager instance.
-                    log.error( "Problem encountered in fixing the caches", ex );
+
+                    c.fixCache(cacheService);
                 }
             }
 
@@ -275,15 +270,15 @@ public class LateralCacheMonitor
     }
 
     /**
-     * Sets the "alright" flag to false in a critical section.
+     * Sets the "allright" flag to false in a critical section.
      */
     private void bad()
     {
-        if ( alright )
+        if ( allright )
         {
             synchronized ( this )
             {
-                alright = false;
+                allright = false;
             }
         }
     }

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java Mon Apr  6 13:54:48 2015
@@ -69,7 +69,7 @@ public class LateralCacheNoWait<K, V>
     private int putCount = 0;
 
     /**
-     * Constructs with the given lateral cache, and fires up an event queue for aysnchronous
+     * Constructs with the given lateral cache, and fires up an event queue for asynchronous
      * processing.
      * <p>
      * @param cache

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java Mon Apr  6 13:54:48 2015
@@ -19,15 +19,25 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
-import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheFactory;
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
-import org.apache.commons.jcs.auxiliary.lateral.LateralCacheAbstractFactory;
+import org.apache.commons.jcs.auxiliary.lateral.LateralCache;
+import org.apache.commons.jcs.auxiliary.lateral.LateralCacheMonitor;
 import org.apache.commons.jcs.auxiliary.lateral.LateralCacheNoWait;
 import org.apache.commons.jcs.auxiliary.lateral.LateralCacheNoWaitFacade;
 import org.apache.commons.jcs.auxiliary.lateral.behavior.ILateralCacheAttributes;
 import org.apache.commons.jcs.auxiliary.lateral.behavior.ILateralCacheListener;
 import org.apache.commons.jcs.auxiliary.lateral.socket.tcp.behavior.ITCPLateralCacheAttributes;
+import org.apache.commons.jcs.engine.CacheWatchRepairable;
+import org.apache.commons.jcs.engine.ZombieCacheServiceNonLocal;
+import org.apache.commons.jcs.engine.ZombieCacheWatch;
 import org.apache.commons.jcs.engine.behavior.ICache;
+import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.behavior.IShutdownObserver;
@@ -37,9 +47,6 @@ import org.apache.commons.jcs.utils.disc
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import java.util.ArrayList;
-import java.util.StringTokenizer;
-
 /**
  * Constructs a LateralCacheNoWaitFacade for the given configuration. Each lateral service / local
  * relationship is managed by one manager. This manager can have multiple caches. The remote
@@ -48,13 +55,25 @@ import java.util.StringTokenizer;
  * The facade provides a front to the composite cache so the implementation is transparent.
  */
 public class LateralTCPCacheFactory
-    extends LateralCacheAbstractFactory
+    extends AbstractAuxiliaryCacheFactory
 {
     /** The logger */
     private static final Log log = LogFactory.getLog( LateralTCPCacheFactory.class );
 
-    /** Non singleton manager. Used by this instance of the factory. */
-    private LateralTCPDiscoveryListenerManager lateralTCPDiscoveryListenerManager;
+    /** Address to service map. */
+    private ConcurrentHashMap<String, ICacheServiceNonLocal<?, ?>> csnlInstances;
+
+    /** Map of available discovery listener instances, keyed by port. */
+    private ConcurrentHashMap<String, LateralTCPDiscoveryListener> lTCPDLInstances;
+
+    /** Monitor thread */
+    private LateralCacheMonitor monitor;
+
+    /**
+     * Wrapper of the lateral cache watch service; or wrapper of a zombie
+     * service if failed to connect.
+     */
+    private CacheWatchRepairable lateralWatch;
 
     /**
      * Creates a TCP lateral.
@@ -63,10 +82,10 @@ public class LateralTCPCacheFactory
      * @param cacheMgr
      * @param cacheEventLogger
      * @param elementSerializer
-     * @return AuxiliaryCache
+     * @return LateralCacheNoWaitFacade
      */
     @Override
-    public <K, V> AuxiliaryCache<K, V> createCache(
+    public <K, V> LateralCacheNoWaitFacade<K, V> createCache(
             AuxiliaryCacheAttributes iaca, ICompositeCacheManager cacheMgr,
            ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
     {
@@ -92,24 +111,22 @@ public class LateralTCPCacheFactory
                 }
                 ITCPLateralCacheAttributes lacC = (ITCPLateralCacheAttributes) lac.copy();
                 lacC.setTcpServer( server );
-                LateralTCPCacheManager lcm = LateralTCPCacheManager.getInstance( lacC, cacheMgr, cacheEventLogger,
-                                                                                 elementSerializer );
 
-                // register for shutdown notification
-                cacheMgr.registerShutdownObserver( lcm );
+                LateralCacheNoWait<K, V> lateralNoWait = createCacheNoWait(lacC, cacheEventLogger, elementSerializer);
 
-                ICache<K, V> ic = lcm.getCache( lacC.getCacheName() );
-                noWaits.add( ic );
+                addListenerIfNeeded( lacC, cacheMgr );
+                monitor.addCache(lateralNoWait);
+                noWaits.add( lateralNoWait );
             }
         }
 
-        ILateralCacheListener<K, V> listener = createListener( (ILateralCacheAttributes) iaca, cacheMgr );
+        ILateralCacheListener<K, V> listener = createListener( lac, cacheMgr );
 
         // create the no wait facade.
         @SuppressWarnings("unchecked") // No generic arrays in java
         LateralCacheNoWait<K, V>[] lcnwArray = noWaits.toArray( new LateralCacheNoWait[0] );
         LateralCacheNoWaitFacade<K, V> lcnwf =
-            new LateralCacheNoWaitFacade<K, V>(listener, lcnwArray, (ILateralCacheAttributes) iaca );
+            new LateralCacheNoWaitFacade<K, V>(listener, lcnwArray, lac );
 
         // create udp discovery if available.
         createDiscoveryService( lac, lcnwf, cacheMgr, cacheEventLogger, elementSerializer );
@@ -117,6 +134,213 @@ public class LateralTCPCacheFactory
         return lcnwf;
     }
 
+    protected <K, V> LateralCacheNoWait<K, V> createCacheNoWait( ITCPLateralCacheAttributes lca,
+            ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
+    {
+        ICacheServiceNonLocal<K, V> lateralService = getCSNLInstance(lca);
+
+        LateralCache<K, V> cache = new LateralCache<K, V>( lca, lateralService, this.monitor );
+        cache.setCacheEventLogger( cacheEventLogger );
+        cache.setElementSerializer( elementSerializer );
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Created cache for noWait, cache [" + cache + "]" );
+        }
+
+        LateralCacheNoWait<K, V> lateralNoWait = new LateralCacheNoWait<K, V>( cache );
+        lateralNoWait.setCacheEventLogger( cacheEventLogger );
+        lateralNoWait.setElementSerializer( elementSerializer );
+
+        if ( log.isInfoEnabled() )
+        {
+            log.info( "Created LateralCacheNoWait for [" + lca + "] LateralCacheNoWait = [" + lateralNoWait
+                + "]" );
+        }
+
+        return lateralNoWait;
+    }
+
+    /**
+     * Initialize this factory
+     */
+    @Override
+    public void initialize()
+    {
+        this.csnlInstances = new ConcurrentHashMap<String, ICacheServiceNonLocal<?, ?>>();
+        this.lTCPDLInstances = new ConcurrentHashMap<String, LateralTCPDiscoveryListener>();
+
+        // Create the monitoring daemon thread
+        this.monitor = new LateralCacheMonitor(this);
+        this.monitor.setDaemon( true );
+
+        this.lateralWatch = new CacheWatchRepairable();
+        this.lateralWatch.setCacheWatch( new ZombieCacheWatch() );
+    }
+
+    /**
+     * Dispose of this factory, clean up shared resources
+     */
+    @Override
+    public void dispose()
+    {
+        for (ICacheServiceNonLocal<?, ?> service : this.csnlInstances.values())
+        {
+            try
+            {
+                service.dispose("");
+            }
+            catch (IOException e)
+            {
+                log.error("Could not dispose service " + service, e);
+            }
+        }
+
+        this.csnlInstances.clear();
+
+        // TODO: shut down discovery listeners
+        this.lTCPDLInstances.clear();
+
+        if (this.monitor != null)
+        {
+            this.monitor.notifyShutdown();
+            // this.monitor.join(5000);
+            this.monitor = null;
+        }
+    }
+
+    /**
+     * Returns an instance of the cache service.
+     * <p>
+     * @param lca configuration for the creation of a new service instance
+     *
+     * @return ICacheServiceNonLocal<K, V>
+     */
+    public <K, V> ICacheServiceNonLocal<K, V> getCSNLInstance( ITCPLateralCacheAttributes lca )
+    {
+        String key = lca.getTcpServer();
+        synchronized ( csnlInstances )
+        {
+            // Need to cast because of common map for all cache services
+            @SuppressWarnings("unchecked")
+            ICacheServiceNonLocal<K, V> service = (ICacheServiceNonLocal<K, V>)csnlInstances.get( key );
+
+            // If service creation did not succeed last time, force retry
+            if ( service instanceof ZombieCacheServiceNonLocal)
+            {
+                service = null;
+                log.info("Disposing of zombie service instance for [" + key + "]");
+            }
+
+            if ( service == null )
+            {
+                log.info( "Instance for [" + key + "] is null, creating" );
+
+                // Create the service
+                try
+                {
+                    if ( log.isInfoEnabled() )
+                    {
+                        log.info( "Creating TCP service, lca = " + lca );
+                    }
+
+                    service = new LateralTCPService<K, V>( lca );
+                }
+                catch ( IOException ex )
+                {
+                    // Failed to connect to the lateral server.
+                    // Configure this LateralCacheManager instance to use the
+                    // "zombie" services.
+                    log.error( "Failure, lateral instance will use zombie service", ex );
+
+                    service = new ZombieCacheServiceNonLocal<K, V>( lca.getZombieQueueMaxSize() );
+
+                    // Notify the cache monitor about the error, and kick off
+                    // the recovery process.
+                    monitor.notifyError();
+                }
+
+                csnlInstances.put( key, service );
+            }
+
+            return service;
+        }
+    }
+
+    /**
+     * Gets the instance attribute of the LateralCacheTCPListener class.
+     * <p>
+     * @param ilca ITCPLateralCacheAttributes
+     * @param cacheManager a reference to the global cache manager
+     *
+     * @return The instance value
+     */
+    private LateralTCPDiscoveryListener getDiscoveryListener( ITCPLateralCacheAttributes ilca, ICompositeCacheManager cacheManager )
+    {
+        String key = ilca.getUdpDiscoveryAddr() + ":" + ilca.getUdpDiscoveryPort();
+        LateralTCPDiscoveryListener ins = null;
+
+        LateralTCPDiscoveryListener newListener = new LateralTCPDiscoveryListener( this.getName(),  cacheManager);
+        ins = lTCPDLInstances.putIfAbsent(key, newListener );
+
+        if ( ins == null )
+        {
+            ins = newListener;
+
+            if ( log.isInfoEnabled() )
+            {
+                log.info( "Created new discovery listener for " + key + " cacheName for request " + ilca.getCacheName() );
+            }
+        }
+
+        return ins;
+    }
+
+    /**
+     * Add listener for receivers
+     * <p>
+     * @param iaca cache configuration attributes
+     * @param cacheMgr the composite cache manager
+     */
+    private void addListenerIfNeeded( ITCPLateralCacheAttributes iaca, ICompositeCacheManager cacheMgr )
+    {
+        // don't create a listener if we are not receiving.
+        if ( iaca.isReceive() )
+        {
+            try
+            {
+                addLateralCacheListener( iaca.getCacheName(), LateralTCPListener.getInstance( iaca, cacheMgr ) );
+            }
+            catch ( IOException ioe )
+            {
+                log.error( "Problem creating lateral listener", ioe );
+            }
+        }
+        else
+        {
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "Not creating a listener since we are not receiving." );
+            }
+        }
+    }
+
+    /**
+     * Adds the lateral cache listener to the underlying cache-watch service.
+     * <p>
+     * @param cacheName The feature to be added to the LateralCacheListener attribute
+     * @param listener The feature to be added to the LateralCacheListener attribute
+     * @throws IOException
+     */
+    private <K, V> void addLateralCacheListener( String cacheName, ILateralCacheListener<K, V> listener )
+        throws IOException
+    {
+        synchronized ( this.lateralWatch )
+        {
+            lateralWatch.addCacheListener( cacheName, listener );
+        }
+    }
+
     /**
      * Makes sure a listener gets created. It will get monitored as soon as it
      * is used.
@@ -128,9 +352,8 @@ public class LateralTCPCacheFactory
      *
      * @return the listener if created, else null
      */
-    @Override
-    public <K, V>
-        ILateralCacheListener<K, V> createListener( ILateralCacheAttributes lac, ICompositeCacheManager cacheMgr )
+    private <K, V> ILateralCacheListener<K, V> createListener( ILateralCacheAttributes lac,
+            ICompositeCacheManager cacheMgr )
     {
         ITCPLateralCacheAttributes attr = (ITCPLateralCacheAttributes) lac;
         ILateralCacheListener<K, V> listener = null;
@@ -189,15 +412,8 @@ public class LateralTCPCacheFactory
         // create the UDP discovery for the TCP lateral
         if ( lac.isUdpDiscoveryEnabled() )
         {
-            if ( lateralTCPDiscoveryListenerManager == null )
-            {
-                lateralTCPDiscoveryListenerManager = new LateralTCPDiscoveryListenerManager();
-            }
-
             // One can be used for all regions
-            LateralTCPDiscoveryListener discoveryListener = lateralTCPDiscoveryListenerManager
-                .getDiscoveryListener( lac, cacheMgr, cacheEventLogger, elementSerializer );
-
+            LateralTCPDiscoveryListener discoveryListener = getDiscoveryListener( lac, cacheMgr );
             discoveryListener.addNoWaitFacade( lac.getCacheName(), lcnwf );
 
             // need a factory for this so it doesn't

Modified: commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java
URL: http://svn.apache.org/viewvc/commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java?rev=1671536&r1=1671535&r2=1671536&view=diff
==============================================================================
--- commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java (original)
+++ commons/proper/jcs/trunk/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java Mon Apr  6 13:54:48 2015
@@ -19,14 +19,13 @@ package org.apache.commons.jcs.auxiliary
  * under the License.
  */
 
+import org.apache.commons.jcs.auxiliary.AuxiliaryCache;
+import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
 import org.apache.commons.jcs.auxiliary.lateral.LateralCacheAttributes;
 import org.apache.commons.jcs.auxiliary.lateral.LateralCacheNoWait;
 import org.apache.commons.jcs.auxiliary.lateral.LateralCacheNoWaitFacade;
 import org.apache.commons.jcs.auxiliary.lateral.socket.tcp.behavior.ITCPLateralCacheAttributes;
-import org.apache.commons.jcs.engine.behavior.ICache;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
-import org.apache.commons.jcs.engine.behavior.IElementSerializer;
-import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
 import org.apache.commons.jcs.utils.discovery.DiscoveredService;
 import org.apache.commons.jcs.utils.discovery.behavior.IDiscoveryListener;
 import org.apache.commons.logging.Log;
@@ -64,28 +63,22 @@ public class LateralTCPDiscoveryListener
     private final Set<String> knownDifferentlyConfiguredRegions =
         Collections.synchronizedSet( new HashSet<String>() );
 
-    /** The cache manager. */
-    private final ICompositeCacheManager cacheMgr;
+    /** The name of the cache factory */
+    private String factoryName;
 
-    /** The event logger. */
-    private final ICacheEventLogger cacheEventLogger;
-
-    /** The serializer. */
-    private final IElementSerializer elementSerializer;
+    /** Reference to the cache manager for auxiliary cache access */
+    private ICompositeCacheManager cacheManager;
 
     /**
      * This plugs into the udp discovery system. It will receive add and remove events.
      * <p>
-     * @param cacheMgr
-     * @param cacheEventLogger
-     * @param elementSerializer
+     * @param factoryName the name of the related cache factory
+     * @param cacheManager the global cache manager
      */
-    protected LateralTCPDiscoveryListener( ICompositeCacheManager cacheMgr, ICacheEventLogger cacheEventLogger,
-                                           IElementSerializer elementSerializer )
+    protected LateralTCPDiscoveryListener( String factoryName, ICompositeCacheManager cacheManager )
     {
-        this.cacheMgr = cacheMgr;
-        this.cacheEventLogger = cacheEventLogger;
-        this.elementSerializer = elementSerializer;
+        this.factoryName = factoryName;
+        this.cacheManager = cacheManager;
     }
 
     /**
@@ -246,37 +239,42 @@ public class LateralTCPDiscoveryListener
         // get a cache and add it to the no waits
         // the add method should not add the same.
         // we need the listener port from the original config.
-        LateralTCPCacheManager lcm = findManagerForServiceEndPoint( service );
-
         ArrayList<String> regions = service.getCacheNames();
+        String serverAndPort = service.getServiceAddress() + ":" + service.getServicePort();
+
         if ( regions != null )
         {
             // for each region get the cache
             for (String cacheName : regions)
             {
-                try
+                AuxiliaryCache<?, ?> ic = cacheManager.getAuxiliaryCache(factoryName, cacheName);
+
+                if ( log.isDebugEnabled() )
                 {
-                    ICache<?, ?> ic = lcm.getCache( cacheName );
+                    log.debug( "Got cache, ic = " + ic );
+                }
 
-                    if ( log.isDebugEnabled() )
+                // add this to the nowaits for this cachename
+                if ( ic != null )
+                {
+                    AuxiliaryCacheAttributes aca = ic.getAuxiliaryCacheAttributes();
+                    if (aca instanceof ITCPLateralCacheAttributes)
                     {
-                        log.debug( "Got cache, ic = " + ic );
+                        ITCPLateralCacheAttributes lca = (ITCPLateralCacheAttributes)aca;
+                        if (lca.getTransmissionType() != LateralCacheAttributes.Type.TCP
+                            || !serverAndPort.equals(lca.getTcpServer()) )
+                        {
+                            // skip caches not belonging to this service
+                            continue;
+                        }
                     }
 
-                    // add this to the nowaits for this cachename
-                    if ( ic != null )
+                    addNoWait( (LateralCacheNoWait<?, ?>) ic );
+                    if ( log.isDebugEnabled() )
                     {
-                        addNoWait( (LateralCacheNoWait<?, ?>) ic );
-                        if ( log.isDebugEnabled() )
-                        {
-                            log.debug( "Called addNoWait for cacheName [" + cacheName + "]" );
-                        }
+                        log.debug( "Called addNoWait for cacheName [" + cacheName + "]" );
                     }
                 }
-                catch ( Exception e )
-                {
-                    log.error( "Problem creating no wait", e );
-                }
             }
         }
         else
@@ -299,37 +297,42 @@ public class LateralTCPDiscoveryListener
         // get a cache and add it to the no waits
         // the add method should not add the same.
         // we need the listener port from the original config.
-        LateralTCPCacheManager lcm = findManagerForServiceEndPoint( service );
-
         ArrayList<String> regions = service.getCacheNames();
+        String serverAndPort = service.getServiceAddress() + ":" + service.getServicePort();
+
         if ( regions != null )
         {
             // for each region get the cache
             for (String cacheName : regions)
             {
-                try
+                AuxiliaryCache<?, ?> ic = cacheManager.getAuxiliaryCache(factoryName, cacheName);
+
+                if ( log.isDebugEnabled() )
                 {
-                    ICache<?, ?> ic = lcm.getCache( cacheName );
+                    log.debug( "Got cache, ic = " + ic );
+                }
 
-                    if ( log.isDebugEnabled() )
+                // remove this to the nowaits for this cachename
+                if ( ic != null )
+                {
+                    AuxiliaryCacheAttributes aca = ic.getAuxiliaryCacheAttributes();
+                    if (aca instanceof ITCPLateralCacheAttributes)
                     {
-                        log.debug( "Got cache, ic = " + ic );
+                        ITCPLateralCacheAttributes lca = (ITCPLateralCacheAttributes)aca;
+                        if (lca.getTransmissionType() != LateralCacheAttributes.Type.TCP
+                            || !serverAndPort.equals(lca.getTcpServer()) )
+                        {
+                            // skip caches not belonging to this service
+                            continue;
+                        }
                     }
 
-                    // remove this to the nowaits for this cachename
-                    if ( ic != null )
+                    removeNoWait( (LateralCacheNoWait<?, ?>) ic );
+                    if ( log.isDebugEnabled() )
                     {
-                        removeNoWait( (LateralCacheNoWait<?, ?>) ic );
-                        if ( log.isDebugEnabled() )
-                        {
-                            log.debug( "Called removeNoWait for cacheName [" + cacheName + "]" );
-                        }
+                        log.debug( "Called removeNoWait for cacheName [" + cacheName + "]" );
                     }
                 }
-                catch ( Exception e )
-                {
-                    log.error( "Problem removing no wait", e );
-                }
             }
         }
         else
@@ -337,20 +340,4 @@ public class LateralTCPDiscoveryListener
             log.warn( "No cache names found in message " + service );
         }
     }
-
-    /**
-     * Gets the appropriate manager.
-     * <p>
-     * @param service
-     * @return LateralTCPCacheManager configured for that end point.
-     */
-    private LateralTCPCacheManager findManagerForServiceEndPoint( DiscoveredService service )
-    {
-        ITCPLateralCacheAttributes lca = new TCPLateralCacheAttributes();
-        lca.setTransmissionType( LateralCacheAttributes.Type.TCP );
-        lca.setTcpServer( service.getServiceAddress() + ":" + service.getServicePort() );
-        LateralTCPCacheManager lcm = LateralTCPCacheManager.getInstance( lca, cacheMgr, cacheEventLogger,
-                                                                         elementSerializer );
-        return lcm;
-    }
 }