[jbosscache-commits] JBoss Cache SVN: r4851 - in core/trunk/src: main/java/org/jboss/cache/buddyreplication and 12 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Dec 13 17:36:59 EST 2007


Author: manik.surtani at jboss.com
Date: 2007-12-13 17:36:59 -0500 (Thu, 13 Dec 2007)
New Revision: 4851

Modified:
   core/trunk/src/main/java/org/jboss/cache/AbstractNode.java
   core/trunk/src/main/java/org/jboss/cache/CacheImpl.java
   core/trunk/src/main/java/org/jboss/cache/NodeFactory.java
   core/trunk/src/main/java/org/jboss/cache/RegionManager.java
   core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
   core/trunk/src/main/java/org/jboss/cache/VersionedNode.java
   core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.java
   core/trunk/src/main/java/org/jboss/cache/factories/ComponentFactory.java
   core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
   core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/MethodDispacherInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/ReplicationInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/UnlockInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
   core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
   core/trunk/src/main/java/org/jboss/cache/invocation/RemoteCacheInvocationDelegate.java
   core/trunk/src/main/java/org/jboss/cache/loader/CacheLoaderManager.java
   core/trunk/src/main/java/org/jboss/cache/marshall/AbstractMarshaller.java
   core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
   core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller210.java
   core/trunk/src/main/java/org/jboss/cache/marshall/InactiveRegionAwareRpcDispatcher.java
   core/trunk/src/main/java/org/jboss/cache/optimistic/WorkspaceNodeImpl.java
   core/trunk/src/test/java/org/jboss/cache/api/NodeAPITest.java
   core/trunk/src/test/java/org/jboss/cache/factories/ComponentRegistryTest.java
   core/trunk/src/test/java/org/jboss/cache/lock/PessimisticLockTest.java
   core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java
   core/trunk/src/test/java/org/jboss/cache/optimistic/CacheTest.java
   core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTest.java
Log:
reduced failure count, improved logging and comments

Modified: core/trunk/src/main/java/org/jboss/cache/AbstractNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/AbstractNode.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/AbstractNode.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -36,7 +36,7 @@
          {
             for (Node<?, ?> child : children.values())
             {
-               ((AbstractNode) child).markAsDeleted(marker, true);
+               ((NodeSPI) child).markAsDeleted(marker, true);
             }
          }
       }

Modified: core/trunk/src/main/java/org/jboss/cache/CacheImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/CacheImpl.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/CacheImpl.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -13,13 +13,14 @@
 import org.jboss.cache.buddyreplication.BuddyNotInitException;
 import org.jboss.cache.buddyreplication.GravitateResult;
 import org.jboss.cache.config.Configuration;
-import org.jboss.cache.config.Configuration.NodeLockingScheme;
 import org.jboss.cache.config.Option;
 import org.jboss.cache.config.RuntimeConfig;
 import org.jboss.cache.factories.ComponentRegistry;
 import org.jboss.cache.factories.InterceptorChainFactory;
+import org.jboss.cache.factories.annotations.ComponentName;
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.interceptors.Interceptor;
+import org.jboss.cache.invocation.NodeInvocationDelegate;
 import org.jboss.cache.invocation.RemoteCacheInvocationDelegate;
 import org.jboss.cache.loader.CacheLoader;
 import org.jboss.cache.loader.CacheLoaderManager;
@@ -218,10 +219,14 @@
       return componentRegistry;
    }
 
+   // NOTE: The RemoteCacheInvocationDelegate is a bit tricky since it is a subclass for CacheInvocationDelegate and hence
+   // also an implementation of CacheSPI.  Components requesting a CacheSPI may inadvertently get a RemoteCacheInvocationDelegate
+   // To work around this, I'm explicitly naming the RCID as a "remoteDelegate".  Perhaps all components should be named.
+
    @Inject
-   private void injectDependencies(Notifier notifier, RegionManager regionManager, TransactionManager transactionManager,
+   private void injectDependencies(Notifier notifier, RegionManager regionManager, TransactionManager transactionManager, Marshaller marshaller,
                                    TransactionTable transactionTable, StateTransferManager stateTransferManager, NodeFactory nodeFactory,
-                                   CacheSPI spi, CacheMessageListener messageListener, RemoteCacheInvocationDelegate remoteDelegate)
+                                   CacheSPI spi, CacheMessageListener messageListener, @ComponentName("remoteDelegate")RemoteCacheInvocationDelegate remoteDelegate)
    {
       this.notifier = notifier;
       this.regionManager = regionManager;
@@ -232,6 +237,7 @@
       this.spi = spi;
       this.messageListener = messageListener;
       this.remoteDelegate = remoteDelegate;
+      this.marshaller = marshaller;
    }
 
    public Configuration getConfiguration()
@@ -549,12 +555,7 @@
 //      if (notifier == null)
 //         notifier = new Notifier(this);
 
-      // create a new root temporarily.
-      NodeSPI tempRoot = nodeFactory.createRootDataNode();
-      // if we don't already have a root or the new (temp) root is of a different class (optimistic vs pessimistic) to
-      // the current root, then we use the new one.  Helps preserve data between cache restarts.
-      if (root == null || !root.getClass().equals(tempRoot.getClass()))
-         root = tempRoot;
+      correctRootNodeType();
 
 //      if (configuration.getCacheLoaderConfig() != null && cacheLoaderManager == null)
 //      {
@@ -582,57 +583,12 @@
 
       //createEvictionPolicy();
 
-      regionManager.setDefaultInactive(configuration.isInactiveOnStartup());
+      // now done inside the regionManager
+      //regionManager.setDefaultInactive(configuration.isInactiveOnStartup());
 
       cacheStatus = CacheStatus.CREATED;
    }
 
-   private void createTransactionManager()
-   {
-      // See if we had a TransactionManager injected into our config
-      this.transactionManager = configuration.getRuntimeConfig().getTransactionManager();
-      if (transactionManager == null)
-      {
-         // Nope. See if we can look it up from JNDI
-         if (this.tm_lookup == null && configuration.getTransactionManagerLookupClass() != null)
-         {
-            try
-            {
-               Class clazz = Thread.currentThread().getContextClassLoader().loadClass(configuration.getTransactionManagerLookupClass());
-               this.tm_lookup = (TransactionManagerLookup) clazz.newInstance();
-            }
-            catch (Exception e)
-            {
-               throw new CacheException("Problems creating the cache", e);
-            }
-         }
-
-         try
-         {
-            if (tm_lookup != null)
-            {
-               transactionManager = tm_lookup.getTransactionManager();
-               configuration.getRuntimeConfig().setTransactionManager(transactionManager);
-            }
-            else
-            {
-               if (configuration.getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC)
-               {
-                  log.fatal("No transaction manager lookup class has been defined. Transactions cannot be used and thus OPTIMISTIC locking cannot be used");
-               }
-               else
-               {
-                  log.info("No transaction manager lookup class has been defined. Transactions cannot be used");
-               }
-            }
-         }
-         catch (Exception e)
-         {
-            log.debug("failed looking up TransactionManager, will not use transactions", e);
-         }
-      }
-   }
-
    protected boolean shouldFetchStateOnStartup()
    {
       boolean loaderFetch = cacheLoaderManager != null && cacheLoaderManager.isFetchPersistentState();
@@ -640,6 +596,22 @@
    }
 
    /**
+    * Creates a new root node if one does not exist, or if the existing one does not match the type according to the configuration.
+    */
+   private void correctRootNodeType()
+   {
+      // create a new root temporarily.
+      NodeSPI tempRoot = nodeFactory.createRootDataNode();
+      // if we don't already have a root or the new (temp) root is of a different class (optimistic vs pessimistic) to
+      // the current root, then we use the new one.
+
+      Class currentRootType = root == null ? null : ((NodeInvocationDelegate) root).getDelegationTarget().getClass();
+      Class tempRootType = ((NodeInvocationDelegate) tempRoot).getDelegationTarget().getClass();
+
+      if (!tempRootType.equals(currentRootType)) root = tempRoot;
+   }
+
+   /**
     * Lifecyle method.
     *
     * @throws CacheException
@@ -678,8 +650,10 @@
       // re-wire all dependencies in case stuff has changed since the cache was created?
       // TODO: Do we really need to nuke old deps?  :/
       CacheSPI spi = componentRegistry.getComponent(CacheSPI.class);
-      componentRegistry.reset();
 
+      // remove the Interceptor.class component though, since it may pertain to an old config
+      componentRegistry.unregisterComponent(Interceptor.class);
+
       componentRegistry.registerComponent(configuration);
       componentRegistry.registerComponent(this);
       componentRegistry.registerComponent(CacheSPI.class, spi);
@@ -693,22 +667,19 @@
       // start all internal components
       componentRegistry.startComponents();
 
-      // create a new root temporarily.
-      NodeSPI tempRoot = nodeFactory.createRootDataNode();
-      // if we don't already have a root or the new (temp) root is of a different class (optimistic vs pessimistic) to
-      // the current root, then we use the new one.  Helps preserve data between cache restarts.
-      if (root == null || !root.getClass().equals(tempRoot.getClass()))
-         root = tempRoot;
+      correctRootNodeType();
 
 //      createTransactionManager();
 
       // cache loaders should be initialised *before* any state transfers take place to prevent
       // exceptions involving cache loaders not being started. - Manik
       // create cache loader
-      if (cacheLoaderManager != null)
-      {
-         cacheLoaderManager.startCacheLoader();
-      }
+
+      // now done in the CLM
+//      if (cacheLoaderManager != null)
+//      {
+//         cacheLoaderManager.startCacheLoader();
+//      }
       // now that we have a TM we can init the interceptor chain
 //      InterceptorChainFactory.getInstance().initialiseInterceptors(interceptor_chain, this);
 
@@ -939,12 +910,14 @@
    {
       cacheStatus = CacheStatus.STOPPING;
 
+      componentRegistry.stopComponents();
+
       // before closing the channel stop the buddy manager
-      if (buddyManager != null && buddyManager.isEnabled())
-      {
-         log.debug("stop(): stopping buddy manager");
-         buddyManager.stop();
-      }
+//      if (buddyManager != null && buddyManager.isEnabled())
+//      {
+//         log.debug("stop(): stopping buddy manager");
+//         buddyManager.stop();
+//      }
 
       if (channel != null)
       {
@@ -975,13 +948,15 @@
          repl_queue.stop();
       }
 
-      if (cacheLoaderManager != null)
-      {
-         log.debug("stop(): stopping cache loader manager");
-         cacheLoaderManager.stopCacheLoader();
-      }
+      // now done in the CLM
+//      if (cacheLoaderManager != null)
+//      {
+//         log.debug("stop(): stopping cache loader manager");
+//         cacheLoaderManager.stopCacheLoader();
+//      }
 
-      if (regionManager.isUsingEvictions()) regionManager.stopEvictionThread();
+      // now done in the region manager
+//      if (regionManager.isUsingEvictions()) regionManager.stopEvictionThread();
 
       if (notifier != null)
       {
@@ -2659,7 +2634,7 @@
     */
    public void invalidate(Fqn fqn, DataVersion versionToInvalidate)
    {
-      Node node = get(fqn); // force interceptor chain, load if necessary from cache loader.
+      Node node = spi.getNode(fqn); // force interceptor chain, load if necessary from cache loader.
 
       if (node == null)
       {
@@ -2684,7 +2659,7 @@
                {
                   suspended = getTransactionManager().suspend();
                }
-               put(fqn, m);
+               spi.put(fqn, m);
                if (suspended != null) getTransactionManager().resume(suspended);
                ic.getOptionOverrides().setCacheModeLocal(origCacheModeLocal);
             }
@@ -3757,6 +3732,8 @@
 
       disp.setRequestMarshaller(marshaller);
       disp.setResponseMarshaller(marshaller);
+
+      if (log.isTraceEnabled()) log.trace("Started with RpcDispatcher " + disp);
    }
 
    private JChannel getMultiplexerChannel() throws CacheException

