[jboss-cvs] JBossAS SVN: r70871 - in projects/ejb3/branches/cluster-dev/ejb3-cache/src: main/java/org/jboss/ejb3/cache/impl and 8 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Mar 14 11:14:03 EDT 2008


Author: bstansberry at jboss.com
Date: 2008-03-14 11:14:02 -0400 (Fri, 14 Mar 2008)
New Revision: 70871

Added:
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupImpl.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberImpl.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/SerializationGroup.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/SerializationGroupMember.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/SharedXPC.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/XPC.java
Removed:
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/SerializationGroup.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupImpl.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupMember.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java
Modified:
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cache.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivationManager.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactoryRegistry.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupAwareTransactionalCache.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/TransactionalCache.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/GroupAwareBackingCacheImpl.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheImpl.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/PassivatingBackingCacheImpl.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupContainer.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberContainer.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/GroupAwareCacheFactory.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonClusteredIntegratedObjectStoreSource.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonPassivatingCacheFactory.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCache.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupAwareBackingCache.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStoreSource.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingBackingCache.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractStatefulCacheFactory.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/GroupCreationContext.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/GroupedPassivatingUnitTestCase.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockCluster.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockClusterMember.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockIntegratedObjectStoreSource.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/PassivatingBackingCacheImplUnitTestCase.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/GroupAwareTransactionalCacheUnitTestCase.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContainer.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContext.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEjb3System.java
   projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockStatefulObjectFactory.java
Log:
[EJBTHREE-1026] Remove group concept from API

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cache.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cache.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -86,25 +86,8 @@
     * @param key    the identifier of the object
     */
    void remove(Object key);
-   
-   /**
-    * Gets whether this cache supports {@link SerializationGroup} management.
-    * 
-    * @return <code>true</code> if group management is supported;
-    *         <code>false</code> otherwise
-    */
-   boolean isGroupAware();
 
    /**
-    * Gets the group to which the given object belongs.
-    * 
-    * @param obj the object
-    * @return the group, or <code>null</code> if the object is not a member
-    *         of a group
-    */
-   SerializationGroup<T> getGroup(T obj);
-
-   /**
     * Start the cache.
     */
    void start();

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivationManager.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivationManager.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivationManager.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -23,8 +23,6 @@
 
 import java.io.Serializable;
 
-import org.jboss.ejb3.cache.SerializationGroup;
-
 /**
  * Manages passivation and replication lifecycle callbacks on an object.
  *
@@ -48,11 +46,10 @@
     * @param obj    the object
     * 
     * @throws IllegalStateException if <code>obj</code>, or another object in the 
-    *                            same {@link SerializationGroup} as 
-    *                            <code>obj</code>, is in use. Checking if
-    *                            an object is in use and throwing this
-    *                            exception is not required, so callers should
-    *                            not assume it will be thrown.
+    *                            same serialization group as <code>obj</code>, 
+    *                            is in use. Checking if an object is in use and 
+    *                            throwing this exception is not required, so 
+    *                            callers should not assume it will be thrown.
     */
    void prePassivate(T obj);
    
@@ -69,13 +66,12 @@
     * cache.
     * 
     * @param obj    the object
-    * 
+    *
     * @throws IllegalStateException if <code>obj</code>, or another object in the 
-    *                            same {@link SerializationGroupImpl} as 
-    *                            <code>obj</code>, is in use. Checking if
-    *                            an object is in use and throwing this
-    *                            exception is not required, so callers should
-    *                            not assume it will be thrown.
+    *                            same serialization group as <code>obj</code>, 
+    *                            is in use. Checking if an object is in use and 
+    *                            throwing this exception is not required, so 
+    *                            callers should not assume it will be thrown.
     */
    void preReplicate(T obj);
 }

Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/SerializationGroup.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/SerializationGroup.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/SerializationGroup.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -1,49 +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.ejb3.cache;
-
-import java.util.Iterator;
-
-/**
- * Defines a group of cache items which must always be serialized in one 
- * unit of work.
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @author Brian Stansberry
- * @version $Revision: $
- */
-public interface SerializationGroup<T extends CacheItem> 
-  extends CacheItem
-{   
-   /**
-    * Gets the number of group members.
-    */
-   int size();
-   
-   /**
-    * Returns an iterator over the group members. The iterator does not
-    * support the {@link Iterator#remove()} operation.
-    * 
-    * @return the iterator
-    */
-   Iterator<T> iterator();   
-}

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactoryRegistry.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactoryRegistry.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactoryRegistry.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -27,7 +27,7 @@
  * Registry for all configured Stateful Cache Factory implementations
  * 
  * TODO Does this belong in ejb3-core? That would allow all of the
- * StatefulCacheFactory<? extends CacheItem> usage to be replaced with
+ * StatefulCacheFactory<T extends CacheItem> usage to be replaced with
  * StatefulCacheFactory<StatefulBeanContext> without leaking the
  * StatefulBeanContext class to ejb3-cache.
  * 

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -21,6 +21,8 @@
  */
 package org.jboss.ejb3.cache;
 
+import java.util.Map;
+
 /**
  * Creates and destroys stateful objects.
  * 
@@ -40,9 +42,13 @@
     * 
     * @param initTypes  the argument types for the init method
     * @param initValues the arguments for the init method
-    * @return
+    * @param sharedState map into which any objects meant to be shared with
+    *                    other members of the new items group should be
+    *                    stored. 
+    * 
+    * @return the new item
     */
-   T create(Class<?> initTypes[], Object initValues[]);
+   T create(Class<?> initTypes[], Object initValues[], Map<Object, Object> sharedState);
    
    /**
     * Perform any cleanup actions on the object, such as

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupAwareTransactionalCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupAwareTransactionalCache.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupAwareTransactionalCache.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -22,19 +22,21 @@
 
 package org.jboss.ejb3.cache.impl;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.transaction.TransactionManager;
 
 import org.jboss.ejb3.cache.Cache;
 import org.jboss.ejb3.cache.CacheItem;
-import org.jboss.ejb3.cache.SerializationGroup;
 import org.jboss.ejb3.cache.spi.BackingCacheEntry;
 import org.jboss.ejb3.cache.spi.GroupAwareBackingCache;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
 import org.jboss.ejb3.cache.spi.SynchronizationCoordinator;
 import org.jboss.ejb3.cache.spi.impl.GroupCreationContext;
 import org.jboss.ejb3.cache.spi.impl.ItemCachePair;
+import org.jboss.logging.Logger;
 
 /**
  * {@link Cache#isGroupAware Group-aware} version of {@link TransactionalCache}.
@@ -44,6 +46,8 @@
 public class GroupAwareTransactionalCache<C extends CacheItem, T extends BackingCacheEntry<C>> 
    extends TransactionalCache<C, T>
 {
+   private static final Logger log = Logger.getLogger(GroupAwareTransactionalCache.class);
+   
    /** 
     * Another ref to super.delegate. Just saves having to do casts all the time. 
     */
@@ -57,9 +61,10 @@
     */
    public GroupAwareTransactionalCache(GroupAwareBackingCache<C, T> delegate, 
                                        TransactionManager tm,
-                                       SynchronizationCoordinator syncCoordinator)
+                                       SynchronizationCoordinator syncCoordinator,
+                                       boolean strictGroups)
    {
-      super(delegate, tm, syncCoordinator);
+      super(delegate, tm, syncCoordinator, strictGroups);
       this.groupedCache = delegate;
    }
 
