[jbosscache-commits] JBoss Cache SVN: r5528 - in core/trunk/src: main/java/org/jboss/cache/interceptors and 6 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Apr 10 19:12:19 EDT 2008


Author: mircea.markus
Date: 2008-04-10 19:12:19 -0400 (Thu, 10 Apr 2008)
New Revision: 5528

Added:
   core/trunk/src/test/java/org/jboss/cache/invocation/
   core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java
Modified:
   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/CallInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/base/ChainedInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/invocation/CacheData.java
   core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
   core/trunk/src/main/java/org/jboss/cache/invocation/CacheLifecycleManager.java
   core/trunk/src/main/java/org/jboss/cache/invocation/InterceptorChain.java
   core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
   core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainTestBase.java
Log:
JBCACHE-1222 - updated wiering and bug fixing

Modified: core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/factories/ComponentRegistry.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -323,9 +323,8 @@
 
    private boolean isNonBootstrapClass(Class<?> componentClass)
    {
-      return !(componentClass.equals(CacheSPI.class) ||
-            componentClass.equals(CacheLifecycleManager.class) || componentClass.equals(Cache.class) ||
-            componentClass.equals(CacheData.class) || componentClass.equals(ComponentRegistry.class) ||
+      return !(componentClass.equals(CacheSPI.class) || componentClass.equals(CacheLifecycleManager.class) ||
+            componentClass.equals(Cache.class) || componentClass.equals(ComponentRegistry.class) ||
             componentClass.equals(Configuration.class));
    }
 

Modified: core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -39,53 +39,41 @@
       if (i == null)
       {
          i = clazz.newInstance();
-         // add this interceptor as a NAMED component into the registry
          componentRegistry.registerComponent(clazz.getName(), i, clazz);
       } else
       {
          // wipe next/last chaining!!
-         i.setLast(null);
          i.setNext(null);
       }
       return i;
    }
 
