[jboss-svn-commits] JBL Code SVN: r8436 - in labs/jbosstm/trunk: ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore ArjunaJTA/jta/classes/com/arjuna/ats/jta/common ArjunaJTA/jta/classes/com/arjuna/ats/jta/utils atsintegration/classes/com/arjuna/ats/jbossatx/jta

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Dec 20 08:37:41 EST 2006


Author: jhalliday
Date: 2006-12-20 08:37:33 -0500 (Wed, 20 Dec 2006)
New Revision: 8436

Added:
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionSynchronizationRegistryImple.java
Modified:
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseCoordinator.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/SynchronizationImple.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionImple.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/Environment.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/utils/JNDIManager.java
   labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jta/TransactionManagerService.java
Log:
Added JTA support for the TransactionSynchronizationRegistry interface defined in JTA 1.1
Including: Make SynchronizationImple Comparable, add an isInterposed property to it.
Modify TwoPhaseCoordinator to store and iterate registered Synchronizations in defined order.
Modify TransactionImple to support a per-instance Map of key/values pairs and refactor synchronization registration code.
Update JNDIManager and Environment to be aware of TSR.
Modify TransactionManagerService to bind TSR into JNDI at service startup.


Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseCoordinator.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseCoordinator.java	2006-12-20 13:19:57 UTC (rev 8435)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/coordinator/TwoPhaseCoordinator.java	2006-12-20 13:37:33 UTC (rev 8436)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
- * as indicated by the @author tags. 
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
  * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
+ * full listing of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
  * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -24,7 +24,7 @@
  * Hewlett-Packard Arjuna Labs,
  * Newcastle upon Tyne,
  * Tyne and Wear,
- * UK.  
+ * UK.
  *
  * $Id: TwoPhaseCoordinator.java 2342 2006-03-30 13:06:17Z  $
  */
@@ -35,14 +35,17 @@
 
 import com.arjuna.ats.arjuna.logging.tsLogger;
 
-import com.arjuna.ats.internal.arjuna.template.*;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Iterator;
+import java.util.Stack;
 
 /**
  * Adds support for synchronizations to BasicAction. It does not change thread
  * associations either. It also allows any thread to terminate a transaction,
  * even if it is not the transaction that is marked as current for the thread
  * (unlike the BasicAction default).
- * 
+ *
  * @author Mark Little (mark at arjuna.com)
  * @version $Id: TwoPhaseCoordinator.java 2342 2006-03-30 13:06:17Z  $
  * @since JTS 3.0.
@@ -109,12 +112,12 @@
 	}
 
 	public int addSynchronization (SynchronizationRecord sr)
-	{		
+	{
 		if (sr == null)
 			return AddOutcome.AR_REJECTED;
 
 		int result = AddOutcome.AR_REJECTED;
-		
+
 		if (parent() != null)
 			return AddOutcome.AR_REJECTED;
 
@@ -123,10 +126,15 @@
 			case ActionStatus.RUNNING:
 			{
 				if (_synchs == null)
-					_synchs = new HashList(10);
-	
+				{
+					// Synchronizations should be stored (or at least iterated) in their natural order
+					_synchs = new TreeSet();
+				}
+
 				if (_synchs.add(sr))
+				{
 					result = AddOutcome.AR_ADDED;
+				}
 			}
 			break;
 		default:
@@ -185,20 +193,23 @@
 
 		if (_synchs != null)
 		{
-			HashListIterator iterator = new HashListIterator(_synchs);
-			SynchronizationRecord record = (SynchronizationRecord) iterator.iterate();
+			Iterator iterator = _synchs.iterator();
 
 			/*
 			 * We must always call afterCompletion() methods, so just catch (and
 			 * log) any exceptions/errors from beforeCompletion() methods.
+			 *
+			 * If one of the Syncs throws an error the Record wrapper returns false
+			 * and we will rollback. Hence we don't then bother to call beforeCompletion
+			 * on the remaining records (it's not done for rollabcks anyhow).
 			 */