Modified: core/trunk/src/main/java/org/jboss/cache/NodeFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/NodeFactory.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/NodeFactory.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -92,6 +92,7 @@
       un.setDataLoaded(false);
       NodeInvocationDelegate<K, V> nid = new NodeInvocationDelegate(un);
       componentRegistry.wireDependencies(nid);
+      componentRegistry.wireDependencies(un);
       // back ref
       un.setDelegate(nid);
       return nid;

Modified: core/trunk/src/main/java/org/jboss/cache/RegionManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RegionManager.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/RegionManager.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -13,6 +13,7 @@
 import org.jboss.cache.eviction.RegionNameConflictException;
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.factories.annotations.Stop;
 import org.jboss.cache.lock.NodeLock;
 import org.jgroups.Address;
 
@@ -39,7 +40,7 @@
     * eviction settings bound under this 'default' Fqn is appplied to {@link org.jboss.cache.Fqn#ROOT} internally so
     * any region that is not explicitly defined comes under the settings defined for this default.
     */
-   public static final Fqn DEFAULT_REGION = new Fqn("_default_");
+   public static final Fqn<?> DEFAULT_REGION = new Fqn<String>("_default_");
 
    /**
     * A registry of regions that have been defined.
@@ -64,6 +65,7 @@
       Region r = new RegionImpl(Fqn.ROOT, this);
       r.registerContextClassLoader(Thread.currentThread().getContextClassLoader() == null ? this.getClass().getClassLoader() : Thread.currentThread().getContextClassLoader());
       r.setActive(true);
+      regionsRegistry.put(Fqn.ROOT, r);
    }
 
    @Inject
@@ -74,8 +76,9 @@
    }
 
    @Start
-   protected void createEvictionPolicy()
+   protected void start()
    {
+      log.trace("Starting region manager");
       if (configuration.getEvictionConfig() != null
             && configuration.getEvictionConfig().isValidConfig())
       {
@@ -87,10 +90,20 @@
          setUsingEvictions(false);
          log.debug("Not using an EvictionPolicy");
       }
+
+      setDefaultInactive(configuration.isInactiveOnStartup());
+      if (log.isTraceEnabled())
+         log.trace("Finished region manager.  Default region is " + regionsRegistry.get(Fqn.ROOT));
    }
 
+   @Stop
+   protected void stop()
+   {
+      if (isUsingEvictions()) stopEvictionThread();
+   }
+
    /**
-    * Returns true if evictions are being processed.
+    * @return true if evictions are being processed.
     */
    public boolean isUsingEvictions()
    {
@@ -98,7 +111,7 @@
    }
 
    /**
-    * Returns true if replication is by default inactive for new {@link Region}s.
+    * @return true if replication is by default inactive for new {@link Region}s.
     */
    public boolean isDefaultInactive()
    {
@@ -161,6 +174,7 @@
     */
    public Region getRegion(Fqn fqn, Region.Type type, boolean createIfAbsent)
    {
+      if (log.isTraceEnabled()) log.trace("Contents of RegionsRegistry: " + regionsRegistry);
       Fqn fqnToUse = fqn;
       if (DEFAULT_REGION.equals(fqnToUse)) fqnToUse = Fqn.ROOT;
       // first see if a region for this specific Fqn exists
@@ -201,6 +215,7 @@
          if (regionsRegistry.containsKey(nextFqn))
          {
             Region r = regionsRegistry.get(nextFqn);
+            if (log.isTraceEnabled()) log.trace("Trying next region " + nextFqn + " and got " + r);
 
             // this is a very poor way of telling whether a region is a marshalling one or an eviction one.  :-(
             // mandates that class loaders be registered for marshalling regions.
@@ -219,6 +234,8 @@
       if ((nextBestThing == null || nextBestThing.getFqn().isRoot() && !regionsRegistry.containsKey(Fqn.ROOT))
             && type == EVICTION)
       {
+         if (log.isTraceEnabled())
+            log.trace("Next best region is " + nextBestThing + ".  RegionsRegistry contains a default? " + regionsRegistry.containsKey(Fqn.ROOT) + " Region type requested = " + type);
          throw new RuntimeException("No default eviction region defined!");
       }
 

Modified: core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -30,7 +30,7 @@
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 2.0.0
  */
-public class UnversionedNode<K, V> extends AbstractNode<K, V>// implements NodeSPI<K, V>
+public class UnversionedNode<K, V> extends AbstractNode<K, V>
 {
 
    /**
@@ -41,7 +41,7 @@
    /**
     * Debug log.
     */
-   private static Log log = LogFactory.getLog(UnversionedNode.class);
+   protected static Log log = LogFactory.getLog(UnversionedNode.class);
 
    /**
     * True if all children have been loaded. This is set when CacheImpl.getChildrenNames() is called.

Modified: core/trunk/src/main/java/org/jboss/cache/VersionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/VersionedNode.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/VersionedNode.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -6,6 +6,7 @@
  */
 package org.jboss.cache;
 
+import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.optimistic.DataVersion;
 import org.jboss.cache.optimistic.DefaultDataVersion;
 
@@ -26,7 +27,7 @@
 {
    private static final String DATA_VERSION_INTERNAL_KEY = "_JBOSS_INTERNAL_OPTIMISTIC_DATA_VERSION";
    private DataVersion version;
-   
+
    /**
     * Although this object has a reference to the CacheImpl, the optimistic
     * node is actually disconnected from the CacheImpl itself.
@@ -40,6 +41,8 @@
       if (parent == null && !fqn.isRoot()) throw new NullPointerException("parent");
       this.parent = parent;
       if (this.version == null) this.version = DefaultDataVersion.ZERO;
+
+      log = LogFactory.getLog(VersionedNode.class);
    }
 
    /**

Modified: core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyManager.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -18,6 +18,7 @@
 import org.jboss.cache.config.BuddyReplicationConfig.BuddyLocatorConfig;
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.Stop;
 import org.jboss.cache.lock.TimeoutException;
 import org.jboss.cache.marshall.MethodCall;
 import org.jboss.cache.marshall.MethodCallFactory;
@@ -215,24 +216,29 @@
    /**
     * Stops the buddy manager and the related async thread.
     */
+   @Stop
    public void stop()
    {
-      // unregister the viewChangeListener
-      if (cache != null) cache.removeCacheListener(viewChangeListener);
-      try
+      if (config.isEnabled())
       {
-         queue.clear();
-         queue.put(STOP_NOTIFIER);
+         log.debug("Stopping BuddyManager");
+         // unregister the viewChangeListener
+         if (cache != null) cache.removeCacheListener(viewChangeListener);
+         try
+         {
+            queue.clear();
+            queue.put(STOP_NOTIFIER);
+         }
+         catch (InterruptedException ie)
+         {
+            // do nothing - we're stopping anyway
+         }
       }
-      catch (InterruptedException ie)
-      {
-         // do nothing - we're stopping anyway
-      }
    }
 
    public void init() throws CacheException
    {
-      log.debug("Starting buddy manager");
+      log.debug("Starting BuddyManager");
       buddyGroup = new BuddyGroup();
       buddyGroup.setDataOwner(cache.getLocalAddress());
       buddyGroup.setGroupName(getGroupNameFromAddress(cache.getLocalAddress()));

Modified: core/trunk/src/main/java/org/jboss/cache/factories/ComponentFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/ComponentFactory.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/factories/ComponentFactory.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -35,18 +35,11 @@
    /**
     * Constructs a component.
     *
-    * @param componentName     optional, if the ComponentName annotation is used with the parameter, it's value is passed in here for the implementing factory to use.
-    * @param componentType     type of component
-    * @param configuration     configuration to use
-    * @param componentRegistry component registry to use
+    * @param componentName optional, if the ComponentName annotation is used with the parameter, it's value is passed in here for the implementing factory to use.
+    * @param componentType type of component
     * @return a component
     */
    protected abstract <T> T construct(String componentName, Class<T> componentType);
-//   {
-//      // not making this method abstract since it is valid that classes extend ComponentFactory for the wiring and injection
-//      // but not for component creation.
-//      throw new UnsupportedOperationException("Meant to be overridden!");
-//   }
 
    protected void assertTypeConstructable(Class requestedType, Class... ableToConstruct)
    {

Modified: core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -11,7 +11,6 @@
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.Start;
 import org.jboss.cache.factories.annotations.Stop;
-import org.jboss.cache.interceptors.Interceptor;
 import org.jboss.cache.util.BeanUtils;
 
 import java.lang.annotation.Annotation;
@@ -102,6 +101,7 @@
     * @param c type to be able to assign component to.
     * @return component, if found, or a null otherwise.
     */
+   @SuppressWarnings("unchecked")
    public <T> T getComponent(Class<T> c)
    {
       if (c == null)
@@ -110,7 +110,7 @@
          return null;
       }
 
-      if (log.isTraceEnabled()) log.trace("Scanning registry for an instance that can be assigned to class " + c);
+      //if (log.isTraceEnabled()) log.trace("Scanning registry for an instance that can be assigned to class " + c);
       T component = (T) registry.get(c);
 
       if (component == null)
@@ -136,9 +136,10 @@
     * @param c type to be able to assign component to.
     * @return component, if found, or a null otherwise.
     */
+   @SuppressWarnings("unchecked")
    public <T> T getComponent(String name, Class<T> c)
    {
-      T component = (T) registry.get(c);
+      T component = (T) registry.get(name);
       if (component == null) return null;
       if (c.isAssignableFrom(component.getClass())) return component;
       else
@@ -196,8 +197,7 @@
    @SuppressWarnings("unchecked")
    private <T> T getFromConfiguration(Class<T> componentClass)
    {
-      if (log.isDebugEnabled())
-         log.debug("Looking in configuration for an instance of " + componentClass + " that may have been injected from an external source.");
+      //if (log.isDebugEnabled()) log.debug("Looking in configuration for an instance of " + componentClass + " that may have been injected from an external source.");
       Method getter = BeanUtils.getterMethod(Configuration.class, componentClass);
       T returnValue = null;
 
@@ -246,23 +246,9 @@
       // make sure we work off a copy of the values set since wireDependencies may add components to the registry
       // and this may otherwise end up in a CME.
 
-      Set components = new HashSet(registry.values());
+      Set<Object> components = new HashSet<Object>(registry.values());
 
-      for (Object component : components)
-      {
-         wireDependencies(component);
-         if (component instanceof Interceptor)
-         {
-            // special behaviour - need to wire for all chained interceptors
-            Interceptor i = (Interceptor) component;
-            Interceptor next = i.getNext();
-            if (next != null)
-            {
-               wireDependencies(next);
-               next = next.getNext();
-            }
-         }
-      }
+      for (Object component : components) wireDependencies(component);
    }
 
    /**
@@ -292,23 +278,21 @@
     * as needed based on the Configuration passed in if these additional components don't exist in the
     * {@link ComponentRegistry}.
     *
-    * @param target        object to wire
-    * @param configuration Configuration object with knowledge of what components to create and how to create them
+    * @param target object to wire
     * @throws ConfigurationException if there is a problem wiring the instance
     */
    public void wireDependencies(Object target) throws ConfigurationException
    {
-      if (log.isTraceEnabled()) log.trace("Inspecting class " + target.getClass());
+      //if (log.isTraceEnabled()) log.trace("Inspecting class " + target.getClass());
       try
       {
          List<Method> methods = getAllMethods(target.getClass(), Inject.class);
-         if (log.isTraceEnabled())
-            log.trace("Found method set containing " + methods.size() + " methods that need injection: " + methods);
+         //if (log.isTraceEnabled()) log.trace("Found method set containing " + methods.size() + " methods that need injection: " + methods);
 
          // search for anything we need to inject
          for (Method method : methods)
          {
-            if (log.isTraceEnabled()) log.trace("Method " + method + " needs some other components injected!");
+            //if (log.isTraceEnabled()) log.trace("Method " + method + " needs some other components injected!");
             performInjection(method, target);
          }
       }
@@ -322,9 +306,8 @@
     * Looks through the parameter list of the given method, attempts to locate parameters that fit the types that may
     * exist in the {@link ComponentRegistry}, and then calls the method on the target object with the necessary parameters.
     *
-    * @param method        Method to call
-    * @param target        Instance on which to call the method
-    * @param configuration contains details of how to create components if they do not already exist.
+    * @param method Method to call
+    * @param target Instance on which to call the method
     * @throws IllegalAccessException if the method cannot be called
     * @throws java.lang.reflect.InvocationTargetException
     *                                if the method cannot be called
@@ -558,6 +541,7 @@
          {
             try
             {
+               m.setAccessible(true);
                m.invoke(component);
             }
             catch (Exception e)

Modified: core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -70,9 +70,20 @@
 
    private Interceptor createInterceptor(Class<? extends Interceptor> clazz) throws IllegalAccessException, InstantiationException
    {
-      Interceptor i = clazz.newInstance();
-      componentRegistry.wireDependencies(i);
-      i.setStatisticsEnabled(configuration.getExposeManagementStatistics());
+      Interceptor i = componentRegistry.getComponent(clazz.getName(), clazz);
+      if (i == null)
+      {
+         i = clazz.newInstance();
+         componentRegistry.wireDependencies(i);
+         // add this interceptor as a NAMED component into the registry
+         componentRegistry.registerComponent(clazz.getName(), i);
+      }
+      else
+      {
+         // wipe next/last chaining!!
+         i.setLast(null);
+         i.setNext(null);
+      }
       return i;
    }
 

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -1,8 +1,15 @@
 package org.jboss.cache.interceptors;
 
-import org.jboss.cache.*;
+import org.apache.commons.logging.Log;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.config.Configuration;
 import static org.jboss.cache.config.Configuration.CacheMode;
 import org.jboss.cache.loader.CacheLoader;
+import org.jboss.cache.loader.CacheLoaderManager;
 import org.jboss.cache.lock.NodeLock;
 import org.jboss.cache.marshall.MethodCall;
 import org.jboss.cache.marshall.MethodCallFactory;
@@ -10,7 +17,6 @@
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jboss.cache.transaction.TransactionEntry;
 import org.jboss.cache.transaction.TransactionTable;
-import org.apache.commons.logging.Log;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -32,6 +38,7 @@
    private TransactionTable txTable = null;
    protected boolean isActivation = false;
    protected CacheLoader loader;
+   protected CacheLoaderManager clm;
    protected boolean usingOptimisticInvalidation = false;
 
    /**
@@ -46,15 +53,21 @@
       return log;
    }
 
-   public void setCache(CacheSPI cache)
+   protected void injectDependencies(TransactionTable txTable, CacheLoaderManager clm, Configuration configuration)
    {
-      super.setCache(cache);
-      txTable = cache.getTransactionTable();
-      this.loader = cache.getCacheLoaderManager().getCacheLoader();
-      CacheMode mode = cache.getConfiguration().getCacheMode();
-      usingOptimisticInvalidation = cache.getConfiguration().isNodeLockingOptimistic() && mode.isInvalidation();
+      this.txTable = txTable;
+      this.clm = clm;
+      CacheMode mode = configuration.getCacheMode();
+      usingOptimisticInvalidation = configuration.isNodeLockingOptimistic() && mode.isInvalidation();
    }
 
+   public Object invoke(InvocationContext ctx) throws Throwable
+   {
+      if (loader == null) loader = clm.getCacheLoader();
+      return super.invoke(ctx);
+   }
+
+
    protected Object handlePutDataEraseMethod(InvocationContext ctx, GlobalTransaction gt, Fqn fqn, Map newData, boolean createUndoOps, boolean eraseContents) throws Throwable
    {
       if (fqn != null)
@@ -428,7 +441,7 @@
       if (configuration.isNodeLockingOptimistic()) return;
 
       MethodCall m = MethodCallFactory.create(MethodDeclarations.lockMethodLocal,
-              fqn, lock_type, recursive);
+            fqn, lock_type, recursive);
 
       // hacky
       cache.getInterceptorChain().get(0).invoke(InvocationContext.fromMethodCall(m));
@@ -470,7 +483,7 @@
       for (MethodCall m : entry.getCacheLoaderModifications())
       {
          if (m.getMethodId() == MethodDeclarations.removeNodeMethodLocal_id
-                 && fqn.isChildOrEquals((Fqn) m.getArgs()[1]))
+               && fqn.isChildOrEquals((Fqn) m.getArgs()[1]))
          {
             return true;
          }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -45,6 +45,7 @@
    @Inject
    void setRegionManager(RegionManager regionManager)
    {
+      log.trace("Having region manager " + regionManager + " injected.");
       this.regionManager = regionManager;
    }
 

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -73,6 +73,7 @@
    @Start
    private void start()
    {
+      setStatisticsEnabled(configuration.getExposeManagementStatistics());
       // for backward compatibility, this must only be done when the cache starts.
       setCache(cache);
    }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/MethodDispacherInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/MethodDispacherInterceptor.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/MethodDispacherInterceptor.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -24,7 +24,7 @@
  *    - the parameters of the hendler methods are passes in strongly typed, rather than as an array of Objects
  * </pre>
  * This interceptor acts as a switch that delegates method calls to handlers/methods.
- *
+ * <p/>
  * Implementation notes:
  * Current implementation checks to see the methods that are overwritten and does only perform calls to those methods.
  * This is for avoiding the casts needed to build parameter list. If a non overwritten method is invoked,
@@ -47,7 +47,7 @@
       processOverwritternMethods();
    }
 
-    /**
+   /**
     * Acts like a 'switch case' that delegates the call to the appropriate method.
     */
    public Object invoke(InvocationContext ctx) throws Throwable
@@ -63,12 +63,13 @@
       MethodCall m = ctx.getMethodCall();
       if (!overwrittenMethods.contains(m.getMethodId()))
       {
+         log.trace("Not registered for any handlers, passing up the chain.");
          return nextInterceptor(ctx);
       }
       Object[] args = m.getArgs();
       Object result;
       switch (m.getMethodId())
-         {
+      {
          case MethodDeclarations.putDataEraseMethodLocal_id:
             result = handlePutDataEraseMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], (Map) args[2], (Boolean) args[3], (Boolean) args[4]);
             break;
@@ -124,43 +125,43 @@
             result = handleCommitMethod(ctx, (GlobalTransaction) args[0]);
             break;
          case MethodDeclarations.optimisticPrepareMethod_id:
-            result = handleOptimisticPrepareMethod(ctx, (GlobalTransaction) args[0], (List)args[1],(Map)args[2], (Address)args[3], (Boolean)args[4]);
+            result = handleOptimisticPrepareMethod(ctx, (GlobalTransaction) args[0], (List) args[1], (Map) args[2], (Address) args[3], (Boolean) args[4]);
             break;
          case MethodDeclarations.prepareMethod_id:
-            result = handlePrepareMethod(ctx, (GlobalTransaction) args[0], (List)args[1], (Address)args[2], (Boolean)args[3]);
+            result = handlePrepareMethod(ctx, (GlobalTransaction) args[0], (List) args[1], (Address) args[2], (Boolean) args[3]);
             break;
          case MethodDeclarations.evictNodeMethodLocal_id:
-            result = handleEvictMethod(ctx, (Fqn)args[0]);
+            result = handleEvictMethod(ctx, (Fqn) args[0]);
             break;
          case MethodDeclarations.evictVersionedNodeMethodLocal_id:
-            result = handleEvictVersionedNodeMethod(ctx, (Fqn)args[0], (DataVersion)args[1]);
+            result = handleEvictVersionedNodeMethod(ctx, (Fqn) args[0], (DataVersion) args[1]);
             break;
          case MethodDeclarations.existsMethod_id:
-            result = handleExistsMethod(ctx, (Fqn)args[0]);
+            result = handleExistsMethod(ctx, (Fqn) args[0]);
             break;
          case MethodDeclarations.putDataEraseVersionedMethodLocal_id:
-            result = handlePutDataEraseVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn)args[1], (Map)args[2], (Boolean)args[3], (Boolean)args[4], (DataVersion)args[5]);
+            result = handlePutDataEraseVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], (Map) args[2], (Boolean) args[3], (Boolean) args[4], (DataVersion) args[5]);
             break;
          case MethodDeclarations.putDataVersionedMethodLocal_id:
-            result = handlePutDataVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn)args[1], (Map)args[2], (Boolean)args[3], (DataVersion)args[4]);
+            result = handlePutDataVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], (Map) args[2], (Boolean) args[3], (DataVersion) args[4]);
             break;
          case MethodDeclarations.putKeyValVersionedMethodLocal_id:
-            result = handlePutKeyValueVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn)args[1], args[2], args[3], (Boolean)args[4], (DataVersion)args[5]);
+            result = handlePutKeyValueVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], args[2], args[3], (Boolean) args[4], (DataVersion) args[5]);
             break;
          case MethodDeclarations.putForExternalReadVersionedMethodLocal_id:
-            result = handlePutForExternalReadVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn)args[1], args[2], args[3], (DataVersion)args[5]);
+            result = handlePutForExternalReadVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], args[2], args[3], (DataVersion) args[5]);
             break;
          case MethodDeclarations.dataGravitationCleanupMethod_id:
-            result = handleDataGravitationCleanupMethod(ctx, (GlobalTransaction) args[0], (Fqn)args[1], (Fqn)args[2]);
+            result = handleDataGravitationCleanupMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], (Fqn) args[2]);
             break;
          case MethodDeclarations.removeNodeVersionedMethodLocal_id:
-            result = handleRemoveNodeVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn)args[1], (Boolean)args[2], (DataVersion)args[3]);
+            result = handleRemoveNodeVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], (Boolean) args[2], (DataVersion) args[3]);
             break;
          case MethodDeclarations.removeKeyVersionedMethodLocal_id:
-            result = handleRemoveKeyVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn)args[1], args[2], (Boolean)args[3], (DataVersion)args[4]);
+            result = handleRemoveKeyVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], args[2], (Boolean) args[3], (DataVersion) args[4]);
             break;
          case MethodDeclarations.removeDataVersionedMethodLocal_id:
-            result = handleRemoveDataVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn)args[1], (Boolean)args[2], (DataVersion)args[3]);
+            result = handleRemoveDataVersionedMethod(ctx, (GlobalTransaction) args[0], (Fqn) args[1], (Boolean) args[2], (DataVersion) args[3]);
             break;
          case MethodDeclarations.blockChannelMethodLocal_id:
             result = handleBlockChannelMethod(ctx);