-   /**
-    * Adds an interceptor at the end of the chain
-    */
-   private void addInterceptor(ChainedInterceptor first, ChainedInterceptor i)
-   {
-      if (first == null) return;
-      while (first.getNext() != null) first = first.getNext();
-      first.setNext(i);
-   }
-
    public InterceptorChain buildInterceptorChain() throws IllegalAccessException, InstantiationException, ClassNotFoundException
    {
       boolean optimistic = configuration.isNodeLockingOptimistic();
       // load the icInterceptor first
-      ChainedInterceptor first = setFirstInterceptor(createInterceptor(InvocationContextInterceptor.class));
+      ChainedInterceptor first = createInterceptor(InvocationContextInterceptor.class);
       InterceptorChain interceptorChain = new InterceptorChain(first);
 
       // load the cache management interceptor next
       if (configuration.getExposeManagementStatistics())
-         interceptorChain.addInterceptor(first, CacheMgmtInterceptor.class);
+         interceptorChain.appendIntereceptor(createInterceptor(CacheMgmtInterceptor.class));
 
       // load the tx interceptor
-      interceptorChain.addInterceptor(first, TxInterceptor.class);
+      interceptorChain.appendIntereceptor(createInterceptor(TxInterceptor.class));
       if (configuration.isUseLazyDeserialization())
-         interceptorChain.addInterceptor(first, MarshalledValueInterceptor.class);
-      interceptorChain.addInterceptor(first, NotificationInterceptor.class);
+         interceptorChain.appendIntereceptor(createInterceptor(MarshalledValueInterceptor.class));
+      interceptorChain.appendIntereceptor(createInterceptor(NotificationInterceptor.class));
 
       switch (configuration.getCacheMode())
       {
          case REPL_SYNC:
          case REPL_ASYNC:
-            interceptorChain.addInterceptor(first, optimistic ? OptimisticReplicationInterceptor.class : ReplicationInterceptor.class);
+            interceptorChain.appendIntereceptor(optimistic ? createInterceptor(OptimisticReplicationInterceptor.class) : createInterceptor(ReplicationInterceptor.class));
             break;
          case INVALIDATION_SYNC:
          case INVALIDATION_ASYNC:
-            interceptorChain.addInterceptor(first, InvalidationInterceptor.class);
+            interceptorChain.appendIntereceptor(createInterceptor(InvalidationInterceptor.class));
             break;
          case LOCAL:
             //Nothing...
@@ -93,52 +81,42 @@
 
       if (!optimistic)
       {
-         interceptorChain.addInterceptor(first, PessimisticLockInterceptor.class);
-//         addInterceptor(first, UnlockInterceptor.class);
+         interceptorChain.appendIntereceptor(createInterceptor(PessimisticLockInterceptor.class));
       }
 
       if (configuration.isUsingCacheLoaders())
       {
          if (configuration.getCacheLoaderConfig().isPassivation())
          {
-            interceptorChain.addInterceptor(first, ActivationInterceptor.class);
-            interceptorChain.addInterceptor(first, PassivationInterceptor.class);
-
+            interceptorChain.appendIntereceptor(createInterceptor(ActivationInterceptor.class));
+            interceptorChain.appendIntereceptor(createInterceptor(PassivationInterceptor.class));
          } else
          {
-            interceptorChain.addInterceptor(first, CacheLoaderInterceptor.class);
-            interceptorChain.addInterceptor(first, CacheStoreInterceptor.class);
+            interceptorChain.appendIntereceptor(createInterceptor(CacheLoaderInterceptor.class));
+            interceptorChain.appendIntereceptor(createInterceptor(CacheStoreInterceptor.class));
          }
       }
 
       if (configuration.isUsingBuddyReplication())
-         interceptorChain.addInterceptor(first, DataGravitatorInterceptor.class);
+         interceptorChain.appendIntereceptor(createInterceptor(DataGravitatorInterceptor.class));
 
       if (optimistic)
       {
-         interceptorChain.addInterceptor(first, OptimisticLockingInterceptor.class);
-         interceptorChain.addInterceptor(first, OptimisticValidatorInterceptor.class);
-         interceptorChain.addInterceptor(first, OptimisticCreateIfNotExistsInterceptor.class);
+         interceptorChain.appendIntereceptor(createInterceptor(OptimisticLockingInterceptor.class));
+         interceptorChain.appendIntereceptor(createInterceptor(OptimisticValidatorInterceptor.class));
+         interceptorChain.appendIntereceptor(createInterceptor(OptimisticCreateIfNotExistsInterceptor.class));
       }
       // eviction interceptor to come before the optimistic node interceptor
       if (configuration.getEvictionConfig() != null && configuration.getEvictionConfig().isValidConfig())
-         interceptorChain.addInterceptor(first, EvictionInterceptor.class);
+         interceptorChain.appendIntereceptor(createInterceptor(EvictionInterceptor.class));
 
-      if (optimistic) interceptorChain.addInterceptor(first, OptimisticNodeInterceptor.class);
-
+      if (optimistic) interceptorChain.appendIntereceptor(createInterceptor(OptimisticNodeInterceptor.class));
       ChainedInterceptor callInterceptor = createInterceptor(CallInterceptor.class);
-      addInterceptor(first, callInterceptor);
-      interceptorChain.setLastInterceptorPointer(callInterceptor);
+      interceptorChain.appendIntereceptor(callInterceptor);
+      if (log.isTraceEnabled()) log.trace("Finished building interceptor chain.");
       return interceptorChain;
    }
 
-
-   public ChainedInterceptor setFirstInterceptor(ChainedInterceptor i)
-   {
-      componentRegistry.registerComponent(ChainedInterceptor.class.getName(), i, ChainedInterceptor.class);
-      return i;
-   }
-
    @Override
    @SuppressWarnings("unchecked")
    protected <T> T construct(String componentName, Class<T> componentType)

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CallInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CallInterceptor.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CallInterceptor.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -155,6 +155,6 @@
                transactionTable.addCacheLoaderModification(gtx, command);
          }
       }
-      return command;
+      return result;
    }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/Interceptor.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -22,27 +22,26 @@
 package org.jboss.cache.interceptors;
 
 import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.CacheSPI;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.InvocationContext;
 import org.jboss.cache.NodeSPI;
-import org.jboss.cache.interceptors.base.ChainedInterceptor;
-import org.jboss.cache.marshall.MethodDeclarations;
 import org.jboss.cache.commands.CacheCommand;
 import org.jboss.cache.commands.EvictFqnCommand;
 import org.jboss.cache.commands.InvalidateCommand;
