[jboss-cvs] JBossAS SVN: r80732 - in projects/cluster: ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl and 5 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Nov 10 02:46:11 EST 2008


Author: bstansberry at jboss.com
Date: 2008-11-10 02:46:11 -0500 (Mon, 10 Nov 2008)
New Revision: 80732

Added:
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/AbstractJBossCacheService.java
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/AttributeBasedJBossCacheService.java
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/SessionBasedJBossCacheService.java
Removed:
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheService.java
   projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/FieldBasedDistributedCacheManager.java
Modified:
   projects/cluster/ha-server-cache-jbc/trunk/.classpath
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryImpl.java
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/CacheListener.java
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/CacheListenerBase.java
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/FieldBasedJBossCacheService.java
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheWrapper.java
   projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/Util.java
   projects/cluster/ha-server-cache-jbc/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/impl/CacheListenerUnitTestCase.java
   projects/cluster/ha-server-cache-spi/trunk/.classpath
   projects/cluster/ha-server-cache-spi/trunk/.settings/org.eclipse.jdt.core.prefs
   projects/cluster/ha-server-cache-spi/trunk/pom.xml
   projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/BatchingManager.java
   projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributableSession.java
   projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributedCacheManager.java
   projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributedCacheManagerFactory.java
   projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/LocalDistributableSessionManager.java
Log:
[JBAS-6186] Use JBossWebMetaData to drive DistributedCacheManagerFactory

Modified: projects/cluster/ha-server-cache-jbc/trunk/.classpath
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/.classpath	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/.classpath	2008-11-10 07:46:11 UTC (rev 80732)
@@ -7,6 +7,7 @@
   <classpathentry kind="var" path="M2_REPO/org/jboss/cluster/jboss-ha-server-api/1.1.0.GA/jboss-ha-server-api-1.1.0.GA.jar" sourcepath="M2_REPO/org/jboss/cluster/jboss-ha-server-api/1.1.0.GA/jboss-ha-server-api-1.1.0.GA-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/cluster/jboss-ha-server-cache-spi/1.1.0-SNAPSHOT/jboss-ha-server-cache-spi-1.1.0-SNAPSHOT.jar" sourcepath="M2_REPO/org/jboss/cluster/jboss-ha-server-cache-spi/1.1.0-SNAPSHOT/jboss-ha-server-cache-spi-1.1.0-SNAPSHOT-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/logging/jboss-logging-spi/2.0.5.GA/jboss-logging-spi-2.0.5.GA.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging-spi/2.0.5.GA/jboss-logging-spi-2.0.5.GA-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jboss/metadata/jboss-metadata/1.0.0.CR5/jboss-metadata-1.0.0.CR5.jar" sourcepath="M2_REPO/org/jboss/metadata/jboss-metadata/1.0.0.CR5/jboss-metadata-1.0.0.CR5-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/jboss/jboss-serialization/1.0.3.GA/jboss-serialization-1.0.3.GA.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/javaee/jboss-transaction-api/1.0.1.GA/jboss-transaction-api-1.0.1.GA.jar" sourcepath="M2_REPO/org/jboss/javaee/jboss-transaction-api/1.0.1.GA/jboss-transaction-api-1.0.1.GA-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/cache/jbosscache-core/3.0.0.CR4/jbosscache-core-3.0.0.CR4.jar" sourcepath="M2_REPO/org/jboss/cache/jbosscache-core/3.0.0.CR4/jbosscache-core-3.0.0.CR4-sources.jar"/>

Modified: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryImpl.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryImpl.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/DistributedCacheManagerFactoryImpl.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -34,12 +34,14 @@
 import org.jboss.cache.pojo.PojoCacheFactory;
 import org.jboss.cache.pojo.jmx.PojoCacheJmxWrapper;
 import org.jboss.cache.pojo.jmx.PojoCacheJmxWrapperMBean;
-import org.jboss.cache.transaction.BatchModeTransactionManagerLookup;
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.AttributeBasedJBossCacheService;
 import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.FieldBasedJBossCacheService;
-import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.JBossCacheService;
+import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.SessionBasedJBossCacheService;
+import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.Util;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.FieldBasedDistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.TomcatClusterConfig;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.TomcatClusterDistributedCacheManagerFactory;
 
