You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-dev@jakarta.apache.org by as...@apache.org on 2008/12/08 23:24:43 UTC

svn commit: r724518 [1/2] - in /jakarta/jcs/trunk/src: java/org/apache/jcs/auxiliary/lateral/ java/org/apache/jcs/auxiliary/remote/http/ java/org/apache/jcs/auxiliary/remote/http/behavior/ java/org/apache/jcs/auxiliary/remote/http/client/ java/org/apac...

Author: asmuts
Date: Mon Dec  8 14:24:42 2008
New Revision: 724518

URL: http://svn.apache.org/viewvc?rev=724518&view=rev
Log:
Adding a rough version of a simple Http Remote Cache Service / Servlet.  It does handle listeners, but it could be used for get, update, and remove in place of the RMI remote cache.  I'll create a basic client framework next.  Eventually we can add in listener registration and UDP discovery, etc.  For now, I'm keeping it very simple.  

Added:
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/behavior/
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/behavior/IRemoteHttpCacheConstants.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/client/
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/client/RemoteHttpClientRequestFactory.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteCacheServiceAdaptor.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServerAttributes.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheSeviceFactory.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheRequest.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheResponse.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/http/
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/http/client/
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/http/client/RemoteHttpClientRequestFactoryUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/http/server/
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/http/server/RemoteCacheServiceAdaptorUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServiceUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheSeviceFactoryUnitTest.java
Modified:
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/ZombieLateralCacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java
    jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICompositeCacheManager.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/MockAuxiliaryCache.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheClient.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheService.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/server/RemoteCacheServerUnitTest.java
    jakarta/jcs/trunk/src/test/org/apache/jcs/engine/control/MockCompositeCacheManager.java

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/ZombieLateralCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/ZombieLateralCacheService.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/ZombieLateralCacheService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/lateral/ZombieLateralCacheService.java Mon Dec  8 14:24:42 2008
@@ -19,7 +19,6 @@
  * under the License.
  */
 
-import java.io.IOException;
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.Map;
@@ -83,19 +82,16 @@
     {
         return Collections.EMPTY_SET;
     }
-    
+
     /**
      * The service does not get via this method, so this return empty.
      * <p>
      * @param cacheName
      * @param pattern
-     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no
-     *         data in cache matching the pattern.
-     * @throws IOException
+     * @return Collections.EMPTY_MAP.
      */
     public Map getMatching( String cacheName, String pattern )