+import org.jboss.cache.commands.cachedata.*;
 import org.jboss.cache.commands.channel.BlockChannelCommand;
 import org.jboss.cache.commands.channel.UnblockChannelCommand;
 import org.jboss.cache.commands.remote.*;
-import org.jboss.cache.commands.tx.PrepareCommand;
-import org.jboss.cache.commands.tx.RollbackCommand;
 import org.jboss.cache.commands.tx.CommitCommand;
 import org.jboss.cache.commands.tx.OptimisticPrepareCommand;
-import org.jboss.cache.commands.cachedata.*;
+import org.jboss.cache.commands.tx.PrepareCommand;
+import org.jboss.cache.commands.tx.RollbackCommand;
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.interceptors.base.ChainedInterceptor;
+import org.jboss.cache.marshall.MethodDeclarations;
 
 import java.util.Collections;
 import java.util.Map;
@@ -55,7 +54,7 @@
  */
 public abstract class Interceptor extends ChainedInterceptor implements InterceptorMBean
 {
-   protected Interceptor next = null, last = null;
+   protected Interceptor next = null;
    protected CacheSPI<?, ?> cache;
    protected Log log = null;
    protected Configuration configuration;
@@ -121,16 +120,6 @@
       statsEnabled = enabled;
    }
 
-   public Interceptor getLast()
-   {
-      return last;
-   }
-
-   public void setLast(Interceptor last)
-   {
-      this.last = last;
-   }
-
    /**
     * This implementation returns an empty Map.  If individual Interceptors wish to expose statistics, they can override this
     * method.
@@ -153,8 +142,6 @@
       return getClass().getName()
             + "{next: "
             + (getNext() == null ? null : getNext().getClass())
-            + "; last: "
-            + (getLast() == null ? null : getLast().getClass())
             + "}";
    }
 

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -10,6 +10,7 @@
 import org.jboss.cache.InvocationContext;
 import org.jboss.cache.RPCManager;
 import org.jboss.cache.ReplicationException;
+import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.commands.CacheCommand;
 import org.jboss.cache.commands.CommandsFactory;
 import org.jboss.cache.commands.DataVersionCommand;
@@ -73,10 +74,19 @@
    private long rollbacks = 0;
    private GlobalTransactionCommandsVisitor globalTransactionCommandsVisitor;
 
-   public TxInterceptor()
+
+   @Inject
+   public void intialize(Configuration configuration, CommandsFactory commandsFactory, RPCManager rpcManager,
+                         CacheTransactionHelper transactionHelper, Notifier notifier, InvocationContextContainer icc,
+                         CacheLifecycleManager lifecycleManager) 
    {
-      log = LogFactory.getLog(getClass());
-      trace = log.isTraceEnabled();
+      this.configuration = configuration;
+      this.commandsFactory = commandsFactory;
+      this.rpcManager = rpcManager;
+      this.transactionHelper = transactionHelper;
+      this.notifier = notifier;
+      this.invocationContextContainer = icc;
+      this.lifecycleManager = lifecycleManager;
    }
 
    @SuppressWarnings("unchecked")

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/base/ChainedInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/base/ChainedInterceptor.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/base/ChainedInterceptor.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -20,8 +20,6 @@
 
    private ChainedInterceptor next;
 
-   private ChainedInterceptor last;
-
    protected Log log;
    protected boolean trace;
 
@@ -55,21 +53,16 @@
       return next;
    }
 
-   public void setNext(ChainedInterceptor next)
+   public boolean hasNext()
    {
-      this.next = next;
+      return getNext() != null;
    }
 
-   public ChainedInterceptor getLast()
+   public void setNext(ChainedInterceptor next)
    {
-      return last;
+      this.next = next;
    }
 
-   public void setLast(ChainedInterceptor last)
-   {
-      this.last = last;
-   }
-
    public Object invokeNextInterceptor(InvocationContext ctx, CacheCommand command) throws Throwable
    {
       return command.accept(ctx, getNext());

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/CacheData.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/CacheData.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/CacheData.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -571,4 +571,8 @@
       }
    }
 
+   public void setRoot(NodeSPI root)
+   {
+      this.root = root;
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -56,11 +56,27 @@
    {
    }
 
+//   @Inject
+//   public void initialize(CacheData cacheData)
+//   {
+//      this.stateTransferManager = stateTransferManager;
+//      this.cacheLoaderManager = cacheLoaderManager;
+//      this.notifier = notifier;
+//      this.transactionManager = transactionManager;
+//      this.buddyManager = buddyManager;
+//      this.transactionTable = transactionTable;
+//      this.rpcManager = rpcManager;
+//      this.regionManager = regionManager;
+//      this.marshaller = marshaller;
+//      this.cacheData = cacheData;
+//      this.commandsFactory = commandsFactory;
+//      this.transactionHelper = transactionHelper;
+//   }
    @Inject
    public void initialize(StateTransferManager stateTransferManager, CacheLoaderManager cacheLoaderManager, Notifier notifier,
                                    TransactionManager transactionManager, BuddyManager buddyManager, TransactionTable transactionTable,
                                    RPCManager rpcManager, RegionManager regionManager, Marshaller marshaller,
-                                   CacheTransactionHelper transactionHelper, CommandsFactory commandsFactory)
+                                   CacheTransactionHelper transactionHelper, CommandsFactory commandsFactory, CacheData cacheData)
    {
       this.stateTransferManager = stateTransferManager;
       this.cacheLoaderManager = cacheLoaderManager;
@@ -71,7 +87,7 @@
       this.rpcManager = rpcManager;
       this.regionManager = regionManager;
       this.marshaller = marshaller;
-      this.cacheData = new CacheData();
+      this.cacheData = cacheData;
       this.commandsFactory = commandsFactory;
       this.transactionHelper = transactionHelper;
    }
@@ -126,7 +142,7 @@
 
    public List<ChainedInterceptor> getInterceptorChain()
    {
-      return invoker.getInterceptorsList();
+      return invoker.getInterceptorsAsList();
    }
 
    public void removeInterceptor(int position)

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/CacheLifecycleManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/CacheLifecycleManager.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/CacheLifecycleManager.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -25,7 +25,6 @@
 {
    private static Log log = LogFactory.getLog(CacheLifecycleManager.class);
 
-   private NodeSPI root;
    private CacheStatus cacheStatus;
    
    /* dependencies*/