-			while ((record != null) && !problem)
+			while(iterator.hasNext() && !problem)
 			{
+				SynchronizationRecord record = (SynchronizationRecord)iterator.next();
+
 				try
 				{
 					problem = !record.beforeCompletion();
-
-					record = (SynchronizationRecord) iterator.iterate();
 				}
 				catch (Exception ex)
 				{
@@ -255,16 +266,23 @@
 
 		if (_synchs != null)
 		{
-			HashListIterator iterator = new HashListIterator(_synchs);
-			SynchronizationRecord record = (SynchronizationRecord) iterator.iterate();
+			// afterCompletions should run in reverse order compared to beforeCompletions
+			Stack stack = new Stack();
+			Iterator iterator = _synchs.iterator();
+			while(iterator.hasNext()) {
+				stack.push(iterator.next());
+			}
 
+			iterator = stack.iterator();
+
 			/*
 			 * Regardless of failures, we must tell all synchronizations what
 			 * happened.
 			 */
+			while(!stack.isEmpty())
+			{
+				SynchronizationRecord record = (SynchronizationRecord)stack.pop();
 
-			while (record != null)
-			{
 				try
 				{
 					if (!record.afterCompletion(myStatus))
@@ -287,8 +305,6 @@
 					{ record });
 					problem = true;
 				}
-
-				record = (SynchronizationRecord) iterator.iterate();
 			}
 
 			_synchs = null;
@@ -297,6 +313,7 @@
 		return !problem;
 	}
 
-	private HashList _synchs;
+	//private HashList _synchs;
+	private SortedSet _synchs;
 
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/SynchronizationImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/SynchronizationImple.java	2006-12-20 13:19:57 UTC (rev 8435)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/SynchronizationImple.java	2006-12-20 13:37:33 UTC (rev 8436)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
- * as indicated by the @author tags. 
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
  * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
+ * full listing of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
  * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -24,7 +24,7 @@
  * Arjuna Solutions Limited,
  * Newcastle upon Tyne,
  * Tyne and Wear,
- * UK.  
+ * UK.
  *
  * $Id: SynchronizationImple.java 2342 2006-03-30 13:06:17Z  $
  */
@@ -45,6 +45,7 @@
 import com.arjuna.common.util.logging.*;
 
 import java.util.Hashtable;
+import java.util.Comparator;
 
 import javax.transaction.*;
 
@@ -67,16 +68,22 @@
  * @since JTS 1.2.4.
  */
 
-public class SynchronizationImple implements SynchronizationRecord
+public class SynchronizationImple implements SynchronizationRecord, Comparable
 {
-    
+
     public SynchronizationImple (javax.transaction.Synchronization ptr)
     {
 	_theSynch = ptr;
 	_theUid = new Uid();
     }
 
-    public void finalize ()
+	public SynchronizationImple (javax.transaction.Synchronization ptr, boolean isInterposed) {
+		_theSynch = ptr;
+		_theUid = new Uid();
+		_isInterposed = isInterposed;
+	}
+
+	public void finalize ()
     {
 	_theSynch = null;
 
@@ -93,7 +100,7 @@
     {
 	return _theUid;
     }
-    
+
     public boolean beforeCompletion ()
     {
 	if (jtaLogger.logger.isDebugEnabled())
@@ -146,7 +153,39 @@
 	    return false; // should not cause any affect!
     }
 
-    private javax.transaction.Synchronization _theSynch;
+	/*
+	 * SyncronizationsImples are ordered first according to the isInterposed property and then by Uid.
+	 * Interposed synchronizations must come after non-interposed ones  (see TwoPhaseCoordinator and
+	 * TransactionSynchronizationRegistry)  The ordering within the interposed/non-interposed categories
+	 * is arbitrary but must be defined for correct functioning of the sort. Just don't rely on it in
+	 * application level code.
+	 *
+	 * @param object
+	 * @return
+	 */
+	public int compareTo(Object object)
+	{
+		SynchronizationImple other = (SynchronizationImple)object;
+
+		if(this._isInterposed && (!other._isInterposed))
+		{
+			return 1;
+		}
+		else if((!this._isInterposed) && other._isInterposed)
+		{
+			return -1;
+		}
+		else if(this._theUid.equals(other._theUid))
+		{
+			return 0;
+		}
+		else
+		{
+			return this._theUid.lessThan(other._theUid) ? -1 : 1;
+		}
+	}
+
+	private javax.transaction.Synchronization _theSynch;
     private Uid _theUid;
-    
+	private boolean _isInterposed;
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionImple.java	2006-12-20 13:19:57 UTC (rev 8435)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionImple.java	2006-12-20 13:37:33 UTC (rev 8436)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
- * as indicated by the @author tags. 
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
  * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
+ * full listing of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
  * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -58,8 +58,7 @@
 
 import javax.transaction.xa.*;
 
-import java.util.Hashtable;
-import java.util.Enumeration;
+import java.util.*;
 
 import javax.transaction.RollbackException;
 import java.lang.IllegalStateException;
@@ -173,7 +172,7 @@
 	 * HeuristicRollback from a resource, and can successfully rollback the
 	 * other resources, this is then the same as having simply been forced to
 	 * rollback the transaction during phase 1.
-	 * 
+	 *
 	 * @message com.arjuna.ats.internal.jta.transaction.arjunacore.invalidstate
 	 *          [com.arjuna.ats.internal.jta.transaction.arjunacore.invalidstate]
 	 *          Invalid transaction state
@@ -368,18 +367,26 @@
 		}
 
 		if (sync == null)
+		{
 			throw new javax.transaction.SystemException(
 					"TransactionImple.registerSynchronization - "
 							+ jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.nullparam"));
+		}
 
+		registerSynchronizationImple(new SynchronizationImple(sync, false));
+	}
+
+	// package-private method also for use by TransactionSynchronizationRegistryImple
+	void registerSynchronizationImple(SynchronizationImple synchronizationImple)
+			throws javax.transaction.RollbackException,
+			java.lang.IllegalStateException, javax.transaction.SystemException
+	{
 		if (_theTransaction != null)
 		{
-			SynchronizationImple s = new SynchronizationImple(sync);
-
-			if (_theTransaction.addSynchronization(s) != AddOutcome.AR_ADDED)
+			if (_theTransaction.addSynchronization(synchronizationImple) != AddOutcome.AR_ADDED)
 			{
 				int status = _theTransaction.status();
-				
+
 				switch (status)
 				{
 				case ActionStatus.ABORTED:
@@ -403,7 +410,7 @@
 	 * know that your XAResource and family are truly compliant implementations.
 	 * If they aren't then we may fail gracefully (e.g., some versions of Oracle
 	 * don't work with arbitrary Xid implementations!)
-	 * 
+	 *
 	 * If the family isn't compliant, then you should use the other method and
 	 * pass through a relevant XAModifier, which should address the issues we
 	 * have already come across.
@@ -448,7 +455,7 @@
 							+ jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.nullres"));
 
 		int status = getStatus();
-	
+
 		switch (status)
 		{
 		case javax.transaction.Status.STATUS_MARKED_ROLLBACK:
@@ -630,9 +637,9 @@
 				 * another server, since we keep track of our own registrations.
 				 * So, if this happens we create a new transaction branch and
 				 * try again.
-				 * 
+				 *
 				 * To save time we could always just create branches by default.
-				 * 
+				 *
 				 * Is there a benefit to a zero branch?
 				 */
 
@@ -1097,11 +1104,27 @@
 		}
 	}
 
+	// get a key-value pair from a transaction specific Map
+	Object getTxLocalResource(Object key) {
+		if(txLocalResources == null) {
+			return null;
+		}
+		return txLocalResources.get(key);
+	}
+
+	// store a key-value pair in the scope of the transaction.
+	void putTxLocalResource(Object key, Object value) {
+		if(txLocalResources == null) {
+			txLocalResources = Collections.synchronizedMap(new HashMap());
+		}
+		txLocalResources.put(key, value);
+	}
+
 	protected TransactionImple ()
 	{
 		this(null);
-	}	
-	
+	}
+
 	/**
 	 * Create a new TransactionImple representation of a specified
 	 * transaction.
@@ -1136,7 +1159,7 @@
 			_resources = null;
 			_duplicateResources = null;
 		}
-		
+
 		_suspendCount = 0;
 		_xaTransactionTimeoutEnabled = getXATransactionTimeoutEnabled() ;
 	}
@@ -1177,7 +1200,7 @@
     				throw new IllegalStateException(
     						jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.inactive"));
     			}
-                
+
 				switch (_theTransaction.commit(true))
 				{
 				case ActionStatus.COMMITTED:
@@ -1208,16 +1231,16 @@
 	/**
 	 * If this is an imported transaction (via JCA) then this will be the Xid
 	 * we are pretending to be. Otherwise, it will be null.
-	 * 
+	 *
 	 * @return null if we are a local transaction, a valid Xid if we have been
 	 * imported.
 	 */
-	
+
 	protected Xid baseXid ()
 	{
 		return null;
 	}
-	
+
 	/**
 	 * Does the same as rollback, but also changes the thread-to-tx association.
 	 */
@@ -1278,7 +1301,7 @@
 	/**
 	 * If there are any suspended RMs then we should call end on them before the
 	 * transaction is terminated.
-	 * 
+	 *
 	 * @message com.arjuna.ats.internal.jta.transaction.arjunacore.xaenderror
 	 *          [com.arjuna.ats.internal.jta.transaction.arjunacore.xaenderror]
 	 *          Could not call end on a suspended resource!
@@ -1415,7 +1438,7 @@
 	/**
 	 * isNewRM returns an existing TxInfo for the same RM, if present. Null
 	 * otherwise.
-	 * 
+	 *
 	 * @message com.arjuna.ats.internal.jta.transaction.arjunacore.newtmerror
 	 *          [com.arjuna.ats.internal.jta.transaction.arjunacore.newtmerror]
 	 *          {0} caught XAException: {0}
@@ -1488,10 +1511,10 @@
 	private final Xid createXid(boolean branch, XAModifier theModifier)
 	{
 		Xid xid = baseXid();
-		
+
 		if (xid != null)
 			return xid;
-		
+
 		xid = new XidImple(_theTransaction, branch);
 
 		if (theModifier != null)
@@ -1566,7 +1589,8 @@
 	private Hashtable _resources;
 	private Hashtable _duplicateResources;
 	private int _suspendCount;
-	private final boolean _xaTransactionTimeoutEnabled ;
+	private final boolean _xaTransactionTimeoutEnabled;
+	private Map txLocalResources;
 
 	private static final boolean XA_TRANSACTION_TIMEOUT_ENABLED ;
 	private static final Class LAST_RESOURCE_OPTIMISATION_INTERFACE ;

Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionSynchronizationRegistryImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionSynchronizationRegistryImple.java	2006-12-20 13:19:57 UTC (rev 8435)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/TransactionSynchronizationRegistryImple.java	2006-12-20 13:37:33 UTC (rev 8436)
@@ -0,0 +1,249 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2006,
+ * @author JBoss Inc.
+ *
+ * $Id$
+ */
+package com.arjuna.ats.internal.jta.transaction.arjunacore;
+
+import com.arjuna.ats.jta.logging.jtaLogger;
+import com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple;
+import com.arjuna.common.util.logging.DebugLevel;
+import com.arjuna.common.util.logging.VisibilityLevel;
+
+import javax.transaction.*;
+
+/**
+ * Implementation of the TransactionSynchronizationRegistry interface, in line with the JTA 1.1 specification.
+ *
+ * @author jonathan.halliday at jboss.com
+ */
+public class TransactionSynchronizationRegistryImple // implements TransactionSynchronizationRegistry
+{
+	/*
+	 * http://java.sun.com/javaee/5/docs/api/javax/transaction/TransactionSynchronizationRegistry.html
+	 * http://jcp.org/aboutJava/communityprocess/maintenance/jsr907/907ChangeLog.html
+	 */
+
+	// Return an opaque object to represent the transaction bound to the current thread at the time this method is called.
+	/**
+	 * @message com.arjuna.ats.internal.jta.transaction.arjunacore.systemexception
+	 * [com.arjuna.ats.internal.jta.transaction.arjunacore.systemexception]
+	 * The transaction implementation threw a SystemException
+	 */
+	public Object getTransactionKey()
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.getTransactionKey");
+		}
+
+		javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+		TransactionImple transactionImple = null;
+		try
+		{
+			transactionImple = (TransactionImple)tm.getTransaction();
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.systemexception"), e);
+		}
+
+		if (transactionImple == null) {
+			return null;
+		} else {
+			return transactionImple.get_uid();
+		}
+	}
+
+	// Add or replace an object in the Map of resources being managed for the transaction bound to the current thread at the time this method is called.
+	public void putResource(Object key, Object value)
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.putResource");
+		}
+
+		if(key ==  null)
+		{
+			throw new NullPointerException();
+		}
+
+		TransactionImple transactionImple = getTransactionImple();
+		transactionImple.putTxLocalResource(key, value);
+	}
+
+	// Get an object from the Map of resources being managed for the transaction bound to the current thread at the time this method is called.
+	public Object getResource(Object key)
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.getResource");
+		}
+
+		if(key ==  null)
+		{
+			throw new NullPointerException();
+		}
+
+		TransactionImple transactionImple = getTransactionImple();
+		return transactionImple.getTxLocalResource(key);
+	}
+
+	// Register a Synchronization instance with special ordering semantics.
+	/**
+	 * @message com.arjuna.ats.internal.jta.transaction.arjunacore.syncrollbackexception
+	 * [com.arjuna.ats.internal.jta.transaction.arjunacore.syncrollbackexception]
+	 * The transaction implementation threw a RollbackException
+	 */
+	public void registerInterposedSynchronization(Synchronization synchronization)
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.registerInterposedSynchronization");
+		}
+
+		TransactionImple transactionImple = getTransactionImple();
+
+		try
+		{
+			transactionImple.registerSynchronizationImple(new SynchronizationImple(synchronization, true));
+		}
+		catch (RollbackException e)
+		{
+			throw new RuntimeException(jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.syncrollbackmexception"), e);
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.systemexception"), e);
+		}
+	}
+
+	// Return the status of the transaction bound to the current thread at the time this method is called.
+	public int getTransactionStatus()
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.getTransactionStatus");
+		}
+
+		javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+		try
+		{
+			return tm.getStatus();
+		}
+		catch(SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.systemexception"), e);
+		}
+
+	}
+
+	// Set the rollbackOnly status of the transaction bound to the current thread at the time this method is called.
+	public void setRollbackOnly()
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.setRollbackOnly");
+		}
+
+		javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+		try
+		{
+			Transaction transaction = tm.getTransaction();
+
+			if(transaction == null)
+			{
+				throw new IllegalStateException();
+			}
+
+			tm.setRollbackOnly();
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.systemexception"), e);
+		}
+	}
+
+	// Get the rollbackOnly status of the transaction bound to the current thread at the time this method is called.
+	public boolean getRollbackOnly()
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.getRollbackOnly");
+		}
+
+		TransactionImple transactionImple = getTransactionImple();
+
+		if(transactionImple == null) {
+			throw new IllegalStateException();
+		}
+
+		try
+		{
+			return (transactionImple.getStatus() == Status.STATUS_MARKED_ROLLBACK);
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.systemexception"), e);
+		}
+	}
+
+	private TransactionImple getTransactionImple() throws IllegalStateException
+	{
+		javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+		TransactionImple transactionImple = null;
+		try
+		{
+			transactionImple = (TransactionImple)tm.getTransaction();
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.logMesg.getString("com.arjuna.ats.internal.jta.transaction.arjunacore.systemexception"), e);
+		}
+
+		if(transactionImple == null)
+		{
+			throw new IllegalStateException();
+		}
+		
+		return transactionImple;
+	}
+}

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/Environment.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/Environment.java	2006-12-20 13:19:57 UTC (rev 8435)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/Environment.java	2006-12-20 13:37:33 UTC (rev 8436)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
- * as indicated by the @author tags. 
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
  * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