@@ -49,7 +51,6 @@
  */
 public class DistributedCacheManagerFactoryImpl implements TomcatClusterDistributedCacheManagerFactory
 {
-
    public static final String DEFAULT_CLUSTER_NAME = "Tomcat-Cluster";
 
    /** TreeCache's isolation level */
@@ -62,8 +63,9 @@
    public static final long DEFAULT_LOCK_TIMEOUT = 15000;
    
    /** TransactionManagerLookup implementation that the TreeCache should use. */
+   @SuppressWarnings("deprecation")
    public static final String DEFAULT_TM_LOOKUP = 
-      BatchModeTransactionManagerLookup.class.getName();
+      org.jboss.cache.transaction.BatchModeTransactionManagerLookup.class.getName();
    
    private TomcatClusterConfig tomcatConfig;
    private MBeanServer mserver;
@@ -72,18 +74,23 @@
    private PojoCache pojoCache;
    private Cache plainCache;
    
-   public DistributedCacheManager getDistributedCacheManager(String cacheConfigName)
+   public DistributedCacheManager getDistributedCacheManager(LocalDistributableSessionManager localManager)
          throws ClusteringNotSupportedException
    {
-      return plainCache == null? new JBossCacheService(cacheConfigName) : new JBossCacheService(plainCache);
+      ReplicationGranularity granularity = Util.getReplicationGranularity(localManager);
+      switch(granularity)
+      {
+         case SESSION:
+            return plainCache == null? new SessionBasedJBossCacheService(localManager) : new SessionBasedJBossCacheService(localManager, plainCache);
+         case ATTRIBUTE:
+            return plainCache == null? new AttributeBasedJBossCacheService(localManager) : new AttributeBasedJBossCacheService(localManager, plainCache);
+         case FIELD:
+            return pojoCache == null? new FieldBasedJBossCacheService(localManager) : new FieldBasedJBossCacheService(localManager, pojoCache);
+         default:
+            throw new IllegalStateException("Unknown ReplicationGranularity " + granularity);
+      }
    }
 
-   public FieldBasedDistributedCacheManager getFieldBasedDistributedCacheManager(String cacheConfigName)
-         throws ClusteringNotSupportedException
-   {
-      return pojoCache == null? new FieldBasedJBossCacheService(cacheConfigName) : new FieldBasedJBossCacheService(pojoCache);
-   }
-
    public TomcatClusterConfig getTomcatClusterConfig()
    {
       return tomcatConfig;
@@ -157,7 +164,6 @@
       this.pojoCache = null;
    }
    
-   
    /**
     * Gets our PojCache, either from a local reference or the JMX
     * server.  If one is not found, creates and configures it.

Added: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/AbstractJBossCacheService.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/AbstractJBossCacheService.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/AbstractJBossCacheService.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -0,0 +1,702 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.web.tomcat.service.session.distributedcache.impl.jbc;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheManager;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.Region;
+import org.jboss.cache.buddyreplication.BuddyManager;
+import org.jboss.cache.config.BuddyReplicationConfig;
+import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.pojo.impl.InternalConstant;
+import org.jboss.cache.transaction.BatchModeTransactionManager;
+import org.jboss.ha.framework.interfaces.CachableMarshalledValue;
+import org.jboss.ha.framework.server.CacheManagerLocator;
+import org.jboss.ha.framework.server.MarshalledValueHelper;
+import org.jboss.ha.framework.server.SimpleCachableMarshalledValue;
+import org.jboss.logging.Logger;
+import org.jboss.util.loading.ContextClassLoaderSwitcher;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSession;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionSerializationFactory;
+
+/**
+ * Abstract base implementation of {@link DistributedCacheManager}.
+ */
+public abstract class AbstractJBossCacheService implements DistributedCacheManager
+{   
+   public static final String BUDDY_BACKUP = BuddyManager.BUDDY_BACKUP_SUBTREE;
+   public static final Fqn BUDDY_BACKUP_FQN = BuddyManager.BUDDY_BACKUP_SUBTREE_FQN;
+   public static final String SESSION = "JSESSION";
+   
+   // Use Integers as JBC keys -- replication performant but won't be
+   // confused with String attribute keys for ATTRIBUTE granularity sessions
+   // Alternative is an enum, but then we replicate a long classname
+   public static final Integer VERSION_KEY = Integer.valueOf(0);
+   public static final Integer TIMESTAMP_KEY = Integer.valueOf(1);
+   public static final Integer METADATA_KEY = Integer.valueOf(2);
+   public static final Integer ATTRIBUTE_KEY = Integer.valueOf(3);
+   protected static final Set<Integer> INTERNAL_KEYS = new HashSet<Integer>(Arrays.asList(VERSION_KEY, TIMESTAMP_KEY, METADATA_KEY, ATTRIBUTE_KEY)); 
+    
+   public static final String FQN_DELIMITER = "/";
+   
+   public static String getCombinedPath(String hostname, String contextPath)
+   {
+      return contextPath + "_" + hostname;
+   }
+   
+   public static Fqn getSessionFqn(String contextHostPath, String sessionId)
+   {
+      Object[] objs = new Object[]{SESSION, contextHostPath, sessionId};
+      return Fqn.fromList(Arrays.asList(objs), true);
+   }
+   
+   public static Fqn getBuddyBackupSessionFqn(String dataOwner, String contextHostPath, String sessionId)
+   {
+      Object[] objs = new Object[]{BUDDY_BACKUP, dataOwner, SESSION, contextHostPath, sessionId};
+      return Fqn.fromList(Arrays.asList(objs), true);
+   }   
+   
+   private static ContextClassLoaderSwitcher getContextClassLoaderSwitcher()
+   {
+      return (ContextClassLoaderSwitcher) AccessController.doPrivileged(ContextClassLoaderSwitcher.INSTANTIATOR);
+   }
+   
+   protected Logger log_ = Logger.getLogger(getClass());
+   
+   private Cache plainCache_;
+   
+   /** Context path for webapp + hostName; this + session id is a unique combo. */
+   protected String combinedPath_;
+   protected BatchingManager batchingManager;
+
+   private LocalDistributableSessionManager manager_;
+   private ClassLoader webAppClassLoader_;
+   private CacheListener cacheListener_;
+   protected JBossCacheWrapper cacheWrapper_;
+   
+   /** Do we have to marshall attributes ourself or can we let JBC do it? */
+   private boolean useTreeCacheMarshalling_ = false;
+   
+   /** Are we configured for passivation? */
+   private boolean usePassivation_ = false;
+   private PassivationListener passivationListener_;
+   
+   /** Is cache configured for buddy replication? */
+   private boolean useBuddyReplication_ = false;
+   
+   protected String cacheConfigName_;
+   
+   protected AbstractJBossCacheService(LocalDistributableSessionManager localManager) throws ClusteringNotSupportedException
+   {
+      this(localManager, Util.findPlainCache(Util.getCacheConfigName(localManager)));
+      
+      this.cacheConfigName_ = Util.getCacheConfigName(localManager);
+   }
+   
+   protected AbstractJBossCacheService(LocalDistributableSessionManager localManager, Cache cache)
+   {
+      this.manager_    = localManager;
+      this.plainCache_ = cache;
+      
+      this.cacheWrapper_ = new JBossCacheWrapper(plainCache_);
+      
+      this.useTreeCacheMarshalling_ = plainCache_.getConfiguration().isUseRegionBasedMarshalling();
+      CacheLoaderConfig clc = plainCache_.getConfiguration().getCacheLoaderConfig();
+      if(clc != null)
+      {
+         usePassivation_ = (clc.isPassivation() && !clc.isShared());
+      }
+   }
+   
+   protected LocalDistributableSessionManager getManager()
+   {
+      return manager_;
+   }
+   
+   protected Cache getCache()
+   {
+      return plainCache_;
+   }
+   
+   protected void setCache(Cache cache)
+   {
+      this.plainCache_ = cache;
+   }
+   
+   protected abstract boolean getStoreAttributesInSingleKey();
+   protected abstract boolean isFieldBased();
+
+   public void start()
+   {
+      this.webAppClassLoader_ = this.manager_.getApplicationClassLoader();
+      
+      String webAppPath;
+      String path = manager_.getContextName();
+      if( path.length() == 0 || path.equals("/")) {
+         // If this is root.
+         webAppPath = "ROOT";
+      } else if ( path.startsWith("/") ) {
+         webAppPath = path.substring(1);
+      } else {
+         webAppPath = path;
+      }
+      // JBAS-3941 -- context path can be multi-level, but we don't
+      // want that turning into a multilevel Fqn, so escape it
+      // Use '-' which is legal in a filesystem path
+      webAppPath = webAppPath.replace('/', '_');
+      log_.debug("Old and new web app path are: " +path + ", " +webAppPath);
+      
+      String hostName;      
+      String host = manager_.getHostName();
+      if( host == null || host.length() == 0) {
+         hostName = "localhost";
+      }else {
+         hostName = host;
+      }
+      log_.debug("Old and new virtual host name are: " + host + ", " + hostName);
+
+      this.combinedPath_ = getCombinedPath(hostName, webAppPath);
+      
+      if (plainCache_.getCacheStatus() != CacheStatus.STARTED)
+      {
+         plainCache_.start();
+      }
+
+      // We require the cache batchingManager to be BatchModeTransactionManager now.
+      TransactionManager tm = plainCache_.getConfiguration().getRuntimeConfig().getTransactionManager();
+      if( ! (tm instanceof BatchModeTransactionManager) )
+      {
+         throw new RuntimeException("start(): JBoss Cache transaction manager " +
+                                    "is not of type BatchModeTransactionManager. " +
+                                    "It is " + (tm == null ? "null" : tm.getClass().getName()));
+      }
+      this.batchingManager = new BatchingManagerImpl(tm);
+      
+      Object[] objs = new Object[]{SESSION, combinedPath_};
+      Fqn pathFqn = Fqn.fromList(Arrays.asList(objs), true);
+      
+      BuddyReplicationConfig brc = plainCache_.getConfiguration().getBuddyReplicationConfig();
+      this.useBuddyReplication_ = brc != null && brc.isEnabled();
+      if (useTreeCacheMarshalling_ || this.useBuddyReplication_)
+      {
+         // JBAS-5628/JBAS-5629 -- clean out persistent store
+         cleanWebappRegion(pathFqn);
+      }
+
+      // Listen for cache changes
+      cacheListener_ = new CacheListener(cacheWrapper_, manager_, combinedPath_, 
+                                         Util.getReplicationGranularity(manager_));
+      plainCache_.addCacheListener(cacheListener_);
+      
+      if(useTreeCacheMarshalling_)
+      {
+         // register the tcl and bring over the state for the webapp
+         try
+         {
+            
+            log_.debug("UseMarshalling is true. We will register the fqn: " +
+                        pathFqn + " with class loader" +webAppClassLoader_ +
+                        " and activate the webapp's Region");
+            Node root = plainCache_.getRoot();
+            if (root.hasChild(pathFqn) == false)
+            {
+               plainCache_.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+               root.addChild(pathFqn);
+            }
+            Region region = plainCache_.getRegion(pathFqn, true);
+            region.registerContextClassLoader(webAppClassLoader_);
+            region.activate(); 
+         }
+         catch (Exception ex)
+         {
+            throw new RuntimeException("Can't register class loader", ex);
+         }
+      }
+      
+      if(manager_.isPassivationEnabled())
+      {
+         log_.debug("Passivation is enabled");
+         passivationListener_ = new PassivationListener(manager_, combinedPath_);
+         plainCache_.addCacheListener(passivationListener_);
+      }
+      else
+      {
+         log_.debug("Passivation is disabled");
+      }
+   }
+
+   public void stop()
+   {
+      plainCache_.removeCacheListener(cacheListener_);      
+      if (passivationListener_ != null)
+         plainCache_.removeCacheListener(passivationListener_);
+      
+      // Construct the fqn
+      Object[] objs = new Object[]{SESSION, combinedPath_};
+      Fqn pathFqn = Fqn.fromList(Arrays.asList(objs), true);
+
+      if(useTreeCacheMarshalling_)
+      {
+         log_.debug("UseMarshalling is true. We will inactivate the fqn: " +
+                    pathFqn + " and un-register its classloader");
+            
+         try {
+            Region region = plainCache_.getRegion(pathFqn, false);
+            if (region != null)
+            {
+               region.deactivate();
+               region.unregisterContextClassLoader();
+            }
+         } 
+         catch (Exception e) 
+         {
+            log_.error("Exception during inactivation of webapp region " + pathFqn + 
+                       " or un-registration of its class loader", e);
+         }
+      } 
+      BuddyReplicationConfig brc = plainCache_.getConfiguration().getBuddyReplicationConfig();
+      this.useBuddyReplication_ = brc != null && brc.isEnabled();
+      if (useTreeCacheMarshalling_ || this.useBuddyReplication_)
+      {
+         // JBAS-5628/JBAS-5629 -- clean out persistent store
+         cleanWebappRegion(pathFqn);
+      }
+      // remove session data
+      // BES 2007/08/18 Can't do this as it will 
+      // 1) blow away passivated sessions
+      // 2) leave the cache in an inconsistent state if the war
+      //    is restarted
+//      cacheWrapper_.removeLocalSubtree(pathFqn);
+      
+      this.webAppClassLoader_ = null;
+      
+      if (cacheConfigName_ != null)
+      {
+         releaseCacheToManager(cacheConfigName_);
+      }
+   }
+
+   /**
+    * Get specfically the BatchModeTransactionManager.
+    */
+   public BatchingManager getBatchingManager()
+   {
+      return batchingManager;
+   }
+   
+   /**
+    * Gets whether TreeCache-based marshalling is available
+    */
+   public boolean isMarshallingAvailable()
+   {
+      return useTreeCacheMarshalling_;
+   }
+   
+   
+
+   public void sessionCreated(DistributableSession session)
+   {
+      if (session.needRegionForSession())
+      {
+         Fqn fqn = getSessionFqn(combinedPath_, session.getRealId());
+         setupSessionRegion(session, fqn);
+      }      
+   }
+
+   /**
+    * Loads any serialized data in the cache into the given session
+    * using its <code>readExternal</code> method.
+    *
+    * @return the session passed as <code>toLoad</code>, or
+    *         <code>null</code> if the cache had no data stored
+    *         under the given session id.
+    */
+   public <T extends DistributableSession> T loadSession(String realId, T toLoad)
+   {
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      Map sessionData =  cacheWrapper_.getData(fqn, true);
+      
+      if (sessionData == null) {
+         // Requested session is no longer in the cache; return null
+         return null;
+      }
+      
+      if (toLoad.needRegionForSession())
+      {
+         setupSessionRegion(toLoad, fqn);
+      }
+      
+      DistributableSessionData dsd = getDistributableSessionData(realId, sessionData, true);
+      toLoad.update(dsd);
+      
+      return toLoad;
+   }
+
+   public void putSession(DistributableSession session)
+   { 
+      String realId = session.getRealId();
+      
+      if (log_.isTraceEnabled())
+      {
+         log_.trace("putSession(): putting session " + realId);
+      }     
+      
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      
+      Map map = new HashMap();
+      map.put(VERSION_KEY, session.getVersion());
+      
+      boolean replicateTimestamp = false;
+      
+      if (session.isSessionMetadataDirty())
+      {   
+         map.put(METADATA_KEY, session.getSessionMetadata()); 
+         replicateTimestamp = true;
+      }
+     
+      if (session.isSessionAttributeMapDirty())
+      {
+         if (getStoreAttributesInSingleKey())
+         {
+            Map attrs = session.getSessionAttributeMap();
+            map.put(ATTRIBUTE_KEY, getMarshalledValue(attrs));
+         }
+         // Whether or not we stored the attributes above, we need
+         // to replicate timestamp
+         replicateTimestamp = true;
+      }
+      
+      if (replicateTimestamp || session.getMustReplicateTimestamp())
+      {
+         map.put(TIMESTAMP_KEY, session.getSessionTimestamp());
+      }
+      
+      cacheWrapper_.put(fqn, map);
+   }
+
+   /**
+    * If the session requires a region in the cache, establishes one.
+    * 
+    * @param session the session
+    * @param fqn the fqn for the session
+    */
+   protected void setupSessionRegion(DistributableSession session, Fqn fqn)
+   {
+      plainCache_.getRegion(fqn, true);
+      session.createdRegionForSession();
+      if (log_.isTraceEnabled())
+      {
+         log_.trace("Created region for session at " + fqn);
+      }
+   }
+
+   public void removeSession(String realId, boolean removeRegion)
+   {
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      if (log_.isTraceEnabled())
+      {
+         log_.trace("Remove session from distributed store. Fqn: " + fqn);
+      }
+      
+      if (removeRegion)
+      {
+         plainCache_.removeRegion(fqn);
+      }
+
+      cacheWrapper_.remove(fqn);
+   }
+
+   public void removeSessionLocal(String realId, boolean removeRegion)
+   {
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      if (log_.isTraceEnabled())
+      {
+         log_.trace("Remove session from my own distributed store only. Fqn: " + fqn);
+      }
+      
+      if (removeRegion)
+      {
+         plainCache_.removeRegion(fqn);
+      }
+      
+      cacheWrapper_.removeLocal(fqn);
+   }
+
+   public void removeSessionLocal(String realId, String dataOwner)
+   {
+      if (dataOwner == null)
+      {
+         removeSessionLocal(realId, false);
+      }
+      else
+      {         
+         Fqn fqn = getBuddyBackupSessionFqn(dataOwner, combinedPath_, realId);
+         if (log_.isTraceEnabled())
+         {
+            log_.trace("Remove session from my own distributed store only. Fqn: " + fqn);
+         }
+         cacheWrapper_.removeLocal(fqn);
+      }
+   }   
+      
+   public void evictSession(String realId)
+   {
+      evictSession(realId, null);      
+   }   
+      
+   public void evictSession(String realId, String dataOwner)
+   {    
+      Fqn fqn = dataOwner == null ? getSessionFqn(combinedPath_, realId) : getBuddyBackupSessionFqn(dataOwner, combinedPath_, realId);
+      if(log_.isTraceEnabled())
+      {
+         log_.trace("evictSession(): evicting session from my distributed store. Fqn: " + fqn);
+      }
+      cacheWrapper_.evictSubtree(fqn);      
+   }
+   
+   public DistributableSessionData getSessionData(String realId, String dataOwner, boolean includeAttributes)
+   {
+      Fqn fqn = dataOwner == null ? getSessionFqn(combinedPath_, realId) : getBuddyBackupSessionFqn(dataOwner, combinedPath_, realId);
+      Map<Object, Object> distributedCacheData = cacheWrapper_.getData(fqn, false);
+      return getDistributableSessionData(realId, distributedCacheData, includeAttributes);
+   }
+
+   /**
+    * Gets the ids of all sessions in the underlying cache.
+    *
+    * @return Map<String, String> containing all of the session ids of sessions in the cache
+    *         (with any jvmRoute removed) as keys, and the identifier of the data owner for
+    *         the session as value (or a <code>null</code>  value if buddy
+    *         replication is not enabled.) Will not return <code>null</code>.
+    */
+   public Map<String, String> getSessionIds()
+   {
+      Map<String, String> result = new HashMap<String, String>();
+      
+      Fqn webappFqn = getWebappFqn();
+      
+      Node bbRoot = plainCache_.getRoot().getChild(BUDDY_BACKUP_FQN);
+      if (bbRoot != null)
+      {
+         Set<Node> owners = bbRoot.getChildren();
+         if (owners != null)
+         {
+            for (Node owner : owners)
+            {
+               Node webRoot = owner.getChild(webappFqn);
+               if (webRoot != null)
+               {
+                  Set<String> ids = webRoot.getChildrenNames();
+                  storeSessionOwners(ids, (String) owner.getFqn().getLastElement(), result);
+               }
+            }
+         }
+      }
+      
+      storeSessionOwners(getChildrenNames(webappFqn), null, result);
+
+      return result;
+   }
+   
+   protected Set getChildrenNames(Fqn fqn)
+   {
+      Node node = plainCache_.getRoot().getChild(fqn);
+      return (node == null ? Collections.EMPTY_SET : node.getChildrenNames());
+   }
+
+   private void storeSessionOwners(Set<String> ids, String owner, Map<String, String> map)
+   {
+      if (ids != null)
+      {
+         for (String id : ids)
+         {            
+            if (!InternalConstant.JBOSS_INTERNAL_STRING.equals(id))
+            {
+               map.put(id, owner);
+            }
+         }
+      }
+   }
+ 
+   public boolean isPassivationEnabled()
+   {
+      return usePassivation_;      
+   }
+
+   protected Fqn getWebappFqn()
+   {
+      // /SESSION/webAppPath_hostName
+      Object[] objs = new Object[]{SESSION, combinedPath_};
+      return Fqn.fromList(Arrays.asList(objs), true);
+   }
+   
+   /**
+    * Extracts the contents of <code>distributedCacheData</code>.
+    * 
+    * <strong>Note:</strong> This operation may alter the contents of the 
+    * passed in map. If this is unacceptable, pass in a defensive copy.
+    */
+   protected DistributableSessionData getDistributableSessionData(String realId, 
+                                       Map<Object, Object> distributedCacheData, 
+                                       boolean includeAttributes)
+   {
+      AtomicInteger version = (AtomicInteger) distributedCacheData.get(VERSION_KEY);
+      AtomicLong timestamp = (AtomicLong) distributedCacheData.get(TIMESTAMP_KEY);
+      DistributableSessionMetadata metadata = (DistributableSessionMetadata) distributedCacheData.get(METADATA_KEY);
+      Map<String, Object> attrs = includeAttributes ? getSessionAttributes(realId, distributedCacheData) : null;      
+      return new DistributableSessionDataImpl(version, timestamp, metadata, attrs);
+   }
+   
+   /**
+    * Returns the session attributes, possibly using the passed in 
+    * <code>distributedCacheData</code> as a source.
+    * 
+    * <strong>Note:</strong> This operation may alter the contents of the 
+    * passed in map. If this is unacceptable, pass in a defensive copy.
+    */
+   protected abstract Map<String, Object> getSessionAttributes(String realId, Map<Object, Object> distributedCacheData);
+   
+   protected void releaseCacheToManager(String cacheConfigName)
+   {      
+      try
+      {
+         CacheManager cm = CacheManagerLocator.getCacheManagerLocator().getCacheManager(null);
+         cm.releaseCache(cacheConfigName);
+      }
+      catch (Exception e)
+      {
+         log_.error("Problem releasing cache to CacheManager -- config is " + cacheConfigName, e);
+      }
+   }
+
+   protected Object getMarshalledValue(Object value)
+   {
+      // JBAS-2920.  For now, continue using MarshalledValue, as 
+      // it allows lazy deserialization of the attribute on remote nodes
+      // For Branch_4_0 this is what we have to do anyway for backwards
+      // compatibility. For HEAD we'll follow suit for now.
+      // TODO consider only using MV for complex objects (i.e. not primitives)
+      // and Strings longer than X.
+      
+//      if (useTreeCacheMarshalling_)
+//      {
+//         return value;
+//      }
+//      else
+//      {
+         
+         // JBAS-2921 - replaced MarshalledValue calls with SessionSerializationFactory calls
+         // to allow for switching between JBossSerialization and JavaSerialization using
+         // system property -D=session.serialization.jboss=true / false
+         // MarshalledValue mv = new MarshalledValue(value);
+         if  (MarshalledValueHelper.isTypeExcluded(value.getClass()))
+         {
+            return value;               
+         }
+         else 
+         {
+            try
+            {
+               CachableMarshalledValue mv = SessionSerializationFactory.createMarshalledValue((Serializable) value);
+               return mv;
+            }
+            catch (ClassCastException e)
+            {
+               throw new IllegalArgumentException(value + " does not implement java.io.Serializable");
+            }
+         }
+//      }
+   }
+
+   protected Object getUnMarshalledValue(Object obj)
+   {
+      if (!(obj instanceof SimpleCachableMarshalledValue))
+            return obj;
+         
+      // Swap in/out the tcl for this web app. Needed only for un marshalling.
+      ContextClassLoaderSwitcher.SwitchContext switcher = null;
+      try
+      {
+         switcher = getContextClassLoaderSwitcher().getSwitchContext();
+         switcher.setClassLoader(webAppClassLoader_);
+         
+         SimpleCachableMarshalledValue mv = (SimpleCachableMarshalledValue) obj;
+         mv.setObjectStreamSource(SessionSerializationFactory.getObjectStreamSource());
+         return mv.get();
+      }
+      catch (IOException e)
+      {
+         log_.error("IOException occurred unmarshalling value ", e);
+         return null;
+      }
+      catch (ClassNotFoundException e)
+      {
+         log_.error("ClassNotFoundException occurred unmarshalling value ", e);
+         return null;
+      }
+      finally
+      {
+         if (switcher != null)
+         {
+            switcher.reset();
+         }
+      }
+   }
+
+   private void cleanWebappRegion(Fqn regionFqn)
+   {
+      try {
+         // Remove locally.
+         plainCache_.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+         plainCache_.removeNode(regionFqn);
+      }
+      catch (CacheException e)
+      {
+         log_.error("can't clean content from the underlying distributed cache");
+      }
+   }
+
+}

Added: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/AttributeBasedJBossCacheService.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/AttributeBasedJBossCacheService.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/AttributeBasedJBossCacheService.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -0,0 +1,180 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.web.tomcat.service.session.distributedcache.impl.jbc;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
+
+/**
+ * DistributedCacheManager impl for ReplicationGranularity.ATTRIBUTE.
+ */
+public class AttributeBasedJBossCacheService extends AbstractJBossCacheService
+{   
+   public AttributeBasedJBossCacheService(LocalDistributableSessionManager localManager) throws ClusteringNotSupportedException
+   {
+      super(localManager);
+   }
+   
+   public AttributeBasedJBossCacheService(LocalDistributableSessionManager localManager, Cache cache)
+   {
+      super(localManager, cache);
+   }
+
+   public boolean getSupportsAttributeOperations()
+   {
+      return true;
+   }
+
+   public Object getAttribute(String realId, String key)
+   {
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      return getUnMarshalledValue(cacheWrapper_.get(fqn, key));
+   }
+
+   public void putAttribute(String realId, String key, Object value)
+   {
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      cacheWrapper_.put(fqn, key, getMarshalledValue(value));
+   }
+
+   public void putAttribute(String realId, Map<String, Object> map)
+   {
+      // Duplicate the map with marshalled values
+      Map marshalled = new HashMap(map.size());
+      Set entries = map.entrySet();
+      for (Iterator it = entries.iterator(); it.hasNext(); )
+      {
+         Map.Entry entry = (Map.Entry) it.next();
+         marshalled.put(entry.getKey(), getMarshalledValue(entry.getValue()));
+      }
+      
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      cacheWrapper_.put(fqn, marshalled);
+      
+   }
+
+   public Object removeAttribute(String realId, String key)
+   {
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      if (log_.isTraceEnabled())
+      {
+         log_.trace("Remove attribute from distributed store. Fqn: " + fqn + " key: " + key);
+      }
+      return getUnMarshalledValue(cacheWrapper_.remove(fqn, key));
+   }
+
+   public void removeAttributeLocal(String realId, String key)
+   {
+
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      if (log_.isTraceEnabled())
+      {
+         log_.trace("Remove attribute from distributed store. Fqn: " + fqn + " key: " + key);
+      }
+      cacheWrapper_.removeLocal(fqn, key);
+   }
+
+   /**
+    * Obtain the keys associated with this fqn. Note that it is not the fqn children.
+    *
+    */
+   public Set getAttributeKeys(String realId)
+   {
+      Set keys = null;
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      try
+      {
+         Node node = getCache().getRoot().getChild(fqn);
+         if (node != null)
+         {
+            keys = node.getKeys();
+            keys.removeAll(INTERNAL_KEYS);
+         }
+      }
+      catch (CacheException e)
+      {
+         log_.error("getAttributeKeys(): Exception getting keys for session " + realId, e);
+      }
+      
+      return keys;
+   }
+
+   /**
+    * Return all attributes associated with this session id.
+    * 
+    * @param realId the session id with any jvmRoute removed
+    * @return the attributes, or any empty Map if none are found.
+    */
+   public Map<String, Object> getAttributes(String realId)
+   {
+      if (realId == null || realId.length() == 0) return Collections.EMPTY_MAP;
+      
+      Fqn fqn = getSessionFqn(combinedPath_, realId);
+      
+      Node node = getCache().getRoot().getChild(fqn);
+      Map<Object, Object> rawData = node.getData();
+      
+      return getSessionAttributes(realId, rawData);
+   }
+   
+   /**
+    * Returns the session attributes, possibly using the passed in 
+    * <code>distributedCacheData</code> as a source.
+    * 
+    * <strong>Note:</strong> This operation may alter the contents of the 
+    * passed in map. If this is unacceptable, pass in a defensive copy.
+    */
+   protected Map<String, Object> getSessionAttributes(String realId, Map<Object, Object> distributedCacheData)
+   {
+      Map<String, Object> attrs = new HashMap<String, Object>();         
+      for (Map.Entry<Object, Object> entry : distributedCacheData.entrySet())
+      {
+         if (entry.getKey() instanceof String)
+         {
+            attrs.put((String) entry.getKey(), getUnMarshalledValue(entry.getValue()));
+         }                
+      }
+      
+      return attrs;
+   }
+   
+   protected boolean isFieldBased()
+   {
+      return false;
+   }
+   
+   protected boolean getStoreAttributesInSingleKey()
+   {
+      return false;
+   }
+
+}

Modified: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/CacheListener.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/CacheListener.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/CacheListener.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -31,6 +31,7 @@
 import org.jboss.cache.notifications.event.NodeModifiedEvent;
 import org.jboss.cache.notifications.event.NodeRemovedEvent;
 import org.jboss.logging.Logger;
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
 
@@ -52,12 +53,16 @@
    // Minimum size of an FQN that is below the root of a session's internal pojo storage area
    private static final int POJO_INTERNAL_FQN_SIZE = POJO_INTERNAL_FQN_INDEX + 1;
    private static Logger log_ = Logger.getLogger(CacheListener.class);
+   private boolean attributeBased_;
    private boolean fieldBased_;
 
-   CacheListener(JBossCacheWrapper wrapper, LocalDistributableSessionManager manager, String contextHostPath, boolean field)
+   CacheListener(JBossCacheWrapper wrapper, LocalDistributableSessionManager manager, String contextHostPath, ReplicationGranularity granularity)
    {      
       super(manager, contextHostPath);
-      fieldBased_ = field;
+      if (granularity == ReplicationGranularity.FIELD)
+         fieldBased_ = true;
+      else if (granularity == ReplicationGranularity.ATTRIBUTE)
+         attributeBased_ = true;
    }
 
    // --------------- CacheListener methods ------------------------------------
@@ -115,12 +120,12 @@
          // Query if we have version value in the distributed cache. 
          // If we have a version value, compare the version and invalidate if necessary.
          Map data = event.getData();
-         AtomicInteger version = (AtomicInteger) data.get(JBossCacheService.VERSION_KEY);
+         AtomicInteger version = (AtomicInteger) data.get(AbstractJBossCacheService.VERSION_KEY);
          if(version != null)
          {
             String realId = getIdFromFqn(fqn, isBuddy);
             String owner = isBuddy ? getBuddyOwner(fqn) : null;
-            AtomicLong timestamp = (AtomicLong) data.get(JBossCacheService.TIMESTAMP_KEY);
+            AtomicLong timestamp = (AtomicLong) data.get(AbstractJBossCacheService.TIMESTAMP_KEY);
             if (timestamp == null)
             {
                log_.warn("No timestamp attribute found in " + fqn);
@@ -131,7 +136,7 @@
                boolean updated = manager_.sessionChangedInDistributedCache(realId, owner, 
                                                   version.get(), 
                                                   timestamp.get(), 
-                                                  (DistributableSessionMetadata) data.get(JBossCacheService.METADATA_KEY));
+                                                  (DistributableSessionMetadata) data.get(AbstractJBossCacheService.METADATA_KEY));
                if (!updated && !isBuddy)
                {
                   log_.warn("Possible concurrency problem: Replicated version id " + 
@@ -146,7 +151,7 @@
                 */
             }
          }
-         else
+         else if (!attributeBased_) // other granularities can modify attributes only
          {
             log_.warn("No version attribute found in " + fqn);
          }

Modified: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/CacheListenerBase.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/CacheListenerBase.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/CacheListenerBase.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -53,7 +53,7 @@
       try
       {
          if (contextHostPath_.equals(fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + WEBAPP_FQN_INDEX : WEBAPP_FQN_INDEX))
-               && JBossCacheService.SESSION.equals(fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + JSESSION_FQN_INDEX : JSESSION_FQN_INDEX)))
+               && AbstractJBossCacheService.SESSION.equals(fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + JSESSION_FQN_INDEX : JSESSION_FQN_INDEX)))
             return true;
       }
       catch (IndexOutOfBoundsException e)