@@ -198,7 +197,7 @@
       //todo [mmarkus] updateDependencies should be moved in this class. Component registry's is not to care
       // todo about particular instances that are manipulated there ; it should be keept generic
       componentRegistry.updateDependencies();
-      componentRegistry.wireDependencies(root);
+      componentRegistry.wireDependencies(cacheData.getRoot());
 
       cacheStatus = CacheStatus.STARTING;
 
@@ -354,8 +353,8 @@
       // unset transaction manager reference
       cacheStatus = CacheStatus.STOPPED;
       // empty in-memory state
-      root.clearDataDirect();
-      root.removeChildrenDirect();
+      cacheData.getRoot().clearDataDirect();
+      cacheData.getRoot().removeChildrenDirect();
    }
 
    //todo - this should reather be implemented as follows:
@@ -381,10 +380,10 @@
       // 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 currentRootType = cacheData.getRoot() == null ? null : ((NodeInvocationDelegate) cacheData.getRoot()).getDelegationTarget().getClass();
       Class tempRootType = ((NodeInvocationDelegate) tempRoot).getDelegationTarget().getClass();
 
-      if (!tempRootType.equals(currentRootType)) root = tempRoot;
+      if (!tempRootType.equals(currentRootType)) cacheData.setRoot(tempRoot);
    }
 
    /**

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/InterceptorChain.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/InterceptorChain.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/InterceptorChain.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -1,193 +1,187 @@
 package org.jboss.cache.invocation;
 
-import org.jboss.cache.factories.ComponentRegistry;
-import org.jboss.cache.factories.InterceptorChainFactory;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.commands.CacheCommand;
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.interceptors.base.ChainedInterceptor;
-import org.jboss.cache.InvocationContext;
-import org.jboss.cache.commands.CacheCommand;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedList;
 import java.util.List;
 
 /**
- * The purpose of this class is to build and manage additional interceptor chains.
+ * Knows how to build and manage an chain of interceptors. Also in charge with invoking methods on the chain.
  *
  * @author Mircea.Markus at jboss.com
  * @since 2.2
  */
 public class InterceptorChain
 {
+   /**
+    * reference to the first interceptor in the chain
+    */
    private ChainedInterceptor firstInChain;
 
-   private ComponentRegistry componentRegistry;
-
+   /**
+    * used for invoking commands on the chain
+    */
    private InvocationContextContainer invocationContextContainer;
 
+   /**
+    * Constructs an interceptor chain having the supplied interceptor as first.
+    */
    public InterceptorChain(ChainedInterceptor first)
    {
       this.firstInChain = first;
    }
 
    @Inject
-   public void initialize(InvocationContextContainer invocationContextContainer, ComponentRegistry componentRegistry)
+   public void initialize(InvocationContextContainer invocationContextContainer)
    {
       this.invocationContextContainer = invocationContextContainer;
-      this.componentRegistry = componentRegistry;
    }
 
-   public synchronized void addInterceptor(ChainedInterceptor i, int position)
+   /**
+    * Inserts the given interceptor at the specified position in the chain (o based indexing).
+    * If the position is invalid (e.g. 5 and there are only 2 interceptors in the chain) this is a no-op.
+    */
+   public synchronized void addInterceptor(ChainedInterceptor interceptor, int position)
    {
-      List<ChainedInterceptor> interceptors = getInterceptorsList();
-      interceptors.add(position, i);
-      // now correct the chaining of interceptors...
-      ChainedInterceptor linkedChain = correctInterceptorChaining(interceptors);
-      setFirstInChain(linkedChain);
-   }
+      if (position == 0)
+      {
+         interceptor.setNext(firstInChain);
+         firstInChain = interceptor;
+         return;
+      }
+      if (firstInChain == null) return;
+      ChainedInterceptor it = firstInChain;
+      int index = 0;
+      while (it != null)
+      {
+         if (++index == position)
+         {
+            interceptor.setNext(it.getNext());
+            it.setNext(interceptor);
+            return;
+         }
+         it = it.getNext();
 
-   public synchronized void removeInterceptor(int position)
-   {
-      List<ChainedInterceptor> i = getInterceptorsList();
-      i.remove(position);
-      setFirstInChain(correctInterceptorChaining(i));
+      }
    }
 
    /**
-    * "Fixes" the next() and last() pointers for each interceptor, based on the order presented in the list passed in, and
-    * also re-assesses dependencies for each interceptor, injecting dependencies accordingingly.
-    *
-    * @param interceptors interceptor chain to correct
-    * @return the first interceptor in the chain.
+    * Removes the interceptor at the given postion.
+    * If the position is invalid (e.g. 5 and there are only 2 interceptors in the chain) this is a no-op.
     */
-   public ChainedInterceptor correctInterceptorChaining(List<ChainedInterceptor> interceptors)
+   public synchronized void removeInterceptor(int position)
    {
-      ChainedInterceptor first = null, last = null;
-      for (ChainedInterceptor next : interceptors)
+      if (firstInChain == null) return;
+      if (position == 0)
       {
-         if (first == null)
+         firstInChain = firstInChain.getNext();
+         return;
+      }
+      ChainedInterceptor it = firstInChain;
+      int index = 0;
+      while (it != null)
+      {
+         if (++index == position)
          {
-            first = last = next;
-            continue;
+            if (it.getNext() == null) return; //nothing to remove
+            it.setNext(it.getNext().getNext());
          }
-         last.setNext(next);
-         last = next;
+         it = it.getNext();
       }
-
-      if (last != null) last.setNext(null);
-
-      // now set the 'last' pointer.
-      ChainedInterceptor i = setLastInterceptorPointer(last);
-      return i;
    }
 
-   public ChainedInterceptor setLastInterceptorPointer(ChainedInterceptor last)
+   /**
+    * Returns the number of interceptors in the chain.
+    */
+   public int size()
    {
-      ChainedInterceptor i = firstInChain;
-      while (i != null)
+      int size = 0;
+      ChainedInterceptor it = firstInChain;
+      while (it != null)
       {
-         i.setLast(last);
-         i = i.getNext();
+         size++;
+         it = it.getNext();
       }
-      return firstInChain;
+      return size;
+
    }
 
-
-   public List<ChainedInterceptor> getInterceptorsList()
+   /**
+    * Returns an unmofiable list with all the interceptors in sequence.
+    * If first in chain is null an empty list is returned.
+    */
+   public List<ChainedInterceptor> getInterceptorsAsList()
    {
-      List<ChainedInterceptor> result;
-      if (firstInChain == null)
-      {
-         result = null;
-      }
-      int num = 1;
-      ChainedInterceptor tmp = firstInChain;
-      while ((tmp = tmp.getNext()) != null)
-      {
-         num++;
-      }
-      List<ChainedInterceptor> retval = new ArrayList<ChainedInterceptor>(num);
-      tmp = firstInChain;
-      num = 0;
-      do
-      {
-         retval.add(tmp);
-         tmp = tmp.getNext();
-      }
-      while (tmp != null);
-      return Collections.unmodifiableList(retval);
+      return Collections.unmodifiableList(getInterceptorsAsListModifiable());
    }
 
 
-   private void setFirstInChain(ChainedInterceptor startOfNewChain)
+   /**
+    * Removes all the occurences of supplied interceptor type from the chain.
+    */
+   public synchronized void removeInterceptor(Class<? extends ChainedInterceptor> clazz)
    {
-      firstInChain = startOfNewChain;
-   }
-
-   public synchronized void removeInterceptor(Class<? extends ChainedInterceptor> interceptorType)
-   {
-      List<ChainedInterceptor> interceptors = getInterceptorsList();
-      int position = -1;
-      boolean found = false;
-      for (ChainedInterceptor interceptor : interceptors)
+      if (firstInChain.getClass() == clazz)
       {
-         position++;
-         if (interceptor.getClass().equals(interceptorType))
+         firstInChain = firstInChain.getNext();
+      }
+      ChainedInterceptor it = firstInChain.getNext();
+      ChainedInterceptor prevIt = firstInChain;
+      while (it != null)
+      {
+         if (it.getClass() == clazz)
          {
-            found = true;
-            break;
+            prevIt.setNext(it.getNext());
          }
+         prevIt = it;
+         it = it.getNext();
       }
-      if (found)
-      {
-         interceptors.remove(position);
-         setFirstInChain(correctInterceptorChaining(interceptors));
-      }
    }
 
-   public synchronized boolean addInterceptor(ChainedInterceptor i, Class<? extends ChainedInterceptor> afterInterceptor)
+   /**
+    * Adds a new interceptor in list after an interceptor of a given type.
+    *
+    * @return true if the interceptor was added; i.e. the afterInterceptor exists
+    */
+   public synchronized boolean addInterceptor(ChainedInterceptor toAdd, Class<? extends ChainedInterceptor> afterInterceptor)
    {
-      List<ChainedInterceptor> interceptors = getInterceptorsList();
-      int position = -1;
-      boolean found = false;
-      for (ChainedInterceptor interceptor : interceptors)
+      ChainedInterceptor it = firstInChain;
+      while (it != null)
       {
-         position++;
-         if (interceptor.getClass().equals(afterInterceptor))
+         if (it.getClass().equals(afterInterceptor))
          {
-            found = true;
-            break;
+            toAdd.setNext(it.getNext());
+            it.setNext(toAdd);
+            return true;
          }
+         it = it.getNext();
       }
-
-      if (found)
-      {
-         interceptors.add(++position, i);
-         setFirstInChain(correctInterceptorChaining(interceptors));
-         // make sure I start the last 2 "manually startable" components
-      }
-      return found;
+      return false;
    }
 
+   /**
+    * Returns the chain as a list.
+    */
    public List<ChainedInterceptor> asList()
    {
-      return asList(this.firstInChain);
-   }
-
-   public List<ChainedInterceptor> asList(ChainedInterceptor interceptor)
-   {
-      if (interceptor == null)
+      List<ChainedInterceptor> result;
+      if (this.firstInChain == null)
       {
-         return null;
+         result = null;
       }
       int num = 1;
-      ChainedInterceptor tmp = interceptor;
+      ChainedInterceptor tmp = this.firstInChain;
       while ((tmp = tmp.getNext()) != null)
       {
          num++;
       }
       List<ChainedInterceptor> retval = new ArrayList<ChainedInterceptor>(num);
-      tmp = interceptor;
+      tmp = this.firstInChain;
       num = 0;
       do
       {
@@ -195,10 +189,21 @@
          tmp = tmp.getNext();
       }
       while (tmp != null);
-      return retval;
+      result = retval;
+      return result;
    }
 
    /**
+    * Appends at the end.
+    */
+   public void appendIntereceptor(ChainedInterceptor ci)
+   {
+      ChainedInterceptor it = firstInChain;
+      while (it.hasNext()) it = it.getNext();
+      it.setNext(ci);
+   }
+
+   /**
     * Walks the command through the interceptor chain. The received ctx is being passed in.
     */
    public Object invoke(InvocationContext ctx, CacheCommand command) throws Throwable
@@ -215,4 +220,26 @@
       InvocationContext ctxt = invocationContextContainer.get();
       return cacheCommand.accept(ctxt, firstInChain);
    }