+ * full listing of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
  * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -24,7 +24,7 @@
  * Hewlett-Packard Arjuna Labs,
  * Newcastle upon Tyne,
  * Tyne and Wear,
- * UK.  
+ * UK.
  *
  * $Id: Environment.java 2342 2006-03-30 13:06:17Z  $
  */
@@ -44,16 +44,20 @@
 {
     public static final String PROPERTIES_FILE = "com.arjuna.ats.jta.common.propertiesFile";
     public static final String SUPPORT_SUBTRANSACTIONS = "com.arjuna.ats.jta.supportSubtransactions";
+
     public static final String JTA_TM_IMPLEMENTATION = "com.arjuna.ats.jta.jtaTMImplementation";
     public static final String JTA_UT_IMPLEMENTATION = "com.arjuna.ats.jta.jtaUTImplementation";
+	public static final String JTA_TSR_IMPLEMENTATION = "com.arjuna.ats.jta.jtaTSRImplementation";
+
     public static final String XA_BACKOFF_PERIOD = "com.arjuna.ats.jta.xaBackoffPeriod";
     public static final String XA_RECOVERY_NODE = "com.arjuna.ats.jta.xaRecoveryNode";
     public static final String XA_ROLLBACK_OPTIMIZATION = "com.arjuna.ats.jta.xaRollbackOptimization";
 
     public static final String UT_JNDI_CONTEXT = "com.arjuna.ats.jta.utils.UTJNDIContext";
     public static final String TM_JNDI_CONTEXT = "com.arjuna.ats.jta.utils.TMJNDIContext";
+	public static final String TSR_JNDI_CONTEXT = "com.arjuna.ats.jta.utils.TSRJNDIContext";
 
-    public static final String XA_ERROR_HANDLER = "com.arjuna.ats.jta.xaErrorHandler";
+	public static final String XA_ERROR_HANDLER = "com.arjuna.ats.jta.xaErrorHandler";
     public static final String XA_TRANSACTION_TIMEOUT_ENABLED = "com.arjuna.ats.jta.xaTransactionTimeoutEnabled";
     public static final String LAST_RESOURCE_OPTIMISATION_INTERFACE = "com.arjuna.ats.jta.lastResourceOptimisationInterface";
 

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/utils/JNDIManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/utils/JNDIManager.java	2006-12-20 13:19:57 UTC (rev 8435)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/utils/JNDIManager.java	2006-12-20 13:37:33 UTC (rev 8436)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors 
- * as indicated by the @author tags. 
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
  * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
+ * full listing of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
  * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -50,6 +50,7 @@
 	{
 		bindJTATransactionManagerImplementation(ctx);
 		bindJTAUserTransactionImplementation(ctx);
+		bindJTATransactionSynchronizationRegistryImplementation(ctx);
 	}
 
     /**
@@ -60,7 +61,8 @@
     {
         bindJTATransactionManagerImplementation();
         bindJTAUserTransactionImplementation();
-    }
+		bindJTATransactionSynchronizationRegistryImplementation();
+	}
 
 	public static String getTransactionManagerImplementationClassname()
 	{
@@ -72,7 +74,12 @@
 		return jtaPropertyManager.propertyManager.getProperty(Environment.JTA_UT_IMPLEMENTATION, DEFAULT_UT_IMPLEMENTATION);
 	}
 
-    /**
+	public static String getTransactionSynchronizationRegistryImplementationClassname()
+	{
+		return jtaPropertyManager.propertyManager.getProperty(Environment.JTA_TSR_IMPLEMENTATION, DEFAULT_TSR_IMPLEMENTATION);
+	}
+
+	/**
      * Bind the currently configured transaction manager implementation to the default
      * JNDI context.
      * @throws javax.naming.NamingException
@@ -124,6 +131,32 @@
         initialContext.rebind(getUserTransactionJNDIName(), ref);
 	}
 
+	/**
+	 * Bind the currently configured TransactionSynchronizationRegistry implementation to the default JNDI
+	 * context.
+	 * @throws javax.naming.NamingException
+	 */
+	public static void bindJTATransactionSynchronizationRegistryImplementation() throws javax.naming.NamingException
+	{
+		bindJTATransactionSynchronizationRegistryImplementation(new InitialContext());
+	}
+
+	/**
+     * Bind the currently configured TransactionSynchronizationRegistry implementation to the passed in
+     * JNDI context.
+     * @param initialContext
+     * @throws javax.naming.NamingException
+     */
+	public static void bindJTATransactionSynchronizationRegistryImplementation(InitialContext initialContext) throws javax.naming.NamingException
+	{
+        /** Look up and instantiate an instance of the configured TransactionSynchronizationRegistry implementation **/
+        String tsrImplementation = getTransactionSynchronizationRegistryImplementationClassname();
+
+        /** Bind the TransactionSynchronizationRegistry to the appropriate JNDI context **/
+        Reference ref = new Reference(tsrImplementation, tsrImplementation, null);
+        initialContext.rebind(getTransactionSynchronizationRegistryJNDIName(), ref);
+	}
+
 	public final static String getTransactionManagerJNDIName()
 	{
 		return jtaPropertyManager.propertyManager.getProperty(Environment.TM_JNDI_CONTEXT, DEFAULT_TM_JNDI_CONTEXT);
@@ -134,9 +167,16 @@
 		return jtaPropertyManager.propertyManager.getProperty(Environment.UT_JNDI_CONTEXT, DEFAULT_UT_JNDI_CONTEXT);
 	}
 
+	private final static String getTransactionSynchronizationRegistryJNDIName()
+	{
+		return jtaPropertyManager.propertyManager.getProperty(Environment.TSR_JNDI_CONTEXT, DEFAULT_TSR_JNDI_CONTEXT);
+	}
+
 	private static final String DEFAULT_TM_JNDI_CONTEXT = "java:/TransactionManager";
 	private static final String DEFAULT_UT_JNDI_CONTEXT = "java:/UserTransaction";
+	private static final String DEFAULT_TSR_JNDI_CONTEXT = "java:comp/TransactionSynchronizationRegistry";
 
 	private static final String DEFAULT_UT_IMPLEMENTATION = "com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple";
 	private static final String DEFAULT_TM_IMPLEMENTATION = "com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple";
+	private static final String DEFAULT_TSR_IMPLEMENTATION = "com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionSynchronizationRegistryImple";
 }