@@ -169,15 +170,15 @@
             result = handleUnblockChannelMethod(ctx);
             break;
          case MethodDeclarations.lockMethodLocal_id:
-            result = handleLockMethod(ctx, (Fqn)args[0], (NodeLock.LockType)args[1], (Boolean)args[2]);
+            result = handleLockMethod(ctx, (Fqn) args[0], (NodeLock.LockType) args[1], (Boolean) args[2]);
             break;
          default:
             return nextInterceptor(ctx);
-         }
+      }
       return result;
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_lock(org.jboss.cache.Fqn, org.jboss.cache.lock.NodeLock.LockType, boolean)}
     */
    protected Object handleLockMethod(InvocationContext ctx, Fqn fqn, NodeLock.LockType lockType, boolean recursive) throws Throwable
@@ -185,7 +186,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_unblock()}
     */
    protected Object handleUnblockChannelMethod(InvocationContext ctx) throws Throwable
@@ -193,7 +194,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_block()}
     */
    protected Object handleBlockChannelMethod(InvocationContext ctx) throws Throwable
@@ -201,7 +202,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_removeData(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, boolean, org.jboss.cache.optimistic.DataVersion)}
     */
    protected Object handleRemoveDataVersionedMethod(InvocationContext ctx, GlobalTransaction gtx, Fqn fqn, boolean createUndoOps, DataVersion dv) throws Throwable
@@ -209,7 +210,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_remove(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, Object, boolean, org.jboss.cache.optimistic.DataVersion)}
     */
    protected Object handleRemoveKeyVersionedMethod(InvocationContext ctx, GlobalTransaction gtx, Fqn fqn, Object key, boolean createUndoOps, DataVersion dv) throws Throwable
@@ -217,7 +218,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_remove(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, boolean, org.jboss.cache.optimistic.DataVersion)}
     */
    protected Object handleRemoveNodeVersionedMethod(InvocationContext ctx, GlobalTransaction gtx, Fqn fqn, boolean createUndoOps, DataVersion dv) throws Throwable
@@ -225,7 +226,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_dataGravitationCleanup(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, org.jboss.cache.Fqn)}
     */
    protected Object handleDataGravitationCleanupMethod(InvocationContext ctx, GlobalTransaction globalTransaction, Fqn primary, Fqn backup) throws Throwable
@@ -233,7 +234,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_putForExternalRead(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, Object, Object, org.jboss.cache.optimistic.DataVersion)}
     */
    protected Object handlePutForExternalReadVersionedMethod(InvocationContext ctx, GlobalTransaction gtx, Fqn fqn, Object key, Object value, DataVersion dv) throws Throwable
@@ -241,7 +242,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_put(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, Object, Object, boolean, org.jboss.cache.optimistic.DataVersion)}
     */
    protected Object handlePutKeyValueVersionedMethod(InvocationContext ctx, GlobalTransaction gtx, Fqn fqn, Object key, Object value, boolean createUndoOps, DataVersion dv) throws Throwable
@@ -249,7 +250,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_put(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, java.util.Map, boolean, org.jboss.cache.optimistic.DataVersion)}
     */
    protected Object handlePutDataVersionedMethod(InvocationContext ctx, GlobalTransaction globalTransaction, Fqn fqn, Map map, Boolean createUndoOps, DataVersion dataVersion) throws Throwable
@@ -257,7 +258,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_put(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, java.util.Map, boolean, boolean, org.jboss.cache.optimistic.DataVersion)}
     */
    protected Object handlePutDataEraseVersionedMethod(InvocationContext ctx, GlobalTransaction gtx, Fqn fqn, Map data, boolean createUndoOps, boolean eraseContent, DataVersion dv) throws Throwable
@@ -265,7 +266,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#exists(String)}
     */
    protected Object handleExistsMethod(InvocationContext ctx, Fqn fqn) throws Throwable
@@ -273,12 +274,12 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * used for logging various steps. if null is returned than nothing is logged.
     */
    protected abstract Log getLog();
 
-    /**
+   /**
     * Each interceptor should extend this if it does not need any processing for current call.
     * An sample usage would be: this interceptor is only interested if thre is one transaction going on. If so all
     * handleXYZ would know that we have a transaction going and would not check its state.
@@ -288,7 +289,7 @@
       return false;
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_evict(org.jboss.cache.Fqn, org.jboss.cache.optimistic.DataVersion)}
     */
    protected Object handleEvictVersionedNodeMethod(InvocationContext ctx, Fqn fqn, DataVersion dataVersion) throws Throwable
@@ -296,7 +297,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#evict(org.jboss.cache.Fqn)}
     */
    protected Object handleEvictMethod(InvocationContext ctx, Fqn fqn) throws Throwable
@@ -304,7 +305,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#prepare(org.jboss.cache.transaction.GlobalTransaction, java.util.List, org.jgroups.Address, boolean)}
     */
    protected Object handlePrepareMethod(InvocationContext ctx, GlobalTransaction gtx, List modification, Address coordinator, boolean onePhaseCommit) throws Throwable
@@ -312,7 +313,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#optimisticPrepare(org.jboss.cache.transaction.GlobalTransaction, java.util.List, java.util.Map, org.jgroups.Address, boolean)}
     */
    protected Object handleOptimisticPrepareMethod(InvocationContext ctx, GlobalTransaction gtx, List modifications, Map data, Address address, boolean onePhaseCommit) throws Throwable
@@ -320,7 +321,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#commit(org.jboss.cache.transaction.GlobalTransaction)}
     */
    protected Object handleCommitMethod(InvocationContext ctx, GlobalTransaction globalTransaction) throws Throwable
@@ -328,7 +329,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_removeData(org.jboss.cache.transaction.GlobalTransaction, Fqn, boolean)}
     */
    protected Object handleRemoveDataMethod(InvocationContext ctx, GlobalTransaction tx, Fqn fqn, boolean createUndoOps) throws Throwable
@@ -336,7 +337,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_remove(org.jboss.cache.transaction.GlobalTransaction, String, Object, boolean)}
     */
    protected Object handleRemoveKeyMethod(InvocationContext ctx, GlobalTransaction tx, Fqn fqn, Object key, boolean createUndoOps) throws Throwable
