Author: manik.surtani(a)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@jboss.org">manik@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@jboss.org">manik@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@jboss.org">manik@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@jboss.org">manik@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<ReversibleCommand> 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();
+ }
+}