Modified: labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jta/TransactionManagerService.java
===================================================================
--- labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jta/TransactionManagerService.java	2006-12-20 13:19:57 UTC (rev 8435)
+++ labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/jbossatx/jta/TransactionManagerService.java	2006-12-20 13:37:33 UTC (rev 8436)
@@ -61,6 +61,7 @@
 import javax.naming.InitialContext;
 import javax.transaction.TransactionManager;
 import javax.transaction.UserTransaction;
+import javax.transaction.TransactionSynchronizationRegistry;
 import java.net.Socket;
 import java.net.InetAddress;
 import java.io.BufferedReader;
@@ -93,7 +94,7 @@
     private final static String PROPAGATION_CONTEXT_EXPORTER_JNDI_REFERENCE = "java:/TransactionPropagationContextExporter";
     private static final JBossXATerminator TERMINATOR = new XATerminator() ;
 
-    private RecoveryManager _recoveryManager;
+	private RecoveryManager _recoveryManager;
     private boolean _runRM = true;
 
     /**
@@ -174,14 +175,16 @@
             throw e;
         }
 
-        /** Bind the transaction manager JNDI reference **/
+        /** Bind the transaction manager and tsr JNDI references **/
         this.getLog().info("Binding TransactionManager JNDI Reference");
 
         jtaPropertyManager.propertyManager.setProperty(Environment.JTA_TM_IMPLEMENTATION, TransactionManagerDelegate.class.getName());
         jtaPropertyManager.propertyManager.setProperty(Environment.JTA_UT_IMPLEMENTATION, UserTransactionImple.class.getName());
+		jtaPropertyManager.propertyManager.setProperty(Environment.JTA_TSR_IMPLEMENTATION, TransactionSynchronizationRegistry.class.getName());
 
         JNDIManager.bindJTATransactionManagerImplementation();
-    }
+		JNDIManager.bindJTATransactionSynchronizationRegistryImplementation();
+	}
 
     /**
      * Handle JMX notification.




More information about the jboss-svn-commits mailing list