@@ -344,7 +345,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_remove(org.jboss.cache.transaction.GlobalTransaction, String, boolean)}
     */
    protected Object handleRemoveNodeMethod(InvocationContext ctx, GlobalTransaction tx, Fqn fqn, boolean createUndoOps) throws Throwable
@@ -353,7 +354,7 @@
    }
 
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#rollback(org.jboss.cache.transaction.GlobalTransaction)}
     */
    protected Object handleRollbackMethod(InvocationContext ctx, GlobalTransaction globalTransaction) throws Throwable
@@ -361,7 +362,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_getData(org.jboss.cache.Fqn)}
     */
    protected Object handleGetDataMapMethod(InvocationContext ctx, Fqn fqn) throws Throwable
@@ -369,7 +370,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#getKeys(Fqn)}
     */
    protected Object handleGetKeysMethod(InvocationContext ctx, Fqn fqn) throws Throwable
@@ -377,7 +378,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_print(org.jboss.cache.Fqn)}
     */
    protected Object handlePrintMethod(InvocationContext ctx, Fqn fqn) throws Throwable
@@ -385,7 +386,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_releaseAllLocks(org.jboss.cache.Fqn)}
     */
    protected Object handleReleaseAllLocksMethod(InvocationContext ctx, Fqn fqn) throws Throwable
@@ -393,7 +394,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_getChildrenNames(org.jboss.cache.Fqn)}
     */
    protected Object handleGetChildrenNamesMethod(InvocationContext ctx, Fqn fqn) throws Throwable
@@ -401,7 +402,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_get(org.jboss.cache.Fqn)}
     */
    protected Object handleGetNodeMethod(InvocationContext ctx, Fqn fqn) throws Throwable
@@ -409,7 +410,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_get(org.jboss.cache.Fqn, Object, boolean)}
     */
    protected Object handleGetKeyValueMethod(InvocationContext ctx, Fqn fqn, Object key, boolean sendNodeEvent) throws Throwable
@@ -417,7 +418,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_addChild(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, Object, org.jboss.cache.Node, boolean)}
     */
    protected Object handleAddChildMethod(InvocationContext ctx, GlobalTransaction tx, Fqn parentFqn, Object childName, Node cn, boolean createUndoOps) throws Throwable
@@ -426,7 +427,7 @@
    }
 
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_move(org.jboss.cache.Fqn, org.jboss.cache.Fqn)}
     */
    protected Object handleMoveMethod(InvocationContext ctx, Fqn from, Fqn to) throws Throwable
@@ -434,7 +435,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_put(org.jboss.cache.transaction.GlobalTransaction, String, Object, Object, boolean)}
     */
    protected Object handlePutKeyValueMethod(InvocationContext ctx, GlobalTransaction gtx, Fqn fqn, Object key, Object value, boolean createUndoOps) throws Throwable
@@ -442,7 +443,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_putForExternalRead(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, Object, Object)}
     */
    protected Object handlePutForExternalReadMethod(InvocationContext ctx, GlobalTransaction tx, Fqn fqn, Object key, Object value) throws Throwable
@@ -450,7 +451,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_put(org.jboss.cache.transaction.GlobalTransaction, String, java.util.Map, boolean)}
     */
    protected Object handlePutDataMethod(InvocationContext ctx, GlobalTransaction tx, Fqn fqn, Map data, boolean createUndoOps) throws Throwable
@@ -458,7 +459,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handles {@link org.jboss.cache.CacheImpl#_put(org.jboss.cache.transaction.GlobalTransaction, org.jboss.cache.Fqn, java.util.Map, boolean, boolean)}
     */
    protected Object handlePutDataEraseMethod(InvocationContext ctx, GlobalTransaction gt, Fqn fqn, Map newData, boolean createUndoOps, boolean eraseContents) throws Throwable
@@ -466,7 +467,7 @@
       return defaultHandlersBehavior();
    }
 