-        throws IOException
     {
         return Collections.EMPTY_MAP;
-    }    
+    }
 }

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/behavior/IRemoteHttpCacheConstants.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/behavior/IRemoteHttpCacheConstants.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/behavior/IRemoteHttpCacheConstants.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/behavior/IRemoteHttpCacheConstants.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,30 @@
+package org.apache.jcs.auxiliary.remote.http.behavior;
+
+/** Constants used throughout the HTTP remote cache. */
+public interface IRemoteHttpCacheConstants
+{
+    /** Get request type. */
+    public static final byte REQUEST_TYPE_GET = 0;
+
+    /** Get Multiple request type. */
+    public static final byte REQUEST_TYPE_GET_MULTIPLE = 1;
+
+    /** Get Matching request type. */
+    public static final byte REQUEST_TYPE_GET_MATCHING = 2;
+
+    /** Update request type. */
+    public static final byte REQUEST_TYPE_UPDATE = 3;
+
+    /** Remove request type. */
+    public static final byte REQUEST_TYPE_REMOVE = 4;
+
+    /** Remove All request type. */
+    public static final byte REQUEST_TYPE_REMOVE_ALL = 5;
+
+    /** The prefix for cache server config. */
+    public final static String HTTP_CACHE_SERVER_PREFIX = "jcs.remotehttpcache";
+
+    /** All of the RemoteHttpCacheServiceAttributes can be configured this way. */
+    public final static String HTTP_CACHE_SERVER_ATTRIBUTES_PROPERTY_PREFIX = HTTP_CACHE_SERVER_PREFIX
+        + ".serverattributes";
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/client/RemoteHttpClientRequestFactory.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/client/RemoteHttpClientRequestFactory.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/client/RemoteHttpClientRequestFactory.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/client/RemoteHttpClientRequestFactory.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,169 @@
+package org.apache.jcs.auxiliary.remote.http.client;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.remote.http.behavior.IRemoteHttpCacheConstants;
+import org.apache.jcs.auxiliary.remote.http.value.RemoteHttpCacheRequest;
+import org.apache.jcs.engine.behavior.ICacheElement;
+
+/**
+ * This creates request objects. You could write your own client and use the objects from this
+ * factory.
+ */
+public class RemoteHttpClientRequestFactory
+{
+    /** The Logger. */
+    private final static Log log = LogFactory.getLog( RemoteHttpClientRequestFactory.class );
+    
+    /**
+     * Creates a get Request.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @return RemoteHttpCacheRequest
+     */
+    public static RemoteHttpCacheRequest createGetRequest( String cacheName, Serializable key, long requesterId )
+    {
+        RemoteHttpCacheRequest request = new RemoteHttpCacheRequest();
+        request.setCacheName( cacheName );
+        request.setKey( key );
+        request.setRequesterId( requesterId );
+        request.setRequestType( IRemoteHttpCacheConstants.REQUEST_TYPE_GET );
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Created: " + request );
+        }
+
+        return request;
+    }
+    
+    /**
+     * Creates a getMatching Request.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @param requesterId
+     * @return RemoteHttpCacheRequest
+     */
+    public static RemoteHttpCacheRequest createGetMatchingRequest( String cacheName, String pattern, long requesterId )
+    {
+        RemoteHttpCacheRequest request = new RemoteHttpCacheRequest();
+        request.setCacheName( cacheName );
+        request.setPattern( pattern );
+        request.setRequesterId( requesterId );
+        request.setRequestType( IRemoteHttpCacheConstants.REQUEST_TYPE_GET_MATCHING );
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Created: " + request );
+        }
+
+        return request;
+    }
+    
+    /**
+     * Creates a getMultiple Request.
+     * <p>
+     * @param cacheName
+     * @param keys
+     * @param requesterId
+     * @return RemoteHttpCacheRequest
+     */
+    public static RemoteHttpCacheRequest createGetMultipleRequest( String cacheName, Set keys, long requesterId )
+    {
+        RemoteHttpCacheRequest request = new RemoteHttpCacheRequest();
+        request.setCacheName( cacheName );
+        request.setKeySet( keys );
+        request.setRequesterId( requesterId );
+        request.setRequestType( IRemoteHttpCacheConstants.REQUEST_TYPE_GET_MULTIPLE );
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Created: " + request );
+        }
+
+        return request;
+    }
+    
+    /**
+     * Creates a remove Request.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @return RemoteHttpCacheRequest
+     */
+    public static RemoteHttpCacheRequest createRemoveRequest( String cacheName, Serializable key, long requesterId )
+    {
+        RemoteHttpCacheRequest request = new RemoteHttpCacheRequest();
+        request.setCacheName( cacheName );
+        request.setKey( key );
+        request.setRequesterId( requesterId );
+        request.setRequestType( IRemoteHttpCacheConstants.REQUEST_TYPE_REMOVE );
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Created: " + request );
+        }
+
+        return request;
+    }
+    
+    /**
+     * Creates a removeAll Request.
+     * <p>
+     * @param cacheName
+     * @param requesterId
+     * @return RemoteHttpCacheRequest
+     */
+    public static RemoteHttpCacheRequest createRemoveAllRequest( String cacheName, long requesterId )
+    {
+        RemoteHttpCacheRequest request = new RemoteHttpCacheRequest();
+        request.setCacheName( cacheName );
+        request.setRequesterId( requesterId );
+        request.setRequestType( IRemoteHttpCacheConstants.REQUEST_TYPE_REMOVE_ALL );
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Created: " + request );
+        }
+
+        return request;
+    }
+    
+    /**
+     * Creates an Update Request.
+     * <p>
+     * @param cacheElement
+     * @param requesterId
+     * @return RemoteHttpCacheRequest
+     */
+    public static RemoteHttpCacheRequest createUpdateRequest( ICacheElement cacheElement, long requesterId )
+    {
+        RemoteHttpCacheRequest request = new RemoteHttpCacheRequest();
+        if ( cacheElement != null )
+        {
+            request.setCacheName( cacheElement.getCacheName() );
+            request.setCacheElement( cacheElement );
+            request.setKey( cacheElement.getKey() );
+        }
+        else
+        {
+            log.error( "Can't create a proper update request for a null cache element." );
+        }
+        request.setRequesterId( requesterId );
+        request.setRequestType( IRemoteHttpCacheConstants.REQUEST_TYPE_UPDATE );
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Created: " + request );
+        }
+
+        return request;
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,581 @@
+package org.apache.jcs.auxiliary.remote.http.server;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheService;
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.behavior.ICompositeCacheManager;
+import org.apache.jcs.engine.control.CompositeCache;
+import org.apache.jcs.engine.control.CompositeCacheManager;
+import org.apache.jcs.engine.logging.CacheEvent;
+import org.apache.jcs.engine.logging.behavior.ICacheEvent;
+import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
+
+/**
+ * This class contains common methods for remote cache services. Eventually I hope to extract out
+ * much of the RMI server to use this as well. I'm starting with the Http service.
+ */
+public abstract class AbstractRemoteCacheService
+    implements IRemoteCacheService
+{
+    /** An optional event logger */
+    private transient ICacheEventLogger cacheEventLogger;
+
+    /** If there is no event logger, we will return this event for all create calls. */
+    private static final ICacheEvent EMPTY_ICACHE_EVENT = new CacheEvent();
+
+    /** The central hub */
+    private ICompositeCacheManager cacheManager;
+
+    /** Name of the event log source. */
+    private String eventLogSourceName = "AbstractRemoteCacheService";
+
+    /** Number of puts into the cache. */
+    private int puts = 0;
+
+    /** The interval at which we will log updates. */
+    private int logInterval = 100;
+
+    /** log instance */
+    private final static Log log = LogFactory.getLog( AbstractRemoteCacheService.class );
+
+    /**
+     * Creates the super with the needed items.
+     * <p>
+     * @param cacheManager
+     * @param cacheEventLogger
+     */
+    public AbstractRemoteCacheService( ICompositeCacheManager cacheManager, ICacheEventLogger cacheEventLogger )
+    {
+        this.cacheManager = cacheManager;
+        this.cacheEventLogger = cacheEventLogger;
+    }
+
+    /**
+     * @param item
+     * @throws IOException
+     */
+    public void update( ICacheElement item )
+        throws IOException
+    {
+        update( item, 0 );
+    }
+
+    /**
+     * The internal processing is wrapped in event logging calls.
+     * <p>
+     * @param item
+     * @param requesterId
+     * @throws IOException
+     */
+    public void update( ICacheElement item, long requesterId )
+        throws IOException
+    {
+        ICacheEvent cacheEvent = createICacheEvent( item, requesterId, ICacheEventLogger.UPDATE_EVENT );
+        try
+        {
+            logUpdateInfo( item );
+
+            processUpdate( item, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+    }
+
+    /**
+     * The internal processing is wrapped in event logging calls.
+     * <p>
+     * @param item
+     * @param requesterId
+     * @throws IOException
+     */
+    abstract void processUpdate( ICacheElement item, long requesterId )
+        throws IOException;
+
+    /**
+     * Log some details.
+     * <p>
+     * @param item
+     */
+    private void logUpdateInfo( ICacheElement item )
+    {
+        if ( log.isInfoEnabled() )
+        {
+            // not thread safe, but it doesn't have to be accurate
+            puts++;
+            if ( puts % logInterval == 0 )
+            {
+                log.info( "puts = " + puts );
+            }
+        }
+
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "In update, put [" + item.getKey() + "] in [" + item.getCacheName() + "]" );
+        }
+    }
+
+    /**
+     * Returns a cache value from the specified remote cache; or null if the cache or key does not
+     * exist.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @return ICacheElement
+     * @throws IOException
+     */
+    public ICacheElement get( String cacheName, Serializable key )
+        throws IOException
+    {
+        return this.get( cacheName, key, 0 );
+    }
+
+    /**
+     * Returns a cache bean from the specified cache; or null if the key does not exist.
+     * <p>
+     * Adding the requestor id, allows the cache to determine the source of the get.
+     * <p>
+     * The internal processing is wrapped in event logging calls.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @return ICacheElement
+     * @throws IOException
+     */
+    public ICacheElement get( String cacheName, Serializable key, long requesterId )
+        throws IOException
+    {
+        ICacheElement element = null;
+        ICacheEvent cacheEvent = createICacheEvent( cacheName, key, requesterId, ICacheEventLogger.GET_EVENT );
+        try
+        {
+            element = processGet( cacheName, key, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+        return element;
+    }
+
+    /**
+     * Returns a cache bean from the specified cache; or null if the key does not exist.
+     * <p>
+     * Adding the requestor id, allows the cache to determine the source of the get.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @return ICacheElement
+     * @throws IOException
+     */
+    abstract ICacheElement processGet( String cacheName, Serializable key, long requesterId )
+        throws IOException;
+
+    /**
+     * Gets all matching items.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @return Map of keys and wrapped objects
+     * @throws IOException
+     */
+    public Map getMatching( String cacheName, String pattern )
+        throws IOException
+    {
+        return getMatching( cacheName, pattern, 0 );
+    }
+
+    /**
+     * Retrieves all matching keys.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @param requesterId
+     * @return Map of keys and wrapped objects
+     * @throws IOException
+     */
+    public Map getMatching( String cacheName, String pattern, long requesterId )
+        throws IOException
+    {
+        ICacheEvent cacheEvent = createICacheEvent( cacheName, pattern, requesterId,
+                                                    ICacheEventLogger.GETMATCHING_EVENT );
+        try
+        {
+            return processGetMatching( cacheName, pattern, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+    }
+
+    /**
+     * Retrieves all matching keys.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @param requesterId
+     * @return Map of keys and wrapped objects
+     * @throws IOException
+     */
+    abstract Map processGetMatching( String cacheName, String pattern, long requesterId )
+        throws IOException;
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param cacheName
+     * @param keys
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no
+     *         data in cache for any of these keys
+     * @throws IOException
+     */
+    public Map getMultiple( String cacheName, Set keys )
+        throws IOException
+    {
+        return this.getMultiple( cacheName, keys, 0 );
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * The internal processing is wrapped in event logging calls.
+     * <p>
+     * @param cacheName
+     * @param keys
+     * @param requesterId
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no
+     *         data in cache for any of these keys
+     * @throws IOException
+     */
+    public Map getMultiple( String cacheName, Set keys, long requesterId )
+        throws IOException
+    {
+        ICacheEvent cacheEvent = createICacheEvent( cacheName, (Serializable) keys, requesterId,
+                                                    ICacheEventLogger.GETMULTIPLE_EVENT );
+        try
+        {
+            return processGetMultiple( cacheName, keys, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+    }
+
+    /**
+     * Gets multiple items from the cache based on the given set of keys.
+     * <p>
+     * @param cacheName
+     * @param keys
+     * @param requesterId
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no
+     *         data in cache for any of these keys
+     * @throws IOException
+     */
+    abstract Map processGetMultiple( String cacheName, Set keys, long requesterId )
+        throws IOException;
+
+    /**
+     * Gets the set of keys of objects currently in the group.
+     * <p>
+     * @param cacheName
+     * @param group
+     * @return A Set of group keys
+     */
+    public Set getGroupKeys( String cacheName, String group )
+    {
+        return processGetGroupKeys( cacheName, group );
+    }
+
+    /**
+     * Gets the set of keys of objects currently in the group.
+     * <p>
+     * @param cacheName
+     * @param groupName
+     * @return Set
+     */
+    public Set processGetGroupKeys( String cacheName, String groupName )
+    {
+        CompositeCache cache = (CompositeCache) getCacheManager().getCache( cacheName );
+
+        return cache.getGroupKeys( groupName );
+    }
+
+    /**
+     * Removes the given key from the specified remote cache. Defaults the listener id to 0.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @throws IOException
+     */
+    public void remove( String cacheName, Serializable key )
+        throws IOException
+    {
+        remove( cacheName, key, 0 );
+    }
+
+    /**
+     * Remove the key from the cache region and don't tell the source listener about it.
+     * <p>
+     * The internal processing is wrapped in event logging calls.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @throws IOException
+     */
+    public void remove( String cacheName, Serializable key, long requesterId )
+        throws IOException
+    {
+        ICacheEvent cacheEvent = createICacheEvent( cacheName, key, requesterId, ICacheEventLogger.REMOVE_EVENT );
+        try
+        {
+            processRemove( cacheName, key, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+
+        return;
+    }
+
+    /**
+     * Remove the key from the cache region and don't tell the source listener about it.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @throws IOException
+     */
+    abstract void processRemove( String cacheName, Serializable key, long requesterId )
+        throws IOException;
+
+    /**
+     * Remove all keys from the specified remote cache.
+     * <p>
+     * @param cacheName
+     * @throws IOException
+     */
+    public void removeAll( String cacheName )
+        throws IOException
+    {
+        removeAll( cacheName, 0 );
+    }
+
+    /**
+     * Remove all keys from the specified remote cache.
+     * <p>
+     * The internal processing is wrapped in event logging calls.
+     * <p>
+     * @param cacheName
+     * @param requesterId
+     * @throws IOException
+     */
+    public void removeAll( String cacheName, long requesterId )
+        throws IOException
+    {
+        ICacheEvent cacheEvent = createICacheEvent( cacheName, "all", requesterId, ICacheEventLogger.REMOVEALL_EVENT );
+        try
+        {
+            processRemoveAll( cacheName, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+        return;
+    }
+
+    /**
+     * Remove all keys from the specified remote cache.
+     * <p>
+     * @param cacheName
+     * @param requesterId
+     * @throws IOException
+     */
+    abstract void processRemoveAll( String cacheName, long requesterId )
+        throws IOException;
+
+    /**
+     * Frees the specified remote cache.
+     * <p>
+     * @param cacheName
+     * @throws IOException
+     */
+    public void dispose( String cacheName )
+        throws IOException
+    {
+        dispose( cacheName, 0 );
+    }
+
+    /**
+     * Frees the specified remote cache.
+     * <p>
+     * @param cacheName
+     * @param requesterId
+     * @throws IOException
+     */
+    public void dispose( String cacheName, long requesterId )
+        throws IOException
+    {
+        ICacheEvent cacheEvent = createICacheEvent( cacheName, "none", requesterId, ICacheEventLogger.DISPOSE_EVENT );
+        try
+        {
+            processDispose( cacheName, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+        return;
+    }
+
+    /**
+     * @param cacheName
+     * @param requesterId
+     * @throws IOException
+     */
+    abstract void processDispose( String cacheName, long requesterId )
+        throws IOException;
+
+    /**
+     * Gets the stats attribute of the RemoteCacheServer object.
+     * <p>
+     * @return The stats value
+     * @throws IOException
+     */
+    public String getStats()
+        throws IOException
+    {
+        return cacheManager.getStats();
+    }
+
+    /**
+     * Logs an event if an event logger is configured.
+     * <p>
+     * @param item
+     * @param requesterId
+     * @param eventName
+     * @return ICacheEvent
+     */
+    protected ICacheEvent createICacheEvent( ICacheElement item, long requesterId, String eventName )
+    {
+        if ( cacheEventLogger == null )
+        {
+            return EMPTY_ICACHE_EVENT;
+        }
+        String ipAddress = getExtraInfoForRequesterId( requesterId );
+        return cacheEventLogger.createICacheEvent( getEventLogSourceName(), item.getCacheName(), eventName, ipAddress,
+                                                   item );
+    }
+
+    /**
+     * Logs an event if an event logger is configured.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @param eventName
+     * @return ICacheEvent
+     */
+    protected ICacheEvent createICacheEvent( String cacheName, Serializable key, long requesterId, String eventName )
+    {
+        if ( cacheEventLogger == null )
+        {
+            return EMPTY_ICACHE_EVENT;
+        }
+        String ipAddress = getExtraInfoForRequesterId( requesterId );
+        return cacheEventLogger.createICacheEvent( getEventLogSourceName(), cacheName, eventName, ipAddress, key );
+    }
+
+    /**
+     * Logs an event if an event logger is configured.
+     * <p>
+     * @param source
+     * @param eventName
+     * @param optionalDetails
+     */
+    protected void logApplicationEvent( String source, String eventName, String optionalDetails )
+    {
+        if ( cacheEventLogger != null )
+        {
+            cacheEventLogger.logApplicationEvent( source, eventName, optionalDetails );
+        }
+    }
+
+    /**
+     * Logs an event if an event logger is configured.
+     * <p>
+     * @param cacheEvent
+     */
+    protected void logICacheEvent( ICacheEvent cacheEvent )
+    {
+        if ( cacheEventLogger != null )
+        {
+            cacheEventLogger.logICacheEvent( cacheEvent );
+        }
+    }
+
+    /**
+     * Ip address for the client, if one is stored.
+     * <p>
+     * Protected for testing.
+     * <p>
+     * @param requesterId
+     * @return String
+     */
+    protected abstract String getExtraInfoForRequesterId( long requesterId );
+
+    /**
+     * Allows it to be injected.
+     * <p>
+     * @param cacheEventLogger
+     */
+    public void setCacheEventLogger( ICacheEventLogger cacheEventLogger )
+    {
+        this.cacheEventLogger = cacheEventLogger;
+    }
+
+    /**
+     * @param cacheManager the cacheManager to set
+     */
+    protected void setCacheManager( CompositeCacheManager cacheManager )
+    {
+        this.cacheManager = cacheManager;
+    }
+
+    /**
+     * @return the cacheManager
+     */
+    protected ICompositeCacheManager getCacheManager()
+    {
+        return cacheManager;
+    }
+
+    /**
+     * @param eventLogSourceName the eventLogSourceName to set
+     */
+    protected void setEventLogSourceName( String eventLogSourceName )
+    {
+        this.eventLogSourceName = eventLogSourceName;
+    }
+
+    /**
+     * @return the eventLogSourceName
+     */
+    protected String getEventLogSourceName()
+    {
+        return eventLogSourceName;
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteCacheServiceAdaptor.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteCacheServiceAdaptor.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteCacheServiceAdaptor.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteCacheServiceAdaptor.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,139 @@
+package org.apache.jcs.auxiliary.remote.http.server;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheService;
+import org.apache.jcs.auxiliary.remote.http.behavior.IRemoteHttpCacheConstants;
+import org.apache.jcs.auxiliary.remote.http.value.RemoteHttpCacheRequest;
+import org.apache.jcs.auxiliary.remote.http.value.RemoteHttpCacheResponse;
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.control.CompositeCacheManager;
+
+/**
+ * The Servlet deserializes the request object. The request object is passed to the processor. The
+ * processor then calls the service which does the work of talking to the cache.
+ * <p>
+ * This is essentially an adaptor on top of the service.
+ */
+public class RemoteCacheServiceAdaptor
+{
+    /** The Logger. */
+    private final static Log log = LogFactory.getLog( RemoteCacheServiceAdaptor.class );
+
+    /** The service that does the work. */
+    private IRemoteCacheService remoteCacheService;
+    
+    /** This is for testing without the factory. */
+    protected RemoteCacheServiceAdaptor()
+    {
+        // for testing.
+    }
+    
+    /**
+     * Create a process with a cache manager.
+     * <p>
+     * @param cacheManager
+     */
+    public RemoteCacheServiceAdaptor( CompositeCacheManager cacheManager )
+    {
+        setRemoteCacheService( RemoteHttpCacheSeviceFactory.createRemoteHttpCacheService( cacheManager ) );
+    }
+
+    /**
+     * Processes the request. It will call the appropriate method on the service
+     * <p>
+     * @param request
+     * @return RemoteHttpCacheResponse, never null
+     */
+    public RemoteHttpCacheResponse processRequest( RemoteHttpCacheRequest request )
+    {
+        RemoteHttpCacheResponse response = new RemoteHttpCacheResponse();
+
+        if ( request == null )
+        {
+            String message = "The request is null.  Cannot process";
+            log.warn( message );
+            response.setSuccess( false );
+            response.setErrorMessage( message );
+        }
+        else
+        {
+            try
+            {
+                switch ( request.getRequestType() )
+                {
+                    case IRemoteHttpCacheConstants.REQUEST_TYPE_GET:
+                        ICacheElement element = getRemoteCacheService().get( request.getCacheName(),
+                                                                                 request.getKey(),
+                                                                                 request.getRequesterId() );
+                        if ( element != null )
+                        {
+                            response.getPayload().put( element.getKey(), element );
+                        }
+                        break;
+                    case IRemoteHttpCacheConstants.REQUEST_TYPE_GET_MULTIPLE:
+                        Map elementMap = getRemoteCacheService().getMultiple( request.getCacheName(),
+                                                                                  request.getKeySet(),
+                                                                                  request.getRequesterId() );
+                        if ( elementMap != null )
+                        {
+                            response.getPayload().putAll( elementMap );
+                        }
+                        break;
+                    case IRemoteHttpCacheConstants.REQUEST_TYPE_GET_MATCHING:
+                        Map elementMapMatching = getRemoteCacheService().getMatching( request.getCacheName(),
+                                                                                          request.getPattern(),
+                                                                                          request.getRequesterId() );
+                        if ( elementMapMatching != null )
+                        {
+                            response.getPayload().putAll( elementMapMatching );
+                        }
+                        break;
+                    case IRemoteHttpCacheConstants.REQUEST_TYPE_REMOVE:
+                        getRemoteCacheService().remove( request.getCacheName(), request.getKey(),
+                                                            request.getRequesterId() );
+                        break;
+                    case IRemoteHttpCacheConstants.REQUEST_TYPE_REMOVE_ALL:
+                        getRemoteCacheService().removeAll( request.getCacheName(), request.getRequesterId() );
+                        break;
+                    case IRemoteHttpCacheConstants.REQUEST_TYPE_UPDATE:
+                        getRemoteCacheService().update( request.getCacheElement(), request.getRequesterId() );
+                        break;
+                    default:
+                        String message = "Unknown event type.  Cannot process " + request;
+                        log.warn( message );
+                        response.setSuccess( false );
+                        response.setErrorMessage( message );
+                        break;
+                }
+            }
+            catch ( Exception e )
+            {
+                String message = "Problem processing request. " + request + " Error: " + e.getMessage();
+                log.error( message, e );
+                response.setSuccess( false );
+                response.setErrorMessage( message );
+            }
+        }
+
+        return response;
+    }
+
+    /**
+     * @param remoteHttpCacheService the remoteHttpCacheService to set
+     */
+    public void setRemoteCacheService( IRemoteCacheService remoteHttpCacheService )
+    {
+        this.remoteCacheService = remoteHttpCacheService;
+    }
+
+    /**
+     * @return the remoteHttpCacheService
+     */
+    public IRemoteCacheService getRemoteCacheService()
+    {
+        return remoteCacheService;
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServerAttributes.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServerAttributes.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServerAttributes.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServerAttributes.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,94 @@
+package org.apache.jcs.auxiliary.remote.http.server;
+
+import org.apache.jcs.auxiliary.AbstractAuxiliaryCacheAttributes;
+import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
+
+/**
+ * Configuration for the RemoteHttpCacheServer. Most of these properties are used only by the
+ * service.
+ */
+public class RemoteHttpCacheServerAttributes
+    extends AbstractAuxiliaryCacheAttributes
+{
+    /** Don't change. */
+    private static final long serialVersionUID = -3987239306108780496L;
+
+    /** Can a cluster remote put to other remotes */
+    private boolean localClusterConsistency = true;
+
+    /** Can a cluster remote get from other remotes */
+    private boolean allowClusterGet = true;
+
+    /**
+     * clones
+     * <p>
+     * @return AuxiliaryCacheAttributes clone
+     */
+    public AuxiliaryCacheAttributes copy()
+    {
+        try
+        {
+            return (AuxiliaryCacheAttributes) this.clone();
+        }
+        catch ( Exception e )
+        {
+            // swallow
+        }
+        return this;
+    }
+
+    /**
+     * Should cluster updates be propagated to the locals
+     * <p>
+     * @return The localClusterConsistency value
+     */
+    public boolean isLocalClusterConsistency()
+    {
+        return localClusterConsistency;
+    }
+
+    /**
+     * Should cluster updates be propagated to the locals
+     * <p>
+     * @param r The new localClusterConsistency value
+     */
+    public void setLocalClusterConsistency( boolean r )
+    {
+        this.localClusterConsistency = r;
+    }
+
+    /**
+     * Should gets from non-cluster clients be allowed to get from other remote auxiliaries.
+     * <p>
+     * @return The localClusterConsistency value
+     */
+    public boolean isAllowClusterGet()
+    {
+        return allowClusterGet;
+    }
+
+    /**
+     * Should we try to get from other cluster servers if we don't find the items locally.
+     * <p>
+     * @param r The new localClusterConsistency value
+     */
+    public void setAllowClusterGet( boolean r )
+    {
+        allowClusterGet = r;
+    }
+
+    /**
+     * @return String details
+     */
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.append( "\nRemoteHttpCacheServiceAttributes" );
+        buf.append( "\n cacheName = [" + this.getCacheName() + "]" );
+        buf.append( "\n allowClusterGet = [" + this.isAllowClusterGet() + "]" );
+        buf.append( "\n localClusterConsistency = [" + this.isLocalClusterConsistency() + "]" );
+        buf.append( "\n eventQueueType = [" + this.getEventQueueType() + "]" );
+        buf.append( "\n eventQueuePoolName = [" + this.getEventQueuePoolName() + "]" );
+        return buf.toString();
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheService.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheService.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheService.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,242 @@
+package org.apache.jcs.auxiliary.remote.http.server;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.behavior.ICompositeCacheManager;
+import org.apache.jcs.engine.control.CompositeCache;
+import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
+
+/**
+ * This does the work. It's called by the processor. The base class wraps the processing calls in
+ * event logs, if an event logger is present.
+ * <p>
+ * For now we assume that all clients are non-cluster clients. And listener notification is not
+ * supported.
+ */
+public class RemoteHttpCacheService
+    extends AbstractRemoteCacheService
+{
+    /** The name used in the event logs. */
+    private static final String EVENT_LOG_SOURCE_NAME = "RemoteHttpCacheServer";
+
+    /** The configuration */
+    private RemoteHttpCacheServerAttributes remoteHttpCacheServerAttributes;
+
+    /**
+     * Create a process with a cache manager.
+     * <p>
+     * @param cacheManager
+     * @param remoteHttpCacheServerAttributes
+     * @param cacheEventLogger
+     */
+    public RemoteHttpCacheService( ICompositeCacheManager cacheManager,
+                                   RemoteHttpCacheServerAttributes remoteHttpCacheServerAttributes,
+                                   ICacheEventLogger cacheEventLogger )
+    {
+        super( cacheManager, cacheEventLogger );
+        setEventLogSourceName( EVENT_LOG_SOURCE_NAME );
+        this.remoteHttpCacheServerAttributes = remoteHttpCacheServerAttributes;
+    }
+
+    /**
+     * Processes a get request.
+     * <p>
+     * If isAllowClusterGet is enabled we will treat this as a normal request or non-remote origins.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @return ICacheElement
+     * @throws IOException
+     */
+    public ICacheElement processGet( String cacheName, Serializable key, long requesterId )
+        throws IOException
+    {
+        CompositeCache cache = (CompositeCache) getCacheManager().getCache( cacheName );
+
+        boolean keepLocal = !remoteHttpCacheServerAttributes.isAllowClusterGet();
+        if ( keepLocal )
+        {
+            return cache.localGet( key );
+        }
+        else
+        {
+            return cache.get( key );
+        }
+    }
+
+    /**
+     * Processes a get request.
+     * <p>
+     * If isAllowClusterGet is enabled we will treat this as a normal request of non-remote
+     * origination.
+     * <p>
+     * @param cacheName
+     * @param keys
+     * @param requesterId
+     * @return Map
+     * @throws IOException
+     */
+    public Map processGetMultiple( String cacheName, Set keys, long requesterId )
+        throws IOException
+    {
+        CompositeCache cache = (CompositeCache) getCacheManager().getCache( cacheName );
+
+        boolean keepLocal = !remoteHttpCacheServerAttributes.isAllowClusterGet();
+        if ( keepLocal )
+        {
+            return cache.localGetMultiple( keys );
+        }
+        else
+        {
+            return cache.getMultiple( keys );
+        }
+    }
+
+    /**
+     * Processes a get request.
+     * <p>
+     * If isAllowClusterGet is enabled we will treat this as a normal request of non-remote
+     * origination.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @param requesterId
+     * @return Map
+     * @throws IOException
+     */
+    public Map processGetMatching( String cacheName, String pattern, long requesterId )
+        throws IOException
+    {
+        CompositeCache cache = (CompositeCache) getCacheManager().getCache( cacheName );
+
+        boolean keepLocal = !remoteHttpCacheServerAttributes.isAllowClusterGet();
+        if ( keepLocal )
+        {
+            return cache.localGetMatching( pattern );
+        }
+        else
+        {
+            return cache.getMatching( pattern );
+        }
+    }
+
+    /**
+     * Processes an update request.
+     * <p>
+     * If isLocalClusterConsistency is enabled we will treat this as a normal request of non-remote
+     * origination.
+     * <p>
+     * @param item
+     * @param requesterId
+     * @throws IOException
+     */
+    public void processUpdate( ICacheElement item, long requesterId )
+        throws IOException
+    {
+        CompositeCache cache = (CompositeCache) getCacheManager().getCache( item.getCacheName() );
+
+        boolean keepLocal = !remoteHttpCacheServerAttributes.isLocalClusterConsistency();
+        if ( keepLocal )
+        {
+            cache.localUpdate( item );
+        }
+        else
+        {
+            cache.update( item );
+        }
+    }
+
+    /**
+     * Processes a remove request.
+     * <p>
+     * If isLocalClusterConsistency is enabled we will treat this as a normal request of non-remote
+     * origination.
+     * <p>
+     * @param cacheName
+     * @param key
+     * @param requesterId
+     * @throws IOException
+     */
+    public void processRemove( String cacheName, Serializable key, long requesterId )
+        throws IOException
+    {
+        CompositeCache cache = (CompositeCache) getCacheManager().getCache( cacheName );
+
+        boolean keepLocal = !remoteHttpCacheServerAttributes.isLocalClusterConsistency();
+        if ( keepLocal )
+        {
+            cache.localRemove( key );
+        }
+        else
+        {
+            cache.remove( key );
+        }
+    }
+
+    /**
+     * Processes a removeAll request.
+     * <p>
+     * If isLocalClusterConsistency is enabled we will treat this as a normal request of non-remote
+     * origination.
+     * <p>
+     * @param cacheName
+     * @param requesterId
+     * @throws IOException
+     */
+    public void processRemoveAll( String cacheName, long requesterId )
+        throws IOException
+    {
+        CompositeCache cache = (CompositeCache) getCacheManager().getCache( cacheName );
+
+        boolean keepLocal = !remoteHttpCacheServerAttributes.isLocalClusterConsistency();
+        if ( keepLocal )
+        {
+            cache.localRemoveAll();
+        }
+        else
+        {
+            cache.removeAll();
+        }
+    }
+
+    /**
+     * Processes a shutdown request.
+     * <p>
+     * @param cacheName
+     * @param requesterId
+     * @throws IOException
+     */
+    public void processDispose( String cacheName, long requesterId )
+        throws IOException
+    {
+        CompositeCache cache = (CompositeCache) getCacheManager().getCache( cacheName );
+        cache.dispose();
+    }
+
+    /**
+     * This general method should be deprecated.
+     * <p>
+     * @throws IOException
+     */
+    public void release()
+        throws IOException
+    {
+        //nothing.
+    }
+
+    /**
+     * This is called by the event log.
+     * <p>
+     * @param requesterId
+     * @return requesterId + ""
+     */
+    protected String getExtraInfoForRequesterId( long requesterId )
+    {
+        return requesterId + "";
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,202 @@
+package org.apache.jcs.auxiliary.remote.http.server;
+
+/*
+ * 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 java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.remote.http.value.RemoteHttpCacheRequest;
+import org.apache.jcs.auxiliary.remote.http.value.RemoteHttpCacheResponse;
+import org.apache.jcs.engine.control.CompositeCacheManager;
+
+/**
+ * This servlet simply reads and writes objects. The requests are packaged in a general wrapper. The
+ * processor works on the wrapper object and returns a response wrapper.
+ */
+public class RemoteHttpCacheServlet
+    extends HttpServlet
+{
+    /** Don't change. */
+    private static final long serialVersionUID = 8752849397531933346L;
+
+    /** The Logger. */
+    private final static Log log = LogFactory.getLog( RemoteHttpCacheServlet.class );
+
+    /** The cache manager */
+    private static CompositeCacheManager cacheMgr;
+
+    /** Processes requests */
+    private RemoteCacheServiceAdaptor remoteHttpCacheServiceAdaptor;
+
+    /**
+     * Initializes the cache.
+     * <p>
+     * This provides an easy extension point. Simply extend this servlet and override the init
+     * method to change the way the properties are loaded.
+     * @param config
+     * @throws ServletException
+     */
+    public void init( ServletConfig config )
+        throws ServletException
+    {
+        ensureCacheManager();
+
+        setRemoteHttpCacheServiceAdaptor( new RemoteCacheServiceAdaptor( cacheMgr ) );
+
+        super.init( config );
+    }
+
+    /**
+     * Read the request, call the processor, write the response.
+     * <p>
+     * @param request
+     * @param response
+     * @throws ServletException
+     * @throws IOException
+     */
+    public void service( HttpServletRequest request, HttpServletResponse response )
+        throws ServletException, IOException
+    {
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "Servicing a request." );
+        }
+
+        RemoteHttpCacheRequest remoteRequest = readRequest( request );
+
+        RemoteHttpCacheResponse cacheResponse = getRemoteHttpCacheServiceAdaptor().processRequest( remoteRequest );
+
+        writeResponse( response, cacheResponse );
+    }
+
+    /**
+     * Read the request from the input stream.
+     * <p>
+     * @param request
+     * @return RemoteHttpCacheRequest
+     */
+    protected RemoteHttpCacheRequest readRequest( HttpServletRequest request )
+    {
+        RemoteHttpCacheRequest remoteRequest = null;
+        try
+        {
+            ObjectInputStream ois = new ObjectInputStream( request.getInputStream() );
+
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "after getting input stream and before reading it" );
+            }
+
+            remoteRequest = (RemoteHttpCacheRequest) ois.readObject();
+            ois.close();
+        }
+        catch ( Exception e )
+        {
+            log.error( "Could not get a RemoteHttpCacheRequest object from the input stream.", e );
+        }
+        return remoteRequest;
+    }
+
+    /**
+     * Write the response to the output stream.
+     * <p>
+     * @param response
+     * @param cacheResponse
+     */
+    protected void writeResponse( HttpServletResponse response, RemoteHttpCacheResponse cacheResponse )
+    {
+        try
+        {
+            response.setContentType( "application/octet-stream" );
+
+            ObjectOutputStream oos = new ObjectOutputStream( response.getOutputStream() );
+
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "Opened output stream." );
+            }
+
+            // WRITE
+            oos.writeObject( cacheResponse );
+            oos.flush();
+            oos.close();
+        }
+        catch ( Exception e )
+        {
+            log.error( "Problem writing response. " + cacheResponse, e );
+        }
+    }
+
+    /**
+     * Make sure we have a cache manager. This should have happened in the init method.
+     */
+    protected synchronized void ensureCacheManager()
+    {
+        if ( cacheMgr == null )
+        {
+            cacheMgr = CompositeCacheManager.getInstance();
+        }
+    }
+
+    /** Release the cache manager. */
+    public void destroy()
+    {
+        if ( log.isInfoEnabled() )
+        {
+            log.info( "Servlet Destroyed, shutting down JCS." );
+        }
+        cacheMgr.shutDown();
+    }
+
+    /**
+     * Get servlet information
+     * <p>
+     * @return basic info
+     */
+    public String getServletInfo()
+    {
+        return "RemoteHttpCacheServlet";
+    }
+
+    /**
+     * @param remoteHttpCacheProcessor the remoteHttpCacheProcessor to set
+     */
+    public void setRemoteHttpCacheServiceAdaptor( RemoteCacheServiceAdaptor remoteHttpCacheProcessor )
+    {
+        this.remoteHttpCacheServiceAdaptor = remoteHttpCacheProcessor;
+    }
+
+    /**
+     * @return the remoteHttpCacheProcessor
+     */
+    public RemoteCacheServiceAdaptor getRemoteHttpCacheServiceAdaptor()
+    {
+        return remoteHttpCacheServiceAdaptor;
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheSeviceFactory.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheSeviceFactory.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheSeviceFactory.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/server/RemoteHttpCacheSeviceFactory.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,71 @@
+package org.apache.jcs.auxiliary.remote.http.server;
+
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.AuxiliaryCacheConfigurator;
+import org.apache.jcs.auxiliary.remote.http.behavior.IRemoteHttpCacheConstants;
+import org.apache.jcs.engine.behavior.ICompositeCacheManager;
+import org.apache.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.jcs.utils.config.PropertySetter;
+
+/** Creates the server. */
+public class RemoteHttpCacheSeviceFactory
+{
+    /** The logger */
+    private final static Log log = LogFactory.getLog( RemoteHttpCacheSeviceFactory.class );
+
+    /**
+     * Configures the attributes and the event logger and constructs a service.
+     * <p>
+     * @param cacheManager
+     * @return RemoteHttpCacheService
+     */
+    public static RemoteHttpCacheService createRemoteHttpCacheService( ICompositeCacheManager cacheManager )
+    {
+        Properties props = cacheManager.getConfigurationProperties();
+        ICacheEventLogger cacheEventLogger = configureCacheEventLogger( props );
+        RemoteHttpCacheServerAttributes attributes = configureRemoteHttpCacheServerAttributes( props );
+
+        RemoteHttpCacheService service = new RemoteHttpCacheService( cacheManager, attributes, cacheEventLogger );
+        if ( log.isInfoEnabled() )
+        {
+            log.info( "Created new RemoteHttpCacheService " + service );
+        }
+        return service;
+    }
+
+    /**
+     * Tries to get the event logger.
+     * <p>
+     * @param props
+     * @return ICacheEventLogger
+     */
+    protected static ICacheEventLogger configureCacheEventLogger( Properties props )
+    {
+        ICacheEventLogger cacheEventLogger = AuxiliaryCacheConfigurator
+            .parseCacheEventLogger( props, IRemoteHttpCacheConstants.HTTP_CACHE_SERVER_PREFIX );
+
+        return cacheEventLogger;
+    }
+
+    /**
+     * Configure.
+     * <p>
+     * jcs.remotehttpcache.serverattributes.ATTRIBUTENAME=ATTRIBUTEVALUE
+     * <p>
+     * @param prop
+     * @return RemoteCacheServerAttributesconfigureRemoteCacheServerAttributes
+     */
+    protected static RemoteHttpCacheServerAttributes configureRemoteHttpCacheServerAttributes( Properties prop )
+    {
+        RemoteHttpCacheServerAttributes rcsa = new RemoteHttpCacheServerAttributes();
+
+        // configure automatically
+        PropertySetter.setProperties( rcsa, prop,
+                                      IRemoteHttpCacheConstants.HTTP_CACHE_SERVER_ATTRIBUTES_PROPERTY_PREFIX + "." );
+
+        return rcsa;
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheRequest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheRequest.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheRequest.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheRequest.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,167 @@
+package org.apache.jcs.auxiliary.remote.http.value;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import org.apache.jcs.engine.behavior.ICacheElement;
+
+/**
+ * The basic request wrapper. The different types of requests are differentiated by their types.
+ * <p>
+ * Rather than creating sub object types, I created on object thsat has values for all types of
+ * requests.
+ */
+public class RemoteHttpCacheRequest
+    implements Serializable
+{
+    /** Don't change. */
+    private static final long serialVersionUID = -8858447417390442569L;
+
+    /** The request type specifies the type of request: get, put, remove, . . */
+    private byte requestType = -1;
+
+    /** Used to identify the source. Same as listener id on the client side. */
+    private long requesterId = 0;
+
+    /** The name of the region */
+    private String cacheName;
+
+    /** The key, if this request has a key. */
+    private Serializable key;
+
+    /** The keySet, if this request has a keySet. Only getMultiple requests. */
+    private Set keySet;
+
+    /** The pattern, if this request uses a pattern. Ony getMatching requests. */
+    private String pattern;
+
+    /** The ICacheEleemnt, if this request contains a value. Only update requests will have this. */
+    private ICacheElement cacheElement;
+
+    /**
+     * @param requestType the requestType to set
+     */
+    public void setRequestType( byte requestType )
+    {
+        this.requestType = requestType;
+    }
+
+    /**
+     * @return the requestType
+     */
+    public byte getRequestType()
+    {
+        return requestType;
+    }
+
+    /**
+     * @param cacheName the cacheName to set
+     */
+    public void setCacheName( String cacheName )
+    {
+        this.cacheName = cacheName;
+    }
+
+    /**
+     * @return the cacheName
+     */
+    public String getCacheName()
+    {
+        return cacheName;
+    }
+
+    /**
+     * @param key the key to set
+     */
+    public void setKey( Serializable key )
+    {
+        this.key = key;
+    }
+
+    /**
+     * @return the key
+     */
+    public Serializable getKey()
+    {
+        return key;
+    }
+
+    /**
+     * @param pattern the pattern to set
+     */
+    public void setPattern( String pattern )
+    {
+        this.pattern = pattern;
+    }
+
+    /**
+     * @return the pattern
+     */
+    public String getPattern()
+    {
+        return pattern;
+    }
+
+    /**
+     * @param cacheElement the cacheElement to set
+     */
+    public void setCacheElement( ICacheElement cacheElement )
+    {
+        this.cacheElement = cacheElement;
+    }
+
+    /**
+     * @return the cacheElement
+     */
+    public ICacheElement getCacheElement()
+    {
+        return cacheElement;
+    }
+
+    /**
+     * @param requesterId the requesterId to set
+     */
+    public void setRequesterId( long requesterId )
+    {
+        this.requesterId = requesterId;
+    }
+
+    /**
+     * @return the requesterId
+     */
+    public long getRequesterId()
+    {
+        return requesterId;
+    }
+
+    /**
+     * @param keySet the keySet to set
+     */
+    public void setKeySet( Set keySet )
+    {
+        this.keySet = keySet;
+    }
+
+    /**
+     * @return the keySet
+     */
+    public Set getKeySet()
+    {
+        return keySet;
+    }
+
+    /** @return string */
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.append( "\nRemoteHttpCacheRequest" );
+        buf.append( "\n requesterId [" + getRequesterId() + "]" );
+        buf.append( "\n requestType [" + getRequestType() + "]" );
+        buf.append( "\n cacheName [" + getCacheName() + "]" );
+        buf.append( "\n key [" + getKey() + "]" );
+        buf.append( "\n keySet [" + getKeySet() + "]" );
+        buf.append( "\n pattern [" + getPattern() + "]" );
+        buf.append( "\n cacheElement [" + getCacheElement() + "]" );
+        return buf.toString();
+    }
+}

Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheResponse.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheResponse.java?rev=724518&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheResponse.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/http/value/RemoteHttpCacheResponse.java Mon Dec  8 14:24:42 2008
@@ -0,0 +1,87 @@
+package org.apache.jcs.auxiliary.remote.http.value;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This is the response wrapper. The servlet wraps all different type of responses in one of these
+ * objects.
+ */
+public class RemoteHttpCacheResponse
+    implements Serializable
+{
+    /** Don't change. */
+    private static final long serialVersionUID = -8858447417390442568L;
+
+    /** Was the event processed without error */
+    private boolean success = true;
+
+    /** Simple error messaging */
+    private String errorMessage;
+
+    /**
+     * The payload. Typically a key / ICacheElement map. A normal get will return a map with one
+     * record.
+     */
+    private Map payload = new HashMap();
+
+    /**
+     * @param success the success to set
+     */
+    public void setSuccess( boolean success )
+    {
+        this.success = success;
+    }
+
+    /**
+     * @return the success
+     */
+    public boolean isSuccess()
+    {
+        return success;
+    }
+
+    /**
+     * @param errorMessage the errorMessage to set
+     */
+    public void setErrorMessage( String errorMessage )
+    {
+        this.errorMessage = errorMessage;
+    }
+
+    /**
+     * @return the errorMessage
+     */
+    public String getErrorMessage()
+    {
+        return errorMessage;
+    }
+
+    /**
+     * @param payload the payload to set
+     */
+    public void setPayload( Map payload )
+    {
+        this.payload = payload;
+    }
+
+    /**
+     * @return the payload
+     */
+    public Map getPayload()
+    {
+        return payload;
+    }
+
+    /** @return string */
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.append( "\nRemoteHttpCacheResponse" );
+        buf.append( "\n success [" + isSuccess() + "]" );
+        buf.append( "\n payload [" + getPayload() + "]" );
+        buf.append( "\n errorMessage [" + getErrorMessage() + "]" );
+        return buf.toString();
+    }
+}

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServer.java Mon Dec  8 14:24:42 2008
@@ -265,7 +265,7 @@
             CacheListeners cacheDesc = getCacheListeners( item.getCacheName() );
             /* Object val = */item.getVal();
 
-            boolean fromCluster = isRequestFromCluster( requesterId );            
+            boolean fromCluster = isRequestFromCluster( requesterId );
 
             if ( log.isDebugEnabled() )
             {
@@ -451,7 +451,7 @@
     private ICacheElement processGet( String cacheName, Serializable key, long requesterId )
     {
         boolean fromCluster = isRequestFromCluster( requesterId );
-        
+
         if ( log.isDebugEnabled() )
         {
             log.debug( "get [" + key + "] from cache [" + cacheName + "] requesterId = [" + requesterId
@@ -537,7 +537,21 @@
     }
 
     /**
-     * TODO finish
+     * Gets all matching items.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @return Map of keys and wrapped objects
+     * @throws IOException
+     */
+    public Map getMatching( String cacheName, String pattern )
+        throws IOException
+    {
+        return getMatching( cacheName, pattern, 0 );
+    }
+
+    /**
+     * Retrieves all matching keys.
      * <p>
      * @param cacheName
      * @param pattern
@@ -552,36 +566,49 @@
                                                     ICacheEventLogger.GETMATCHING_EVENT );
         try
         {
-            boolean fromCluster = isRequestFromCluster( requesterId );
-            
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "getMatching [" + pattern + "] from cache [" + cacheName + "] requesterId = [" + requesterId
-                    + "] fromCluster = " + fromCluster );
-            }
+            return processGetMatching( cacheName, pattern, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+    }
 
-            CacheListeners cacheDesc = null;
-            try
-            {
-                cacheDesc = getCacheListeners( cacheName );
-            }
-            catch ( Exception e )
-            {
-                log.error( "Problem getting listeners.", e );
+    /**
+     * Retrieves all matching keys.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @param requesterId
+     * @return Map of keys and wrapped objects
+     */
+    protected Map processGetMatching( String cacheName, String pattern, long requesterId )
+    {
+        boolean fromCluster = isRequestFromCluster( requesterId );
 
-                if ( cacheEventLogger != null )
-                {
-                    cacheEventLogger.logError( "RemoteCacheServer", ICacheEventLogger.GETMATCHING_EVENT, e.getMessage()
-                        + cacheName + " pattern: " + pattern );
-                }
-            }
+        if ( log.isDebugEnabled() )
+        {
+            log.debug( "getMatching [" + pattern + "] from cache [" + cacheName + "] requesterId = [" + requesterId
+                + "] fromCluster = " + fromCluster );
+        }
 
-            return getMatchingFromCacheListeners( pattern, fromCluster, cacheDesc );
+        CacheListeners cacheDesc = null;
+        try
+        {
+            cacheDesc = getCacheListeners( cacheName );
         }
-        finally
+        catch ( Exception e )
         {
-            logICacheEvent( cacheEvent );
+            log.error( "Problem getting listeners.", e );
+
+            if ( cacheEventLogger != null )
+            {
+                cacheEventLogger.logError( "RemoteCacheServer", ICacheEventLogger.GETMATCHING_EVENT, e.getMessage()
+                    + cacheName + " pattern: " + pattern );
+            }
         }
+
+        return getMatchingFromCacheListeners( pattern, fromCluster, cacheDesc );
     }
 
     /**
@@ -792,6 +819,18 @@
      */
     public Set getGroupKeys( String cacheName, String group )
     {
+        return processGetGroupKeys( cacheName, group );
+    }
+
+    /**
+     * Gets the set of keys of objects currently in the group.
+     * <p>
+     * @param cacheName
+     * @param group
+     * @return Set
+     */
+    protected Set processGetGroupKeys( String cacheName, String group )
+    {
         CacheListeners cacheDesc = null;
         try
         {
@@ -1044,34 +1083,45 @@
         ICacheEvent cacheEvent = createICacheEvent( cacheName, "none", requesterId, ICacheEventLogger.DISPOSE_EVENT );
         try
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Dispose request received from listener [" + requesterId + "]" );
-            }
+            processDispose( cacheName, requesterId );
+        }
+        finally
+        {
+            logICacheEvent( cacheEvent );
+        }
+        return;
+    }
+
+    /**
+     * @param cacheName
+     * @param requesterId
+     * @throws IOException
+     */
+    private void processDispose( String cacheName, long requesterId )
+        throws IOException
+    {
+        if ( log.isInfoEnabled() )
+        {
+            log.info( "Dispose request received from listener [" + requesterId + "]" );
+        }
 
-            CacheListeners cacheDesc = (CacheListeners) cacheListenersMap.get( cacheName );
+        CacheListeners cacheDesc = (CacheListeners) cacheListenersMap.get( cacheName );
 
-            // this is dangerous
-            if ( cacheDesc != null )
+        // this is dangerous
+        if ( cacheDesc != null )
+        {
+            // best attempt to achieve ordered free-cache-op and notification.
+            synchronized ( cacheDesc )
             {
-                // best attempt to achieve ordered free-cache-op and notification.
-                synchronized ( cacheDesc )
-                {
-                    ICacheEventQueue[] qlist = getEventQList( cacheDesc, requesterId );
+                ICacheEventQueue[] qlist = getEventQList( cacheDesc, requesterId );
 
-                    for ( int i = 0; i < qlist.length; i++ )
-                    {
-                        qlist[i].addDisposeEvent();
-                    }
-                    cacheManager.freeCache( cacheName );
+                for ( int i = 0; i < qlist.length; i++ )
+                {
+                    qlist[i].addDisposeEvent();
                 }
+                cacheManager.freeCache( cacheName );
             }
         }
-        finally
-        {
-            logICacheEvent( cacheEvent );
-        }
-        return;
     }
 
     /**
@@ -1558,7 +1608,7 @@
         {
             return EMPTY_ICACHE_EVENT;
         }
-        String ipAddress = getIPAddressForRequesterId( requesterId );
+        String ipAddress = getExtraInfoForRequesterId( requesterId );
         return cacheEventLogger
             .createICacheEvent( "RemoteCacheServer", item.getCacheName(), eventName, ipAddress, item );
     }
@@ -1578,7 +1628,7 @@
         {
             return EMPTY_ICACHE_EVENT;
         }
-        String ipAddress = getIPAddressForRequesterId( requesterId );
+        String ipAddress = getExtraInfoForRequesterId( requesterId );
         return cacheEventLogger.createICacheEvent( "RemoteCacheServer", cacheName, eventName, ipAddress, key );
     }
 
@@ -1618,7 +1668,7 @@
      * @param requesterId
      * @return String
      */
-    protected String getIPAddressForRequesterId( long requesterId )
+    protected String getExtraInfoForRequesterId( long requesterId )
     {
         String ipAddress = (String) idIPMap.get( new Long( requesterId ) );
         return ipAddress;

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java Mon Dec  8 14:24:42 2008
@@ -131,9 +131,7 @@
             RemoteUtils.configureGlobalCustomSocketFactory( rcsa.getRmiSocketFactoryTimeoutMillis() );
 
             // CONFIGURE THE EVENT LOGGER
-            ICacheEventLogger cacheEventLogger;
-
-            cacheEventLogger = configureCacheEventLogger( props );
+            ICacheEventLogger cacheEventLogger = configureCacheEventLogger( props );
 
             // CREATE SERVER
             if ( customRMISocketFactory != null )

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/ZombieCacheService.java Mon Dec  8 14:24:42 2008
@@ -20,7 +20,7 @@
  */
 
 import java.io.Serializable;
-import java.util.HashMap;
+import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 
@@ -76,11 +76,23 @@
      * <p>
      * @param cacheName
      * @param keys
-     * @return an empty map
+     * @return Collections.EMPTY_MAP
      */
     public Map getMultiple( String cacheName, Set keys )
     {
-        return new HashMap();
+        return Collections.EMPTY_MAP;
+    }
+
+    /**
+     * Returns an empty map. Zombies have no internal data.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @return Collections.EMPTY_MAP
+     */
+    public Map getMatching( String cacheName, String pattern )
+    {
+        return Collections.EMPTY_MAP;
     }
 
     /**

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICacheService.java Mon Dec  8 14:24:42 2008
@@ -70,6 +70,18 @@
         throws ObjectNotFoundException, IOException;
 
     /**
+     * Gets multiple items from the cache matching the pattern.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @return a map of Serializable key to ICacheElement element, or an empty map if there is no
+     *         data in cache matching the pattern.
+     * @throws IOException
+     */
+    Map getMatching( String cacheName, String pattern )
+        throws IOException;
+    
+    /**
      * Removes the given key from the specified cache.
      * <p>
      * @param cacheName

Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICompositeCacheManager.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICompositeCacheManager.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICompositeCacheManager.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/behavior/ICompositeCacheManager.java Mon Dec  8 14:24:42 2008
@@ -44,4 +44,11 @@
      * @return the configurationProperties
      */
     Properties getConfigurationProperties();
+    
+    /**
+     * Gets stats for debugging.
+     * <p>
+     * @return String
+     */
+    String getStats();
 }

Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/MockAuxiliaryCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/MockAuxiliaryCache.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/MockAuxiliaryCache.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/MockAuxiliaryCache.java Mon Dec  8 14:24:42 2008
@@ -140,25 +140,24 @@
 
     /**
      * @return int
-     * 
      */
     public int getStatus()
     {
         return status;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getCacheName()
+    /**
+     * @return null
      */
     public String getCacheName()
     {
         return null;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getGroupKeys(java.lang.String)
+    /**
+     * @param group
+     * @return null
+     * @throws IOException
      */
     public Set getGroupKeys( String group )
         throws IOException
@@ -166,27 +165,24 @@
         return null;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getStatistics()
+    /**
+     * @return null
      */
     public IStats getStatistics()
     {
         return null;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.engine.behavior.ICache#getStats()
+    /**
+     * @return null
      */
     public String getStats()
     {
         return null;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.engine.behavior.ICacheType#getCacheType()
+    /**
+     * @return cacheType
      */
     public int getCacheType()
     {

Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheClient.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheClient.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheClient.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheClient.java Mon Dec  8 14:24:42 2008
@@ -149,27 +149,26 @@
         return false;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#removeAll()
+    /**
+     * Removes all cached items from the cache.
      */
     public void removeAll()
     {
         // do nothing
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#dispose()
+    /**
+     * Prepares for shutdown.
      */
     public void dispose()
     {
         // do nothing
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getSize()
+    /**
+     * Returns the current cache size in number of elements.
+     * <p>
+     * @return number of elements
      */
     public int getSize()
     {
@@ -185,27 +184,27 @@
         return status;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getCacheName()
+    /**
+     * Returns the cache name.
+     * <p>
+     * @return usually the region name.
      */
     public String getCacheName()
     {
         return null;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getGroupKeys(java.lang.String)
+    /**
+     * @param group
+     * @return null
      */
     public Set getGroupKeys( String group )
     {
         return null;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.auxiliary.AuxiliaryCache#getStatistics()
+    /**
+     * @return null
      */
     public IStats getStatistics()
     {
@@ -223,19 +222,17 @@
         return attributes;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.engine.behavior.ICache#getStats()
+    /**
+     * Returns the cache stats.
+     * <p>
+     * @return String of important historical information.
      */
     public String getStats()
     {
         return null;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.jcs.engine.behavior.ICacheType#getCacheType()
-     */
+    /** @return 0 */
     public int getCacheType()
     {
         return 0;

Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheService.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheService.java?rev=724518&r1=724517&r2=724518&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheService.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/remote/MockRemoteCacheService.java Mon Dec  8 14:24:42 2008
@@ -37,6 +37,15 @@
 public class MockRemoteCacheService
     implements IRemoteCacheService
 {
+    /** The key last passed to get */
+    public Serializable lastGetKey;
+
+    /** The pattern last passed to get */
+    public String lastGetMatchingPattern;
+
+    /** The keya last passed to getMatching */
+    public Set lastGetMultipleKeys;
+
     /** The object that was last passed to update. */
     public Object lastUpdate;
 
@@ -60,6 +69,7 @@
      */
     public ICacheElement get( String cacheName, Serializable key, long requesterId )
     {
+        lastGetKey = key;
         return null;
     }
 
@@ -128,7 +138,7 @@
      */
     public ICacheElement get( String cacheName, Serializable key )
     {
-        return null;
+        return get( cacheName, key, 0 );
     }
 
     /**
@@ -178,6 +188,7 @@
      */
     public Map getMultiple( String cacheName, Set keys, long requesterId )
     {
+        lastGetMultipleKeys = keys;
         return new HashMap();
     }
 
@@ -188,7 +199,21 @@
      */
     public Map getMultiple( String cacheName, Set keys )
     {
-        return new HashMap();
+        return getMultiple( cacheName, keys, 0 );
+    }
+
+    /**
+     * Returns an empty map. Zombies have no internal data.
+     * <p>
+     * @param cacheName
+     * @param pattern
+     * @return an empty map
+     * @throws IOException
+     */
+    public Map getMatching( String cacheName, String pattern )
+        throws IOException
+    {
+        return getMatching( cacheName, pattern, 0 );
     }
 
     /**
@@ -201,6 +226,7 @@
     public Map getMatching( String cacheName, String pattern, long requesterId )
         throws IOException
     {
+        lastGetMatchingPattern = pattern;
         return new HashMap();
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jcs-dev-help@jakarta.apache.org