@@ -68,60 +73,84 @@
    public Object create(Class<?>[] initTypes, Object[] initValues)
    {
       boolean outer = false;
-      List<ItemCachePair> contextPairs = GroupCreationContext.getGroupCreationContext();
-      if (contextPairs == null)
-      {
-         contextPairs = new ArrayList<ItemCachePair>();
-         GroupCreationContext.setGroupCreationContext(contextPairs);
+      List<ItemCachePair> contextPairs = null;
+      Map<Object, Object> sharedState = null;
+      
+      GroupCreationContext groupContext = GroupCreationContext.getGroupCreationContext();
+      if (groupContext == null)
+      {         
+         groupContext = GroupCreationContext.startGroupCreationContext(getStrictGroups());
+         sharedState = new ConcurrentHashMap<Object, Object>();
+         groupContext.setSharedState(sharedState);
+         contextPairs = groupContext.getPairs();
          outer = true;
       }
+      else
+      {
+         sharedState = groupContext.getSharedState();
+         if (sharedState == null)
+         {
+            // We're in a nested hierarchy, but so far no other cache is group-aware
+            // Check if we're configured to object
+            if (getStrictGroups())
+            {
+               throw new IllegalStateException("Incompatible cache implementations in nested hierarchy");
+            }
+            
+            // It's OK; just set up the shared state for any other
+            // later group participants to share with us.            
+            sharedState = new ConcurrentHashMap<Object, Object>();
+            groupContext.setSharedState(sharedState);
+         }
+         
+         contextPairs = groupContext.getPairs();         
+      }
       
-      C cacheItem = super.createInternal(initTypes, initValues);
-      
-      contextPairs.add(new ItemCachePair(cacheItem, groupedCache));
-            
-      if (outer)
+      try
       {
-         GroupCreationContext.setGroupCreationContext(null);
-         if (contextPairs.size() > 1)
+         // Create our item. This may lead to nested calls to other caches
+         C cacheItem = createInternal(initTypes, initValues, sharedState);
+         
+         contextPairs.add(new ItemCachePair(cacheItem, groupedCache));
+               
+         if (outer)
          {
-            SerializationGroup<C> group = null;
-            try
-            {
+            // If there is more than one item in the context, we need a group
+            if (contextPairs.size() > 1)
+            {            
+               SerializationGroup<C> group = groupedCache.createGroup();
                for (ItemCachePair pair : contextPairs)
                {
-                  if (group == null)
-                  {
-                     group = pair.getCache().createGroup();
-                  }
                   pair.getCache().setGroup(pair.getItem(), group);
                }
             }
-            catch (IllegalStateException e)
+         }
+         return cacheItem.getId();
+      }
+      catch (RuntimeException e)
+      {
+         if (outer)
+         {
+            // Clean up
+            for (ItemCachePair pair : contextPairs)
             {
-               // Clean up
-               for (ItemCachePair pair : contextPairs)
+               try
                {
                   pair.getCache().remove(pair.getItem().getId());
                }
-               throw e;
+               catch (Exception toLog)
+               {
+                  log.error("Caught exception removing " + pair.getItem());
+               }
             }
          }
+         throw e;
       }
-      
-      return cacheItem.getId();
+      finally
+      {
+         if (outer)
+            GroupCreationContext.clearGroupCreationContext();
+      }      
    }
 
-   @Override
-   public boolean isGroupAware()
-   {
-      return true;
-   }
-
-   @Override
-   public SerializationGroup<C> getGroup(C obj)
-   {
-      return groupedCache.getGroup(obj);
-   }
-
 }

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/TransactionalCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/TransactionalCache.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/TransactionalCache.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -21,6 +21,7 @@
  */
 package org.jboss.ejb3.cache.impl;
 
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.locks.ReentrantLock;
@@ -34,14 +35,14 @@
 
 import org.jboss.ejb3.cache.Cache;
 import org.jboss.ejb3.cache.CacheItem;
-import org.jboss.ejb3.cache.SerializationGroup;
 import org.jboss.ejb3.cache.spi.BackingCache;
 import org.jboss.ejb3.cache.spi.BackingCacheEntry;
 import org.jboss.ejb3.cache.spi.IntegratedObjectStore;
 import org.jboss.ejb3.cache.spi.SynchronizationCoordinator;
+import org.jboss.ejb3.cache.spi.impl.GroupCreationContext;
 
 /**
- * {@link Cache#isGroupAware() Non-group-aware} <code>Cache</code> implementation 
+ * Non-group-aware <code>Cache</code> implementation 
  * that applies transactional access and release semantics. Specifically: 
  * <ol>
  * <li>monitors the transactional status of threads that invoke create() and get()</li>
@@ -70,10 +71,15 @@
    /** Our transaction manager */
    private final TransactionManager tm;
    /** 
-    * Helper to allow coordination Transaction Synchronization execution
+    * Helper to allow coordinated Transaction Synchronization execution
     * between ourself and other elements of the caching subsystem.
     */
-   private final SynchronizationCoordinator synchronizationCoordinator;
+   private final SynchronizationCoordinator synchronizationCoordinator;   
+   /** 
+    * Whether we are strict about enforcing that all items associated with
+    * a {@link GroupCreationContext} are consistently group-aware
+    */
+   private boolean strictGroups;
    
    private class Entry
    {
@@ -127,7 +133,8 @@
    
    public TransactionalCache(BackingCache<C, T> delegate, 
                              TransactionManager tm,
-                             SynchronizationCoordinator syncCoordinator)
+                             SynchronizationCoordinator syncCoordinator,
+                             boolean strictGroups)
    {
       assert delegate != null : "delegate is null";
       assert tm != null : "tm is null";
@@ -136,23 +143,61 @@
       this.delegate = delegate;
       this.tm = tm;
       this.synchronizationCoordinator = syncCoordinator;
+      this.strictGroups = strictGroups;
       
       this.inUseCache = new ConcurrentHashMap<Object, Entry>();
       this.synchronizations = new ConcurrentHashMap<Object, CacheReleaseSynchronization<C, T>>();
    }
+   
+   public boolean getStrictGroups()
+   {
+      return strictGroups;
+   }
 
    public Object create(Class<?>[] initTypes, Object[] initValues)
    {
-     return createInternal(initTypes, initValues).getId();
+      boolean outer = false;
+      GroupCreationContext groupContext = GroupCreationContext.getGroupCreationContext();
+      if (groupContext != null)
+      {
+         // There's a nested hierarchy being formed, but we can't participate
+         // in a serialization group. If we're configured to object or the
+         // group itself is configured to object, we throw an ISE
+         if (groupContext.isStrict() 
+               || (getStrictGroups() &&  groupContext.getPairs().size() > 0))
+         {
+            throw new IllegalStateException("Incompatible cache implementations in nested hierarchy");
+         }
+      }
+      else
+      {
+         GroupCreationContext.startGroupCreationContext(getStrictGroups());
+         outer = true;
+      }
+      
+      try
+      {
+         // We don't participate in a group, so our "sharedState" isn't really shared
+         Map<Object, Object> unsharedState = new ConcurrentHashMap<Object, Object>();
+         return createInternal(initTypes, initValues, unsharedState).getId();
+      }
+      finally
+      {
+         if (outer)
+            GroupCreationContext.clearGroupCreationContext();
+      }
    }
    
-   protected C createInternal(Class<?>[] initTypes, Object[] initValues)
+   /**
+    * Does the actual item creation.
+    */
+   protected C createInternal(Class<?>[] initTypes, Object[] initValues, Map<Object, Object> sharedState)
    {
       Entry entry = new Entry(); 
       entry.lock.lock();
       try
       {
-         T backingEntry = delegate.create(initTypes, initValues);
+         T backingEntry = delegate.create(initTypes, initValues, sharedState);
          C obj = backingEntry.getUnderlyingItem();
          
          // Note we deliberately don't assign obj to entry -- we want
@@ -260,16 +305,6 @@
    {
       delegate.stop();
    }
-
-   public boolean isGroupAware()
-   {
-      return false;
-   }
-
-   public SerializationGroup<C> getGroup(C obj)
-   {
-      return null;
-   }
    
    public BackingCache<C, T> getBackingCache()
    {

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/GroupAwareBackingCacheImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/GroupAwareBackingCacheImpl.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/GroupAwareBackingCacheImpl.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -24,11 +24,10 @@
 import javax.ejb.NoSuchEJBException;
 
 import org.jboss.ejb3.cache.CacheItem;
-import org.jboss.ejb3.cache.SerializationGroup;
 import org.jboss.ejb3.cache.spi.GroupAwareBackingCache;
 import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
+import org.jboss.ejb3.cache.spi.SerializationGroupMember;
 
 /**
  * Group-aware  version of {@link PassivatingBackingCacheImpl}.
@@ -43,7 +42,7 @@
    /**
     * Cache that's managing the SerializationGroup
     */
-   private PassivatingBackingCache<C, SerializationGroupImpl<C>> groupCache;
+   private PassivatingBackingCache<C, SerializationGroup<C>> groupCache;
    
    /**
     * Creates a new GroupAwareCacheImpl.
@@ -52,7 +51,7 @@
     * @param groupCache  cache for the group
     */
    public GroupAwareBackingCacheImpl(SerializationGroupMemberContainer<C> memberContainer, 
-                                     PassivatingBackingCache<C, SerializationGroupImpl<C>> groupCache)
+                                     PassivatingBackingCache<C, SerializationGroup<C>> groupCache)
    {
       super(memberContainer, memberContainer, memberContainer);
       assert groupCache != null : "groupCache is null";
@@ -61,9 +60,9 @@
       this.groupCache = groupCache;
    }
    
-   public SerializationGroupImpl<C> createGroup()
+   public SerializationGroup<C> createGroup()
    {
-      return groupCache.create(null, null);
+      return groupCache.create(null, null, null);
    }
 
    public void setGroup(C obj, SerializationGroup<C> group)
@@ -74,11 +73,10 @@
          throw new IllegalStateException("object " + key + " is already associated with passivation group " + entry.getGroup());
       
       // Validate we share a common groupCache with the group
-      SerializationGroupImpl<C> groupImpl = (SerializationGroupImpl<C>) group;
-      if (groupCache != groupImpl.getGroupCache())
-         throw new IllegalStateException(obj + " and " + groupImpl + " use different group caches");
+      if (groupCache != group.getGroupCache())
+         throw new IllegalStateException(obj + " and " + group + " use different group caches");
       
-      entry.setGroup(groupImpl);
+      entry.setGroup(group);
       entry.getGroup().addMember(entry);
    }
 

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheImpl.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheImpl.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -66,9 +66,9 @@
       this.cache = new ConcurrentHashMap<Object, NonPassivatingBackingCacheEntry<C>>();
    }
    
-   public NonPassivatingBackingCacheEntry<C> create(Class<?>[] initTypes, Object[] initValues)
+   public NonPassivatingBackingCacheEntry<C> create(Class<?>[] initTypes, Object[] initValues, Map<Object, Object> sharedState)
    {
-      C obj = factory.create(initTypes, initValues);
+      C obj = factory.create(initTypes, initValues, sharedState);
       NonPassivatingBackingCacheEntry<C> entry = new NonPassivatingBackingCacheEntry<C>(obj);
       cache.put(obj.getId(), entry);      
       return entry;

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/PassivatingBackingCacheImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/PassivatingBackingCacheImpl.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/PassivatingBackingCacheImpl.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -21,6 +21,8 @@
  */
 package org.jboss.ejb3.cache.impl.backing;
 
+import java.util.Map;
+
 import javax.ejb.NoSuchEJBException;
 
 import org.jboss.ejb3.cache.CacheItem;
@@ -66,9 +68,9 @@
       return store.isClustered();
    }
    
-   public T create(Class<?>[] initTypes, Object[] initValues)
+   public T create(Class<?>[] initTypes, Object[] initValues, Map<Object, Object> sharedState)
    {
-      T obj = factory.create(initTypes, initValues);
+      T obj = factory.create(initTypes, initValues, sharedState);
       store.insert(obj);
       return obj;
    }

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupContainer.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupContainer.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupContainer.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -21,11 +21,13 @@
  */
 package org.jboss.ejb3.cache.impl.backing;
 
+import java.util.Map;
+
 import org.jboss.ejb3.cache.CacheItem;
 import org.jboss.ejb3.cache.PassivationManager;
 import org.jboss.ejb3.cache.StatefulObjectFactory;
 import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
 import org.jboss.logging.Logger;
 
 /**
@@ -40,11 +42,11 @@
  * @version $Revision: $
  */
 public class SerializationGroupContainer<T extends CacheItem> 
-   implements StatefulObjectFactory<SerializationGroupImpl<T>>, PassivationManager<SerializationGroupImpl<T>>
+   implements StatefulObjectFactory<SerializationGroup<T>>, PassivationManager<SerializationGroup<T>>
 {
    private static final Logger log = Logger.getLogger(SerializationGroupContainer.class);
    
-   private PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache;
+   private PassivatingBackingCache<T, SerializationGroup<T>> groupCache;
    
    private boolean clustered;
    
@@ -58,7 +60,7 @@
       this.clustered = clustered;
    }
 
-   public SerializationGroupImpl<T> create(Class<?>[] initTypes, Object[] initValues)
+   public SerializationGroup<T> create(Class<?>[] initTypes, Object[] initValues, Map<Object, Object> sharedState)
    {
       SerializationGroupImpl<T> group = new SerializationGroupImpl<T>();
       group.setClustered(clustered);
@@ -66,12 +68,12 @@
       return group;
    }
 
-   public void destroy(SerializationGroupImpl<T> group)
+   public void destroy(SerializationGroup<T> group)
    {
       // TODO: nothing?
    }
 
-   public void postActivate(SerializationGroupImpl<T> group)
+   public void postActivate(SerializationGroup<T> group)
    {
       log.trace("post activate " + group);
       // Restore ref to the groupCache in case it was lost during serialization
@@ -79,13 +81,13 @@
       group.postActivate();
    }
 
-   public void prePassivate(SerializationGroupImpl<T> group)
+   public void prePassivate(SerializationGroup<T> group)
    {
       log.trace("pre passivate " + group);
       group.prePassivate();
    }
 
-   public void postReplicate(SerializationGroupImpl<T> group)
+   public void postReplicate(SerializationGroup<T> group)
    {
       log.trace("post replicate " + group);
       // Restore ref to the groupCache in case it was lost during serialization
@@ -93,18 +95,18 @@
       group.postReplicate();
    }
 
-   public void preReplicate(SerializationGroupImpl<T> group)
+   public void preReplicate(SerializationGroup<T> group)
    {
       log.trace("pre replicate " + group);
       group.preReplicate();
    }
 
-   public PassivatingBackingCache<T, SerializationGroupImpl<T>> getGroupCache()
+   public PassivatingBackingCache<T, SerializationGroup<T>> getGroupCache()
    {
       return groupCache;
    }
 
-   public void setGroupCache(PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache)
+   public void setGroupCache(PassivatingBackingCache<T, SerializationGroup<T>> groupCache)
    {
       this.groupCache = groupCache;
    }

Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupImpl.java	                        (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupImpl.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -0,0 +1,390 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, 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.ejb3.cache.impl.backing;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.Identifiable;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
+import org.jboss.ejb3.cache.spi.SerializationGroupMember;
+import org.jboss.ejb3.cache.spi.impl.AbstractBackingCacheEntry;
+import org.jboss.logging.Logger;
+import org.jboss.serial.io.MarshalledObject;
+import org.jboss.util.id.GUID;
+
+/**
+ * Defines a group of serializable objects which must be serialized in
+ * one unit of work.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @author Brian Stansberry
+ * @version $Revision: $
+ */
+public class SerializationGroupImpl<T extends CacheItem>  
+   extends AbstractBackingCacheEntry<T>
+   implements BackingCacheEntry<T>, SerializationGroup<T>
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -6181048392582344057L;
+
+   private static final Logger log = Logger.getLogger(SerializationGroupImpl.class);
+
+   private final Object id = new GUID();
+   
+   /** 
+    * The actual underlying objects passed in via addMember(). We store them 
+    * here so they aren't lost when they are cleared from the values
+    * stored in the "members" map.
+    */
+   private transient Map<Object, T> memberObjects = new ConcurrentHashMap<Object, T>();
+   
+   /**
+    * Marshalled version of memberObjects map. This is what is stored
+    * after deserialization.  Transient so we can control serialization.
+    */
+   private transient MarshalledObject marshalledMembers;
+   
+   /** 
+    * The active group members.  We don't serialize these. Rather, it is
+    * the responsibility of members to reassociate themselves with the 
+    * group upon deserialization (via addActive())
+    */
+   private transient Map<Object, SerializationGroupMember<T>> active = 
+         new HashMap<Object, SerializationGroupMember<T>>();
+   
+   /**
+    * Set of keys passed to {@link #addInUse(Object)}
+    */
+   private transient Set<Object> inUseKeys = new HashSet<Object>();
+   
+   /** Transient ref to our group cache; used to validate compatibility */
+   private transient PassivatingBackingCache<T, SerializationGroup<T>> groupCache;
+   
+   /** Is this object used in a clustered cache? */
+   private boolean clustered;
+
+   private transient boolean invalid;
+   
+   public Object getId()
+   {
+      return id;
+   }
+   
+   /**
+    * Gets whether this groups supports (and requires) clustering functionality
+    * from its members.
+    * 
+    * @return <code>true</code> if clustering is supported, <code>false</code>
+    *         otherwise
+    */
+   public boolean isClustered()
+   {
+      return clustered;
+   }
+   
+   /**
+    * Sets whether this groups supports (and requires) clustering functionality
+    * from its members.
+    * 
+    * @return
+    */
+   public void setClustered(boolean clustered)
+   {
+      this.clustered = clustered;
+   }
+   
+   /**
+    * Initially associates a new member with the group. Also
+    * {@link #addActive(SerializationGroupMember) marks the member as
+    * active}.
+    * 
+    * @param member
+    * 
+    * @throws IllegalStateException if <code>member</code> was previously
+    *                               added to the group
+    * @throws IllegalArgumentException if the 
+    *   {@link SerializationGroupMember#isClustered() member's support for clustering}
+    *   does not match {@link #isClustered() our own}.
+    */
+   public void addMember(SerializationGroupMember<T> member)
+   {
+      Object key = member.getId();
+      Map<Object, T> membObjs = getMemberObjects();
+      if (membObjs.containsKey(key))
+         throw new IllegalStateException(member + " is already a member");
+      log.trace("add member " + key + ", " + member);
+      membObjs.put(key, member.getUnderlyingItem());
+      active.put(key, member);
+   }
+   
+   /**
+    * Remove the specified member from the group.
+    * 
+    * @param key the {@link Identifiable#getId() id} of the member
+    */
+   public void removeMember(Object key)
+   {
+      removeActive(key);
+      getMemberObjects().remove(key);
+   }
+   
+   /**
+    * Gets the number of group members.
+    */
+   public int size()
+   {
+      return getMemberObjects().size();
+   }
+   
+   /**
+    * Returns the {@link SerializationGroupMember#getUnderlyingItem() member object}
+    * associated with the member whose {@link Identifiable#getId() id}
+    * matches <code>key</code>.
+    * 
+    * @param key the {@link Identifiable#getId() id} of the member
+    * 
+    * @return the object associated with the member, or <code>null</code> if
+    *         <code>key</code> does not identify a member.
+    */
+   public T getMemberObject(Object key)
+   {
+      return getMemberObjects().get(key);
+   }
+   
+   /**
+    * Prepare members for passivation.
+    */
+   public void prePassivate()
+   {
+      for(SerializationGroupMember<T> member : active.values())
+      {
+         member.releaseReferences();
+         if(true)
+            throw new IllegalStateException("this doesn't invoke prePassivate callbacks!");
+      }
+      active.clear();
+   }
+   
+   /**
+    * Notification that the group has been activated from a passivated state.
+    */
+   public void postActivate()
+   {
+      invalid = false;
+   }
+   
+   /**
+    * Prepare members for replication.
+    */
+   public void preReplicate()
+   {
+      for(SerializationGroupMember<T> member : active.values())
+      {
+         member.releaseReferences();
+         if(true)
+            throw new IllegalStateException("this doesn't invoke preReplicate callbacks!");
+      }
+      active.clear();
+   }
+   
+   /**
+    * Notification that the previously replicated group has been retrieved from 
+    * a clustered cache.
+    */
+   public void postReplicate()
+   {
+      invalid = false;
+   }
+   
+   /**
+    * Records that the given member is "active"; i.e. needs to have
+    * @PrePassivate callbacks invoked before serialization.
+    * 
+    * @param member the member
+    * 
+    * @throws IllegalStateException if <code>member</code> wasn't previously
+    *                               added to the group via
+    *                               {@link #addMember(SerializationGroupMember)}
+    */
+   public void addActive(SerializationGroupMember<T> member)
+   {
+      Object key = member.getId();
+      active.put(key, member);
+   }
+   
+   /**
+    * Records that the given member is no longer "active"; i.e. does not need
+    * to have @PrePassivate callbacks invoked before serialization.
+    * 
+    * @param key the {@link Identifiable#getId() id} of the member
+    * 
+    * @throws IllegalStateException if <code>member</code> wasn't previously
+    *                               added to the group via
+    *                               {@link #addMember(SerializationGroupMember)}
+    */
+   public void removeActive(Object key)
+   {
+      active.remove(key);
+   }
+
+   /**
+    * Notification that the given member is "in use", and therefore the
+    * group should not be serialized.
+    * 
+    * @param key the {@link Identifiable#getId() id} of the member
+    * 
+    * @throws IllegalStateException if <code>member</code> wasn't previously
+    *                               added to the group via
+    *                               {@link #addMember(SerializationGroupMember)}
+    */
+   public void addInUse(Object key)
+   {
+      inUseKeys.add(key);
+      setInUse(true);
+   }
+
+   /**
+    * Notification that the given member is no longer "in use", and therefore 
+    * should not prevent the group being serialized.
+    * 
+    * @param key the {@link Identifiable#getId() id} of the member
+    * 
+    * @throws IllegalStateException if <code>member</code> wasn't previously
+    *                               added to the group via
+    *                               {@link #addMember(SerializationGroupMember)}
+    */
+   public void removeInUse(Object key)
+   {
+      if (inUseKeys.remove(key))
+      {
+         setLastUsed(System.currentTimeMillis());
+      }
+      else if (!getMemberObjects().containsKey(key))
+      {
+            throw new IllegalStateException(key + " is not a member of " + this);
+      }      
+   }
+   
+   /**
+    * Gets the number of members currently in use.
+    */
+   public int getInUseCount()
+   {
+      return inUseKeys.size();
+   }
+   
+   /**
+    * Always returns <code>true</code>.
+    */
+   public boolean isModified()
+   {
+      return true;
+   }
+   
+   /**
+    * Returns true if this object has been passivated (meaning whoever
+    * holds a ref to it is holding an out-of-date object)
+    * 
+    * @return
+    */
+   public boolean isInvalid()
+   {
+      return invalid;
+   }
+   
+   public void setInvalid(boolean invalid)
+   {
+      this.invalid = invalid;
+   }
+   
+   /**
+    * FIXME -- returns null; what should it do?
+    */
+   public T getUnderlyingItem()
+   {
+      return null;
+   }
+
+   public PassivatingBackingCache<T, SerializationGroup<T>> getGroupCache()
+   {
+      return groupCache;
+   }
+
+   @Override
+   public String toString()
+   {
+      return super.toString() + "{id=" + id + "}";
+   }
+
+   public void setGroupCache(PassivatingBackingCache<T, SerializationGroup<T>> groupCache)
+   {
+      this.groupCache = groupCache;
+   }
+   
+   @SuppressWarnings("unchecked")
+   private Map<Object, T> getMemberObjects()
+   {
+      // Use our id as a lock object 
+      synchronized (id)
+      {
+         if (memberObjects == null && marshalledMembers != null)
+         {
+            try
+            {
+               memberObjects = (Map<Object, T>) marshalledMembers.get();
+               marshalledMembers = null;
+            }
+            catch (Exception e)
+            {
+               throw new RuntimeException("Cannot unmarshalled members of group " + id, e);
+            }
+         }
+         return memberObjects;
+      }
+   }
+
+   private void readObject(java.io.ObjectInputStream in)
+         throws IOException, ClassNotFoundException
+   {
+      in.defaultReadObject();
+      marshalledMembers= (MarshalledObject) in.readObject();
+      active = new HashMap<Object, SerializationGroupMember<T>>();
+      inUseKeys = new HashSet<Object>();
+   }   
+   
+   private void writeObject(java.io.ObjectOutputStream out)
+      throws IOException
+   {
+      out.defaultWriteObject();
+      MarshalledObject toWrite = marshalledMembers == null ? new MarshalledObject(memberObjects) 
+                                                           : marshalledMembers;
+      out.writeObject(toWrite);
+   }
+}


Property changes on: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupImpl.java
___________________________________________________________________
Name: svn:executable
   + *

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberContainer.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberContainer.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberContainer.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -22,13 +22,15 @@
 
 package org.jboss.ejb3.cache.impl.backing;
 
+import java.util.Map;
+
 import org.jboss.ejb3.cache.CacheItem;
 import org.jboss.ejb3.cache.PassivationManager;
 import org.jboss.ejb3.cache.StatefulObjectFactory;
 import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
 import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
+import org.jboss.ejb3.cache.spi.SerializationGroupMember;
 import org.jboss.logging.Logger;
 
 /**
@@ -50,13 +52,13 @@
    /**
     * Cache that's managing the PassivationGroup
     */
-   private PassivatingBackingCache<C, SerializationGroupImpl<C>> groupCache;
+   private PassivatingBackingCache<C, SerializationGroup<C>> groupCache;
    
    
    public SerializationGroupMemberContainer(StatefulObjectFactory<C> factory, 
                                             PassivationManager<C> passivationManager, 
                                             PassivatingIntegratedObjectStore<C, SerializationGroupMember<C>> store,
-                                            PassivatingBackingCache<C, SerializationGroupImpl<C>> groupCache)
+                                            PassivatingBackingCache<C, SerializationGroup<C>> groupCache)
    {
       assert factory != null : "factory is null";
       assert passivationManager != null : "passivationManager is null";
@@ -69,10 +71,10 @@
       this.groupCache = groupCache;
    }
    