+
+   public ChainedInterceptor getFirstInChain()
+   {
+      return firstInChain;
+   }
+
+   private List<ChainedInterceptor> getInterceptorsAsListModifiable()
+   {
+      if (firstInChain == null)
+      {
+         return Collections.EMPTY_LIST;
+      }
+      List<ChainedInterceptor> retval = new LinkedList<ChainedInterceptor>();
+      ChainedInterceptor tmp = firstInChain;
+      do
+      {
+         retval.add(tmp);
+         tmp = tmp.getNext();
+      }
+      while (tmp != null);
+      return retval;
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -29,7 +29,7 @@
    private static Log log = LogFactory.getLog(LockManager.class);
 
    private Configuration configuration;
-   private long lockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
+   private long lockAcquisitionTimeout;
    private CacheData cacheData;
    private NodeSPI rootNode;
    private TransactionTable txTable;

Modified: core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainTestBase.java	2008-04-10 04:27:48 UTC (rev 5527)
+++ core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainTestBase.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -11,19 +11,6 @@
  */
 public abstract class InterceptorChainTestBase
 {
-   protected void assertLast(ChainedInterceptor first, ChainedInterceptor last)
-   {
-      assertNotNull("First interceptor in the chain cannot be null", first);
-      assertNotNull("Last interceptor in the chain cannot be null", last);
-
-      ChainedInterceptor i = first;
-      while (i != null)
-      {
-         assertEquals("Expected last interceptor (in " + i + ") to be " + last, last, i.getLast());
-         i = i.getNext();
-      }
-   }
-
    protected void assertInterceptorLinkage(List<ChainedInterceptor> list)
    {
       ChainedInterceptor previous = null;
@@ -39,7 +26,5 @@
 
          previous = i;
       }
-
-      assertLast(list.get(0), previous);
    }
 }