Modified: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/FieldBasedJBossCacheService.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/FieldBasedJBossCacheService.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/FieldBasedJBossCacheService.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -36,16 +36,14 @@
 import org.jboss.ha.framework.server.PojoCacheManager;
 import org.jboss.ha.framework.server.PojoCacheManagerLocator;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSession;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.FieldBasedDistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
 
 /**
- * Adds PojoCache-specific capabilities to JBossCacheService.
+ * DistributedCacheManager impl for ReplicationGranularity.FIELD.
  * 
- * @author Brian Stansberry
- *
+ * @author Brian Stansberry *
  */
-public class FieldBasedJBossCacheService extends JBossCacheService implements FieldBasedDistributedCacheManager
+public class FieldBasedJBossCacheService extends AbstractJBossCacheService
 {
    public static final String ATTRIBUTE = "ATTRIBUTE";
 
@@ -78,9 +76,11 @@
    
    private final PojoCache pojoCache_;
    
-   public FieldBasedJBossCacheService(String cacheConfigName) throws ClusteringNotSupportedException
+   public FieldBasedJBossCacheService(LocalDistributableSessionManager localManager) throws ClusteringNotSupportedException
    {
-      this(Util.findPojoCache(cacheConfigName));
+      this(localManager, Util.findPojoCache(Util.getCacheConfigName(localManager)));
+      
+      this.cacheConfigName_ = Util.getCacheConfigName(localManager);
    }
    
    /**
@@ -88,11 +88,10 @@
     * 
     * @param cache
     */
-   public FieldBasedJBossCacheService(PojoCache cache)
+   public FieldBasedJBossCacheService(LocalDistributableSessionManager localManager, PojoCache cache)
    {
-      super(cache.getCache());
+      super(localManager, cache.getCache());
       this.pojoCache_ = cache;
-//      setCache(pojoCache_.getCache());
       if (!isMarshallingAvailable())
       {
          // BES 16/8/2006 -- throw ISE, not ClusteringNotSupportedException, as a
@@ -103,68 +102,29 @@
                "Must set 'useRegionBasedMarshalling' to 'true' in the cache configuration");
       }
    }
