[jbosscache-commits] JBoss Cache SVN: r6856 - core/branches/flat/src/main/java/org/jboss/starobrno/context.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Wed Oct 8 04:46:07 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-10-08 04:46:07 -0400 (Wed, 08 Oct 2008)
New Revision: 6856

Added:
   core/branches/flat/src/main/java/org/jboss/starobrno/context/EntryLookup.java
   core/branches/flat/src/main/java/org/jboss/starobrno/context/TransactionContext.java
   core/branches/flat/src/main/java/org/jboss/starobrno/context/TransactionContextImpl.java
Modified:
   core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContext.java
   core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContextImpl.java
Log:
Contexts

Added: core/branches/flat/src/main/java/org/jboss/starobrno/context/EntryLookup.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/context/EntryLookup.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/context/EntryLookup.java	2008-10-08 08:46:07 UTC (rev 6856)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.context;
+
+import org.jboss.starobrno.mvcc.MVCCEntry;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * // TODO: MANIK: Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public interface EntryLookup
+{
+   MVCCEntry lookupEntry(Object key);
+
+   Map<Object, MVCCEntry> getLookedUpEntries();
+
+   void putLookedUpEntry(MVCCEntry e);
+
+   void putLookedUpEntries(Set<MVCCEntry> lookedUpEntries);
+
+   void clearLookedUpEntries();
+}

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContext.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContext.java	2008-10-08 08:22:02 UTC (rev 6855)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContext.java	2008-10-08 08:46:07 UTC (rev 6856)
@@ -24,13 +24,9 @@
 import org.jboss.cache.commands.VisitableCommand;
 import org.jboss.cache.config.Option;
 import org.jboss.cache.transaction.GlobalTransaction;
-import org.jboss.cache.transaction.TransactionContext;
-import org.jboss.starobrno.mvcc.MVCCEntry;
 
 import javax.transaction.Transaction;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * // TODO: MANIK: Document this
@@ -38,18 +34,8 @@
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 3.0
  */