-    /**
+   /**
     * Handlers defined here should not be called directlly. There are two scenarios in which a handler might be called:
     * 1 - DerivedInterceptor.super - pointless call
     * 2 - if the logic that determines that an handler is overwritten fails. Throwing an exception by default is for
@@ -477,63 +478,64 @@
       throw new IllegalStateException("this is either called from a derived class or nt overwritten and accidentally called. Either way, is not correct.");
    }
 
-    /**
-     * Builds the list of methods that are overwiritten.
-     */
-    private void processOverwritternMethods()
-    {
-        checkIfOverwritten(MethodDeclarations.putDataEraseMethodLocal_id,  "handlePutDataEraseMethod",InvocationContext.class, GlobalTransaction.class, Fqn.class, Map.class, boolean.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.putDataMethodLocal_id,  "handlePutDataMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Map.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.putForExternalReadMethodLocal_id,  "handlePutForExternalReadMethod",InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Object.class);
-        checkIfOverwritten(MethodDeclarations.putKeyValMethodLocal_id,  "handlePutKeyValueMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Object.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.moveMethodLocal_id,  "handleMoveMethod",InvocationContext.class, Fqn.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.addChildMethodLocal_id,  "handleAddChildMethod",InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Node.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.getKeyValueMethodLocal_id,  "handleGetKeyValueMethod", InvocationContext.class, Fqn.class, Object.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.getNodeMethodLocal_id,  "handleGetNodeMethod", InvocationContext.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.getChildrenNamesMethodLocal_id,  "handleGetChildrenNamesMethod",InvocationContext.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.releaseAllLocksMethodLocal_id,  "handleReleaseAllLocksMethod",InvocationContext.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.printMethodLocal_id,  "handlePrintMethod",InvocationContext.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.getKeysMethodLocal_id,  "handleGetKeysMethod", InvocationContext.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.getDataMapMethodLocal_id,  "handleGetDataMapMethod", InvocationContext.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.rollbackMethod_id,  "handleRollbackMethod", InvocationContext.class, GlobalTransaction.class);
-        checkIfOverwritten(MethodDeclarations.removeNodeMethodLocal_id,  "handleRemoveNodeMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.removeKeyMethodLocal_id,  "handleRemoveKeyMethod",InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.removeDataMethodLocal_id,  "handleRemoveDataMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.commitMethod_id,  "handleCommitMethod",InvocationContext.class, GlobalTransaction.class);
-        checkIfOverwritten(MethodDeclarations.optimisticPrepareMethod_id,  "handleOptimisticPrepareMethod", InvocationContext.class, GlobalTransaction.class, List.class, Map.class, Address.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.prepareMethod_id,  "handlePrepareMethod", InvocationContext.class, GlobalTransaction.class, List.class, Address.class, boolean.class);
-        checkIfOverwritten(MethodDeclarations.evictNodeMethodLocal_id,  "handleEvictMethod", InvocationContext.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.evictVersionedNodeMethodLocal_id,  "handleEvictVersionedNodeMethod", InvocationContext.class, Fqn.class, DataVersion.class);
-        checkIfOverwritten(MethodDeclarations.existsMethod_id,  "handleExistsMethod", InvocationContext.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.putDataEraseVersionedMethodLocal_id,  "handlePutDataEraseVersionedMethod",InvocationContext.class, GlobalTransaction.class, Fqn.class, Map.class, boolean.class, boolean.class, DataVersion.class);
-        checkIfOverwritten(MethodDeclarations.putDataVersionedMethodLocal_id,  "handlePutDataVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Map.class, Boolean.class, DataVersion.class);
-        checkIfOverwritten(MethodDeclarations.putKeyValVersionedMethodLocal_id,  "handlePutKeyValueVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Object.class, boolean.class, DataVersion.class);
-        checkIfOverwritten(MethodDeclarations.putForExternalReadVersionedMethodLocal_id,  "handlePutForExternalReadVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Object.class, DataVersion.class);
-        checkIfOverwritten(MethodDeclarations.dataGravitationCleanupMethod_id,  "handleDataGravitationCleanupMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Fqn.class);
-        checkIfOverwritten(MethodDeclarations.removeNodeVersionedMethodLocal_id,  "handleRemoveNodeVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, boolean.class, DataVersion.class);
-        checkIfOverwritten(MethodDeclarations.removeKeyVersionedMethodLocal_id,  "handleRemoveKeyVersionedMethod",InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, boolean.class, DataVersion.class);
-        checkIfOverwritten(MethodDeclarations.removeDataVersionedMethodLocal_id,  "handleRemoveDataVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, boolean.class, DataVersion.class);
-        checkIfOverwritten(MethodDeclarations.blockChannelMethodLocal_id,  "handleBlockChannelMethod",InvocationContext.class);
-        checkIfOverwritten(MethodDeclarations.unblockChannelMethodLocal_id,  "handleUnblockChannelMethod", InvocationContext.class);
-        checkIfOverwritten(MethodDeclarations.lockMethodLocal_id,  "handleLockMethod", InvocationContext.class, Fqn.class, NodeLock.LockType.class, boolean.class);
+   /**
+    * Builds the list of methods that are overwiritten.
+    */
+   private void processOverwritternMethods()
+   {
+      checkIfOverwritten(MethodDeclarations.putDataEraseMethodLocal_id, "handlePutDataEraseMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Map.class, boolean.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.putDataMethodLocal_id, "handlePutDataMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Map.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.putForExternalReadMethodLocal_id, "handlePutForExternalReadMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Object.class);
+      checkIfOverwritten(MethodDeclarations.putKeyValMethodLocal_id, "handlePutKeyValueMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Object.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.moveMethodLocal_id, "handleMoveMethod", InvocationContext.class, Fqn.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.addChildMethodLocal_id, "handleAddChildMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Node.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.getKeyValueMethodLocal_id, "handleGetKeyValueMethod", InvocationContext.class, Fqn.class, Object.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.getNodeMethodLocal_id, "handleGetNodeMethod", InvocationContext.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.getChildrenNamesMethodLocal_id, "handleGetChildrenNamesMethod", InvocationContext.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.releaseAllLocksMethodLocal_id, "handleReleaseAllLocksMethod", InvocationContext.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.printMethodLocal_id, "handlePrintMethod", InvocationContext.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.getKeysMethodLocal_id, "handleGetKeysMethod", InvocationContext.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.getDataMapMethodLocal_id, "handleGetDataMapMethod", InvocationContext.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.rollbackMethod_id, "handleRollbackMethod", InvocationContext.class, GlobalTransaction.class);
+      checkIfOverwritten(MethodDeclarations.removeNodeMethodLocal_id, "handleRemoveNodeMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.removeKeyMethodLocal_id, "handleRemoveKeyMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.removeDataMethodLocal_id, "handleRemoveDataMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.commitMethod_id, "handleCommitMethod", InvocationContext.class, GlobalTransaction.class);
+      checkIfOverwritten(MethodDeclarations.optimisticPrepareMethod_id, "handleOptimisticPrepareMethod", InvocationContext.class, GlobalTransaction.class, List.class, Map.class, Address.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.prepareMethod_id, "handlePrepareMethod", InvocationContext.class, GlobalTransaction.class, List.class, Address.class, boolean.class);
+      checkIfOverwritten(MethodDeclarations.evictNodeMethodLocal_id, "handleEvictMethod", InvocationContext.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.evictVersionedNodeMethodLocal_id, "handleEvictVersionedNodeMethod", InvocationContext.class, Fqn.class, DataVersion.class);
+      checkIfOverwritten(MethodDeclarations.existsMethod_id, "handleExistsMethod", InvocationContext.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.putDataEraseVersionedMethodLocal_id, "handlePutDataEraseVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Map.class, boolean.class, boolean.class, DataVersion.class);
+      checkIfOverwritten(MethodDeclarations.putDataVersionedMethodLocal_id, "handlePutDataVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Map.class, Boolean.class, DataVersion.class);
+      checkIfOverwritten(MethodDeclarations.putKeyValVersionedMethodLocal_id, "handlePutKeyValueVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Object.class, boolean.class, DataVersion.class);
+      checkIfOverwritten(MethodDeclarations.putForExternalReadVersionedMethodLocal_id, "handlePutForExternalReadVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, Object.class, DataVersion.class);
+      checkIfOverwritten(MethodDeclarations.dataGravitationCleanupMethod_id, "handleDataGravitationCleanupMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Fqn.class);
+      checkIfOverwritten(MethodDeclarations.removeNodeVersionedMethodLocal_id, "handleRemoveNodeVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, boolean.class, DataVersion.class);
+      checkIfOverwritten(MethodDeclarations.removeKeyVersionedMethodLocal_id, "handleRemoveKeyVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, Object.class, boolean.class, DataVersion.class);
+      checkIfOverwritten(MethodDeclarations.removeDataVersionedMethodLocal_id, "handleRemoveDataVersionedMethod", InvocationContext.class, GlobalTransaction.class, Fqn.class, boolean.class, DataVersion.class);
+      checkIfOverwritten(MethodDeclarations.blockChannelMethodLocal_id, "handleBlockChannelMethod", InvocationContext.class);
+      checkIfOverwritten(MethodDeclarations.unblockChannelMethodLocal_id, "handleUnblockChannelMethod", InvocationContext.class);
+      checkIfOverwritten(MethodDeclarations.lockMethodLocal_id, "handleLockMethod", InvocationContext.class, Fqn.class, NodeLock.LockType.class, boolean.class);
 
-    }
+   }
 
-    private void checkIfOverwritten(int putDataEraseMethodLocal_id, String methodName, Class... args)
-    {
-        Class currentClass = getClass();
-        //if this is a > 1 inheritace deepth and the method was overwritten in the parent. We also have to look into parents
-        while (currentClass != MethodDispacherInterceptor.class)
-        {
-            try
-            {
-                currentClass.getDeclaredMethod(methodName, args);
-                this.overwrittenMethods.add(putDataEraseMethodLocal_id);
-            } catch (NoSuchMethodException e)
-            {
-                //ignore
-            }
-            currentClass = (Class) currentClass.getGenericSuperclass();
-        }
-    }
+   private void checkIfOverwritten(int putDataEraseMethodLocal_id, String methodName, Class... args)
+   {
+      Class currentClass = getClass();
+      //if this is a > 1 inheritace deepth and the method was overwritten in the parent. We also have to look into parents
+      while (currentClass != MethodDispacherInterceptor.class)
+      {
+         try
+         {
+            currentClass.getDeclaredMethod(methodName, args);
+            this.overwrittenMethods.add(putDataEraseMethodLocal_id);
+         }
+         catch (NoSuchMethodException e)
+         {
+            //ignore
+         }
+         currentClass = (Class) currentClass.getGenericSuperclass();
+      }
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -7,13 +7,13 @@
 package org.jboss.cache.interceptors;
 
 import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.InvocationContext;
 import org.jboss.cache.NodeFactory;
 import org.jboss.cache.NodeNotExistsException;
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.config.Option;
+import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.marshall.MethodCall;
 import org.jboss.cache.marshall.MethodDeclarations;
 import org.jboss.cache.notifications.Notifier;
@@ -44,11 +44,11 @@
    private NodeFactory nodeFactory;
    private Notifier notifier;
 
-   public void setCache(CacheSPI c)
+   @Inject
+   protected void injectDependencies(Notifier notifier, NodeFactory nodeFactory)
    {
-      super.setCache(c);
-      nodeFactory = c.getConfiguration().getRuntimeConfig().getNodeFactory();
-      notifier = cache.getNotifier();
+      this.notifier = notifier;
+      this.nodeFactory = nodeFactory;
    }
 
    public Object invoke(InvocationContext ctx) throws Throwable
@@ -234,7 +234,7 @@
 
       WorkspaceNode oldParent = fetchWorkspaceNode(nodeFqn.getParent(), ws, false, true);
       if (oldParent == null) throw new NodeNotExistsException("Node " + nodeFqn.getParent() + " does not exist!");
-      
+
       if (parentFqn.equals(oldParent.getFqn()))
       {
          log.warn("Attempting to move a node in same place.  Not taking any action, treating this as a no-op.");

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -55,13 +55,13 @@
    /**
     * Map<Thread, List<NodeLock>>. Keys = threads, values = lists of locks held by that thread
     */
-   private Map<Thread, List<NodeLock>> lock_table;
+   private Map<Thread, List<NodeLock>> lockTable;
    private long lock_acquisition_timeout;
 
    @Inject
    public void injectDependencies(@ComponentName("LockTable")Map<Thread, List<NodeLock>> lockTable, Configuration configuration, CacheImpl cacheImpl, TransactionTable txTable)
    {
-      this.lock_table = lockTable;
+      this.lockTable = lockTable;
       lock_acquisition_timeout = configuration.getLockAcquisitionTimeout();
       this.cacheImpl = cacheImpl;
       this.tx_table = txTable;
@@ -90,9 +90,9 @@
    private Object handlePutMethod(InvocationContext ctx, Fqn fqn)
          throws Throwable
    {
-      log.trace("Suppressing locking");
       if (ctx.getOptionOverrides() != null && ctx.getOptionOverrides().isSuppressLocking())
       {
+         log.trace("Suppressing locking");
          log.trace("Creating nodes if necessary");
          int treeNodeSize = fqn.size();
          NodeSPI n = cache.getRoot();
@@ -108,7 +108,7 @@
       }
       else
       {
-         acquireLocksWithTimeout(ctx, fqn, NodeLock.LockType.READ, true, false, false, true);
+         acquireLocksWithTimeout(ctx, fqn, NodeLock.LockType.WRITE, true, false, false, true);
       }
       return nextInterceptor(ctx);
    }
@@ -355,7 +355,7 @@
       long expiryTime = System.currentTimeMillis() + timeout;
       currentNode = cache.getRoot();
       NodeSPI parent = null;
-      String childName = null;
+      Object childName = null;
       int currentIndex = -1;
       do
       {
@@ -422,7 +422,7 @@
             parent = currentNode;
             currentIndex = currentNode.getFqn().size();
             currentNode = currentNode.getChildDirect(fqn.get(currentIndex));
-            childName = (String) fqn.get(currentIndex);
+            childName = fqn.get(currentIndex);
          }
       } while (true);
       return created;
@@ -502,7 +502,7 @@
             if (!locks.contains(lock))
             {
                locks.add(lock);
-               lock_table.put(currentThread, locks);
+               lockTable.put(currentThread, locks);
             }
          }
       }
@@ -512,11 +512,11 @@
    {
       // This sort of looks like a get/put race condition, but
       // since we key off the Thread, it's not
-      List<NodeLock> locks = lock_table.get(currentThread);
+      List<NodeLock> locks = lockTable.get(currentThread);
       if (locks == null)
       {
          locks = Collections.synchronizedList(new LinkedList<NodeLock>());
-         lock_table.put(currentThread, locks);
+         lockTable.put(currentThread, locks);
       }
       return locks;
    }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/ReplicationInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/ReplicationInterceptor.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/ReplicationInterceptor.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -1,14 +1,14 @@
 package org.jboss.cache.interceptors;
 
+import org.apache.commons.logging.Log;
+import org.jboss.cache.Fqn;
 import org.jboss.cache.InvocationContext;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.optimistic.DataVersion;
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.config.Option;
 import org.jboss.cache.marshall.MethodCall;
 import org.jboss.cache.marshall.MethodDeclarations;
+import org.jboss.cache.optimistic.DataVersion;
 import org.jboss.cache.transaction.GlobalTransaction;
-import org.apache.commons.logging.Log;
 import org.jgroups.Address;
 
 import java.util.List;
@@ -58,7 +58,7 @@
       {
          return nextInterceptor(ctx);
       }
-      Object retVal =  nextInterceptor(ctx);
+      Object retVal = nextInterceptor(ctx);
       runPreparePhase(ctx.getMethodCall(), gtx, ctx);
       return retVal;
    }
@@ -84,7 +84,9 @@
          Object returnValue = nextInterceptor(ctx);
          cache.getTransactionTable().get(gtx).setForceAsyncReplication(true);
          return returnValue;
-      } else {
+      }
+      else
+      {
          return handleCrudMethod(ctx);
       }
    }
@@ -195,16 +197,18 @@
     * If the operation didn't originate locally we won't do any replication either.
     */
    private Object handleCrudMethod(InvocationContext ctx)
-      throws Throwable
+         throws Throwable
    {
-      if (ctx.getTransaction() == null && ctx.isOriginLocal() )
+      // FIRST pass this call up the chain.  Only if it succeeds (no exceptions) locally do we attempt to replicate.
+      Object returnValue = nextInterceptor(ctx);
+      if (ctx.getTransaction() == null && ctx.isOriginLocal())
       {
          MethodCall m = ctx.getMethodCall();
          if (log.isTraceEnabled())
          {
             log.trace("invoking method " + m + ", members=" + cache.getMembers() + ", mode=" +
-                    configuration.getCacheMode() + ", exclude_self=" + true + ", timeout=" +
-                    configuration.getSyncReplTimeout());
+                  configuration.getCacheMode() + ", exclude_self=" + true + ", timeout=" +
+                  configuration.getSyncReplTimeout());
          }
          if (!isSynchronous(ctx.getOptionOverrides()) || m.getMethodId() == MethodDeclarations.putForExternalReadMethodLocal_id)
          {
@@ -218,7 +222,7 @@
             replicateCall(m, true, ctx.getOptionOverrides());
          }
       }
-      return nextInterceptor(ctx);
+      return returnValue;
    }
 
    /**

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/UnlockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/UnlockInterceptor.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/UnlockInterceptor.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -1,6 +1,5 @@
 package org.jboss.cache.interceptors;
 
-import org.jboss.cache.CacheSPI;
 import org.jboss.cache.InvocationContext;
 import org.jboss.cache.factories.annotations.ComponentName;
 import org.jboss.cache.factories.annotations.Inject;
@@ -22,21 +21,15 @@
 public class UnlockInterceptor extends Interceptor
 {
 
-   Map<Thread, List<NodeLock>> lock_table = null;
+   Map<Thread, List<NodeLock>> lockTable = null;
    boolean trace = log.isTraceEnabled();
 
    @Inject
    private void injectDependencies(@ComponentName("LockTable")Map<Thread, List<NodeLock>> lockTable)
    {
-      this.lock_table = lockTable;
+      this.lockTable = lockTable;
    }
 
-   public void setCache(CacheSPI cache)
-   {
-      super.setCache(cache);
-      lock_table = cache.getLockTable();
-   }
-
    public Object invoke(InvocationContext ctx) throws Throwable
    {
       try
@@ -59,13 +52,13 @@
             else
             { // no TX
                Thread currentThread = Thread.currentThread();
-               List locks = (List) lock_table.get(currentThread);
-               if (trace) log.trace("Attempting to release locks on current thread.  Lock table is " + lock_table);
+               List locks = lockTable.get(currentThread);
+               if (trace) log.trace("Attempting to release locks on current thread.  Lock table is " + lockTable);
 
                if (locks != null && locks.size() > 0)
                {
                   releaseLocks(locks, currentThread);
-                  lock_table.remove(currentThread);
+                  lockTable.remove(currentThread);
                }
             }
          }

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -1,5 +1,6 @@
 package org.jboss.cache.invocation;
 
+import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.*;
 import org.jboss.cache.buddyreplication.BuddyManager;
 import org.jboss.cache.buddyreplication.GravitateResult;
@@ -52,6 +53,11 @@
    private Marshaller marshaller;
    private Map<Thread, List<NodeLock>> lockTable;
 
+   public CacheInvocationDelegate()
+   {
+      log = LogFactory.getLog(CacheInvocationDelegate.class);
+   }
+
    @Inject
    private void injectDependencies(StateTransferManager stateTransferManager, CacheLoaderManager cacheLoaderManager, Notifier notifier,
                                    TransactionManager transactionManager, BuddyManager buddyManager, TransactionTable transactionTable,
@@ -67,6 +73,7 @@
       this.rpcManager = rpcManager;
       this.regionManager = regionManager;
       this.marshaller = marshaller;
+      this.lockTable = lockTable;
    }
 
    @Override
@@ -386,7 +393,7 @@
          for (Object childName : peek(fqn, false, false).getChildrenNames())
          {
             ctx.setOptionOverrides(o);
-            result = removeNode(new Fqn<Object>(fqn, childName)) && result;
+            result = removeNode(new Fqn<Object>((Fqn<Object>) fqn, childName)) && result;
          }
 
          return result;

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -34,7 +34,7 @@
       this.node = node;
    }
 
-   public UnversionedNode getUnversionedNode()
+   public Object getDelegationTarget()
    {
       return node;
    }
@@ -299,7 +299,7 @@
    public V put(K key, V value)
    {
       assertValid();
-      return (V) spi.put(getFqn(), key, value);
+      return spi.put(getFqn(), key, value);
    }
 
    public V putIfAbsent(K k, V v)

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/RemoteCacheInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/RemoteCacheInvocationDelegate.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/RemoteCacheInvocationDelegate.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -1,5 +1,6 @@
 package org.jboss.cache.invocation;
 
+import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.marshall.MethodCall;
 import org.jboss.cache.marshall.MethodCallFactory;
 import org.jboss.cache.marshall.MethodDeclarations;
@@ -17,6 +18,7 @@
    public RemoteCacheInvocationDelegate()
    {
       originLocal = false;
+      log = LogFactory.getLog(RemoteCacheInvocationDelegate.class);
    }
 
    public Object _replicate(MethodCall methodCall) throws Throwable

Modified: core/trunk/src/main/java/org/jboss/cache/loader/CacheLoaderManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/CacheLoaderManager.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/loader/CacheLoaderManager.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -15,6 +15,8 @@
 import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
 import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig.SingletonStoreConfig;
 import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.factories.annotations.Stop;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -369,31 +371,37 @@
       return fetchPersistentState;
    }
 
+   @Stop
    public void stopCacheLoader()
    {
-      if (loader == null) throw new RuntimeException("Problem with configured cache loader - it has been set to null!");
-      // stop the cache loader
-      loader.stop();
-      // destroy the cache loader
-      loader.destroy();
+      if (loader != null)
+      {
+         // stop the cache loader
+         loader.stop();
+         // destroy the cache loader
+         loader.destroy();
+      }
    }
 
+   @Start
    public void startCacheLoader() throws CacheException
    {
-      if (loader == null) throw new RuntimeException("Improperly configured cache loader - cache loader is null!");
-      try
+      if (loader != null)
       {
-         // create the cache loader
-         loader.create();
-         // start the cache loader
-         loader.start();
+         try
+         {
+            // create the cache loader
+            loader.create();
+            // start the cache loader
+            loader.start();
 
-         purgeLoaders(false);
+            purgeLoaders(false);
+         }
+         catch (Exception e)
+         {
+            throw new CacheException("Unable to start cache loaders", e);
+         }
       }
-      catch (Exception e)
-      {
-         throw new CacheException("Unable to start cache loaders", e);
-      }
    }
 
    public void purgeLoaders(boolean force) throws Exception

Modified: core/trunk/src/main/java/org/jboss/cache/marshall/AbstractMarshaller.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/AbstractMarshaller.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/AbstractMarshaller.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -34,7 +34,7 @@
    protected boolean useRegionBasedMarshalling;
    protected RegionManager regionManager;
    protected boolean defaultInactive;
-   private static Log log = LogFactory.getLog(AbstractMarshaller.class);
+   protected Log log = LogFactory.getLog(AbstractMarshaller.class);
 
    /**
     * Map<GlobalTransaction, Fqn> for prepared tx that have not committed

Modified: core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -6,7 +6,6 @@
  */
 package org.jboss.cache.marshall;
 
-import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.Region;
@@ -33,9 +32,6 @@
  */
 public class CacheMarshaller200 extends AbstractMarshaller
 {
-   // logger
-   private Log log = LogFactory.getLog(CacheMarshaller200.class);
-
    // magic numbers
    protected static final int MAGICNUMBER_METHODCALL = 1;
    protected static final int MAGICNUMBER_FQN = 2;
@@ -69,10 +65,12 @@
 
    public CacheMarshaller200()
    {
+      log = LogFactory.getLog(CacheMarshaller200.class);
    }
 
    public CacheMarshaller200(RegionManager manager, boolean defaultInactive, boolean useRegionBasedMarshalling)
    {
+      log = LogFactory.getLog(CacheMarshaller200.class);
       init(manager, defaultInactive, useRegionBasedMarshalling);
       if (useRegionBasedMarshalling)
       {

Modified: core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller210.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller210.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller210.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -1,5 +1,6 @@
 package org.jboss.cache.marshall;
 
+import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.RegionManager;
 
 import java.io.IOException;
@@ -20,11 +21,13 @@
 {
    public CacheMarshaller210()
    {
+      log = LogFactory.getLog(CacheMarshaller210.class);
    }
 
    public CacheMarshaller210(RegionManager manager, boolean defaultInactive, boolean useRegionBasedMarshalling)
    {
       super(manager, defaultInactive, useRegionBasedMarshalling);
+      log = LogFactory.getLog(CacheMarshaller210.class);
    }
 
    /**

Modified: core/trunk/src/main/java/org/jboss/cache/marshall/InactiveRegionAwareRpcDispatcher.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/InactiveRegionAwareRpcDispatcher.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/InactiveRegionAwareRpcDispatcher.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -81,4 +81,9 @@
          return x;
       }
    }
+
+   public String toString()
+   {
+      return getClass().getSimpleName() + "[Outgoing marshaller: " + req_marshaller + "; incoming marshaller: " + rsp_marshaller + "]";
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/optimistic/WorkspaceNodeImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/optimistic/WorkspaceNodeImpl.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/main/java/org/jboss/cache/optimistic/WorkspaceNodeImpl.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -55,9 +55,9 @@
    public WorkspaceNodeImpl(NodeSPI<K, V> node, TransactionWorkspace workspace)
    {
       NodeInvocationDelegate delegate = (NodeInvocationDelegate) node;
-      if (!(delegate.getUnversionedNode() instanceof VersionedNode))
+      if (!(delegate.getDelegationTarget() instanceof VersionedNode))
       {
-         throw new IllegalArgumentException("node " + delegate.getUnversionedNode() + " not VersionedNode");
+         throw new IllegalArgumentException("node " + delegate.getDelegationTarget() + " not VersionedNode");
       }
       this.node = node;
       this.workspace = workspace;

Modified: core/trunk/src/test/java/org/jboss/cache/api/NodeAPITest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/api/NodeAPITest.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/test/java/org/jboss/cache/api/NodeAPITest.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -5,6 +5,9 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.Node;
 import org.jboss.cache.config.Configuration;
+import org.jboss.cache.interceptors.Interceptor;
+import org.jboss.cache.interceptors.OptimisticNodeInterceptor;
+import org.jboss.cache.interceptors.PessimisticLockInterceptor;
 import org.jboss.cache.optimistic.TransactionWorkspace;
 import org.jboss.cache.transaction.OptimisticTransactionEntry;
 import static org.testng.AssertJUnit.*;
@@ -74,8 +77,24 @@
       }
    }
 
+   private void assertOptimistic()
+   {
+      assert cache.getConfiguration().isNodeLockingOptimistic();
+      boolean interceptorChainOK = false;
+
+      for (Interceptor i : cache.getInterceptorChain())
+      {
+         if (i instanceof PessimisticLockInterceptor) assert false : "Not an optimistic locking chain!!";
+         if (i instanceof OptimisticNodeInterceptor) interceptorChainOK = true;
+      }
+
+      assert interceptorChainOK : "Not an optimistic locking chain!!";
+   }
+
    public void testAddingData()
    {
+      if (optimistic) assertOptimistic();
+
       Node<Object, Object> nodeA = rootNode.addChild(A);
       nodeA.put("key", "value");
 
@@ -215,7 +234,7 @@
       else
       {
          TransactionWorkspace<Object, Object> w = getTransactionWorkspace();
-         assert w.getNodes().size() == 4 : "Should be 4 nodes in the workspace.";
+         assert w.getNodes().size() == 4 : "Should be 4 nodes in the workspace, not " + w.getNodes().size();
          // test deltas
          List<Set<Fqn>> deltas = w.getNodes().get(Fqn.ROOT).getMergedChildren();
          assert deltas.get(0).size() == 1 : "/ should have 1 child added";

Modified: core/trunk/src/test/java/org/jboss/cache/factories/ComponentRegistryTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/factories/ComponentRegistryTest.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/test/java/org/jboss/cache/factories/ComponentRegistryTest.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -78,6 +78,15 @@
       assert cr.defaultFactories.get(Marshaller.class).equals(CacheMarshallerFactory.class);
    }
 
+   public void testNamedComponents()
+   {
+      cr.registerComponent("blah", new Object());
+      Object namedComponent1 = cr.getOrCreateComponent("blah", Object.class);
+      Object namedComponent2 = cr.getOrCreateComponent("blah", Object.class);
+
+      assert namedComponent1 == namedComponent2;
+   }
+
    /**
     * Case 1:
     * nothing injected, nothing specified in Configuration.  Should use default factory.

Modified: core/trunk/src/test/java/org/jboss/cache/lock/PessimisticLockTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/PessimisticLockTest.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/test/java/org/jboss/cache/lock/PessimisticLockTest.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -1,19 +1,24 @@
 package org.jboss.cache.lock;
 
-import static org.testng.AssertJUnit.assertFalse;
-import static org.testng.AssertJUnit.assertTrue;
-
-import javax.transaction.TransactionManager;
-
 import org.jboss.cache.Cache;
+import org.jboss.cache.CacheSPI;
 import org.jboss.cache.DefaultCacheFactory;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.NodeSPI;
+import org.jboss.cache.interceptors.PessimisticLockInterceptor;
+import org.jboss.cache.interceptors.UnlockInterceptor;
+import org.jboss.cache.misc.TestingUtil;
 import org.jboss.cache.transaction.DummyTransactionManagerLookup;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
- /**
+
+import javax.transaction.TransactionManager;
+import java.util.Map;
+
+/**
  * basic locking test
  *
  * @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
@@ -41,10 +46,30 @@
       cache.stop();
    }
 
+   private void assertNoStaleLocks()
+   {
+      CacheSPI spi = (CacheSPI) cache;
+      PessimisticLockInterceptor pli = TestingUtil.findInterceptor(spi, PessimisticLockInterceptor.class);
+      UnlockInterceptor ui = TestingUtil.findInterceptor(spi, UnlockInterceptor.class);
+
+      Map lockTablePLI = (Map) TestingUtil.extractField(pli, "lockTable");
+      Map lockTableUI = (Map) TestingUtil.extractField(ui, "lockTable");
+
+      // they should be the SAME!!
+      assert lockTablePLI == lockTableUI : "PessimisticLockInterceptor and UnlockInterceptor should be referring to the same LockTable!!";
+
+      assert lockTablePLI.size() == 0 : "Lock table on pessimistic lock interceptor should be empty";
+      assert lockTableUI.size() == 0 : "Lock table on unlock interceptor should be empty";
+
+      assert spi.getNumberOfLocksHeld() == 0 : "Should have no stale locks!";
+   }
+
    public void testPut() throws Exception
    {
       cache.put(fqn, "k", "v");
 
+      assertNoStaleLocks();
+
       tm.begin();
       cache.put(fqn, "k2", "v2");
       NodeSPI<Object, Object> n = (NodeSPI<Object, Object>) cache.getRoot().getChild(fqn);
@@ -57,12 +82,16 @@
       assertFalse(n.getParent().getParent().getLock().isWriteLocked());
 
       tm.commit();
+
+      assertNoStaleLocks();
    }
 
    public void testGet() throws Exception
    {
       cache.put(fqn, "k", "v");
 
+      assertNoStaleLocks();
+
       tm.begin();
       cache.get(fqn, "k2");
       NodeSPI<Object, Object> n = (NodeSPI<Object, Object>) cache.getRoot().getChild(fqn);
@@ -75,11 +104,16 @@
       assertFalse(n.getParent().getParent().getLock().isWriteLocked());
 
       tm.commit();
+
+      assertNoStaleLocks();
    }
 
    public void testRemove() throws Exception
    {
       cache.put(fqn, "k", "v");
+
+      assertNoStaleLocks();
+
       tm.begin();
       cache.remove(fqn, "k2");
       NodeSPI<Object, Object> n = (NodeSPI<Object, Object>) cache.getRoot().getChild(fqn);
@@ -93,5 +127,7 @@
 
       tm.commit();
 
+      assertNoStaleLocks();
+
    }
 }

Modified: core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -44,17 +44,30 @@
     */
    public static Object extractField(Object target, String fieldName)
    {
+      return extractField(target.getClass(), target, fieldName);
+   }
+
+   private static Object extractField(Class type, Object target, String fieldName)
+   {
       Field field;
       try
       {
-         field = target.getClass().getDeclaredField(fieldName);
+         field = type.getDeclaredField(fieldName);
          field.setAccessible(true);
          return field.get(target);
       }
       catch (Exception e)
       {
-         e.printStackTrace();
-         return null;
+         if (type.equals(Object.class))
+         {
+            e.printStackTrace();
+            return null;
+         }
+         else
+         {
+            // try with superclass!!
+            return extractField(type.getSuperclass(), target, fieldName);
+         }
       }
    }
 
@@ -511,7 +524,7 @@
       ComponentRegistry cr = extractComponentRegistry(cache);
 
       // This will replace the previous interceptor chain in the component registry
-      cr.registerComponent(interceptor);
+      cr.registerComponent(Interceptor.class, interceptor);
 
       // update all component dependencies
       cr.updateDependencies();

Modified: core/trunk/src/test/java/org/jboss/cache/optimistic/CacheTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/optimistic/CacheTest.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/test/java/org/jboss/cache/optimistic/CacheTest.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -8,7 +8,10 @@
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.CacheSPI;
 import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.VersionedNode;
 import org.jboss.cache.config.Configuration;
+import org.jboss.cache.invocation.NodeInvocationDelegate;
 import org.jboss.cache.loader.SamplePojo;
 import org.jboss.cache.marshall.MethodCall;
 import org.jboss.cache.marshall.MethodCallFactory;
@@ -51,6 +54,12 @@
       c = null;
    }
 
+   public void testRoot()
+   {
+      NodeSPI node = c.getRoot();
+      assert ((NodeInvocationDelegate) node).getDelegationTarget() instanceof VersionedNode;
+   }
+
    public void testExplicitTxFailure() throws Exception
    {
       // explicit.

Modified: core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTest.java	2007-12-13 17:30:43 UTC (rev 4850)
+++ core/trunk/src/test/java/org/jboss/cache/replicated/SyncReplTest.java	2007-12-13 22:36:59 UTC (rev 4851)
@@ -6,21 +6,19 @@
  */
 package org.jboss.cache.replicated;
 
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertFalse;
-import static org.testng.AssertJUnit.assertNotNull;
-import static org.testng.AssertJUnit.assertNull;
-import static org.testng.AssertJUnit.assertTrue;
-
 import org.jboss.cache.Cache;
 import org.jboss.cache.DefaultCacheFactory;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.InvocationContext;
 import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.config.Configuration.CacheMode;
 import org.jboss.cache.config.Option;
-import org.jboss.cache.config.Configuration.CacheMode;
 import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.invocation.CacheInvocationDelegate;
+import org.jboss.cache.invocation.RemoteCacheInvocationDelegate;
 import org.jboss.cache.misc.TestingUtil;
+import static org.testng.AssertJUnit.*;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -28,7 +26,7 @@
 /**
  * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  */
- at Test(groups = { "functional", "jgroups" })
+ at Test(groups = {"functional", "jgroups"})
 public class SyncReplTest
 {
    private Cache[] caches;
@@ -74,6 +72,9 @@
 
       Node node = caches[0].getRoot().addChild(f);
 
+      assert ((NodeSPI) node).getCache() instanceof CacheInvocationDelegate;
+      assert !(((NodeSPI) node).getCache() instanceof RemoteCacheInvocationDelegate);
+
       assertNotNull("Should not be null", node);
 
       node.put(k, v);
@@ -114,7 +115,7 @@
       assertFalse(caches[0].getRoot().hasChild(fqn));
       assertFalse(caches[1].getRoot().hasChild(fqn));
       assertEquals(false, caches[0].removeNode(fqn));
-      
+
       // Confirm it works as expected if the removed node has a child
       Fqn<String> child = Fqn.fromString("/test/fqn/child");
       caches[0].getRoot().addChild(child);




More information about the jbosscache-commits mailing list