-   
-   @Override
-   protected boolean isFieldBased()
+
+   public boolean getSupportsAttributeOperations()
    {
       return true;
    }
 
-   /**
-    * Overrides the superclass to pull in attributes via PojoCache API.
-    */
-   @Override
-   protected Map<String, Object> getSessionAttributes(String realId, Map<Object, Object> distributedCacheData)
-   {
-      Map<String, Object> attrs = new HashMap<String, Object>();
-      Set<String> keys = getPojoKeys(realId);
-      for (String key : keys)
-      {
-         attrs.put(key, getPojo(realId, key));
-      }
-      return attrs;
-   }
-
-   /**
-    * store the pojo instance in the cache. Note that this is for the aop cache.
-    * The pojo needs to be "aspectized".
-    * 
-    * @param realId the session id with any jvmRoute removed
-    * @param key    the attribute key
-    * @param pojo
-    * @param DistributableSession session associated with the pojo
-    */
-   public Object setPojo(String realId, String key, Object pojo, DistributableSession session)
-   {
+   public void putAttribute(String realId, String key, Object value)
+   {   
       if(log_.isTraceEnabled())
       {
-         log_.trace("setPojo(): session id: " + realId + " key: " + key + 
-                    " object: " + pojo.toString());
-      }      
+         log_.trace("putAttribute(): session id: " + realId + " key: " + key + 
+                    " object: " + value.toString());
+      } 
       
-      if (session.needRegionForSession())
-      {
-         Fqn sessionRegion = getSessionFqn(combinedPath_, realId);
-         getCache().getRegion(sessionRegion, true);
-         session.createdRegionForSession();
-         if (log_.isTraceEnabled())
-         {
-            log_.trace("Created region for session at " + sessionRegion);
-         }         
-      }
-      
-      // Construct the fqn.
       Fqn fqn = getFieldFqn(combinedPath_, realId, key);
       try {
-         // Ignore any cache notifications that our own work generates 
-//         SessionReplicationContext.startCacheActivity();            
-         return pojoCache_.attach(fqn.toString(), pojo);
-      } catch (CacheException e) {
-         throw new RuntimeException("JBossCacheService: exception occurred in cache setPojo ... ", e);
+         // Ignore any cache notifications that our own work generates
+         pojoCache_.attach(fqn.toString(), value);
+      } 
+      catch (CacheException e) 
+      {
+         throw new RuntimeException("SessionBasedJBossCacheService: exception occurred in cache setPojo ... ", e);
       }
-      finally {
-//         SessionReplicationContext.finishCacheActivity();
-      }
    }
 
    /**
@@ -173,7 +133,7 @@
     * @param key    the attribute key
     * @return pojo that just removed. Null if there none.
     */
-   public Object removePojo(String realId, String key)
+   public Object removeAttribute(String realId, String key)
    {
       if(log_.isTraceEnabled())
       {
@@ -182,66 +142,26 @@
       // Construct the fqn.
       Fqn fqn = getFieldFqn(combinedPath_, realId, key);
       try {
-         // Ignore any cache notifications that our own work generates 
-//         SessionReplicationContext.startCacheActivity();
          return pojoCache_.detach(fqn.toString());
-      } catch (CacheException e) {
-         throw new RuntimeException("JBossCacheService: exception occurred in cache removePojo ... ", e);
-      }
-      finally {
-//         SessionReplicationContext.finishCacheActivity();
-      }
-   }
-
-   /**
-    * Remove all the pojos from the underlying cache store locally 
-    * without replication.
-    * 
-    * @param realId the session id with any jvmRoute removed
-    */
-   public void removePojosLocal(String realId)
-   {
-      if(log_.isTraceEnabled())
+      } 
+      catch (CacheException e) 
       {
-         log_.trace("removePojoLocal(): session id: " +realId);
+         throw new RuntimeException("Exception occurred in cache removePojo ... ", e);
       }
-      // Construct the fqn.
-      Fqn fqn = getAttributeFqn(combinedPath_, realId);
-      try {
-         // Ignore any cache notifications that our own work generates 
-//         SessionReplicationContext.startCacheActivity();
-         cacheWrapper_.removeLocal(fqn);
-      }
-      finally {
-//         SessionReplicationContext.finishCacheActivity();
-      }
    }
 
-   /**
-    * Remove all the pojos from the underlying cache store locally 
-    * without replication.
-    * 
-    * @param realId the session id with any jvmRoute removed
-    */
-   public void removePojoLocal(String realId, String key)
+   public void removeAttributeLocal(String realId, String key)
    {
       if(log_.isTraceEnabled())
       {
          log_.trace("removePojoLocal(): session id: " + realId + " key: " +key);
       }
-      // Construct the fqn.
+      
       Fqn fqn = getFieldFqn(combinedPath_, realId, key);
-      try {
-         // Ignore any cache notifications that our own work generates 
-//         SessionReplicationContext.startCacheActivity();
-         cacheWrapper_.removeLocal(fqn);
-      }
-      finally {
-//         SessionReplicationContext.finishCacheActivity();
-      }
+      cacheWrapper_.removeLocal(fqn);
    }
    
-   public Set getPojoKeys(String realId)
+   public Set getAttributeKeys(String realId)
    {
       Set keys = null;
       Fqn fqn = getAttributeFqn(combinedPath_, realId);
@@ -264,7 +184,7 @@
     * @param key    the attribute key
     * @return Pojo that is associated with the attribute
     */
-   public Object getPojo(String realId, String key)
+   public Object getAttribute(String realId, String key)
    {
       Fqn fqn = getFieldFqn(combinedPath_, realId, key);
       if(log_.isTraceEnabled())
@@ -279,10 +199,11 @@
       }
       catch (CacheException e) 
       {
-         throw new RuntimeException("JBossCacheService: exception occurred in cache find ... ", e);
+         throw new RuntimeException("SessionBasedJBossCacheService: exception occurred in cache find ... ", e);
       }
    }
    
+   @Override
    protected void releaseCacheToManager(String cacheConfigName)
    {      
       try
@@ -296,4 +217,44 @@
       }
    }
 
+   @Override
+   protected boolean getStoreAttributesInSingleKey()
+   {
+      return false;
+   }
+
+   public Map<String, Object> getAttributes(String realId)
+   {
+      Map<String, Object> attrs = new HashMap<String, Object>();
+      Set<String> keys = getAttributeKeys(realId);
+      for (String key : keys)
+      {
+         attrs.put(key, getAttribute(realId, key));
+      }
+      return attrs;
+   }
+
+   public void putAttribute(String realId, Map<String, Object> map)
+   {
+      for (Map.Entry<String, Object> entry : map.entrySet())
+      {
+         putAttribute(realId, entry.getKey(), entry.getValue());
+      }      
+   }
+   
+   @Override
+   protected boolean isFieldBased()
+   {
+      return true;
+   }
+
+   /**
+    * Overrides the superclass to pull in attributes via PojoCache API.
+    */
+   @Override
+   protected Map<String, Object> getSessionAttributes(String realId, Map<Object, Object> distributedCacheData)
+   {
+      return getAttributes(realId);
+   }
+
 }