-public interface InvocationContext
+public interface InvocationContext extends EntryLookup
 {
-   MVCCEntry lookupEntry(Object key);
-
-   Map<Object, MVCCEntry> getLookedUpEntries();
-
-   void putLookedUpEntry(MVCCEntry e);
-
-   void putLookedUpEntries(Set<MVCCEntry> lookedUpEntries);
-
-   void clearLookedUpEntries();
-
    void setLocalRollbackOnly(boolean localRollbackOnly);
 
    Transaction getTransaction();

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContextImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContextImpl.java	2008-10-08 08:22:02 UTC (rev 6855)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContextImpl.java	2008-10-08 08:46:07 UTC (rev 6856)
@@ -29,7 +29,6 @@
 import org.jboss.cache.config.Option;
 import org.jboss.cache.marshall.MethodCall;
 import org.jboss.cache.transaction.GlobalTransaction;
-import org.jboss.cache.transaction.TransactionContext;
 import org.jboss.cache.transaction.TransactionTable;
 import org.jboss.cache.util.Immutables;
 import org.jboss.starobrno.mvcc.MVCCEntry;
@@ -86,10 +85,8 @@
     */
    public MVCCEntry lookupEntry(Object k)
    {
-      // TODO: Fix this after we have a Transaction context that works.
-//      if (transactionContext != null) return transactionContext.lookupEntry(k);
-//      return lookedUpEntries == null ? null : lookedUpEntries.get(k);
-      return null;
+      if (transactionContext != null) return transactionContext.lookupEntry(k);
+      return lookedUpEntries == null ? null : lookedUpEntries.get(k);
    }
 
    /**
@@ -103,29 +100,26 @@
     */
    public void putLookedUpEntry(MVCCEntry e)
    {
-      // TODO: Fix this after we have a Transaction context that works.
-
-//      if (transactionContext != null)
-//         transactionContext.putLookedUpEntry(e);
-//      else
-//      {
-//         if (lookedUpEntries == null) lookedUpEntries = new HashMap<Object, MVCCEntry>(4);
-//         lookedUpEntries.put(e.getKey(), e);
-//      }
+      if (transactionContext != null)
+         transactionContext.putLookedUpEntry(e);
+      else
+      {
+         if (lookedUpEntries == null) lookedUpEntries = new HashMap<Object, MVCCEntry>(4);
+         lookedUpEntries.put(e.getKey(), e);
+      }
    }
 
    public void putLookedUpEntries(Set<MVCCEntry> lookedUpEntries)
    {
-      // TODO: Fix this after we have a Transaction context that works.
-//      if (transactionContext != null)
-//         transactionContext.putLookedUpEntries(lookedUpEntries);
-//      else
-//      {
-//         if (this.lookedUpEntries == null)
-//            this.lookedUpEntries = new HashMap<Object, MVCCEntry>();
-//
-//         for (MVCCEntry e: lookedUpEntries) this.lookedUpEntries.put(e.getKey(), e);
-//      }
+      if (transactionContext != null)
+         transactionContext.putLookedUpEntries(lookedUpEntries);
+      else
+      {
+         if (this.lookedUpEntries == null)
+            this.lookedUpEntries = new HashMap<Object, MVCCEntry>();
+
+         for (MVCCEntry e : lookedUpEntries) this.lookedUpEntries.put(e.getKey(), e);
+      }
    }
 
    /**
@@ -135,12 +129,9 @@
     */
    public void clearLookedUpEntries()
    {
-      // TODO: see if we can reinstate common behaviour once we have the ICI calling ctx.reset() instead of ctx.clearLookedUpNodes()
-//      if (transactionContext != null)
-//         transactionContext.clearLookedUpNodes();
-//      else
-
-      if (lookedUpEntries != null) lookedUpEntries.clear();
+      if (transactionContext != null)
+         transactionContext.clearLookedUpEntries();
+      else if (lookedUpEntries != null) lookedUpEntries.clear();
    }
 
    /**
@@ -154,10 +145,8 @@
    @SuppressWarnings("unchecked")
    public Map<Object, MVCCEntry> getLookedUpEntries()
    {
-      // TODO: Fix this after we have a Transaction context that works.
-//      if (transactionContext != null) return transactionContext.getLookedUpNodes();
-//      return (Map<Fqn, NodeSPI>) (lookedUpEntries == null ? Collections.emptyMap() : lookedUpEntries);
-      return null;
+      if (transactionContext != null) return transactionContext.getLookedUpEntries();
+      return (Map<Object, MVCCEntry>) (lookedUpEntries == null ? Collections.emptyMap() : lookedUpEntries);
    }
 
    @SuppressWarnings("unchecked")
@@ -299,7 +288,7 @@
    public List getKeysLocked()
    {
       // first check transactional scope
-      if (transactionContext != null) return transactionContext.getLocks();
+      if (transactionContext != null) return transactionContext.getKeysLocked();
       return invocationLocks == null || invocationLocks.isEmpty() ? Collections.emptyList() : Immutables.immutableListConvert(invocationLocks);
    }
 
@@ -316,12 +305,12 @@
     * @param locks locks to add
     */
    @SuppressWarnings("unchecked")
-   public void addAllKeysLocked(List locks)
+   public void addAllKeysLocked(List<Object> locks)
    {
       // first check transactional scope
       if (transactionContext != null)
       {
-         transactionContext.addAllLocks(locks);
+         transactionContext.addAllKeysLocked(locks);
       }
       else
       {
@@ -349,7 +338,7 @@
       // first check transactional scope
       if (transactionContext != null)
       {
-         transactionContext.addLock(lock);
+         transactionContext.addKeyLocked(lock);
       }
       else
       {
@@ -377,7 +366,7 @@
       // first check transactional scope
       if (transactionContext != null)
       {
-         transactionContext.removeLock(lock);
+         transactionContext.removeKeyLocked(lock);
       }
       else
       {
@@ -401,7 +390,7 @@
       // first check transactional scope
       if (transactionContext != null)
       {
-         transactionContext.clearLocks();
+         transactionContext.clearKeysLocked();
       }
       else
       {
@@ -422,7 +411,7 @@
       // first check transactional scope
       if (transactionContext != null)
       {
-         return transactionContext.hasLock(lock);
+         return transactionContext.hasLockedKey(lock);
       }
       else
       {

Added: core/branches/flat/src/main/java/org/jboss/starobrno/context/TransactionContext.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/context/TransactionContext.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/context/TransactionContext.java	2008-10-08 08:46:07 UTC (rev 6856)
@@ -0,0 +1,283 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.context;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
+
+import javax.transaction.Transaction;
+import java.util.List;
+
+/**
+ * Captures information pertaining to a specific JTA transaction.
+ * <p/>
+ * This was a concrete class called TransactionEntry prior to 3.0.
+ * <p/>
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @see org.jboss.cache.InvocationContext
+ */
+public interface TransactionContext extends EntryLookup
+{
+   /**
+    * Adds a modification to the modification list.
+    *
+    * @param command modification
+    */
+   void addModification(WriteCommand command);
+
+   /**
+    * Returns all modifications.  If there are no modifications in this transaction this method will return an empty list.
+    *
+    * @return list of modifications.
+    */
+   List<WriteCommand> getModifications();
+
+   /**
+    * Adds a modification to the local modification list.
+    *
+    * @param command command to add to list.  Should not be null.
+    * @throws NullPointerException if the command to be added is null.
+    */
+   void addLocalModification(WriteCommand command);
+
+   /**
+    * Returns all modifications that have been invoked with the LOCAL cache mode option.  These will also be in the standard modification list.
+    *
+    * @return list of LOCAL modifications, or an empty list.
+    */
+   List<WriteCommand> getLocalModifications();
+
+   /**
+    * Adds the node that has been removed in the scope of the current transaction.
+    *
+    * @param fqn fqn that has been removed.
+    * @throws NullPointerException if the Fqn is null.
+    */
+   void addRemovedNode(Fqn fqn);
+
+   /**
+    * Gets the list of removed nodes.
+    *
+    * @return list of nodes removed in the current transaction scope.  Note that this method will return an empty list if nothing has been removed.  The list returned is defensively copied.
+    */
+   List<Fqn> getRemovedNodes();
+
+   /**
+    * Sets the local transaction to be associated with this transaction context.
+    *
+    * @param tx JTA transaction to associate with.
+    */
+   void setTransaction(Transaction tx);
+
+   /**
+    * Returns a local transaction associated with this context.
+    *
+    * @return a JTA transaction
+    */
+   Transaction getTransaction();
+
+   /**
+    * Adds a lock to the currently maintained collection of locks acquired.
+    * <p/>
+    * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#addLock(Object)} instead,
+    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+    * <p/>
+    * Note that currently (as of 3.0.0) this lock is weakly typed.  This is to allow support for both MVCC (which uses {@link org.jboss.cache.Fqn}s as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link org.jboss.cache.Fqn}.
+    *
+    * @param lock lock to add
+    * @see org.jboss.cache.InvocationContext#addLock(Object)
+    */
+   @SuppressWarnings("unchecked")
+   void addKeyLocked(Object lock);
+
+   /**
+    * Removes a lock from the currently maintained collection of locks acquired.
+    * <p/>
+    * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#removeLock(Object)}  instead,
+    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+    * <p/>
+    * Note that currently (as of 3.0.0) this lock is weakly typed.  This is to allow support for both MVCC (which uses {@link org.jboss.cache.Fqn}s as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link org.jboss.cache.Fqn}.
+    *
+    * @param lock lock to remove
+    * @see org.jboss.cache.InvocationContext#removeLock(Object)
+    */
+   @SuppressWarnings("unchecked")
+   void removeKeyLocked(Object lock);
+
+   /**
+    * Clears all locks from the currently maintained collection of locks acquired.
+    * <p/>
+    * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#clearLocks()} instead,
+    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+    * <p/>
+    * Note that currently (as of 3.0.0) this lock is weakly typed.  This is to allow support for both MVCC (which uses {@link org.jboss.cache.Fqn}s as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link org.jboss.cache.Fqn}.
+    *
+    * @see org.jboss.cache.InvocationContext#clearLocks()
+    */
+   void clearKeysLocked();
+
+   /**
+    * Adds a List of locks to the currently maintained collection of locks acquired.
+    * <p/>
+    * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#addAllLocks(java.util.List)} instead,
+    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+    * <p/>
+    * Note that currently (as of 3.0.0) this list is unchecked.  This is to allow support for both MVCC (which uses Fqns as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to accept <tt>List<Fqn></tt>.
+    *
+    * @param newLocks locks to add
+    * @see org.jboss.cache.InvocationContext#addAllLocks(java.util.List)
+    */
+   @SuppressWarnings("unchecked")
+   void addAllKeysLocked(List<Object> newLocks);
+
+   /**
+    * Returns an immutable,  defensive copy of the List of locks currently maintained for the transaction.
+    * <p/>
+    * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#getLocks()} instead,
+    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+    * <p/>
+    * Note that currently (as of 3.0.0) this list is unchecked.  This is to allow support for both MVCC (which uses Fqns as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to return <tt>List<Fqn></tt>.
+    *
+    * @return locks held in current scope.
+    * @see org.jboss.cache.InvocationContext#getLocks()
+    */
+   @SuppressWarnings("unchecked")
+   List<Object> getKeysLocked();
+
+   /**
+    * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#hasLock(Object)} ()} instead,
+    * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+    *
+    * @param lock lock to test
+    * @return true if the lock being tested is already held in the current scope, false otherwise.
+    */
+   boolean hasLockedKey(Object lock);
+
+   /**
+    * Gets the value of the forceAsyncReplication flag.  Used by ReplicationInterceptor and OptimisticReplicationInterceptor
+    * when dealing with {@link org.jboss.cache.Cache#putForExternalRead(org.jboss.cache.Fqn,Object,Object)} within
+    * a transactional context.
+    *
+    * @return true if the forceAsyncReplication flag is set to true.
+    */
+   boolean isForceAsyncReplication();
+
+   /**
+    * Sets the value of the forceAsyncReplication flag.  Used by ReplicationInterceptor and OptimisticReplicationInterceptor
+    * when dealing with {@link org.jboss.cache.Cache#putForExternalRead(org.jboss.cache.Fqn,Object,Object)} within
+    * a transactional context. Also used by OptimisticReplicationInterceptor when dealing
+    * with {@link org.jboss.cache.config.Option#setForceAsynchronous(boolean)} in a
+    * non-transactional context (i.e. with an implicit transaction).
+    *
+    * @param forceAsyncReplication value of forceAsyncReplication
+    */
+   void setForceAsyncReplication(boolean forceAsyncReplication);
+
+   /**
+    * Gets the value of the forceSyncReplication flag.  Used by ReplicationInterceptor and OptimisticReplicationInterceptor
+    * when dealing with {@link org.jboss.cache.Cache#putForExternalRead(org.jboss.cache.Fqn,Object,Object)} within
+    * a transactional context.
+    *
+    * @return true if the forceAsyncReplication flag is set to true.
+    */
+   boolean isForceSyncReplication();
+
+   /**
+    * Sets the value of the forceSyncReplication flag.  Used by ReplicationInterceptor and OptimisticReplicationInterceptor
+    * when dealing with {@link org.jboss.cache.Cache#putForExternalRead(org.jboss.cache.Fqn,Object,Object)} within
+    * a transactional context.
+    *
+    * @param forceSyncReplication value of forceSyncReplication
+    */
+   void setForceSyncReplication(boolean forceSyncReplication);
+
+   /**
+    * Adds an Fqn to the list of uninitialized nodes created by the cache loader.
+    *
+    * @param fqn fqn to add.  Must not be null.
+    */
+   void addDummyNodeCreatedByCacheLoader(Fqn fqn);
+
+   /**
+    * @return a list of uninitialized nodes created by the cache loader, or an empty list.
+    */
+   List<Fqn> getDummyNodesCreatedByCacheLoader();
+
+   /**
+    * Sets a transaction-scope option override
+    *
+    * @param o option to set
+    */
+   void setOption(Option o);
+
+   /**
+    * Retrieves a transaction scope option override
+    *
+    * @return option
+    */
+   Option getOption();
+
+   /**
+    * @return the ordered sync handler associated with this transaction
+    */
+   OrderedSynchronizationHandler getOrderedSynchronizationHandler();
+
+   /**
+    * Associates an ordered sync handler with this transaction.
+    *
+    * @param orderedSynchronizationHandler to set
+    */
+   void setOrderedSynchronizationHandler(OrderedSynchronizationHandler orderedSynchronizationHandler);
+
+   /**
+    * @return true if modifications were registered.
+    */
+   boolean hasModifications();
+
+   /**
+    * @return true if any modifications have been invoked with cache mode being LOCAL.
+    */
+   boolean hasLocalModifications();
+
+   /**
+    * @return true if either there are modifications or local modifications that are not for replicating.
+    */
+   boolean hasAnyModifications();
+
+   /**
+    * Cleans up internal state, freeing up references.
+    */
+   void reset();
+}

Added: core/branches/flat/src/main/java/org/jboss/starobrno/context/TransactionContextImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/context/TransactionContextImpl.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/context/TransactionContextImpl.java	2008-10-08 08:46:07 UTC (rev 6856)
@@ -0,0 +1,346 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.context;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
+import org.jboss.cache.util.Immutables;
+import org.jboss.starobrno.mvcc.MVCCEntry;
+
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A transaction context specially geared to dealing with MVCC.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class TransactionContextImpl implements TransactionContext
+{
+   /**
+    * Local transaction
+    */
+   private Transaction ltx = null;
+   private Option option;
+   private OrderedSynchronizationHandler orderedSynchronizationHandler;
+
+   private boolean forceAsyncReplication = false;
+   private boolean forceSyncReplication = false;
+
+   /**
+    * List&lt;ReversibleCommand&gt; of modifications ({@link org.jboss.cache.commands.WriteCommand}). They will be replicated on TX commit
+    */
+   private List<WriteCommand> modificationList;
+   /**
+    * A list of modifications that have been encountered with a LOCAL mode option.  These will be removed from the modification list during replication.
+    */
+   private List<WriteCommand> localModifications;
+
+   /**
+    * LinkedHashSet of locks acquired by the transaction. We use a LinkedHashSet because we need efficient Set semantics
+    * but also need guaranteed ordering for use by lock release code (see JBCCACHE-874).
+    * <p/>
+    * This needs to be unchecked since we support both MVCC (Fqns held here) or legacy Opt/Pess locking (NodeLocks held here).
+    * once we drop support for opt/pess locks we can genericise this to contain Fqns. - Manik Surtani, June 2008
+    */
+   private LinkedHashSet<Object> transactionLocks;
+
+   /**
+    * A list of dummy uninitialised nodes created by the cache loader interceptor to load data for a
+    * given node in this tx.
+    */
+   private List<Fqn> dummyNodesCreatedByCacheLoader;
+
+   /**
+    * List<Fqn> of nodes that have been removed by the transaction
+    */
+   private List<Fqn> removedNodes = null;
+
+   private final Map<Object, MVCCEntry> lookedUpEntries = new HashMap<Object, MVCCEntry>(8);
+
+   public TransactionContextImpl(Transaction tx) throws SystemException, RollbackException
+   {
+      ltx = tx;
+      orderedSynchronizationHandler = new OrderedSynchronizationHandler(tx);
+   }
+
+   /**
+    * Retrieves a node from the registry of looked up nodes in the current scope.
+    * <p/>
+    * This is not normally called directly since {@link org.jboss.cache.InvocationContext#lookUpNode(org.jboss.cache.Fqn)}
+    * would delegate to this method if a transaction is in scope.
+    * <p/>
+    *
+    * @param fqn fqn to look up
+    * @return a node, or null if it cannot be found.
+    */
+   public MVCCEntry lookupEntry(Object key)
+   {
+      return lookedUpEntries.get(key);
+   }
+
+   /**
+    * Puts an entry in the registry of looked up nodes in the current scope.
+    * <p/>
+    * This is not normally called directly since {@link org.jboss.cache.InvocationContext#putLookedUpNode(org.jboss.cache.Fqn, org.jboss.cache.NodeSPI)}
+    * would delegate to this method if a transaction is in scope.
+    * <p/>
+    *
+    * @param f fqn to add
+    * @param n node to add
+    */
+   public void putLookedUpEntry(MVCCEntry entry)
+   {
+      lookedUpEntries.put(entry.getKey(), entry);
+   }
+
+   /**
+    * Clears the registry of looked up nodes.
+    * <p/>
+    * This is not normally called directly since {@link org.jboss.cache.InvocationContext#clearLookedUpNodes()}
+    * would delegate to this method if a transaction is in scope.
+    * <p/>
+    */
+   public void clearLookedUpEntries()
+   {
+      lookedUpEntries.clear();
+   }
+
+   /**
+    * Retrieves a map of nodes looked up within the current invocation's scope.
+    * <p/>
+    * This is not normally called directly since {@link org.jboss.cache.InvocationContext#getLookedUpNodes()}
+    * would delegate to this method if a transaction is in scope.
+    * <p/>
+    *
+    * @return a map of looked up nodes.
+    */
+   public Map<Object, MVCCEntry> getLookedUpEntries()
+   {
+      return lookedUpEntries;
+   }
+
+   public void reset()
+   {
+      orderedSynchronizationHandler = null;
+      modificationList = null;
+      localModifications = null;
+      option = null;
+      if (transactionLocks != null) transactionLocks.clear();
+      if (dummyNodesCreatedByCacheLoader != null) dummyNodesCreatedByCacheLoader.clear();
+      if (removedNodes != null) removedNodes.clear();
+      lookedUpEntries.clear();
+   }
+
+   public void putLookedUpEntries(Set<MVCCEntry> entries)
+   {
+      for (MVCCEntry e : entries) lookedUpEntries.put(e.getKey(), e);
+   }
+
+   public void addModification(WriteCommand command)
+   {
+      if (command == null) return;
+      if (modificationList == null) modificationList = new LinkedList<WriteCommand>();
+      modificationList.add(command);
+   }
+
+   public List<WriteCommand> getModifications()
+   {
+      if (modificationList == null) return Collections.emptyList();
+      return modificationList;
+   }
+
+   public void addLocalModification(WriteCommand command)
+   {
+      if (command == null) throw new NullPointerException("Command is null!");
+      if (localModifications == null) localModifications = new LinkedList<WriteCommand>();
+      localModifications.add(command);
+   }
+
+   public List<WriteCommand> getLocalModifications()
+   {
+      if (localModifications == null) return Collections.emptyList();
+      return localModifications;
+   }
+
+
+   public void addRemovedNode(Fqn fqn)
+   {
+      if (fqn == null) throw new NullPointerException("Fqn is null!");
+      if (removedNodes == null) removedNodes = new LinkedList<Fqn>();
+      removedNodes.add(fqn);
+   }
+
+   public List<Fqn> getRemovedNodes()
+   {
+      if (removedNodes == null) return Collections.emptyList();
+      return new ArrayList<Fqn>(removedNodes);
+   }
+
+   public void setTransaction(Transaction tx)
+   {
+      ltx = tx;
+   }
+
+   public Transaction getTransaction()
+   {
+      return ltx;
+   }
+
+   @SuppressWarnings("unchecked")
+   public void addKeyLocked(Object lock)
+   {
+      // no need to worry about concurrency here - a context is only valid for a single thread.
+      if (transactionLocks == null) transactionLocks = new LinkedHashSet(5);
+      transactionLocks.add(lock);
+   }
+
+   @SuppressWarnings("unchecked")
+   public void removeKeyLocked(Object lock)
+   {
+      // no need to worry about concurrency here - a context is only valid for a single thread.
+      if (transactionLocks != null) transactionLocks.remove(lock);
+   }
+
+   public void clearKeysLocked()
+   {
+      if (transactionLocks != null) transactionLocks.clear();
+   }
+
+   @SuppressWarnings("unchecked")
+   public void addAllKeysLocked(List<Object> newLocks)
+   {
+      // no need to worry about concurrency here - a context is only valid for a single thread.
+      if (transactionLocks == null) transactionLocks = new LinkedHashSet(5);
+      transactionLocks.addAll(newLocks);
+   }
+
+   @SuppressWarnings("unchecked")
+   public List<Object> getKeysLocked()
+   {
+      return transactionLocks == null || transactionLocks.isEmpty() ? Collections.emptyList() : Immutables.immutableListConvert(transactionLocks);
+   }
+
+   public boolean hasLockedKey(Object lock)
+   {
+      return transactionLocks != null && transactionLocks.contains(lock);
+   }
+
+   public boolean isForceAsyncReplication()
+   {
+      return forceAsyncReplication;
+   }
+
+   public void setForceAsyncReplication(boolean forceAsyncReplication)
+   {
+      this.forceAsyncReplication = forceAsyncReplication;
+      if (forceAsyncReplication)
+      {
+         forceSyncReplication = false;
+      }
+   }
+
+   public boolean isForceSyncReplication()
+   {
+      return forceSyncReplication;
+   }
+
+   public void setForceSyncReplication(boolean forceSyncReplication)
+   {
+      this.forceSyncReplication = forceSyncReplication;
+      if (forceSyncReplication)
+      {
+         forceAsyncReplication = false;
+      }
+   }
+
+   /**
+    * Returns debug information about this transaction.
+    */
+   @Override
+   public String toString()
+   {
+      StringBuilder sb = new StringBuilder();
+      sb.append("TransactionEntry\nmodificationList: ").append(modificationList);
+      return sb.toString();
+   }
+
+   public void addDummyNodeCreatedByCacheLoader(Fqn fqn)
+   {
+      if (dummyNodesCreatedByCacheLoader == null)
+         dummyNodesCreatedByCacheLoader = new LinkedList<Fqn>();
+      dummyNodesCreatedByCacheLoader.add(fqn);
+   }
+
+   public List<Fqn> getDummyNodesCreatedByCacheLoader()
+   {
+      if (dummyNodesCreatedByCacheLoader == null) return Collections.emptyList();
+      return dummyNodesCreatedByCacheLoader;
+   }
+
+   public void setOption(Option o)
+   {
+      this.option = o;
+   }
+
+   public Option getOption()
+   {
+      return this.option;
+   }
+
+   public OrderedSynchronizationHandler getOrderedSynchronizationHandler()
+   {
+      return orderedSynchronizationHandler;
+   }
+
+   public void setOrderedSynchronizationHandler(OrderedSynchronizationHandler orderedSynchronizationHandler)
+   {
+      this.orderedSynchronizationHandler = orderedSynchronizationHandler;
+   }
+
+   public boolean hasModifications()
+   {
+      return modificationList != null && !modificationList.isEmpty();
+   }
+
+   public boolean hasLocalModifications()
+   {
+      return localModifications != null && !localModifications.isEmpty();
+   }
+
+   public boolean hasAnyModifications()
+   {
+      return hasModifications() || hasLocalModifications();
+   }
+}




More information about the jbosscache-commits mailing list