\ No newline at end of file

Added: core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java	2008-04-10 23:12:19 UTC (rev 5528)
@@ -0,0 +1,164 @@
+package org.jboss.cache.invocation;
+
+import org.jboss.cache.interceptors.*;
+import org.jboss.cache.interceptors.base.ChainedInterceptor;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests functionality defined by InterceptorChain.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+ at Test(groups = {"functional"})
+public class InterceptorChainTest
+{
+   private ChainedInterceptor icInterceptor;
+   private ChainedInterceptor invalidationInterceptor;
+   private ChainedInterceptor txInterceptor;
+   private ChainedInterceptor pessimisticInterceptor;
+   private ChainedInterceptor callInterceptor;
+   private InterceptorChain chain;
+
+   @BeforeMethod
+   public void setUp()
+   {
+      icInterceptor = create(InvocationContextInterceptor.class);
+      invalidationInterceptor = create(InvalidationInterceptor.class);
+      txInterceptor = create(TxInterceptor.class);
+      pessimisticInterceptor = create(PessimisticLockInterceptor.class);
+      callInterceptor = create(CallInterceptor.class);
+      chain = new InterceptorChain(icInterceptor);
+   }
+
+   public void testGetIntercpetorsAsList() throws Throwable
+   {
+      invalidationInterceptor.setNext(txInterceptor);
+      txInterceptor.setNext(pessimisticInterceptor);
+      pessimisticInterceptor.setNext(callInterceptor);
+      
+      InterceptorChain chain = new InterceptorChain(invalidationInterceptor);
+      List<ChainedInterceptor> expectedList = new ArrayList<ChainedInterceptor>();
+      expectedList.add(invalidationInterceptor);
+      expectedList.add(txInterceptor);
+      expectedList.add(pessimisticInterceptor);
+      expectedList.add(callInterceptor);
+      
+      assert chain.getInterceptorsAsList().equals(expectedList);
+   }
+
+   public void testAddAtPosition() throws Throwable
+   {
+      chain.addInterceptor(invalidationInterceptor, 1);
+      assert invalidationInterceptor.equals(icInterceptor.getNext());
+
+      chain.addInterceptor(pessimisticInterceptor,1);
+      assert pessimisticInterceptor.equals(icInterceptor.getNext());
+      assert invalidationInterceptor.equals(pessimisticInterceptor.getNext());
+      assert invalidationInterceptor.getNext() == null;
+
+      chain.addInterceptor(callInterceptor, 3);
+      assert invalidationInterceptor.getNext().equals(callInterceptor);
+   }
+
+   public void testAddAtPositionIncremented()
+   {
+      chain.addInterceptor(txInterceptor,1);
+      chain.addInterceptor(invalidationInterceptor,2);
+      chain.addInterceptor(pessimisticInterceptor,3);
+      chain.addInterceptor(callInterceptor,4);
+      assert icInterceptor.getNext().equals(txInterceptor);
+      assert txInterceptor.getNext().equals(invalidationInterceptor);
+      assert invalidationInterceptor.getNext().equals(pessimisticInterceptor);
+      assert pessimisticInterceptor.getNext().equals(callInterceptor);
+   }
+
+   public void testRemoveAtPostion() throws Throwable
+   {
+      chain.addInterceptor(txInterceptor,1);
+      chain.addInterceptor(invalidationInterceptor,2);
+      chain.addInterceptor(pessimisticInterceptor,3);
+      chain.addInterceptor(callInterceptor,4);
+
+      chain.removeInterceptor(4);
+      assert chain.size() == 4;
+      assert pessimisticInterceptor.getNext() == null;
+
+      chain.removeInterceptor(0);
+      assert chain.size() == 3;
+      chain.getFirstInChain().equals(txInterceptor);
+
+      chain.removeInterceptor(1);
+      assert chain.size() == 2;
+      assert txInterceptor.getNext().equals(pessimisticInterceptor);
+   }
+
+   public void testGetSize()
+   {
+      assert chain.size() == 1;
+      chain.addInterceptor(txInterceptor,1);
+      assert chain.size() == 2;
+      chain.addInterceptor(invalidationInterceptor,2);
+      assert chain.size() == 3;
+      chain.addInterceptor(pessimisticInterceptor,3);
+      assert chain.size() == 4;
+      chain.addInterceptor(callInterceptor,4);
+      assert chain.size() == 5;
+   }
+
+   public void testAppendInterceptor()
+   {
+      chain.appendIntereceptor(txInterceptor);
+      assert chain.size() == 2;
+      assert icInterceptor.getNext().equals(txInterceptor);
+
+      chain.appendIntereceptor(invalidationInterceptor);
+      assert chain.size() == 3;
+      assert txInterceptor.getNext().equals(invalidationInterceptor);
+   }
+
+   public void removeInterceptorWithtType()
+   {
+      chain.addInterceptor(txInterceptor,1);
+      chain.addInterceptor(invalidationInterceptor,2);
+      chain.addInterceptor(pessimisticInterceptor,3);
+      chain.addInterceptor(callInterceptor,4);
+
+      chain.removeInterceptor(InvalidationInterceptor.class);
+      assert chain.size() == 4;
+      assert txInterceptor.getNext().equals(pessimisticInterceptor);
+
+      chain.removeInterceptor(InvocationContextInterceptor.class);
+      assert chain.size() == 3;
+      assert chain.getFirstInChain().equals(txInterceptor);
+
+      chain.removeInterceptor(CallInterceptor.class);
+      assert chain.size() == 2;
+      assert pessimisticInterceptor.getNext() == null;
+   }
+
+   public void addInterceptorWithType()
+   {
+      assert chain.addInterceptor(invalidationInterceptor, icInterceptor.getClass());
+      assert icInterceptor.getNext().equals(invalidationInterceptor);
+
+      chain.addInterceptor(txInterceptor, icInterceptor.getClass());
+      assert icInterceptor.getNext().equals(txInterceptor);
+      assert txInterceptor.getNext().equals(invalidationInterceptor);
+   }
+
+   public ChainedInterceptor create(Class<? extends ChainedInterceptor> toInstantiate)
+   {
+      try
+      {
+         return toInstantiate.newInstance();
+      } catch (Throwable th)
+      {
+         throw new RuntimeException(th);
+      }
+   }
+}




More information about the jbosscache-commits mailing list