Deleted: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheService.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheService.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheService.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -1,786 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.web.tomcat.service.session.distributedcache.impl.jbc;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.transaction.TransactionManager;
-
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheManager;
-import org.jboss.cache.CacheStatus;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
-import org.jboss.cache.Region;
-import org.jboss.cache.buddyreplication.BuddyManager;
-import org.jboss.cache.config.BuddyReplicationConfig;
-import org.jboss.cache.config.CacheLoaderConfig;
-import org.jboss.cache.pojo.impl.InternalConstant;
-import org.jboss.cache.transaction.BatchModeTransactionManager;
-import org.jboss.ha.framework.interfaces.CachableMarshalledValue;
-import org.jboss.ha.framework.server.CacheManagerLocator;
-import org.jboss.ha.framework.server.MarshalledValueHelper;
-import org.jboss.ha.framework.server.SimpleCachableMarshalledValue;
-import org.jboss.logging.Logger;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSession;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionSerializationFactory;
-
-/**
- * A wrapper class to JBossCache. This is currently needed to handle various operations such as
- * <ul>
- * <li>Using MarshalledValue to replace Serializable used inside different web app class loader context.</li>
- * <li>Stripping out any id string after ".". This is to handle the JK failover properly with
- * Tomcat JvmRoute.</li>
- * <li>Cache exception retry.</li>
- * <li>Helper APIS.</li>
- * </ul>
- */
-public class JBossCacheService implements DistributedCacheManager
-{   
-   protected static Logger log_ = Logger.getLogger(JBossCacheService.class);
-   public static final String BUDDY_BACKUP = BuddyManager.BUDDY_BACKUP_SUBTREE;
-   public static final Fqn BUDDY_BACKUP_FQN = BuddyManager.BUDDY_BACKUP_SUBTREE_FQN;
-   public static final String SESSION = "JSESSION";
-   
-   // Use Integers as JBC keys -- replication performant but won't be
-   // confused with String attribute keys for ATTRIBUTE granularity sessions
-   // Alternative is an enum, but then we replicate a long classname
-   public static final Integer VERSION_KEY = Integer.valueOf(0);
-   public static final Integer TIMESTAMP_KEY = Integer.valueOf(1);
-   public static final Integer METADATA_KEY = Integer.valueOf(2);
-   public static final Integer ATTRIBUTE_KEY = Integer.valueOf(3);
-   private static final Set<Integer> INTERNAL_KEYS = new HashSet<Integer>(Arrays.asList(VERSION_KEY, TIMESTAMP_KEY, METADATA_KEY, ATTRIBUTE_KEY)); 
-    
-   public static final String FQN_DELIMITER = "/";
-   
-   public static String getCombinedPath(String hostname, String contextPath)
-   {
-      return contextPath + "_" + hostname;
-   }
-   
-   public static Fqn getSessionFqn(String contextHostPath, String sessionId)
-   {
-      Object[] objs = new Object[]{SESSION, contextHostPath, sessionId};
-      return Fqn.fromList(Arrays.asList(objs), true);
-   }
-   
-   public static Fqn getBuddyBackupSessionFqn(String dataOwner, String contextHostPath, String sessionId)
-   {
-      Object[] objs = new Object[]{BUDDY_BACKUP, dataOwner, SESSION, contextHostPath, sessionId};
-      return Fqn.fromList(Arrays.asList(objs), true);
-   }
-   
-   private Cache plainCache_;
-   
-   /** Context path for webapp + hostName; this + session id is a unique combo. */
-   protected String combinedPath_;
-   protected BatchingManager batchingManager;
-
-   private LocalDistributableSessionManager manager_;
-   private ClassLoader webAppClassLoader_;
-   private CacheListener cacheListener_;
-   protected JBossCacheWrapper cacheWrapper_;
-   
-   /** Do we have to marshall attributes ourself or can we let JBC do it? */
-   private boolean useTreeCacheMarshalling_ = false;
-   
-   /** Are we configured for passivation? */
-   private boolean usePassivation_ = false;
-   private PassivationListener passivationListener_;
-   
-   /** Is cache configured for buddy replication? */
-   private boolean useBuddyReplication_ = false;
-   
-   private String cacheConfigName_;;
-   
-   public JBossCacheService(String cacheConfigName) throws ClusteringNotSupportedException
-   {
-      this(Util.findPlainCache(cacheConfigName));
-      
-      this.cacheConfigName_ = cacheConfigName;
-   }
-   
-   public JBossCacheService(Cache cache)
-   {
-      plainCache_ = cache;
-      
-      cacheWrapper_ = new JBossCacheWrapper(plainCache_);
-      
-      useTreeCacheMarshalling_ = plainCache_.getConfiguration().isUseRegionBasedMarshalling();
-      CacheLoaderConfig clc = plainCache_.getConfiguration().getCacheLoaderConfig();
-      if(clc != null)
-      {
-         usePassivation_ = (clc.isPassivation() && !clc.isShared());
-      }
-   }
-   
-   protected LocalDistributableSessionManager getManager()
-   {
-      return manager_;
-   }
-   
-   protected Cache getCache()
-   {
-      return plainCache_;
-   }
-   
-   protected void setCache(Cache cache)
-   {
-      this.plainCache_ = cache;
-   }
-   
-   protected boolean isFieldBased()
-   {
-      return false;
-   }
-
-   public void start(ClassLoader tcl, LocalDistributableSessionManager manager)
-   {
-      manager_ = manager;
-      webAppClassLoader_ = tcl;
-      
-      String webAppPath;
-      String path = manager_.getContextName();
-      if( path.length() == 0 || path.equals("/")) {
-         // If this is root.
-         webAppPath = "ROOT";
-      } else if ( path.startsWith("/") ) {
-         webAppPath = path.substring(1);
-      } else {
-         webAppPath = path;
-      }
-      // JBAS-3941 -- context path can be multi-level, but we don't
-      // want that turning into a multilevel Fqn, so escape it
-      // Use '-' which is legal in a filesystem path
-      webAppPath = webAppPath.replace('/', '_');
-      log_.debug("Old and new web app path are: " +path + ", " +webAppPath);
-      
-      String hostName;      
-      String host = manager_.getHostName();
-      if( host == null || host.length() == 0) {
-         hostName = "localhost";
-      }else {
-         hostName = host;
-      }
-      log_.debug("Old and new virtual host name are: " + host + ", " + hostName);
-
-      this.combinedPath_ = getCombinedPath(hostName, webAppPath);
-      
-      if (plainCache_.getCacheStatus() != CacheStatus.STARTED)
-      {
-         plainCache_.start();
-      }
-
-      // We require the cache batchingManager to be BatchModeTransactionManager now.
-      TransactionManager tm = plainCache_.getConfiguration().getRuntimeConfig().getTransactionManager();
-      if( ! (tm instanceof BatchModeTransactionManager) )
-      {
-         throw new RuntimeException("start(): JBoss Cache transaction manager " +
-                                    "is not of type BatchModeTransactionManager. " +
-                                    "It is " + (tm == null ? "null" : tm.getClass().getName()));
-      }
-      this.batchingManager = new BatchingManagerImpl(tm);
-      
-      Object[] objs = new Object[]{SESSION, combinedPath_};
-      Fqn pathFqn = Fqn.fromList(Arrays.asList(objs), true);
-      
-      BuddyReplicationConfig brc = plainCache_.getConfiguration().getBuddyReplicationConfig();
-      this.useBuddyReplication_ = brc != null && brc.isEnabled();
-      if (useTreeCacheMarshalling_ || this.useBuddyReplication_)
-      {
-         // JBAS-5628/JBAS-5629 -- clean out persistent store
-         cleanWebappRegion(pathFqn);
-      }
-
-      // Listen for cache changes
-      cacheListener_ = new CacheListener(cacheWrapper_, manager_, combinedPath_, isFieldBased());
-      plainCache_.addCacheListener(cacheListener_);
-      
-      if(useTreeCacheMarshalling_)
-      {
-         // register the tcl and bring over the state for the webapp
-         try
-         {
-            
-            log_.debug("UseMarshalling is true. We will register the fqn: " +
-                        pathFqn + " with class loader" +webAppClassLoader_ +
-                        " and activate the webapp's Region");
-            Node root = plainCache_.getRoot();
-            if (root.hasChild(pathFqn) == false)
-            {
-               plainCache_.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-               root.addChild(pathFqn);
-            }
-            Region region = plainCache_.getRegion(pathFqn, true);
-            region.registerContextClassLoader(webAppClassLoader_);
-            region.activate(); 
-         }
-         catch (Exception ex)
-         {
-            throw new RuntimeException("Can't register class loader", ex);
-         }
-      }
-      
-      if(manager_.isPassivationEnabled())
-      {
-         log_.debug("Passivation is enabled");
-         passivationListener_ = new PassivationListener(manager_, combinedPath_);
-         plainCache_.addCacheListener(passivationListener_);
-      }
-      else
-      {
-         log_.debug("Passivation is disabled");
-      }
-   }
-
-   private void cleanWebappRegion(Fqn regionFqn)
-   {
-      try {
-         // Remove locally.
-         plainCache_.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-         plainCache_.removeNode(regionFqn);
-      }
-      catch (CacheException e)
-      {
-         log_.error("can't clean content from the underlying distributed cache");
-      }
-   }
-
-   public void stop()
-   {
-      plainCache_.removeCacheListener(cacheListener_);      
-      if (passivationListener_ != null)
-         plainCache_.removeCacheListener(passivationListener_);
-      
-      // Construct the fqn
-      Object[] objs = new Object[]{SESSION, combinedPath_};
-      Fqn pathFqn = Fqn.fromList(Arrays.asList(objs), true);
-
-      if(useTreeCacheMarshalling_)
-      {
-         log_.debug("UseMarshalling is true. We will inactivate the fqn: " +
-                    pathFqn + " and un-register its classloader");
-            
-         try {
-            Region region = plainCache_.getRegion(pathFqn, false);
-            if (region != null)
-            {
-               region.deactivate();
-               region.unregisterContextClassLoader();
-            }
-         } 
-         catch (Exception e) 
-         {
-            log_.error("Exception during inactivation of webapp region " + pathFqn + 
-                       " or un-registration of its class loader", e);
-         }
-      } 
-      BuddyReplicationConfig brc = plainCache_.getConfiguration().getBuddyReplicationConfig();
-      this.useBuddyReplication_ = brc != null && brc.isEnabled();
-      if (useTreeCacheMarshalling_ || this.useBuddyReplication_)
-      {
-         // JBAS-5628/JBAS-5629 -- clean out persistent store
-         cleanWebappRegion(pathFqn);
-      }
-      // remove session data
-      // BES 2007/08/18 Can't do this as it will 
-      // 1) blow away passivated sessions
-      // 2) leave the cache in an inconsistent state if the war
-      //    is restarted
-//      cacheWrapper_.removeLocalSubtree(pathFqn);
-      
-      if (cacheConfigName_ != null)
-      {
-         releaseCacheToManager(cacheConfigName_);
-      }
-   }
-
-   /**
-    * Get specfically the BatchModeTransactionManager.
-    */
-   public BatchingManager getBatchingManager()
-   {
-      return batchingManager;
-   }
-   
-   /**
-    * Gets whether TreeCache-based marshalling is available
-    */
-   public boolean isMarshallingAvailable()
-   {
-      return useTreeCacheMarshalling_;
-   }
-
-   /**
-    * Loads any serialized data in the cache into the given session
-    * using its <code>readExternal</code> method.
-    *
-    * @return the session passed as <code>toLoad</code>, or
-    *         <code>null</code> if the cache had no data stored
-    *         under the given session id.
-    */
-   public <T extends DistributableSession> T loadSession(String realId, T toLoad)
-   {
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      Map sessionData =  cacheWrapper_.getData(fqn, true);
-      
-      if (sessionData == null) {
-         // Requested session is no longer in the cache; return null
-         return null;
-      }
-      
-      setupSessionRegion(toLoad, fqn);
-      
-      DistributableSessionData dsd = getDistributableSessionData(realId, sessionData, true);
-      toLoad.update(dsd);
-      
-      return toLoad;
-   }
-
-   public void putSession(String realId, DistributableSession session)
-   { 
-      if (log_.isTraceEnabled())
-      {
-         log_.trace("putSession(): putting session " + realId);
-      }     
-      
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      
-      setupSessionRegion(session, fqn);
-      
-      Map map = new HashMap();
-      map.put(VERSION_KEY, session.getVersion());
-      
-      boolean replicateTimestamp = false;
-      
-      if (session.isSessionMetadataDirty())
-      {   
-         map.put(METADATA_KEY, session.getSessionMetadata()); 
-         replicateTimestamp = true;
-      }
-     
-      if (session.isSessionAttributeMapDirty())
-      {
-         Map attrs = session.getSessionAttributeMap();
-         // May be null if the session type doesn't use this mechanism to store
-         // attributes (i.e. isn't SessionBasedClusteredSession)
-         if (attrs != null)
-         {
-            map.put(ATTRIBUTE_KEY, getMarshalledValue(attrs));
-         } 
-         
-         replicateTimestamp = true;
-      }
-      
-      if (replicateTimestamp || session.getMustReplicateTimestamp())
-      {
-         map.put(TIMESTAMP_KEY, session.getSessionTimestamp());
-      }
-      
-      cacheWrapper_.put(fqn, map);
-   }
-
-   /**
-    * If the session requires a region in the cache, establishes one.
-    * 
-    * @param session the session
-    * @param fqn the fqn for the session
-    */
-   private void setupSessionRegion(DistributableSession session, Fqn fqn)
-   {
-      if (session.needRegionForSession())
-      {
-         plainCache_.getRegion(fqn, true);
-         session.createdRegionForSession();
-         if (log_.isTraceEnabled())
-         {
-            log_.trace("Created region for session at " + fqn);
-         }
-      }
-   }
-
-   public void removeSession(String realId, boolean removeRegion)
-   {
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      if (log_.isTraceEnabled())
-      {
-         log_.trace("Remove session from distributed store. Fqn: " + fqn);
-      }
-      
-      if (removeRegion)
-      {
-         plainCache_.removeRegion(fqn);
-      }
-
-      cacheWrapper_.remove(fqn);
-   }
-
-   public void removeSessionLocal(String realId, boolean removeRegion)
-   {
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      if (log_.isTraceEnabled())
-      {
-         log_.trace("Remove session from my own distributed store only. Fqn: " + fqn);
-      }
-      
-      if (removeRegion)
-      {
-         plainCache_.removeRegion(fqn);
-      }
-      
-      cacheWrapper_.removeLocal(fqn);
-   }
-
-   public void removeSessionLocal(String realId, String dataOwner)
-   {
-      if (dataOwner == null)
-      {
-         removeSessionLocal(realId, false);
-      }
-      else
-      {         
-         Fqn fqn = getBuddyBackupSessionFqn(dataOwner, combinedPath_, realId);
-         if (log_.isTraceEnabled())
-         {
-            log_.trace("Remove session from my own distributed store only. Fqn: " + fqn);
-         }
-         cacheWrapper_.removeLocal(fqn);
-      }
-   }   
-      
-   public void evictSession(String realId)
-   {
-      evictSession(realId, null);      
-   }   
-      
-   public void evictSession(String realId, String dataOwner)
-   {    
-      Fqn fqn = dataOwner == null ? getSessionFqn(combinedPath_, realId) : getBuddyBackupSessionFqn(dataOwner, combinedPath_, realId);
-      if(log_.isTraceEnabled())
-      {
-         log_.trace("evictSession(): evicting session from my distributed store. Fqn: " + fqn);
-      }
-      cacheWrapper_.evictSubtree(fqn);      
-   }
-   
-   public DistributableSessionData getSessionData(String realId, String dataOwner, boolean includeAttributes)
-   {
-      Fqn fqn = dataOwner == null ? getSessionFqn(combinedPath_, realId) : getBuddyBackupSessionFqn(dataOwner, combinedPath_, realId);
-      Map<Object, Object> distributedCacheData = cacheWrapper_.getData(fqn, false);
-      return getDistributableSessionData(realId, distributedCacheData, includeAttributes);
-   }
-
-   public Object getAttribute(String realId, String key)
-   {
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      return getUnMarshalledValue(cacheWrapper_.get(fqn, key));
-   }
-
-   public void putAttribute(String realId, String key, Object value)
-   {
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      cacheWrapper_.put(fqn, key, getMarshalledValue(value));
-   }
-
-   public void putAttribute(String realId, Map map)
-   {
-      // Duplicate the map with marshalled values
-      Map marshalled = new HashMap(map.size());
-      Set entries = map.entrySet();
-      for (Iterator it = entries.iterator(); it.hasNext(); )
-      {
-         Map.Entry entry = (Map.Entry) it.next();
-         marshalled.put(entry.getKey(), getMarshalledValue(entry.getValue()));
-      }
-      
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      cacheWrapper_.put(fqn, marshalled);
-      
-   }
-
-   public Object removeAttribute(String realId, String key)
-   {
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      if (log_.isTraceEnabled())
-      {
-         log_.trace("Remove attribute from distributed store. Fqn: " + fqn + " key: " + key);
-      }
-      return getUnMarshalledValue(cacheWrapper_.remove(fqn, key));
-   }
-
-   /**
-    * Obtain the keys associated with this fqn. Note that it is not the fqn children.
-    *
-    */
-   public Set getAttributeKeys(String realId)
-   {
-      Set keys = null;
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      try
-      {
-         Node node = plainCache_.getRoot().getChild(fqn);
-         if (node != null)
-         {
-            keys = node.getKeys();
-            keys.removeAll(INTERNAL_KEYS);
-         }
-      }
-      catch (CacheException e)
-      {
-         log_.error("getAttributeKeys(): Exception getting keys for session " + realId, e);
-      }
-      
-      return keys;
-   }
-
-   /**
-    * Return all attributes associated with this session id.
-    * 
-    * @param realId the session id with any jvmRoute removed
-    * @return the attributes, or any empty Map if none are found.
-    */
-   public Map<String, Object> getAttributes(String realId)
-   {
-      if (realId == null || realId.length() == 0) return Collections.EMPTY_MAP;
-      
-      Fqn fqn = getSessionFqn(combinedPath_, realId);
-      
-      Node node = plainCache_.getRoot().getChild(fqn);
-      Map<Object, Object> rawData = node.getData();
-      
-      return getSessionAttributes(realId, rawData);
-   }
-
-   /**
-    * Gets the ids of all sessions in the underlying cache.
-    *
-    * @return Map<String, String> containing all of the session ids of sessions in the cache
-    *         (with any jvmRoute removed) as keys, and the identifier of the data owner for
-    *         the session as value (or a <code>null</code>  value if buddy
-    *         replication is not enabled.) Will not return <code>null</code>.
-    */
-   public Map<String, String> getSessionIds()
-   {
-      Map<String, String> result = new HashMap<String, String>();
-      
-      Fqn webappFqn = getWebappFqn();
-      
-      Node bbRoot = plainCache_.getRoot().getChild(BUDDY_BACKUP_FQN);
-      if (bbRoot != null)
-      {
-         Set owners = bbRoot.getChildren();
-         if (owners != null)
-         {
-            for (Iterator it = owners.iterator(); it.hasNext();)
-            {
-               Node owner = (Node) it.next();
-               Node webRoot = owner.getChild(webappFqn);
-               if (webRoot != null)
-               {
-                  Set<String> ids = webRoot.getChildrenNames();
-                  storeSessionOwners(ids, (String) owner.getFqn().getLastElement(), result);
-               }
-            }
-         }
-      }
-      
-      storeSessionOwners(getChildrenNames(webappFqn), null, result);
-
-      return result;
-   }
-   
-   protected Set getChildrenNames(Fqn fqn)
-   {
-      Node node = plainCache_.getRoot().getChild(fqn);
-      return (node == null ? Collections.EMPTY_SET : node.getChildrenNames());
-   }
-
-   private void storeSessionOwners(Set<String> ids, String owner, Map<String, String> map)
-   {
-      if (ids != null)
-      {
-         for (String id : ids)
-         {            
-            if (!InternalConstant.JBOSS_INTERNAL_STRING.equals(id))
-            {
-               map.put(id, owner);
-            }
-         }
-      }
-   }
- 
-   public boolean isPassivationEnabled()
-   {
-      return usePassivation_;      
-   }
-
-   protected Fqn getWebappFqn()
-   {
-      // /SESSION/hostname/webAppPath
-      Object[] objs = new Object[]{SESSION, combinedPath_};
-      return Fqn.fromList(Arrays.asList(objs), true);
-   }
-   
-   /**
-    * Extracts the contents of <code>distributedCacheData</code>.
-    * 
-    * <strong>Note:</strong> This operation may alter the contents of the 
-    * passed in map. If this is unacceptable, pass in a defensive copy.
-    */
-   protected DistributableSessionData getDistributableSessionData(String realId, 
-                                       Map<Object, Object> distributedCacheData, 
-                                       boolean includeAttributes)
-   {
-      AtomicInteger version = (AtomicInteger) distributedCacheData.get(VERSION_KEY);
-      AtomicLong timestamp = (AtomicLong) distributedCacheData.get(TIMESTAMP_KEY);
-      DistributableSessionMetadata metadata = (DistributableSessionMetadata) distributedCacheData.get(METADATA_KEY);
-      Map<String, Object> attrs = includeAttributes ? getSessionAttributes(realId, distributedCacheData) : null;      
-      return new DistributableSessionDataImpl(version, timestamp, metadata, attrs);
-   }
-   
-   /**
-    * Returns the session attributes, possibly using the passed in 
-    * <code>distributedCacheData</code> as a source.
-    * 
-    * <strong>Note:</strong> This operation may alter the contents of the 
-    * passed in map. If this is unacceptable, pass in a defensive copy.
-    */
-   protected Map<String, Object> getSessionAttributes(String realId, Map<Object, Object> distributedCacheData)
-   {
-      // First check for all attributes stored in a single key/value pair
-      Map<String, Object> attrs = (Map) getUnMarshalledValue(distributedCacheData.get(ATTRIBUTE_KEY));
-      if (attrs == null)
-      {
-         // Copy out all the String K/V pairs; those are attributes
-         attrs = new HashMap<String, Object>();         
-         for (Map.Entry<Object, Object> entry : distributedCacheData.entrySet())
-         {
-            if (entry.getKey() instanceof String)
-            {
-               attrs.put((String) entry.getKey(), getUnMarshalledValue(entry.getValue()));
-            }                
-         }
-      }
-      
-      return attrs;
-   }
-   
-   protected void releaseCacheToManager(String cacheConfigName)
-   {      
-      try
-      {
-         CacheManager cm = CacheManagerLocator.getCacheManagerLocator().getCacheManager(null);
-         cm.releaseCache(cacheConfigName);
-      }
-      catch (Exception e)
-      {
-         log_.error("Problem releasing cache to CacheManager -- config is " + cacheConfigName, e);
-      }
-   }
-
-   private Object getMarshalledValue(Object value)
-   {
-      // JBAS-2920.  For now, continue using MarshalledValue, as 
-      // it allows lazy deserialization of the attribute on remote nodes
-      // For Branch_4_0 this is what we have to do anyway for backwards
-      // compatibility. For HEAD we'll follow suit for now.
-      // TODO consider only using MV for complex objects (i.e. not primitives)
-      // and Strings longer than X.
-      
-//      if (useTreeCacheMarshalling_)
-//      {
-//         return value;
-//      }
-//      else
-//      {
-         
-         // JBAS-2921 - replaced MarshalledValue calls with SessionSerializationFactory calls
-         // to allow for switching between JBossSerialization and JavaSerialization using
-         // system property -D=session.serialization.jboss=true / false
-         // MarshalledValue mv = new MarshalledValue(value);
-         if  (MarshalledValueHelper.isTypeExcluded(value.getClass()))
-         {
-            return value;               
-         }
-         else 
-         {
-            try
-            {
-               CachableMarshalledValue mv = SessionSerializationFactory.createMarshalledValue((Serializable) value);
-               return mv;
-            }
-            catch (ClassCastException e)
-            {
-               throw new IllegalArgumentException(value + " does not implement java.io.Serializable");
-            }
-         }
-//      }
-   }
-
-   private Object getUnMarshalledValue(Object obj)
-   {
-      if (!(obj instanceof SimpleCachableMarshalledValue))
-            return obj;
-         
-      // Swap in/out the tcl for this web app. Needed only for un marshalling.
-      ClassLoader prevTCL = Thread.currentThread().getContextClassLoader();
-      Thread.currentThread().setContextClassLoader(webAppClassLoader_);
-      try
-      {
-         SimpleCachableMarshalledValue mv = (SimpleCachableMarshalledValue) obj;
-         mv.setObjectStreamSource(SessionSerializationFactory.getObjectStreamSource());
-         return mv.get();
-      }
-      catch (IOException e)
-      {
-         log_.error("IOException occurred unmarshalling value ", e);
-         return null;
-      }
-      catch (ClassNotFoundException e)
-      {
-         log_.error("ClassNotFoundException occurred unmarshalling value ", e);
-         return null;
-      }
-      finally
-      {
-         Thread.currentThread().setContextClassLoader(prevTCL);
-      }
-   }
-
-}