-   public SerializationGroupMember<C> create(Class<?>[] initTypes, Object[] initValues)
+   public SerializationGroupMember<C> create(Class<?>[] initTypes, Object[] initValues, Map<Object, Object> sharedState)
    {
-      SerializationGroupMember<C> member = 
-         new SerializationGroupMember<C>(factory.create(initTypes, initValues), 
+      SerializationGroupMemberImpl<C> member = 
+         new SerializationGroupMemberImpl<C>(factory.create(initTypes, initValues, sharedState), 
                                          delegate);
       return member;
    }
@@ -80,7 +82,7 @@
    public void destroy(SerializationGroupMember<C> entry)
    {
       factory.destroy(entry.getUnderlyingItem());
-      SerializationGroupImpl<C> group = entry.getGroup();
+      SerializationGroup<C> group = entry.getGroup();
       if (group != null) 
       {
          group.removeMember(entry.getId());
@@ -99,7 +101,7 @@
       while (!groupOK)
       {
          // Restore the entry's ref to the group and object
-         SerializationGroupImpl<C> group = entry.getGroup();
+         SerializationGroup<C> group = entry.getGroup();
          if(group == null && entry.getGroupId() != null)
          {
             // TODO: peek or get?
@@ -157,7 +159,7 @@
       // for the group passivation. If the call is coming via entry.prePassivate(), 
       // entry.group *will* be null. In that case we are not the controller 
       // of the passivation and can just return.
-      SerializationGroupImpl<C> group = entry.getGroup();
+      SerializationGroup<C> group = entry.getGroup();
       if(group != null)
       {
          synchronized (group)
@@ -209,7 +211,7 @@
          entry.setPreReplicated(true);
       }
       
-      SerializationGroupImpl<C> group = entry.getGroup();
+      SerializationGroup<C> group = entry.getGroup();
       if(group != null)
       {
          synchronized (group)
@@ -247,7 +249,7 @@
       while (!groupOK)
       {
          // Restore the entry's ref to the group and object
-         SerializationGroupImpl<C> group = entry.getGroup();
+         SerializationGroup<C> group = entry.getGroup();
          if(group == null && entry.getGroupId() != null)
          {
             // TODO: peek or get?

Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberImpl.java	                        (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberImpl.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -0,0 +1,301 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, 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.ejb3.cache.impl.backing;
+
+import java.io.IOException;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
+import org.jboss.ejb3.cache.spi.SerializationGroupMember;
+import org.jboss.ejb3.cache.spi.impl.AbstractBackingCacheEntry;
+import org.jboss.serial.io.MarshalledObject;
+
+/**
+ * A member of a {@link SerializationGroupImpl}.
+ * 
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class SerializationGroupMemberImpl<T extends CacheItem> 
+   extends AbstractBackingCacheEntry<T> implements SerializationGroupMember<T>
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 7268142730501106252L;
+
+   /**
+    * Identifier for our underlying object
+    */
+   private Object id;
+   
+   /**
+    * The underlying object (e.g. bean context).
+    */
+   private transient T obj;
+   
+   private transient MarshalledObject marshalledObj;
+   
+   /**
+    * Hack. We hold two refs to our object; one we clear in prePassivate,
+    * one we keep, but it's transient.  getUnderlyingItem() returns
+    * whichever is available, making it available for passivation callbacks.
+    * 
+    * FIXME WTF???
+    */
+   private transient T transientObj;
+   
+   /** The group. Never serialize the group; only the groupCache does that */
+   private transient SerializationGroup<T> group;
+   
+   /**
+    * Id for our group; serialize this so we can find our group again
+    * after deserialization on a remote node.
+    */
+   private Object groupId;
+   
+   private boolean clustered;
+   
+   private boolean preReplicated;
+   
+   /** The cache that's handling us */
+//   private transient PassivatingBackingCache<T, SerializationGroupMember<T>> cache;
+   
+   public SerializationGroupMemberImpl(T obj, PassivatingBackingCache<T, SerializationGroupMember<T>> cache)
+   {
+      assert obj != null : "obj is null";
+      assert cache != null : "cache is null";
+      
+      this.obj = transientObj = obj;
+      this.id = obj.getId();
+//      this.cache = cache;
+      this.clustered = cache.isClustered();
+   }
+   
+   public Object getId()
+   {
+      return id;
+   }
+   
+   public boolean isModified()
+   {
+      T unmarshalled = getObj();
+      return (unmarshalled != null && unmarshalled.isModified());
+   }
+   
+   /**
+    * Gets whether this member supports clustering functionality.
+    * 
+    * @return <code>true</code> if clustering is supported, <code>false</code>
+    *         otherwise
+    */
+   public boolean isClustered()
+   {
+      return clustered;
+   }
+   
+   @SuppressWarnings("unchecked")
+   public T getUnderlyingItem()
+   {      
+      T unmarshalled = getObj();
+      return unmarshalled == null ? transientObj : unmarshalled;
+   }
+   
+   /**
+    * Sets the underlying {@link CacheItem} associated with this group member.
+    * 
+    * @param item the cache item
+    */
+   public void setUnderlyingItem(T obj)
+   {
+      this.obj = transientObj = obj;
+   }
+   
+   /**
+    * Gets the {@link SerializationGroupImpl} of which this object is a member.
+    * 
+    * @return the group. May return <code>null</code>
+    */
+   public SerializationGroup<T> getGroup()
+   {
+      SerializationGroup<T> result = group;
+      if (result != null)
+      {
+         synchronized (result)
+         {
+            if (result.isInvalid())
+               result = null;
+         }
+      }
+      return result;
+   }
+
+   /**
+    * Sets the {@link SerializationGroupImpl} of which this object is a member.
+    * 
+    * @param the group. May be <code>null</code>
+    */
+   public void setGroup(SerializationGroup<T> group)
+   {
+      this.group = group;
+      if (this.groupId == null && group != null)
+         this.groupId = group.getId();
+   }
+
+   /**
+    * Gets the id for the group
+    * 
+    * @return
+    */
+   public Object getGroupId()
+   {
+      return groupId;
+   }
+
+   /**
+    * Prepares the group member for group passivation by ensuring any 
+    * reference to the {@link #getUnderlyingItem() underlying object} or to the 
+    * {@link #getGroup()} is nulled.
+    */
+   public void releaseReferences()
+   {
+      // make sure we don't passivate the group twice
+      group = null;
+      
+      // null out obj so when delegate passivates this entry
+      // we don't serialize it. It serializes with the PassivationGroup only  
+      // We still have a ref to transientObj, so it can be retrieved
+      // for passivation callbacks
+      obj = null;
+      
+//      cache.passivate(this.id);
+   }
+   
+   /**
+    * Notification that the group has been activated from a passivated state.
+    */
+   public void postActivate()
+   {
+      // no-op
+   }
+   
+   public boolean isPreReplicated()
+   {
+      return preReplicated;
+   }
+   
+   public void setPreReplicated(boolean preReplicated)
+   {
+      this.preReplicated = preReplicated;
+   }
+   
+   /**
+    * Notification that the previously replicated group has been retrieved from 
+    * a clustered cache.
+    */
+   public void postReplicate()
+   {
+      // no-op
+   }
+
+   public void setInUse(boolean inUse)
+   {
+      super.setInUse(inUse);
+      
+      // Tell our group about it
+      if (group != null)
+      {
+         synchronized (group)
+         {
+            if (inUse)
+               group.addActive(this);
+            else
+               group.removeActive(id);
+         }
+      }         
+   }
+   
+   /**
+    * Allows our controlling {@link PassivatingBackingCache} to provide
+    * us a reference after deserialization.
+    * 
+    * @param delegate
+    */
+   public void setPassivatingCache(PassivatingBackingCache<T, SerializationGroupMember<T>> delegate)
+   {
+//      assert delegate != null : "delegate is null";
+//      
+//      this.cache = delegate;
+   }
+
+   @Override
+   public String toString()
+   {
+      return super.toString() + "{id=" + id + ",obj=" + getObj() + ",groupId=" + groupId + ",group=" + group + "}";
+   }
+   
+   @SuppressWarnings("unchecked")
+   private T getObj()
+   {
+      synchronized (id)
+      {
+         if (obj == null && marshalledObj != null)
+         {
+            try
+            {
+               obj = (T) marshalledObj.get();
+               marshalledObj = null;
+            }
+            catch (Exception e)
+            {
+               throw new RuntimeException("Cannot unmarshall item " + id, e);
+            }
+         }
+         return obj;
+      }
+   }
+
+   private void readObject(java.io.ObjectInputStream in)
+         throws IOException, ClassNotFoundException
+   {
+      in.defaultReadObject();
+      if (groupId == null)
+      {
+         marshalledObj = (MarshalledObject) in.readObject();
+      }
+   }
+   
+   private void writeObject(java.io.ObjectOutputStream out) throws IOException
+   {
+      if (groupId != null)
+      {
+         group = null;
+         obj = null;
+      }
+      out.defaultWriteObject();
+      if (groupId == null)
+      {
+         MarshalledObject toWrite = marshalledObj == null ? new MarshalledObject(obj) : marshalledObj;
+         out.writeObject(toWrite);
+      }
+   }
+}

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/GroupAwareCacheFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/GroupAwareCacheFactory.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/GroupAwareCacheFactory.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -40,9 +40,9 @@
 import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
 import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
 import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
+import org.jboss.ejb3.cache.spi.SerializationGroupMember;
 import org.jboss.ejb3.cache.spi.impl.AbstractStatefulCacheFactory;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
 
 /**
  * {@link StatefulCacheFactory} implementation that can return a group-aware 
@@ -56,7 +56,7 @@
 public class GroupAwareCacheFactory<T extends CacheItem> 
    extends AbstractStatefulCacheFactory<T>
 {
-   private final Map<String, PassivatingBackingCache<T, SerializationGroupImpl<T>>> groupCaches;
+   private final Map<String, PassivatingBackingCache<T, SerializationGroup<T>>> groupCaches;
    private final IntegratedObjectStoreSource<T> storeSource;
    
    /**
@@ -68,7 +68,7 @@
       assert storeSource != null : "storeSource is null";
       
       this.storeSource = storeSource;
-      this.groupCaches = new HashMap<String, PassivatingBackingCache<T, SerializationGroupImpl<T>>>();
+      this.groupCaches = new HashMap<String, PassivatingBackingCache<T, SerializationGroup<T>>>();
    }
 
    // --------------------------------------------------- StatefulCacheFactory
@@ -79,7 +79,7 @@
    {
       String configName = getCacheConfigName(cacheConfig);
       
-      PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache = groupCaches.get(configName);
+      PassivatingBackingCache<T, SerializationGroup<T>> groupCache = groupCaches.get(configName);
       if (groupCache == null)
       {
          groupCache = createGroupCache(containerName, configName, cacheConfig);
@@ -111,23 +111,23 @@
       GroupAwareBackingCache<T, SerializationGroupMember<T>> backingCache =
          new GroupAwareBackingCacheImpl<T>(memberContainer, groupCache);
       
-      return new GroupAwareTransactionalCache<T, SerializationGroupMember<T>>(backingCache, getTransactionManager(), getSynchronizationCoordinator());
+      return new GroupAwareTransactionalCache<T, SerializationGroupMember<T>>(backingCache, getTransactionManager(), getSynchronizationCoordinator(), getStrictGroups());
    }
 
-   private PassivatingBackingCache<T, SerializationGroupImpl<T>> createGroupCache(String name, String configName, CacheConfig cacheConfig)
+   private PassivatingBackingCache<T, SerializationGroup<T>> createGroupCache(String name, String configName, CacheConfig cacheConfig)
    {
       SerializationGroupContainer<T> container = new SerializationGroupContainer<T>();
-      StatefulObjectFactory<SerializationGroupImpl<T>> factory = container;
-      PassivationManager<SerializationGroupImpl<T>> passivationManager = container;
-      PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> store = 
+      StatefulObjectFactory<SerializationGroup<T>> factory = container;
+      PassivationManager<SerializationGroup<T>> passivationManager = container;
+      PassivatingIntegratedObjectStore<T, SerializationGroup<T>> store = 
          storeSource.createGroupIntegratedObjectStore(name, configName, cacheConfig, getTransactionManager(), getSynchronizationCoordinator());
     
       // The group cache store should not passivate/expire -- that's a 
       // function of the caches for the members
       store.setInterval(0);
       
-      PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache =
-         new PassivatingBackingCacheImpl<T, SerializationGroupImpl<T>>(factory, passivationManager, store);
+      PassivatingBackingCache<T, SerializationGroup<T>> groupCache =
+         new PassivatingBackingCacheImpl<T, SerializationGroup<T>>(factory, passivationManager, store);
       
       container.setGroupCache(groupCache);
       

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonClusteredIntegratedObjectStoreSource.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonClusteredIntegratedObjectStoreSource.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonClusteredIntegratedObjectStoreSource.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -31,10 +31,10 @@
 import org.jboss.ejb3.cache.impl.backing.SimplePassivatingIntegratedObjectStore;
 import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
 import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
+import org.jboss.ejb3.cache.spi.SerializationGroupMember;
 import org.jboss.ejb3.cache.spi.SynchronizationCoordinator;
 import org.jboss.ejb3.cache.spi.impl.FileObjectStore;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
 
 /**
  * {@link IntegratedObjectStoreSource} for a non-clustered cache. Uses
@@ -62,17 +62,17 @@
    private String baseDirectoryName;
    private int subdirectoryCount = DEFAULT_SUBDIRECTORY_COUNT;
    
-   public PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> createGroupIntegratedObjectStore(String containerName, String cacheConfigName,
+   public PassivatingIntegratedObjectStore<T, SerializationGroup<T>> createGroupIntegratedObjectStore(String containerName, String cacheConfigName,
          CacheConfig cacheConfig, TransactionManager transactionManager, SynchronizationCoordinator synchronizationCoordinator)
    {
-      FileObjectStore<SerializationGroupImpl<T>> objectStore = new FileObjectStore<SerializationGroupImpl<T>>();
+      FileObjectStore<SerializationGroup<T>> objectStore = new FileObjectStore<SerializationGroup<T>>();
       objectStore.setStorageDirectory(getFullGroupDirectoryName(containerName));
       objectStore.setSubdirectoryCount(subdirectoryCount);
       
       String storeNameSuffix = (cacheConfig.name().length() == 0) ? "" : "-" + cacheConfig;
       String storeName = "StdGroupStore" + storeNameSuffix;
-      SimplePassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> store = 
-         new SimplePassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>>(objectStore, cacheConfig, storeName, true);
+      SimplePassivatingIntegratedObjectStore<T, SerializationGroup<T>> store = 
+         new SimplePassivatingIntegratedObjectStore<T, SerializationGroup<T>>(objectStore, cacheConfig, storeName, true);
       
       return store;
    }

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonPassivatingCacheFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonPassivatingCacheFactory.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonPassivatingCacheFactory.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -35,8 +35,7 @@
 
 /**
  * {@link StatefulCacheFactory} implementation that will return a 
- * {@link Cache#isGroupAware() non-group-aware} cache that doesn't support
- * passivation.
+ * non-group-aware cache that doesn't support passivation.
  * 
  * @author Brian Stansberry
  */
@@ -64,7 +63,7 @@
          backingCache.setInterval(getDefaultPassivationExpirationInterval());
       }
       
-      return new TransactionalCache<T, NonPassivatingBackingCacheEntry<T>>(backingCache, getTransactionManager(), getSynchronizationCoordinator());
+      return new TransactionalCache<T, NonPassivatingBackingCacheEntry<T>>(backingCache, getTransactionManager(), getSynchronizationCoordinator(), getStrictGroups());
    }
 
 }

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCache.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCache.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -22,6 +22,8 @@
 
 package org.jboss.ejb3.cache.spi;
 
+import java.util.Map;
+
 import javax.ejb.NoSuchEJBException;
 
 import org.jboss.ejb3.cache.Cache;
@@ -69,9 +71,12 @@
     * @param initValues  any parameters to pass to <code>T</code>'s constructor.
     *                    May be null, in which case a default constructor will
     *                    be used.
+    * @param sharedState map into which any objects meant to be shared with
+    *                    other members of the new items group should be
+    *                    stored. 
     * @return the new <code>T</code> 
     */
-   T create(Class<?> initTypes[], Object initValues[]);
+   T create(Class<?> initTypes[], Object initValues[], Map<Object, Object> sharedState);
 
    /**
     * Get the specified object from cache. This will mark

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupAwareBackingCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupAwareBackingCache.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupAwareBackingCache.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -23,7 +23,6 @@
 package org.jboss.ejb3.cache.spi;
 
 import org.jboss.ejb3.cache.CacheItem;
-import org.jboss.ejb3.cache.SerializationGroup;
 
 /**
  * A {@link BackingCache} that can manage the relationship of its 

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStoreSource.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStoreSource.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStoreSource.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -27,8 +27,6 @@
 import org.jboss.ejb3.annotation.CacheConfig;
 import org.jboss.ejb3.cache.CacheItem;
 import org.jboss.ejb3.cache.StatefulCacheFactory;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
 
 /**
  * Provides {@link PassivatingIntegratedObjectStore} instances to a 
@@ -55,7 +53,7 @@
     *                                   tranaction synchronizations
     * @return the store
     */
-   PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> 
+   PassivatingIntegratedObjectStore<T, SerializationGroup<T>> 
          createGroupIntegratedObjectStore(String containerName, 
                                           String cacheConfigName, 
                                           CacheConfig config, 

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingBackingCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingBackingCache.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingBackingCache.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -22,7 +22,7 @@
 package org.jboss.ejb3.cache.spi;
 
 import org.jboss.ejb3.cache.CacheItem;
-import org.jboss.ejb3.cache.SerializationGroup;
+import org.jboss.ejb3.cache.impl.backing.SerializationGroupImpl;
 
 
 /**
@@ -48,7 +48,7 @@
     * @param key    the identifier of the object
     * 
     * @throws IllegalStateException if the object, or another object in the 
-    *                            same {@link SerializationGroup} as the object, 
+    *                            same {@link SerializationGroupImpl} as the object, 
     *                            is in use. 
     */
    void passivate(Object key);

Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/SerializationGroup.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/SerializationGroup.java	                        (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/SerializationGroup.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -0,0 +1,23 @@
+package org.jboss.ejb3.cache.spi;
+
+import org.jboss.ejb3.cache.CacheItem;
+
+public interface SerializationGroup<T extends CacheItem>
+   extends BackingCacheEntry<T>
+{
+   void addMember(SerializationGroupMember<T> member);
+   void removeMember(Object key);
+   int size();
+   boolean isInvalid();
+   void setInvalid(boolean invalid);
+   T getMemberObject(Object key);
+   void addActive(SerializationGroupMember<T> member);
+   void removeActive(Object key);
+   int getInUseCount();
+   PassivatingBackingCache<T, SerializationGroup<T>> getGroupCache();
+   void setGroupCache(PassivatingBackingCache<T, SerializationGroup<T>> groupCache);
+   void postActivate();
+   void prePassivate();
+   void preReplicate();
+   void postReplicate();
+}
\ No newline at end of file

Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/SerializationGroupMember.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/SerializationGroupMember.java	                        (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/SerializationGroupMember.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -0,0 +1,16 @@
+package org.jboss.ejb3.cache.spi;
+
+import org.jboss.ejb3.cache.CacheItem;
+
+public interface SerializationGroupMember<T extends CacheItem>
+  extends BackingCacheEntry<T>
+{
+   Object getGroupId();
+   SerializationGroup<T> getGroup();
+   void setGroup(SerializationGroup<T> group);
+   void releaseReferences();
+   void setPassivatingCache(PassivatingBackingCache<T, SerializationGroupMember<T>> cache);
+   void setUnderlyingItem(T obj);
+   boolean isPreReplicated();
+   void setPreReplicated(boolean preReplicated);
+}
\ No newline at end of file

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractStatefulCacheFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractStatefulCacheFactory.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractStatefulCacheFactory.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -48,6 +48,7 @@
    private int defaultPassivationExpirationInterval = DEFAULT_PASSIVATION_EXPIRATION_INTERVAL;
    private String defaultCacheConfigName;
    private Map<String, String> cacheConfigAliases;
+   private boolean strictGroups = true;
    
    // -------------------------------------------------------------  Properties
    
@@ -168,8 +169,19 @@
       this.cacheConfigAliases = cacheConfigAliases;
    }
    
+   public boolean getStrictGroups()
+   {
+      return strictGroups;
+   }
+
+   public void setStrictGroups(boolean strictGroups)
+   {
+      this.strictGroups = strictGroups;
+   }
+   
+   
    // -----------------------------------------------------------------  Public
-   
+
    public String getCacheConfigName(CacheConfig cacheConfig)
    {
       String name = cacheConfig.name();

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/GroupCreationContext.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/GroupCreationContext.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/GroupCreationContext.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -22,7 +22,9 @@
 
 package org.jboss.ejb3.cache.spi.impl;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 
 /**
@@ -32,20 +34,59 @@
 public class GroupCreationContext
 {
    @SuppressWarnings("unchecked")
-   private static final ThreadLocal<List<ItemCachePair>> groupCreationContext = new ThreadLocal<List<ItemCachePair>>();
+   private static final ThreadLocal<GroupCreationContext> groupCreationContext = new ThreadLocal<GroupCreationContext>();
    
+   private final List<ItemCachePair> pairs;
+   private Map<Object, Object> sharedState;
+   private final boolean strict;
+   
    /**
-    * Prevent instantiation. 
+    * Prevent external instantiation. 
     */
-   private GroupCreationContext() {}
+   private GroupCreationContext(boolean strict) 
+   {
+      this.pairs = new ArrayList<ItemCachePair>();
+      this.strict = strict;
+   }
 
-   public static List<ItemCachePair> getGroupCreationContext()
+   public List<ItemCachePair> getPairs()
    {
+      return pairs;
+   }
+
+   public Map<Object, Object> getSharedState()
+   {
+      return sharedState;
+   }  
+   
+   public void setSharedState(Map<Object, Object> sharedState)
+   {
+      if (this.sharedState != null)
+         throw new IllegalStateException("Shared state already set");
+      this.sharedState = sharedState;
+   }
+   
+   public boolean isStrict()
+   {
+      return strict;
+   }
+
+   public static GroupCreationContext getGroupCreationContext()
+   {
       return groupCreationContext.get();
    }
    
-   public static void setGroupCreationContext(List<ItemCachePair> context)
+   public static GroupCreationContext startGroupCreationContext(boolean strict)
    {
-      groupCreationContext.set(context);
+      if (groupCreationContext.get() != null)
+         throw new IllegalStateException("GroupCreationContext already exists");
+      GroupCreationContext started = new GroupCreationContext(strict);
+      groupCreationContext.set(started);
+      return started;
    }
+   
+   public static void clearGroupCreationContext()
+   {
+      groupCreationContext.set(null);
+   }
 }

Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupImpl.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupImpl.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -1,384 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, 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.ejb3.cache.spi.impl;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.jboss.ejb3.cache.CacheItem;
-import org.jboss.ejb3.cache.Identifiable;
-import org.jboss.ejb3.cache.SerializationGroup;
-import org.jboss.ejb3.cache.spi.BackingCacheEntry;
-import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
-import org.jboss.logging.Logger;
-import org.jboss.util.id.GUID;
-
-/**
- * Defines a group of serializable objects which must be serialized in
- * one unit of work.
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @author Brian Stansberry
- * @version $Revision: $
- */
-public class SerializationGroupImpl<T extends CacheItem>  
-   extends AbstractBackingCacheEntry<T>
-   implements SerializationGroup<T>, BackingCacheEntry<T>
-{
-   /** The serialVersionUID */
-   private static final long serialVersionUID = -6181048392582344057L;
-
-   private static final Logger log = Logger.getLogger(SerializationGroupImpl.class);
-
-   private Object id = new GUID();
-   
-   /** 
-    * The actual underlying objects passed in via addMember(). We store them 
-    * here so they aren't lost when they are cleared from the values
-    * stored in the "members" map.
-    */
-   private Map<Object, T> memberObjects = new ConcurrentHashMap<Object, T>();
-   
-   /** 
-    * The active group members.  We don't serialize these. Rather, it is
-    * the responsibility of members to reassociate themselves with the 
-    * group upon deserialization (via addActive())
-    */
-   private transient Map<Object, SerializationGroupMember<T>> active = 
-         new HashMap<Object, SerializationGroupMember<T>>();
-   
-   /**
-    * Set of keys passed to {@link #addInUse(Object)}
-    */
-   private transient Set<Object> inUseKeys = new HashSet<Object>();
-   
-   /** Transient ref to our group cache; used to validate compatibility */
-   private transient PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache;
-   
-   /** Is this object used in a clustered cache? */
-   private boolean clustered;
-
-   private transient boolean invalid;
-   
-   public Object getId()
-   {
-      return id;
-   }
-   
-   /**
-    * Gets whether this groups supports (and requires) clustering functionality
-    * from its members.
-    * 
-    * @return <code>true</code> if clustering is supported, <code>false</code>
-    *         otherwise
-    */
-   public boolean isClustered()
-   {
-      return clustered;
-   }
-   
-   /**
-    * Sets whether this groups supports (and requires) clustering functionality
-    * from its members.
-    * 
-    * @return
-    */
-   public void setClustered(boolean clustered)
-   {
-      this.clustered = clustered;
-   }
-   
-   /**
-    * Initially associates a new member with the group. Also
-    * {@link #addActive(SerializationGroupMember) marks the member as
-    * active}.
-    * 
-    * @param member
-    * 
-    * @throws IllegalStateException if <code>member</code> was previously
-    *                               added to the group
-    * @throws IllegalArgumentException if the 
-    *   {@link SerializationGroupMember#isClustered() member's support for clustering}
-    *   does not match {@link #isClustered() our own}.
-    */
-   public void addMember(SerializationGroupMember<T> member)
-   {
-      Object key = member.getId();
-      if (memberObjects.containsKey(key))
-         throw new IllegalStateException(member + " is already a member");
-      log.trace("add member " + key + ", " + member);
-      memberObjects.put(key, member.getUnderlyingItem());
-      active.put(key, member);
-   }
-   
-   /**
-    * Remove the specified member from the group.
-    * 
-    * @param key the {@link Identifiable#getId() id} of the member
-    */
-   public void removeMember(Object key)
-   {
-      removeActive(key);
-      memberObjects.remove(key);
-   }
-   
-   /**
-    * Gets the number of group members.
-    */
-   public int size()
-   {
-      return memberObjects.size();
-   }
-   
-   /**
-    * Returns the {@link SerializationGroupMember#getUnderlyingItem() member object}
-    * associated with the member whose {@link Identifiable#getId() id}
-    * matches <code>key</code>.
-    * 
-    * @param key the {@link Identifiable#getId() id} of the member
-    * 
-    * @return the object associated with the member, or <code>null</code> if
-    *         <code>key</code> does not identify a member.
-    */
-   public T getMemberObject(Object key)
-   {
-      return memberObjects.get(key);
-   }
-   
-   public Iterator<T> iterator()
-   {
-      return new UnmodifiableIterator<T>(memberObjects.values().iterator());
-   }
-   
-   /**
-    * Prepare members for passivation.
-    */
-   public void prePassivate()
-   {
-      for(SerializationGroupMember<T> member : active.values())
-      {
-         member.releaseReferences();
-      }
-      active.clear();
-   }
-   
-   /**
-    * Notification that the group has been activated from a passivated state.
-    */
-   public void postActivate()
-   {
-      invalid = false;
-   }
-   
-   /**
-    * Prepare members for replication.
-    */
-   public void preReplicate()
-   {
-      for(SerializationGroupMember<T> member : active.values())
-      {
-         member.releaseReferences();
-      }
-      active.clear();
-   }
-   
-   /**
-    * Notification that the previously replicated group has been retrieved from 
-    * a clustered cache.
-    */
-   public void postReplicate()
-   {
-      invalid = false;
-   }
-   
-   /**
-    * Records that the given member is "active"; i.e. needs to have
-    * @PrePassivate callbacks invoked before serialization.
-    * 
-    * @param member the member
-    * 
-    * @throws IllegalStateException if <code>member</code> wasn't previously
-    *                               added to the group via
-    *                               {@link #addMember(SerializationGroupMember)}
-    */
-   public void addActive(SerializationGroupMember<T> member)
-   {
-      Object key = member.getId();
-      if (!memberObjects.containsKey(key))
-         throw new IllegalStateException(member + " is not a member of " + this);
-      active.put(key, member);
-   }
-   
-   /**
-    * Records that the given member is no longer "active"; i.e. does not need
-    * to have @PrePassivate callbacks invoked before serialization.
-    * 
-    * @param key the {@link Identifiable#getId() id} of the member
-    * 
-    * @throws IllegalStateException if <code>member</code> wasn't previously
-    *                               added to the group via
-    *                               {@link #addMember(SerializationGroupMember)}
-    */
-   public void removeActive(Object key)
-   {
-      active.remove(key);
-   }
-
-   /**
-    * Notification that the given member is "in use", and therefore the
-    * group should not be serialized.
-    * 
-    * @param key the {@link Identifiable#getId() id} of the member
-    * 
-    * @throws IllegalStateException if <code>member</code> wasn't previously
-    *                               added to the group via
-    *                               {@link #addMember(SerializationGroupMember)}
-    */
-   public void addInUse(Object key)
-   {
-      if (!memberObjects.containsKey(key))
-         throw new IllegalStateException(key + " is not a member of " + this);
-      inUseKeys.add(key);
-      setInUse(true);
-   }
-
-   /**
-    * Notification that the given member is no longer "in use", and therefore 
-    * should not prevent the group being serialized.
-    * 
-    * @param key the {@link Identifiable#getId() id} of the member
-    * 
-    * @throws IllegalStateException if <code>member</code> wasn't previously
-    *                               added to the group via
-    *                               {@link #addMember(SerializationGroupMember)}
-    */
-   public void removeInUse(Object key)
-   {
-      if (inUseKeys.remove(key))
-      {
-         setLastUsed(System.currentTimeMillis());
-      }
-      else if (!memberObjects.containsKey(key))
-      {
-            throw new IllegalStateException(key + " is not a member of " + this);
-      }      
-   }
-   
-   /**
-    * Gets the number of members currently in use.
-    */
-   public int getInUseCount()
-   {
-      return inUseKeys.size();
-   }
-   
-   /**
-    * Always returns <code>true</code>.
-    */
-   public boolean isModified()
-   {
-      return true;
-   }
-   
-   /**
-    * Returns true if this object has been passivated (meaning whoever
-    * holds a ref to it is holding an out-of-date object)
-    * 
-    * @return
-    */
-   public boolean isInvalid()
-   {
-      return invalid;
-   }
-   
-   public void setInvalid(boolean invalid)
-   {
-      this.invalid = invalid;
-   }
-   
-   /**
-    * FIXME -- returns null; what should it do?
-    */
-   public T getUnderlyingItem()
-   {
-      return null;
-   }
-
-   public PassivatingBackingCache<T, SerializationGroupImpl<T>> getGroupCache()
-   {
-      return groupCache;
-   }
-
-   @Override
-   public String toString()
-   {
-      return super.toString() + "{id=" + id + "}";
-   }
-
-   public void setGroupCache(PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache)
-   {
-      this.groupCache = groupCache;
-   }
-
-   private void readObject(java.io.ObjectInputStream in)
-         throws IOException, ClassNotFoundException
-   {
-      in.defaultReadObject();
-      active = new HashMap<Object, SerializationGroupMember<T>>();
-      inUseKeys = new HashSet<Object>();
-   }   
-   
-   private class UnmodifiableIterator<C extends CacheItem & Serializable> implements Iterator<C>
-   {
-      private Iterator<C> backingIterator;
-      
-      public UnmodifiableIterator(Iterator<C> backingIterator)
-      {
-         assert backingIterator != null : "backingIterator is null";
-         
-         this.backingIterator = backingIterator;
-      }
-
-      public boolean hasNext()
-      {
-         return backingIterator.hasNext();
-      }
-
-      public C next()
-      {
-         return backingIterator.next();
-      }
-
-      public void remove()
-      {
-         throw new UnsupportedOperationException("remove is not supported");         
-      }
-   }
-   
-   
-}

Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupMember.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupMember.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupMember.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -1,258 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, 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.ejb3.cache.spi.impl;
-
-import java.io.IOException;
-
-import org.jboss.ejb3.cache.CacheItem;
-import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
-
-/**
- * A member of a {@link SerializationGroupImpl}.
- * 
- * @author Brian Stansberry
- * @version $Revision$
- */
-public class SerializationGroupMember<T extends CacheItem> 
-   extends AbstractBackingCacheEntry<T>
-{
-   /** The serialVersionUID */
-   private static final long serialVersionUID = 7268142730501106252L;
-
-   /**
-    * Identifier for our underlying object
-    */
-   private Object id;
-   
-   /**
-    * The underlying object (e.g. bean context).
-    * Preferably, this field would be transient. It isn't now because it is 
-    * possible this entry will never be assigned to a PassivationGroup,
-    * in which case we need to serialize obj.
-    */
-   private T obj;
-   
-   /**
-    * Hack. We hold two refs to our object; one we clear in prePassivate,
-    * one we keep, but it's transient.  getUnderlyingItem() returns
-    * whichever is available, making it available for passivation callbacks.
-    */
-   private transient T transientObj;
-   
-   /** The group. Never serialize the group; only the groupCache does that */
-   private transient SerializationGroupImpl<T> group;
-   
-   /**
-    * Id for our group; serialize this so we can find our group again
-    * after deserialization on a remote node.
-    */
-   private Object groupId;
-   
-   private boolean clustered;
-   
-   private boolean preReplicated;
-   
-   /** The cache that's handling us */
-//   private transient PassivatingBackingCache<T, SerializationGroupMember<T>> cache;
-   
-   public SerializationGroupMember(T obj, PassivatingBackingCache<T, SerializationGroupMember<T>> cache)
-   {
-      assert obj != null : "obj is null";
-      assert cache != null : "cache is null";
-      
-      this.obj = transientObj = obj;
-      this.id = obj.getId();
-//      this.cache = cache;
-      this.clustered = cache.isClustered();
-   }
-   
-   public Object getId()
-   {
-      return id;
-   }
-   
-   public boolean isModified()
-   {
-      return (obj != null && obj.isModified());
-   }
-   
-   /**
-    * Gets whether this member supports clustering functionality.
-    * 
-    * @return <code>true</code> if clustering is supported, <code>false</code>
-    *         otherwise
-    */
-   public boolean isClustered()
-   {
-      return clustered;
-   }
-   
-   @SuppressWarnings("unchecked")
-   public T getUnderlyingItem()
-   {      
-      return obj == null ? transientObj : obj;
-   }
-   
-   /**
-    * Sets the underlying {@link CacheItem} associated with this group member.
-    * 
-    * @param item the cache item
-    */
-   public void setUnderlyingItem(T obj)
-   {
-      this.obj = transientObj = obj;
-   }
-   
-   /**
-    * Gets the {@link SerializationGroupImpl} of which this object is a member.
-    * 
-    * @return the group. May return <code>null</code>
-    */
-   public SerializationGroupImpl<T> getGroup()
-   {
-      SerializationGroupImpl<T> result = group;
-      if (result != null)
-      {
-         synchronized (result)
-         {
-            if (result.isInvalid())
-               result = null;
-         }
-      }
-      return result;
-   }
-
-   /**
-    * Sets the {@link SerializationGroupImpl} of which this object is a member.
-    * 
-    * @param the group. May be <code>null</code>
-    */
-   public void setGroup(SerializationGroupImpl<T> group)
-   {
-      this.group = group;
-      if (this.groupId == null && group != null)
-         this.groupId = group.getId();
-   }
-
-   /**
-    * Gets the id for the group
-    * 
-    * @return
-    */
-   public Object getGroupId()
-   {
-      return groupId;
-   }
-
-   /**
-    * Prepares the group member for group passivation by ensuring any 
-    * reference to the {@link #getUnderlyingItem() underlying object} or to the 
-    * {@link #getGroup()} is nulled.
-    */
-   public void releaseReferences()
-   {
-      // make sure we don't passivate the group twice
-      group = null;
-      
-      // null out obj so when delegate passivates this entry
-      // we don't serialize it. It serializes with the PassivationGroup only  
-      // We still have a ref to transientObj, so it can be retrieved
-      // for passivation callbacks
-      obj = null;
-      
-//      cache.passivate(this.id);
-   }
-   
-   /**
-    * Notification that the group has been activated from a passivated state.
-    */
-   public void postActivate()
-   {
-      // no-op
-   }
-   
-   public boolean isPreReplicated()
-   {
-      return preReplicated;
-   }
-   
-   public void setPreReplicated(boolean preReplicated)
-   {
-      this.preReplicated = preReplicated;
-   }
-   
-   /**
-    * Notification that the previously replicated group has been retrieved from 
-    * a clustered cache.
-    */
-   public void postReplicate()
-   {
-      // no-op
-   }
-
-   public void setInUse(boolean inUse)
-   {
-      super.setInUse(inUse);
-      
-      // Tell our group about it
-      if (group != null)
-      {
-         synchronized (group)
-         {
-            if (inUse)
-               group.addActive(this);
-            else
-               group.removeActive(id);
-         }
-      }         
-   }
-   
-   /**
-    * Allows our controlling {@link PassivatingBackingCache} to provide
-    * us a reference after deserialization.
-    * 
-    * @param delegate
-    */
-   public void setPassivatingCache(PassivatingBackingCache<T, SerializationGroupMember<T>> delegate)
-   {
-//      assert delegate != null : "delegate is null";
-//      
-//      this.cache = delegate;
-   }
-
-   @Override
-   public String toString()
-   {
-      return super.toString() + "{id=" + id + ",obj=" + obj + ",groupId=" + groupId + ",group=" + group + "}";
-   }
-   
-   private void writeObject(java.io.ObjectOutputStream out) throws IOException
-   {
-      if (groupId != null)
-      {
-         group = null;
-         obj = null;
-      }
-      out.defaultWriteObject();
-   }
-}

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/GroupedPassivatingUnitTestCase.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/GroupedPassivatingUnitTestCase.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/GroupedPassivatingUnitTestCase.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -61,9 +61,9 @@
       MockClusterMember node0 = cluster.getNode0();
       MockCacheConfig cacheConfig = new MockCacheConfig();
       cacheConfig.setIdleTimeoutSeconds(1);
-      MockXPC sharedXPC = new MockXPC();
-      MockBeanContainer container1 = node0.deployBeanContainer("MockBeanContainer1", null, CacheType.DISTRIBUTED, cacheConfig, sharedXPC);
-      MockBeanContainer container2 = node0.deployBeanContainer("MockBeanContainer2", "MockBeanContainer1", CacheType.DISTRIBUTED, cacheConfig, sharedXPC);
+      MockXPC sharedXPC = new MockXPC("XPCA");
+      MockBeanContainer container1 = node0.deployBeanContainer("MockBeanContainer1", null, CacheType.DISTRIBUTED, cacheConfig, sharedXPC.getName());
+      MockBeanContainer container2 = node0.deployBeanContainer("MockBeanContainer2", "MockBeanContainer1", CacheType.DISTRIBUTED, cacheConfig, sharedXPC.getName());
       
       cluster.getNode0().setTCCL();
       try

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockCluster.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockCluster.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockCluster.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -27,7 +27,6 @@
 import org.jboss.ejb3.test.cache.mock.CacheType;
 import org.jboss.ejb3.test.cache.mock.MockBeanContainer;
 import org.jboss.ejb3.test.cache.mock.MockCacheConfig;
-import org.jboss.ejb3.test.cache.mock.MockXPC;
 import org.jboss.ejb3.test.cache.mock.tm.MockTransactionManager;
 
 /**
@@ -100,13 +99,11 @@
    public MockBeanContainer[] deployBeanContainer(String containerName, String parentContainerName,
          CacheType cacheType, MockCacheConfig cacheConfig, boolean useXPC) throws Exception
    {
-      MockXPC xpc0 = useXPC ? new MockXPC() : null;
-      MockXPC xpc1 = useXPC ? new MockXPC() : null;
-      return deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, xpc0, xpc1);
+      return deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, "xpc0", "xpc1");
    }
    
    public MockBeanContainer[] deployBeanContainer(String containerName, String parentContainerName,
-         CacheType cacheType, MockCacheConfig cacheConfig, MockXPC xpc0, MockXPC xpc1) throws Exception
+         CacheType cacheType, MockCacheConfig cacheConfig, String xpc0, String xpc1) throws Exception
    {
       MockBeanContainer[] result = new MockBeanContainer[2];
       result[0] = node0.deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, xpc0);

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockClusterMember.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockClusterMember.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockClusterMember.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -30,7 +30,6 @@
 import org.jboss.ejb3.test.cache.mock.MockBeanContext;
 import org.jboss.ejb3.test.cache.mock.MockCacheConfig;
 import org.jboss.ejb3.test.cache.mock.MockEjb3System;
-import org.jboss.ejb3.test.cache.mock.MockXPC;
 
 /**
  * @author Brian Stansberry
@@ -117,7 +116,7 @@
 
    @Override
    public MockBeanContainer deployBeanContainer(String containerName, String parentContainerName,
-         CacheType cacheType, MockCacheConfig cacheConfig, MockXPC xpc) throws Exception
+         CacheType cacheType, MockCacheConfig cacheConfig, String xpc) throws Exception
    {
       boolean tcclSet = setTCCL();
       try

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockIntegratedObjectStoreSource.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockIntegratedObjectStoreSource.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/distributed/MockIntegratedObjectStoreSource.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -28,9 +28,9 @@
 import org.jboss.ejb3.cache.CacheItem;
 import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
 import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.SerializationGroup;
+import org.jboss.ejb3.cache.spi.SerializationGroupMember;
 import org.jboss.ejb3.cache.spi.SynchronizationCoordinator;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
 
 /**
  * @author Brian Stansberry
@@ -48,11 +48,11 @@
       this.remoteMap = remoteMap;
    }
    
-   public PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>>  createGroupIntegratedObjectStore(String containerName,
+   public PassivatingIntegratedObjectStore<T, SerializationGroup<T>>  createGroupIntegratedObjectStore(String containerName,
          String cacheConfigName, CacheConfig cacheConfig, TransactionManager transactionManager, SynchronizationCoordinator synchronizationCoordinator)
    {
       String keyBase = "GroupCache-" + containerName;
-      return new MockJBCIntegratedObjectStore<T, SerializationGroupImpl<T>>(localMap, remoteMap, cacheConfig, keyBase, keyBase);
+      return new MockJBCIntegratedObjectStore<T, SerializationGroup<T>>(localMap, remoteMap, cacheConfig, keyBase, keyBase);
    }
 
    public PassivatingIntegratedObjectStore<T, SerializationGroupMember<T>>  createIntegratedObjectStore(String containerName, String cacheConfigName,

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/PassivatingBackingCacheImplUnitTestCase.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/PassivatingBackingCacheImplUnitTestCase.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/PassivatingBackingCacheImplUnitTestCase.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -21,11 +21,13 @@
  */
 package org.jboss.ejb3.test.cache.impl.backing;
 
+import java.util.HashMap;
+
 import junit.framework.TestCase;
 
 import org.jboss.ejb3.cache.impl.TransactionalCache;
 import org.jboss.ejb3.cache.impl.backing.PassivatingBackingCacheImpl;
-import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+import org.jboss.ejb3.cache.impl.backing.SerializationGroupMemberImpl;
 import org.jboss.ejb3.test.cache.mock.CacheType;
 import org.jboss.ejb3.test.cache.mock.MockBeanContainer;
 import org.jboss.ejb3.test.cache.mock.MockBeanContext;
@@ -56,10 +58,10 @@
       MockXPC sharedXPC = new MockXPC();
       MockCacheConfig config = new MockCacheConfig();
       config.setIdleTimeoutSeconds(100);
-      MockBeanContainer container = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC);
+      MockBeanContainer container = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC.getName());
       TransactionalCache cache = (TransactionalCache) container.getCache();
-      PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMember<MockBeanContext>> backingCache = (PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMember<MockBeanContext>>) cache.getBackingCache();
-      SerializationGroupMember<MockBeanContext> obj = backingCache.create(null, null);
+      PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMemberImpl<MockBeanContext>> backingCache = (PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMemberImpl<MockBeanContext>>) cache.getBackingCache();
+      SerializationGroupMemberImpl<MockBeanContext> obj = backingCache.create(null, null, new HashMap<Object, Object>());
       Object key = obj.getId();
       
       backingCache.peek(key);
@@ -90,10 +92,10 @@
       MockXPC sharedXPC = new MockXPC();
       MockCacheConfig config = new MockCacheConfig();
       config.setIdleTimeoutSeconds(100);
-      MockBeanContainer container = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC);
+      MockBeanContainer container = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC.getName());
       TransactionalCache cache = (TransactionalCache) container.getCache();
-      PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMember<MockBeanContext>> backingCache = (PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMember<MockBeanContext>>) cache.getBackingCache();
-      SerializationGroupMember<MockBeanContext> obj = backingCache.create(null, null);
+      PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMemberImpl<MockBeanContext>> backingCache = (PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMemberImpl<MockBeanContext>>) cache.getBackingCache();
+      SerializationGroupMemberImpl<MockBeanContext> obj = backingCache.create(null, null, new HashMap<Object, Object>());
       Object key = obj.getId();
       
       backingCache.get(key);

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/GroupAwareTransactionalCacheUnitTestCase.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/GroupAwareTransactionalCacheUnitTestCase.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/GroupAwareTransactionalCacheUnitTestCase.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -57,7 +57,7 @@
       MockXPC sharedXPC = new MockXPC();
       MockCacheConfig config = new MockCacheConfig();
       config.setIdleTimeoutSeconds(4);
-      MockBeanContainer container = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC);
+      MockBeanContainer container = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC.getName());
       Cache<MockBeanContext> cache = container.getCache();
       
       Object key = cache.create(null, null);
@@ -99,8 +99,8 @@
       MockXPC sharedXPC = new MockXPC();
       MockCacheConfig config = new MockCacheConfig();
       config.setIdleTimeoutSeconds(1);
-      MockBeanContainer container1 = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC);
-      MockBeanContainer container2 = system.deployBeanContainer("MockBeanContainer2", "MockBeanContainer1", CacheType.SIMPLE, config, sharedXPC);
+      MockBeanContainer container1 = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC.getName());
+      MockBeanContainer container2 = system.deployBeanContainer("MockBeanContainer2", "MockBeanContainer1", CacheType.SIMPLE, config, sharedXPC.getName());
       
       log.info("Containers deployed");
       