Modified: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheWrapper.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheWrapper.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheWrapper.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -186,7 +186,34 @@
     * Wrapper to embed retry logic.
     *
     * @param fqn
+    * @param id
+    * @return
     */
+   Object removeLocal(Fqn fqn, String id)
+   {
+      TimeoutException ex = null;
+      for (int i = 0; i < RETRY; i++)
+      {
+         try
+         {
+            plainCache_.getInvocationContext().getOptionOverrides()
+                                              .setCacheModeLocal(true);
+            return plainCache_.remove(fqn, id);
+         }
+         catch (TimeoutException e)
+         {
+            ex = e;
+         }
+      }
+      
+      throw new RuntimeException(RETRY_FAIL_MSG, ex);
+   }
+
+   /**
+    * Wrapper to embed retry logic.
+    *
+    * @param fqn
+    */
    void remove(Fqn fqn)
    {
       TimeoutException ex = null;

Copied: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/SessionBasedJBossCacheService.java (from rev 80725, projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/JBossCacheService.java)
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/SessionBasedJBossCacheService.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/SessionBasedJBossCacheService.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -0,0 +1,127 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.web.tomcat.service.session.distributedcache.impl.jbc;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.cache.Cache;
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
+
+/**
+ * DistributedCacheManager impl for ReplicationGranularity.SESSION.
+ */
+public class SessionBasedJBossCacheService extends AbstractJBossCacheService
+{   
+   private static UnsupportedOperationException UNSUPPORTED = 
+      new UnsupportedOperationException("Attribute operations not supported " +
+            "with ReplicationGranularity " + ReplicationGranularity.SESSION);
+      
+   public SessionBasedJBossCacheService(LocalDistributableSessionManager localManager) throws ClusteringNotSupportedException
+   {
+      super(localManager);
+   }
+   
+   public SessionBasedJBossCacheService(LocalDistributableSessionManager localManager, Cache cache)
+   {
+      super(localManager, cache);
+   }
+
+   public boolean getSupportsAttributeOperations()
+   {
+      return false;
+   }
+   
+
+   public Object getAttribute(String realId, String key)
+   {
+      throw UNSUPPORTED;
+   }
+
+   public void putAttribute(String realId, String key, Object value)
+   {
+      throw UNSUPPORTED;
+   }
+
+   public void putAttribute(String realId, Map<String, Object> map)
+   {
+      throw UNSUPPORTED;      
+   }
+
+   public Object removeAttribute(String realId, String key)
+   {
+      throw UNSUPPORTED;
+   }
+
+   public void removeAttributeLocal(String realId, String key)
+   {
+      throw UNSUPPORTED;
+   }  
+
+   /**
+    * Obtain the keys associated with this fqn. Note that it is not the fqn children.
+    *
+    */
+   public Set getAttributeKeys(String realId)
+   {
+      throw UNSUPPORTED;
+   }
+
+   /**
+    * Return all attributes associated with this session id.
+    * 
+    * @param realId the session id with any jvmRoute removed
+    * @return the attributes, or any empty Map if none are found.
+    */
+   public Map<String, Object> getAttributes(String realId)
+   {
+      throw UNSUPPORTED;
+   }
+
+   
+   /**
+    * Returns the session attributes, possibly using the passed in 
+    * <code>distributedCacheData</code> as a source.
+    * 
+    * <strong>Note:</strong> This operation may alter the contents of the 
+    * passed in map. If this is unacceptable, pass in a defensive copy.
+    */
+   protected Map<String, Object> getSessionAttributes(String realId, Map<Object, Object> distributedCacheData)
+   {
+      return (Map<String, Object>) getUnMarshalledValue(distributedCacheData.get(ATTRIBUTE_KEY));
+   }
+   
+   @Override
+   protected boolean isFieldBased()
+   {
+      return false;
+   }
+
+   @Override
+   protected boolean getStoreAttributesInSingleKey()
+   {
+      return true;
+   }
+
+}


Property changes on: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/SessionBasedJBossCacheService.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Modified: projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/Util.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/Util.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/impl/jbc/Util.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -29,7 +29,10 @@
 import org.jboss.ha.framework.server.CacheManagerLocator;
 import org.jboss.ha.framework.server.PojoCacheManager;
 import org.jboss.ha.framework.server.PojoCacheManagerLocator;
+import org.jboss.metadata.web.jboss.ReplicationConfig;
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
 
 /**
  * Utility methods related to JBoss distributed sessions.
@@ -39,6 +42,18 @@
  */
 public class Util
 {
+   public static ReplicationGranularity getReplicationGranularity(LocalDistributableSessionManager localManager)
+   {
+      ReplicationConfig config = localManager.getReplicationConfig();
+      return config.getReplicationGranularity();
+   }  
+   
+   public static String getCacheConfigName(LocalDistributableSessionManager localManager)
+   {
+      ReplicationConfig config = localManager.getReplicationConfig();
+      return config.getCacheName();
+   }
+   
    public static PojoCache findPojoCache(String cacheConfigName) throws ClusteringNotSupportedException
    {
       PojoCacheManager pcm = getManagerForPojoCache(cacheConfigName);

Modified: projects/cluster/ha-server-cache-jbc/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/impl/CacheListenerUnitTestCase.java
===================================================================
--- projects/cluster/ha-server-cache-jbc/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/impl/CacheListenerUnitTestCase.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-jbc/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/impl/CacheListenerUnitTestCase.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -29,7 +29,7 @@
 import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.CacheListener;
 import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.CacheListenerBase;
 import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.FieldBasedJBossCacheService;
-import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.JBossCacheService;
+import org.jboss.web.tomcat.service.session.distributedcache.impl.jbc.SessionBasedJBossCacheService;
 
 /**
  * A CacheListenerUnitTestCase.
@@ -42,9 +42,9 @@
 public class CacheListenerUnitTestCase extends TestCase
 {
    private static final String DATA_OWNER = "localhost_12345";
-   private static final String CONTEXT_HOST_PATH = JBossCacheService.getCombinedPath("localhost", "webapp");
-   private static final Fqn BASE = JBossCacheService.getSessionFqn(CONTEXT_HOST_PATH, "123");
-   private static final Fqn BUDDY_BASE = JBossCacheService.getBuddyBackupSessionFqn(DATA_OWNER, CONTEXT_HOST_PATH, "123");
+   private static final String CONTEXT_HOST_PATH = SessionBasedJBossCacheService.getCombinedPath("localhost", "webapp");
+   private static final Fqn BASE = SessionBasedJBossCacheService.getSessionFqn(CONTEXT_HOST_PATH, "123");
+   private static final Fqn BUDDY_BASE = SessionBasedJBossCacheService.getBuddyBackupSessionFqn(DATA_OWNER, CONTEXT_HOST_PATH, "123");
    
    public void testIsBuddyFqn()
    {

Modified: projects/cluster/ha-server-cache-spi/trunk/.classpath
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/.classpath	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/.classpath	2008-11-10 07:46:11 UTC (rev 80732)
@@ -5,6 +5,7 @@
   <classpathentry kind="var" path="M2_REPO/org/jboss/jboss-common-core/2.2.8.GA/jboss-common-core-2.2.8.GA.jar" sourcepath="M2_REPO/org/jboss/jboss-common-core/2.2.8.GA/jboss-common-core-2.2.8.GA-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/cluster/jboss-ha-server-api/1.1.0.GA/jboss-ha-server-api-1.1.0.GA.jar" sourcepath="M2_REPO/org/jboss/cluster/jboss-ha-server-api/1.1.0.GA/jboss-ha-server-api-1.1.0.GA-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/logging/jboss-logging-spi/2.0.5.GA/jboss-logging-spi-2.0.5.GA.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging-spi/2.0.5.GA/jboss-logging-spi-2.0.5.GA-sources.jar"/>
+  <classpathentry kind="var" path="M2_REPO/org/jboss/metadata/jboss-metadata/1.0.0.CR5/jboss-metadata-1.0.0.CR5.jar" sourcepath="M2_REPO/org/jboss/metadata/jboss-metadata/1.0.0.CR5/jboss-metadata-1.0.0.CR5-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/jboss/jboss-serialization/1.0.3.GA/jboss-serialization-1.0.3.GA.jar"/>
   <classpathentry kind="var" path="M2_REPO/jgroups/jgroups/2.6.6.GA/jgroups-2.6.6.GA.jar" sourcepath="M2_REPO/jgroups/jgroups/2.6.6.GA/jgroups-2.6.6.GA-sources.jar"/>
   <classpathentry kind="var" path="M2_REPO/org/jboss/naming/jnp-client/5.0.0.GA/jnp-client-5.0.0.GA.jar" sourcepath="M2_REPO/org/jboss/naming/jnp-client/5.0.0.GA/jnp-client-5.0.0.GA-sources.jar"/>

Modified: projects/cluster/ha-server-cache-spi/trunk/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/.settings/org.eclipse.jdt.core.prefs	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/.settings/org.eclipse.jdt.core.prefs	2008-11-10 07:46:11 UTC (rev 80732)
@@ -1,4 +1,4 @@
-#Fri Aug 29 23:36:08 CDT 2008
+#Sun Nov 09 22:42:13 CST 2008
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
 eclipse.preferences.version=1
 org.eclipse.jdt.core.compiler.source=1.5

Modified: projects/cluster/ha-server-cache-spi/trunk/pom.xml
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/pom.xml	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/pom.xml	2008-11-10 07:46:11 UTC (rev 80732)
@@ -34,6 +34,7 @@
     <version.jboss.logging.spi>2.0.5.GA</version.jboss.logging.spi>
     <version.org.jboss.naming>5.0.0.GA</version.org.jboss.naming>
     <version.jboss.serialization>1.0.3.GA</version.jboss.serialization>
+    <version.org.jboss.metadata>1.0.0.CR5</version.org.jboss.metadata>
     <version.junit>3.8.1</version.junit>
   </properties>
   
@@ -46,7 +47,7 @@
             will create the release tag in the appropriate location. -->
           <tagBase>https://svn.jboss.org/repos/jbossas/projects/cluster/ha-server-cache-spi/tags</tagBase>
         </configuration>
-      </plugin>     
+      </plugin>
     </plugins>
   </build>  
   
@@ -104,6 +105,66 @@
         </exclusion>
       </exclusions>
     </dependency>
+      
+    <dependency>
+      <groupId>org.jboss.metadata</groupId>
+      <artifactId>jboss-metadata</artifactId>
+      <version>${version.org.jboss.metadata}</version>
+      <exclusions>
+       <exclusion>
+         <groupId>org.jboss</groupId>
+         <artifactId>jboss-jaxws</artifactId>
+       </exclusion>      
+	    <exclusion>
+	      <groupId>org.jboss.ejb3</groupId>
+	      <artifactId>jboss-ejb3-ext-api</artifactId>
+	    </exclusion>	    
+	    <exclusion>
+	      <groupId>org.jboss.javaee</groupId>
+	      <artifactId>jboss-ejb-api</artifactId>
+	    </exclusion>	    
+	    <exclusion>
+	      <groupId>org.jboss.javaee</groupId>
+	      <artifactId>jboss-jms-api</artifactId>
+	    </exclusion>	
+	    <exclusion>
+	      <groupId>org.hibernate</groupId>
+	      <artifactId>ejb3-persistence</artifactId>
+	    </exclusion>	      
+	    <exclusion>
+	      <groupId>org.jboss.javaee</groupId>
+	      <artifactId>jboss-transaction-api</artifactId>
+	    </exclusion>	    
+	    <exclusion>
+	      <groupId>org.jboss.ws</groupId>
+	      <artifactId>jbossws-spi</artifactId>
+	    </exclusion>	    
+	    <exclusion>
+	      <groupId>jboss.jbossws</groupId>
+	      <artifactId>jboss-jaxws</artifactId>
+	    </exclusion>	
+	    <exclusion>
+	      <groupId>org.jboss</groupId>
+	      <artifactId>jbossxb</artifactId>
+	    </exclusion>	    
+	    <exclusion>
+	      <groupId>org.jboss</groupId>
+	      <artifactId>jboss-vfs</artifactId>
+	    </exclusion>	
+	    <exclusion>
+	      <groupId>org.jboss</groupId>
+	      <artifactId>jboss-mdr</artifactId>
+	    </exclusion>	
+	    <exclusion>
+	      <groupId>sun-jaxb</groupId>
+	      <artifactId>jaxb-api</artifactId>
+	    </exclusion>	      
+	    <exclusion>
+	      <groupId>apache-xerces</groupId>
+	      <artifactId>xml-apis</artifactId>
+	    </exclusion>        
+      </exclusions>
+    </dependency>
     
     <!-- Test dependencies -->
     <!--  

Modified: projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/BatchingManager.java
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/BatchingManager.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/BatchingManager.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -29,7 +29,7 @@
  */
 public interface BatchingManager
 {
-   boolean isBatchInProgress() throws Exception;
+   boolean isBatchInProgress() throws Exception; 
    void startBatch() throws Exception;
    void setBatchRollbackOnly() throws Exception;
    void endBatch();

Modified: projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributableSession.java
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributableSession.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributableSession.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -39,15 +39,26 @@
     */
    String getRealId();
    
+   /**
+    * Gets the session's version.
+    */
    AtomicInteger getVersion();
 
+   /**
+    * Gets whether the timestamp must be replicated.
+    * 
+    * @return <code>true</code> if timestamp replication is required
+    */
    boolean getMustReplicateTimestamp();
 
+   /**
+    * Gets the timestamp of the most recent access of the session.
+    */
    AtomicLong getSessionTimestamp();
 
    boolean isSessionMetadataDirty();
 
-   DistributableSessionMetadata getSessionMetadata();
+   DistributableSessionMetadata getSessionMetadata(); 
 
    boolean isSessionAttributeMapDirty();
 

Modified: projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributedCacheManager.java
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributedCacheManager.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributedCacheManager.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -34,13 +34,13 @@
 public interface DistributedCacheManager
 {
    /**
-    * Configures and starts the distributed caching layer.
-    * 
-    * @param tcl
-    * @param manager
+    * Starts the distributed caching layer.
     */
-   void start(ClassLoader tcl, LocalDistributableSessionManager manager);
+   void start();
 
+   /**
+    * Stops the distributed caching layer.
+    */
    void stop();
 
    /**
@@ -49,6 +49,14 @@
    BatchingManager getBatchingManager();
 
    /**
+    * Notification to the distributed cache that a session has been
+    * newly created.
+    * 
+    * @param session the new session
+    */
+   void sessionCreated(DistributableSession session);
+
+   /**
     * Loads any serialized data in the cache into the given session
     * using its <code>readExternal</code> method.
     *
@@ -57,56 +65,173 @@
     *         under the given session id.
     */
    <T extends DistributableSession> T loadSession(String realId, T toLoad);
+   
+   /**
+    * Store or update a session in the distributed cache.
+    * 
+    * @param session the session
+    */
+   void putSession(DistributableSession session);
 
-   void putSession(String realId, DistributableSession session);
-
+   /**
+    * Globally remove a session from the distributed cache.
+    * 
+    * @param realId the session's id, excluding any jvmRoute
+    * @param removeRegion FIXME remove
+    */
    void removeSession(String realId, boolean removeRegion);
 
+   /**
+    * Remove a session from the distributed cache on this node only.
+    * 
+    * @param realId the session's id, excluding any jvmRoute
+    * @param removeRegion FIXME remove
+    */
    void removeSessionLocal(String realId, boolean removeRegion);
 
+   /**
+    * Remove a non-locally active session from the distributed cache, but on 
+    * this node only.
+    * 
+    * @param realId the session's id, excluding any jvmRoute
+    * @param dataOwner identifier of node where the session is active
+    */
    void removeSessionLocal(String realId, String dataOwner);
 
+   /**
+    * Evict a session from the in-memory portion of the distributed cache, on
+    * this node only.
+    * 
+    * @param realId the session's id, excluding any jvmRoute
+    */
    void evictSession(String realId);
 
+   /**
+    * Evict a non-locally-active session from the in-memory portion of the 
+    * distributed cache, on this node only.
+    * 
+    * @param realId the session's id, excluding any jvmRoute
+    * @param dataOwner identifier of node where the session is active
+    */
    void evictSession(String realId, String dataOwner);
 
+   /**
+    * Get the {@link DistributableSessionData} that encapsulates the distributed
+    * cache's information about the given session.
+    * 
+    * @param realId the session's id, excluding any jvmRoute
+    * @param dataOwner identifier of node where the session is active; 
+    *                  <code>null</code> if locally active or location where
+    *                  active is unknown
+    * @param includeAttributes should 
+    *                          @link DistributableSessionData#providesSessionAttributes()}
+    *                          return <code>true</code>?
+    *                          
+    * @return the session data
+    */
    DistributableSessionData getSessionData(String realId, String dataOwner, boolean includeAttributes);
 
+   /**
+    * Gets the ids of all sessions in the underlying cache.
+    *
+    * @return Map<String, String> containing all of the session ids of sessions in the cache
+    *         (with any jvmRoute removed) as keys, and the identifier of the data owner for
+    *         the session as value (or a <code>null</code>  value if buddy
+    *         replication is not enabled.) Will not return <code>null</code>.
+    */
+   Map<String, String> getSessionIds();
+
+   /**
+    * Gets whether the underlying cache supports passivation.
+    */
+   boolean isPassivationEnabled();
+   
+   /**
+    * Gets whether this DistributedCacheManager supports operations on
+    * session attributes; if <code>false</code> the various attribute
+    * operations in will throw {@link UnsupportedOperationException}.
+    */
+   boolean getSupportsAttributeOperations();
+
+   /**
+    * Get the value of the attribute with the given key from the given session.
+    * 
+    * @param realId the session id with any jvmRoute removed
+    * @param key the attribute key
+    * @return the attribute value, or <code>null</code>
+    * 
+    * @throws UnsupportedOperationException if {@link #getSupportsAttributeOperations()}
+    *                                       would return <code>false</code>
+    */
    Object getAttribute(String realId, String key);
 
+   /**
+    * Stores the given value under the given key in the given session.
+    * 
+    * @param realId the session id with any jvmRoute removed
+    * @param key the attribute key
+    * @param value the previous attribute value, or <code>null</code>
+    * 
+    * @throws UnsupportedOperationException if {@link #getSupportsAttributeOperations()}
+    *                                       would return <code>false</code>
+    */
    void putAttribute(String realId, String key, Object value);
 
-   void putAttribute(String realId, Map map);
+   /**
+    * Stores the given map of attribute key/value pairs in the given session.
+    * 
+    * @param realId the session id with any jvmRoute removed
+    * @param map
+    * 
+    * @throws UnsupportedOperationException if {@link #getSupportsAttributeOperations()}
+    *                                       would return <code>false</code>
+    */
+   void putAttribute(String realId, Map<String, Object> map);
 
-   Object removeAttribute(String realId, String key);
-
    /**
-    * Obtain the attribute keys associated with this session.
-    *
+    * Removes the attribute with the given key from the given session.
+    * 
+    * @param realId the session id with any jvmRoute removed
+    * @param key the attribute key
+    * @return the previous attribute value, or <code>null</code>
+    * 
+    * @throws UnsupportedOperationException if {@link #getSupportsAttributeOperations()}
+    *                                       would return <code>false</code>
     */
-   Set getAttributeKeys(String realId);
+   Object removeAttribute(String realId, String key);
 
    /**
-    * Return all attributes associated with this session id.
+    * Removes the attribute with the given key from the given session, but 
+    * only on the local node.
     * 
     * @param realId the session id with any jvmRoute removed
-    * @return the attributes, or any empty Map if none are found.
+    * @param key the attribute key
+    * 
+    * @throws UnsupportedOperationException if {@link #getSupportsAttributeOperations()}
+    *                                       would return <code>false</code>
     */
-   Map getAttributes(String realId);
+   void removeAttributeLocal(String realId, String key);
 
    /**
-    * Gets the ids of all sessions in the underlying cache.
-    *
-    * @return Map<String, String> containing all of the session ids of sessions in the cache
-    *         (with any jvmRoute removed) as keys, and the identifier of the data owner for
-    *         the session as value (or a <code>null</code>  value if buddy
-    *         replication is not enabled.) Will not return <code>null</code>.
+    * Obtain the attribute keys associated with this session.
+    * 
+    * @param realId the session id with any jvmRoute removed
+    * @return the attribute keys or an empty Set if none are found
+    * 
+    * @throws UnsupportedOperationException if {@link #getSupportsAttributeOperations()}
+    *                                       would return <code>false</code>
     */
-   Map<String, String> getSessionIds();
+   Set<String> getAttributeKeys(String realId);
 
    /**
-    * Gets whether the underlying cache supports passivation.
+    * Return all attributes associated with this session id.
+    * 
+    * @param realId the session id with any jvmRoute removed
+    * @return the attributes, or any empty Map if none are found.
+    * 
+    * @throws UnsupportedOperationException if {@link #getSupportsAttributeOperations()}
+    *                                       would return <code>false</code>
     */
-   boolean isPassivationEnabled();
+   Map<String, Object> getAttributes(String realId);
 
 }
\ No newline at end of file

Modified: projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributedCacheManagerFactory.java
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributedCacheManagerFactory.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/DistributedCacheManagerFactory.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -30,7 +30,5 @@
  */
 public interface DistributedCacheManagerFactory
 {
-   DistributedCacheManager getDistributedCacheManager(String cacheConfigName) throws ClusteringNotSupportedException;
-   
-   FieldBasedDistributedCacheManager getFieldBasedDistributedCacheManager(String cacheConfigName) throws ClusteringNotSupportedException;
+   DistributedCacheManager getDistributedCacheManager(LocalDistributableSessionManager localManager) throws ClusteringNotSupportedException;
 }

Deleted: projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/FieldBasedDistributedCacheManager.java
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/FieldBasedDistributedCacheManager.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/FieldBasedDistributedCacheManager.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -1,79 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.web.tomcat.service.session.distributedcache.spi;
-
-import java.util.Set;
-
-/**
- * DistributedCacheManager subinterface for FIELD granularity webapps.
- * 
- * @author Brian Stansberry
- */
-public interface FieldBasedDistributedCacheManager extends DistributedCacheManager
-{
-
-   /**
-    * Store the pojo instance in the cache. Note that this is for the aop cache.
-    * THe pojo needs to be "aspectized".
-    * 
-    * @param realId the session id with any jvmRoute removed
-    * @param key    the attribute key
-    * @param pojo
-    * @param createRegion TODO
-    */
-   public abstract Object setPojo(String realId, String key, Object pojo, DistributableSession session);
-
-   /**
-    * Remove pojo from the underlying cache store.
-    * @param realId the session id with any jvmRoute removed
-    * @param key    the attribute key
-    * @return pojo that just removed. Null if there none.
-    */
-   public abstract Object removePojo(String realId, String key);
-
-   /**
-    * Remove all the pojos from the underlying cache store locally 
-    * without replication.
-    * 
-    * @param realId the session id with any jvmRoute removed
-    */
-   public abstract void removePojosLocal(String realId);
-
-   /**
-    * Remove all the pojos from the underlying cache store locally 
-    * without replication.
-    * 
-    * @param realId the session id with any jvmRoute removed
-    */
-   public abstract void removePojoLocal(String realId, String key);
-
-   public abstract Set getPojoKeys(String realId);
-
-   /**
-    *
-    * @param realId the session id with any jvmRoute removed
-    * @param key    the attribute key
-    * @return Pojo that is associated with the attribute
-    */
-   public abstract Object getPojo(String realId, String key);
-
-}
\ No newline at end of file

Modified: projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/LocalDistributableSessionManager.java
===================================================================
--- projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/LocalDistributableSessionManager.java	2008-11-10 04:29:35 UTC (rev 80731)
+++ projects/cluster/ha-server-cache-spi/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/spi/LocalDistributableSessionManager.java	2008-11-10 07:46:11 UTC (rev 80732)
@@ -21,6 +21,8 @@
  */
 package org.jboss.web.tomcat.service.session.distributedcache.spi;
 
+import org.jboss.metadata.web.jboss.ReplicationConfig;
+
 /**
  * Callback interface to allow the distributed caching layer to invoke
  * upon the local session manager.
@@ -45,13 +47,27 @@
    String getContextName();
    
    /**
-    * Gets the name of the Tomcat Host.
+    * Gets the name of the application's virtual host.
     * 
     * @return the name of the host
     */
    String getHostName();
    
    /**
+    * Get the classloader able to load application classes.
+    * 
+    * @return the classloader. Will not return <code>null</code>
+    */
+   ClassLoader getApplicationClassLoader();
+   
+   /**
+    * Gets the web application metadata.
+    * 
+    * @return the metadata. will not return <code>null</code>
+    */
+   ReplicationConfig getReplicationConfig();
+   
+   /**
     * Notifies the manager that a session in the distributed cache has
     * been invalidated
     * 




More information about the jboss-cvs-commits mailing list