@@ -172,8 +172,8 @@
       MockXPC sharedXPC = new MockXPC();
       MockCacheConfig config = new MockCacheConfig();
       config.setIdleTimeoutSeconds(1);
-      MockBeanContainer container1 = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC);
-      MockBeanContainer container2 = system.deployBeanContainer("MockBeanContainer2", "MockBeanContainer1", CacheType.SIMPLE, config, sharedXPC);
+      MockBeanContainer container1 = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC.getName());
+      MockBeanContainer container2 = system.deployBeanContainer("MockBeanContainer2", "MockBeanContainer1", CacheType.SIMPLE, config, sharedXPC.getName());
       
       log.info("Containers deployed");
       

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContainer.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContainer.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContainer.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -47,7 +47,7 @@
    private Cache<MockBeanContext> cache;
    private Set<MockBeanContainer> children;
    
-   private MockXPC xpc;
+   private String xpcName;
    
    public MockBeanContainer(String containerName, String cacheFactoryName,
          StatefulCacheFactoryRegistry<MockBeanContext> cacheFactoryRegistry,
@@ -102,17 +102,17 @@
    {
       return children.contains(child);
    }
-   
-   public MockXPC getXPC()
+
+   public String getXPCName()
    {
-      return xpc;
+      return xpcName;
    }
-
-   public void setXPC(MockXPC xpc)
+   
+   public void setXPCName(String name)
    {
-      this.xpc = xpc;
+      this.xpcName = name;
    }
-
+   
    public StatefulObjectFactory<MockBeanContext> getStatefulObjectFactory()
    {
       return objectFactory;

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContext.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContext.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContext.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -23,12 +23,8 @@
 package org.jboss.ejb3.test.cache.mock;
 
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
-import org.jboss.ejb3.cache.Cache;
-import org.jboss.ejb3.cache.SerializationGroup;
-
 /**
  * @author Brian Stansberry
  *
@@ -48,12 +44,14 @@
    private int postReplicateCount;
    private int postActivateCount;
    private Map<String, Object> children;
+   private final Map<Object, Object> sharedState;
    
-   public MockBeanContext(String containerName)
+   public MockBeanContext(String containerName, Map<Object, Object> sharedState)
    {
       super(createId());
       this.containerName = containerName;
       this.children = new HashMap<String, Object>();
+      this.sharedState = sharedState;
    }
    
    public MockBeanContainer getContainer()
@@ -79,30 +77,9 @@
    {
       if (xpc != null)
       {
-         boolean closeIt = true;
-         Cache<MockBeanContext> cache = getContainer().getCache();
-         if (cache.isGroupAware())
-         {
-            SerializationGroup<MockBeanContext> group = cache.getGroup(this);
-            if (group != null)
-            {
-               for(Iterator<MockBeanContext> it = group.iterator(); it.hasNext();)
-               {
-                  MockBeanContext ctx = it.next();
-                  if (ctx != this)
-                  {
-                     if (xpc.equals(ctx.getXPC()))
-                     {
-                        closeIt = false;
-                        break;
-                     }
-                  }
-               }
-            }
-            
-            if (closeIt)
-               xpc.close();
-         }
+         SharedXPC shared = (SharedXPC) sharedState.get(xpc.getName());
+         if (shared.removeSharedUser() == 0 && !xpc.isClosed())
+            xpc.close();
       }
    }
    
@@ -122,15 +99,32 @@
    {
       return postActivateCount;
    }
+   
+   public MockXPC getExtendedPersistenceContext(String id)
+   {      
+      SharedXPC shared = (SharedXPC) sharedState.get(id);
+      return (shared == null ? null : shared.getXPC());
+   }
 
-   public MockXPC getXPC()
+   public void addExtendedPersistenceContext(String id, MockXPC pc)
    {
-      return xpc;
+      if (xpc != null)
+         throw new IllegalStateException("XPC already configured");
+      
+      SharedXPC shared = (SharedXPC) sharedState.get(id);
+      if (shared == null)
+      {
+         shared = new SharedXPC(pc);
+         sharedState.put(id, shared);
+      }
+      
+      shared.addSharedUser();
+      xpc = pc;
    }
-
-   public void setXPC(MockXPC sharedObject)
+   
+   public XPC getXPC()
    {
-      this.xpc = sharedObject;
+      return xpc;
    }
    
    public void preReplicate()

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEjb3System.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEjb3System.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEjb3System.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -115,7 +115,7 @@
                                                 String parentContainerName,
                                                 CacheType cacheType,
                                                 MockCacheConfig cacheConfig,
-                                                MockXPC xpc) throws Exception
+                                                String xpc) throws Exception
    {
       return deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, xpc, true);
    }
@@ -124,12 +124,12 @@
                                                 String parentContainerName,
                                                 CacheType cacheType,
                                                 MockCacheConfig cacheConfig,
-                                                MockXPC xpc,
+                                                String xpc,
                                                 boolean start) throws Exception
    {
       MockBeanContainer parent = (parentContainerName == null) ? null : getMockBeanContainer(parentContainerName);
       MockBeanContainer container = new MockBeanContainer(containerName, cacheType.mapKey(), cacheFactoryRegistry, cacheConfig);
-      container.setXPC(xpc);
+      container.setXPCName(xpc);
       if (parent != null)
          parent.addChild(container);
       if (start)

Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockStatefulObjectFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockStatefulObjectFactory.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockStatefulObjectFactory.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -22,6 +22,8 @@
 
 package org.jboss.ejb3.test.cache.mock;
 
+import java.util.Map;
+
 import org.jboss.ejb3.cache.StatefulObjectFactory;
 
 
@@ -42,11 +44,24 @@
       this.container = container;
    }
    
-   public MockBeanContext create(Class[] initTypes, Object[] initValues)
+   public MockBeanContext create(Class<?>[] initTypes, Object[] initValues, Map<Object, Object> sharedState)
    {
-      MockBeanContext ctx = new MockBeanContext(container.getName());
-      ctx.setXPC(container.getXPC());
+      MockBeanContext ctx = new MockBeanContext(container.getName(), sharedState);
+      if (container.getXPCName() != null)
+      {
+         MockXPC xpc = ctx.getExtendedPersistenceContext(container.getXPCName());
+         if (xpc == null)
+         {
+            xpc = (MockXPC) MockRegistry.get(container.getXPCName());
+         }
+         if (xpc == null)
+         {
+            xpc = new MockXPC(container.getXPCName());
+         }
+         ctx.addExtendedPersistenceContext(container.getXPCName(), xpc);
+      }
       
+      
       // Here we mock creating nested beans
       for (MockBeanContainer childContainer : container.getChildren())
       {

Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java	2008-03-14 14:30:40 UTC (rev 70870)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -1,70 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, 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.ejb3.test.cache.mock;
-
-import java.io.Serializable;
-
-/**
- * A mock extended PersistenceContext.
- * 
- * @author Brian Stansberry
- * @version $Revision$
- */
-public class MockXPC implements Serializable
-{
-   private static final long serialVersionUID = 1L;
-   
-   private boolean closed = false;
-   private MockEntity entity;
-   
-   public MockEntity createEntity()
-   {
-      if (entity != null)
-         throw new IllegalStateException("entity already created");
-      entity = new MockEntity();
-      return entity;
-   }
-   
-   public MockEntity getEntity()
-   {
-      return entity;
-   }
-   
-   public void removeEntity()
-   {
-      if (entity == null)
-         throw new IllegalStateException("no entity to remove");
-      entity = null;
-   }
-   
-   public boolean isClosed()
-   {
-      return closed;
-   }
-   
-   public void close()
-   {
-      closed = true;
-      entity = null;
-   }
-}

Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java	                        (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -0,0 +1,91 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, 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.ejb3.test.cache.mock;
+
+import java.io.Serializable;
+
+/**
+ * A mock extended PersistenceContext.
+ * 
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class MockXPC implements Serializable, XPC
+{
+   public static final String DEFAULT_XPC_NAME = "xpc";
+
+   private static final long serialVersionUID = 1L;
+   
+   private boolean closed = false;
+   private MockEntity entity;
+   private final String name;
+
+   public MockXPC()
+   {
+      this(DEFAULT_XPC_NAME);
+   }
+   
+   public MockXPC(String name)
+   {
+      this.name = name;
+      MockRegistry.put(name, this);
+   }
+   
+   public MockEntity createEntity()
+   {
+      if (entity != null)
+         throw new IllegalStateException("entity already created");
+      entity = new MockEntity();
+      return entity;
+   }
+   
+   public MockEntity getEntity()
+   {
+      return entity;
+   }
+   
+   public void removeEntity()
+   {
+      if (entity == null)
+         throw new IllegalStateException("no entity to remove");
+      entity = null;
+   }
+   
+   public boolean isClosed()
+   {
+      return closed;
+   }
+   
+   public void close()
+   {
+      closed = true;
+      entity = null;
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+   
+   
+}

Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/SharedXPC.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/SharedXPC.java	                        (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/SharedXPC.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -0,0 +1,64 @@
+/*
+ * 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.ejb3.test.cache.mock;
+
+import java.io.Serializable;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class SharedXPC implements Serializable
+{  
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 4637529179827895356L;
+   
+   private final MockXPC xpc;
+   private final AtomicInteger count = new AtomicInteger();
+   
+   /**
+    * Create a new SharedXPCImpl.
+    * 
+    */
+   public SharedXPC(MockXPC xpc)
+   {
+      assert xpc != null : "xpc is null";
+      this.xpc = xpc;
+   }
+
+   public int addSharedUser()
+   {
+      return count.incrementAndGet();
+   }
+
+   public int removeSharedUser()
+   {
+      return count.decrementAndGet();
+   }
+   
+   public MockXPC getXPC()
+   {
+      return xpc;
+   }
+}

Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/XPC.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/XPC.java	                        (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/XPC.java	2008-03-14 15:14:02 UTC (rev 70871)
@@ -0,0 +1,38 @@
+/*
+ * 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.ejb3.test.cache.mock;
+
+import java.io.Serializable;
+
+public interface XPC extends Serializable
+{
+   MockEntity createEntity();
+
+   MockEntity getEntity();
+
+   void removeEntity();
+
+   boolean isClosed();
+
+   void close();
+}
\ No newline at end of file




More information about the jboss-cvs-commits mailing list