[jboss-svn-commits] JBL Code SVN: r25506 - in labs/jbosstm/trunk: ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/jca and 9 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Mar 5 12:31:21 EST 2009


Author: jhalliday
Date: 2009-03-05 12:31:21 -0500 (Thu, 05 Mar 2009)
New Revision: 25506

Added:
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinateTransaction.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinationManager.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TransactionImporter.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TransactionImporterImple.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TransactionImporterImple.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/subordinate/
   labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/subordinate/SubordinateTestCase.java
Removed:
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxImporter.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxImporter.java
Modified:
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxWorkManager.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/WorkSynchronization.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/XATerminatorImple.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/jca/TransactionImple.java
   labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/build.xml
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxWorkManager.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/WorkSynchronization.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/jca/TransactionImple.java
   labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/internal/jbossatx/jta/jca/XATerminator.java
   labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/internal/jbossatx/jts/jca/XATerminator.java
Log:
Refactor subordinate transaction support. JBTM-505


Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinateTransaction.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinateTransaction.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinateTransaction.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, 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) 2009,
+ * @author JBoss Inc.
+ */
+package com.arjuna.ats.internal.jta.transaction.arjunacore.jca;
+
+import javax.transaction.*;
+import javax.transaction.xa.Xid;
+
+/**
+ * Subordinate transactions are those designed to be driven by a foreign controller,
+ * so they expose methods for driving each of the termination phases individually.
+ */
+public interface SubordinateTransaction extends Transaction
+{
+	/**
+	 * Drive the subordinate transaction through the prepare phase. Any
+	 * enlisted participants will also be prepared as a result.
+	 *
+	 * @return a TwoPhaseOutcome representing the result.
+	 */
+    public int doPrepare();
+    
+	/**
+	 * Drive the subordinate transaction to commit. It must have previously
+	 * been prepared.
+	 *
+	 * @throws IllegalStateException thrown if the transaction has not been prepared
+	 * or is unknown.
+	 * @throws HeuristicMixedException thrown if a heuristic mixed outcome occurs
+	 * (where some participants committed whilst others rolled back).
+	 * @throws HeuristicRollbackException thrown if the transaction rolled back.
+	 * @throws SystemException thrown if some other error occurs.
+	 */
+    public void doCommit () throws IllegalStateException,
+			HeuristicMixedException, HeuristicRollbackException,
+			SystemException;
+        
+	/**
+	 * Drive the subordinate transaction to roll back. It need not have been previously
+	 * prepared.
+	 *
+	 * @throws IllegalStateException thrown if the transaction is not known by the
+	 * system or has been previously terminated.
+	 * @throws HeuristicMixedException thrown if a heuristic mixed outcome occurs
+	 * (can only happen if the transaction was previously prepared and then only if
+	 * some participants commit whilst others roll back).
+	 * @throws HeuristicCommitException thrown if the transaction commits (can only
+	 * happen if it was previously prepared).
+	 * @throws SystemException thrown if any other error occurs.
+	 */
+    public void doRollback () throws IllegalStateException,
+            HeuristicMixedException, HeuristicCommitException, SystemException;
+    
+	/**
+	 * Drive the transaction to commit. It should not have been previously
+	 * prepared and will be the only resource in the global transaction.
+	 *
+	 * @throws IllegalStateException if the transaction has already terminated
+	 * @throws javax.transaction.HeuristicRollbackException thrown if the transaction
+	 * rolls back.
+	 */
+    public void doOnePhaseCommit () throws IllegalStateException,
+			HeuristicRollbackException, SystemException, RollbackException;
+    
+	/**
+	 * Called to tell the transaction to forget any heuristics.
+	 *
+	 * @throws IllegalStateException thrown if the transaction cannot
+	 * be found.
+	 */
+    public void doForget () throws IllegalStateException;
+
+    public boolean activated();
+    
+    public void recover();
+    
+    public Xid baseXid();
+}

Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinationManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinationManager.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/SubordinationManager.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -0,0 +1,114 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, 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) 2009,
+ * @author JBoss Inc.
+ */
+package com.arjuna.ats.internal.jta.transaction.arjunacore.jca;
+
+import com.arjuna.ats.jta.logging.jtaLogger;
+
+import javax.transaction.TransactionManager;
+import javax.resource.spi.XATerminator;
+
+/**
+ * Utility factory class to return appropriate implementations of the TransactionImporter and
+ * XATerminator interfaces. This will automatically instantiate the correct implementations
+ * based on the use of the JTA or JTAX transaction manager configuration and is therefore
+ * preferred to instantiating a specific implementation class directly.
+ */
+public class SubordinationManager
+{
+    private static TransactionImporter transactionImporter = null;
+    private static XATerminator xaTerminator = null;
+
+    public static TransactionImporter getTransactionImporter()
+    {
+        if(transactionImporter == null)
+        {
+            initTransactionImporter();
+        }
+        
+        return transactionImporter;
+    }
+
+    public static XATerminator getXATerminator()
+    {
+        if(xaTerminator == null)
+        {
+            initXATerminator();
+        }
+        
+        return xaTerminator;
+    }
+
+    /**
+     * @message com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager.importerfailure Failed to create instance of TransactionImporter
+     */
+    private static void initTransactionImporter()
+    {
+        TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+        
+        if(tm instanceof com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple)
+        {
+            // we are running in JTA mode
+            transactionImporter = new TransactionImporterImple();
+        }
+        else
+        {
+            // it's not JTA, so it must be JTAX. However, we are in the JTA module and
+            // can't link against the JTS code so we need to do it the hard way...
+            try
+            {
+                Class clazz = Class.forName("com.arjuna.ats.internal.jta.transaction.jts.jca.TransactionImporterImple");
+                transactionImporter = (TransactionImporter)clazz.newInstance();
+            }
+            catch(Exception e)
+            {
+                jtaLogger.loggerI18N.error("com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager.importerfailure", e);
+            }
+        }
+    }
+    
+    /**
+     * @message com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager.terminatorfailure Failed to create instance of XATerminator
+     */
+    private static void initXATerminator()
+    {
+        TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+        
+        if(tm instanceof com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple)
+        {
+            // we are running in JTA mode
+            xaTerminator = new XATerminatorImple();
+        }
+        else
+        {
+            // it's not JTA, so it must be JTAX. However, we are in the JTA module and
+            // can't link against the JTS code so we need to do it the hard way...
+            try
+            {
+                Class clazz = Class.forName("com.arjuna.ats.internal.jta.transaction.jts.jca.XATerminatorImple");
+                xaTerminator = (XATerminator)clazz.newInstance();
+            }
+            catch(Exception e)
+            {
+                jtaLogger.loggerI18N.error("com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager.terminatorfailure", e);
+            }
+        }
+    }
+}

Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TransactionImporter.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TransactionImporter.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TransactionImporter.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -0,0 +1,101 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, 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) 2009,
+ * @author JBoss Inc.
+ */
+package com.arjuna.ats.internal.jta.transaction.arjunacore.jca;
+
+import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
+import com.arjuna.ats.arjuna.common.Uid;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+import javax.transaction.Transaction;
+
+/**
+ * A TransactionImporter is used to manager the relationship with external SubordinateTransactions.
+ */
+public interface TransactionImporter
+{
+	/**
+	 * Create a subordinate transaction associated with the global transaction
+	 * inflow. No timeout is associated with the transaction.
+	 * 
+	 * @param xid
+	 *            the global transaction.
+	 * 
+	 * @return the subordinate transaction.
+	 * 
+	 * @throws javax.transaction.xa.XAException
+	 *             thrown if there are any errors.
+	 */
+    public SubordinateTransaction importTransaction(Xid xid) throws XAException;
+
+	/**
+	 * Create a subordinate transaction associated with the global transaction
+	 * inflow and having a specified timeout.
+	 * 
+	 * @param xid
+	 *            the global transaction.
+	 * @param timeout
+	 *            the timeout associated with the global transaction.
+	 * 
+	 * @return the subordinate transaction.
+	 * 
+	 * @throws javax.transaction.xa.XAException
+	 *             thrown if there are any errors.
+	 */
+    public SubordinateTransaction importTransaction(Xid xid, int timeout) throws XAException;
+
+	/**
+	 * Used to recover an imported transaction.
+	 * 
+	 * @param actId
+	 *            the state to recover.
+	 * @return the recovered transaction object.
+	 * @throws javax.transaction.xa.XAException
+	 */
+    public SubordinateTransaction recoverTransaction(Uid actId) throws XAException;
+
+	/**
+	 * Get the subordinate (imported) transaction associated with the global
+	 * transaction.
+	 * 
+	 * @param xid
+	 *            the global transaction.
+	 * 
+	 * @return the subordinate transaction or <code>null</code> if there is
+	 *         none.
+	 * 
+	 * @throws javax.transaction.xa.XAException
+	 *             thrown if there are any errors.
+	 */
+    public SubordinateTransaction getImportedTransaction(Xid xid) throws XAException;
+
+	/**
+	 * Remove the subordinate (imported) transaction.
+	 * 
+	 * @param xid
+	 *            the global transaction.
+	 * 
+	 * @throws javax.transaction.xa.XAException
+	 *             thrown if there are any errors.
+	 */
+    public void removeImportedTransaction(Xid xid) throws XAException;
+
+}

Copied: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TransactionImporterImple.java (from rev 25489, labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxImporter.java)
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TransactionImporterImple.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TransactionImporterImple.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -0,0 +1,198 @@
+/*
+ * 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) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * Copyright (C) 2005,
+ *
+ * Arjuna Technologies Ltd,
+ * Newcastle upon Tyne,
+ * Tyne and Wear,
+ * UK.
+ *
+ * $Id: TransactionImporterImple.java 2342 2006-03-30 13:06:17Z  $
+ */
+
+package com.arjuna.ats.internal.jta.transaction.arjunacore.jca;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.transaction.xa.*;
+import javax.transaction.Transaction;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
+import com.arjuna.ats.jta.xa.XidImple;
+
+public class TransactionImporterImple implements TransactionImporter
+{
+
+	/**
+	 * Create a subordinate transaction associated with the global transaction
+	 * inflow. No timeout is associated with the transaction.
+	 * 
+	 * @param xid
+	 *            the global transaction.
+	 * 
+	 * @return the subordinate transaction.
+	 * 
+	 * @throws javax.transaction.xa.XAException
+	 *             thrown if there are any errors.
+	 */
+
+	public SubordinateTransaction importTransaction(Xid xid)
+			throws XAException
+	{
+		return importTransaction(xid, 0);
+	}
+
+	/**
+	 * Create a subordinate transaction associated with the global transaction
+	 * inflow and having a specified timeout.
+	 * 
+	 * @param xid
+	 *            the global transaction.
+	 * @param timeout
+	 *            the timeout associated with the global transaction.
+	 * 
+	 * @return the subordinate transaction.
+	 * 
+	 * @throws javax.transaction.xa.XAException
+	 *             thrown if there are any errors.
+	 */
+
+	public SubordinateTransaction importTransaction(Xid xid, int timeout)
+			throws XAException
+	{
+		if (xid == null)
+			throw new IllegalArgumentException();
+
+		/*
+		 * Check to see if we haven't already imported this thing.
+		 */
+
+		SubordinateTransaction imported = getImportedTransaction(xid);
+
+		if (imported == null)
+		{
+			imported = new TransactionImple(timeout, xid);
+
+			_transactions.put(new XidImple(xid), imported);
+		}
+
+		return imported;
+	}
+
+	/**
+	 * Used to recover an imported transaction.
+	 * 
+	 * @param actId
+	 *            the state to recover.
+	 * @return the recovered transaction object.
+	 * @throws javax.transaction.xa.XAException
+	 */
+
+	public TransactionImple recoverTransaction(Uid actId)
+			throws XAException
+	{
+		if (actId == null)
+			throw new IllegalArgumentException();
+
+		TransactionImple recovered = new TransactionImple(actId);
+
+		/*
+		 * Is the transaction already in the list? This may be the case because
+		 * we scan the object store periodically and may get Uids to recover for
+		 * transactions that are progressing normally, i.e., do not need
+		 * recovery. In which case, we need to ignore them.
+		 */
+
+		TransactionImple tx = (TransactionImple) _transactions.get(recovered
+				.baseXid());
+
+		if (tx == null)
+		{
+			_transactions.put(recovered.baseXid(), recovered);
+
+			recovered.recordTransaction();
+
+			return recovered;
+		}
+		else
+		{
+			return tx;
+		}
+	}
+
+	/**
+	 * Get the subordinate (imported) transaction associated with the global
+	 * transaction.
+	 * 
+	 * @param xid
+	 *            the global transaction.
+	 * 
+	 * @return the subordinate transaction or <code>null</code> if there is
+	 *         none.
+	 * 
+	 * @throws javax.transaction.xa.XAException
+	 *             thrown if there are any errors.
+	 */
+
+	public SubordinateTransaction getImportedTransaction(Xid xid)
+			throws XAException
+	{
+		if (xid == null)
+			throw new IllegalArgumentException();
+
+		SubordinateTransaction tx = _transactions.get(new XidImple(xid));
+
+		if (tx == null)
+			return null;
+
+		if (!tx.activated())
+		{
+			tx.recover();
+
+			return tx;
+		}
+		else
+			return tx;
+	}
+
+	/**
+	 * Remove the subordinate (imported) transaction.
+	 * 
+	 * @param xid
+	 *            the global transaction.
+	 * 
+	 * @throws javax.transaction.xa.XAException
+	 *             thrown if there are any errors.
+	 */
+
+	public void removeImportedTransaction(Xid xid) throws XAException
+	{
+		if (xid == null)
+			throw new IllegalArgumentException();
+
+		_transactions.remove(new XidImple(xid));
+	}
+
+	private static ConcurrentHashMap<Xid, SubordinateTransaction> _transactions = new ConcurrentHashMap<Xid, SubordinateTransaction>();
+
+}
\ No newline at end of file

Deleted: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxImporter.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxImporter.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxImporter.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -1,198 +0,0 @@
-/*
- * 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) 2005-2006,
- * @author JBoss Inc.
- */
-/*
- * Copyright (C) 2005,
- *
- * Arjuna Technologies Ltd,
- * Newcastle upon Tyne,
- * Tyne and Wear,
- * UK.
- *
- * $Id: TxImporter.java 2342 2006-03-30 13:06:17Z  $
- */
-
-package com.arjuna.ats.internal.jta.transaction.arjunacore.jca;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.transaction.xa.*;
-
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
-import com.arjuna.ats.jta.xa.XidImple;
-
-public class TxImporter
-{
-
-	/**
-	 * Create a subordinate transaction associated with the global transaction
-	 * inflow. No timeout is associated with the transaction.
-	 * 
-	 * @param xid
-	 *            the global transaction.
-	 * 
-	 * @return the subordinate transaction.
-	 * 
-	 * @throws XAException
-	 *             thrown if there are any errors.
-	 */
-
-	public static TransactionImple importTransaction(Xid xid)
-			throws XAException
-	{
-		return importTransaction(xid, 0);
-	}
-
-	/**
-	 * Create a subordinate transaction associated with the global transaction
-	 * inflow and having a specified timeout.
-	 * 
-	 * @param xid
-	 *            the global transaction.
-	 * @param timeout
-	 *            the timeout associated with the global transaction.
-	 * 
-	 * @return the subordinate transaction.
-	 * 
-	 * @throws XAException
-	 *             thrown if there are any errors.
-	 */
-
-	public static TransactionImple importTransaction(Xid xid, int timeout)
-			throws XAException
-	{
-		if (xid == null)
-			throw new IllegalArgumentException();
-
-		/*
-		 * Check to see if we haven't already imported this thing.
-		 */
-
-		TransactionImple imported = getImportedTransaction(xid);
-
-		if (imported == null)
-		{
-			imported = new TransactionImple(timeout, xid);
-
-			_transactions.put(new XidImple(xid), imported);
-		}
-
-		return imported;
-	}
-
-	/**
-	 * Used to recover an imported transaction.
-	 * 
-	 * @param actId
-	 *            the state to recover.
-	 * @return the recovered transaction object.
-	 * @throws XAException
-	 */
-
-	public static TransactionImple recoverTransaction(Uid actId)
-			throws XAException
-	{
-		if (actId == null)
-			throw new IllegalArgumentException();
-
-		TransactionImple recovered = new TransactionImple(actId);
-
-		/*
-		 * Is the transaction already in the list? This may be the case because
-		 * we scan the object store periodically and may get Uids to recover for
-		 * transactions that are progressing normally, i.e., do not need
-		 * recovery. In which case, we need to ignore them.
-		 */
-
-		TransactionImple tx = (TransactionImple) _transactions.get(recovered
-				.baseXid());
-
-		if (tx == null)
-		{
-			_transactions.put(recovered.baseXid(), recovered);
-
-			recovered.recordTransaction();
-
-			return recovered;
-		}
-		else
-		{
-			return tx;
-		}
-	}
-
-	/**
-	 * Get the subordinate (imported) transaction associated with the global
-	 * transaction.
-	 * 
-	 * @param xid
-	 *            the global transaction.
-	 * 
-	 * @return the subordinate transaction or <code>null</code> if there is
-	 *         none.
-	 * 
-	 * @throws XAException
-	 *             thrown if there are any errors.
-	 */
-
-	public static TransactionImple getImportedTransaction(Xid xid)
-			throws XAException
-	{
-		if (xid == null)
-			throw new IllegalArgumentException();
-
-		TransactionImple tx = (TransactionImple) _transactions
-				.get(new XidImple(xid));
-
-		if (tx == null)
-			return null;
-
-		if (!tx.activated())
-		{
-			tx.recover();
-
-			return tx;
-		}
-		else
-			return tx;
-	}
-
-	/**
-	 * Remove the subordinate (imported) transaction.
-	 * 
-	 * @param xid
-	 *            the global transaction.
-	 * 
-	 * @throws XAException
-	 *             thrown if there are any errors.
-	 */
-
-	public static void removeImportedTransaction(Xid xid) throws XAException
-	{
-		if (xid == null)
-			throw new IllegalArgumentException();
-
-		_transactions.remove(new XidImple(xid));
-	}
-
-	private static ConcurrentHashMap<Xid, TransactionImple> _transactions = new ConcurrentHashMap<Xid, TransactionImple>();
-
-}

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxWorkManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxWorkManager.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/TxWorkManager.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -33,13 +33,13 @@
 
 import java.util.HashMap;
 import java.util.Stack;
+import java.util.Map;
 
 import javax.resource.spi.work.Work;
 import javax.resource.spi.work.WorkCompletedException;
 import javax.resource.spi.work.WorkException;
+import javax.transaction.Transaction;
 
-import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
-
 import com.arjuna.ats.jta.logging.*;
 
 public class TxWorkManager
@@ -64,17 +64,17 @@
 	 *          com.arjuna.ats.internal.jta.transaction.arjunacore.jca.busy] Work already active!
 	 */
 	
-	public static void addWork (Work work, TransactionImple tx) throws WorkCompletedException
+	public static void addWork (Work work, Transaction tx) throws WorkCompletedException
 	{
-		Stack workers;
+		Stack<Work> workers;
 		
 		synchronized (_transactions)
 		{
-			workers = (Stack) _transactions.get(tx);
+			workers = _transactions.get(tx);
 
 			if (workers == null)
 			{
-				workers = new Stack();
+				workers = new Stack<Work>();
 				
 				_transactions.put(tx, workers);
 			}
@@ -95,13 +95,13 @@
 	 * @param tx the transaction the work should be disassociated from.
 	 */
 	
-	public static void removeWork (Work work, TransactionImple tx)
+	public static void removeWork (Work work, Transaction tx)
 	{
-		Stack workers;
+		Stack<Work> workers;
 		
 		synchronized (_transactions)
 		{
-			workers = (Stack) _transactions.get(tx);
+			workers = _transactions.get(tx);
 		}
 		
 		if (workers != null)
@@ -136,11 +136,11 @@
 	 * <code>false</code> otherwise.
 	 */
 	
-	public static boolean hasWork (TransactionImple tx)
+	public static boolean hasWork (Transaction tx)
 	{
 		synchronized (_transactions)
 		{
-			Stack workers = (Stack) _transactions.get(tx);
+			Stack workers = _transactions.get(tx);
 			
 			return (boolean) (workers != null);
 		}
@@ -154,13 +154,13 @@
 	 * @return the work, or <code>null</code> if there is none.
 	 */
 	
-	public static Work getWork (TransactionImple tx)
+	public static Work getWork (Transaction tx)
 	{
-		Stack workers;
+		Stack<Work> workers;
 		
 		synchronized (_transactions)
 		{
-			workers = (Stack) _transactions.get(tx);
+			workers = _transactions.get(tx);
 		}
 		
 		if (workers != null)
@@ -168,13 +168,13 @@
 			synchronized (workers)
 			{
 				if (!workers.empty())
-					return (Work) workers.peek();
+					return workers.peek();
 			}
 		}
 
 		return null;
 	}
 		
-	private static HashMap _transactions = new HashMap();
+	private static final Map<Transaction, Stack<Work>> _transactions = new HashMap<Transaction, Stack<Work>>();
 	
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/WorkSynchronization.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/WorkSynchronization.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/WorkSynchronization.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -31,7 +31,7 @@
 
 package com.arjuna.ats.internal.jta.transaction.arjunacore.jca;
 
-import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
+import javax.transaction.Transaction;
 
 /**
  * Register a single instance of this thing when the first JCA worker is
@@ -46,7 +46,7 @@
 public class WorkSynchronization implements javax.transaction.Synchronization
 {
 
-	public WorkSynchronization (TransactionImple current)
+	public WorkSynchronization (Transaction current)
 	{
 		_current = current;
 	}
@@ -93,6 +93,6 @@
 		// do nothing
 	}
 	
-	private TransactionImple _current;
+	private Transaction _current;
 
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/XATerminatorImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/XATerminatorImple.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/jca/XATerminatorImple.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -42,9 +42,7 @@
 import com.arjuna.ats.arjuna.coordinator.TxControl;
 import com.arjuna.ats.arjuna.objectstore.ObjectStore;
 import com.arjuna.ats.arjuna.state.InputObjectState;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.TransactionImple;
 import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.SubordinateAtomicAction;
-import com.arjuna.ats.jta.xa.XidImple;
 
 /**
  * The XATerminator implementation.
@@ -55,7 +53,6 @@
 
 public class XATerminatorImple implements javax.resource.spi.XATerminator
 {
-
 	/**
 	 * Commit the transaction identified and hence any inflow-associated work.
 	 *
@@ -75,7 +72,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.getImportedTransaction(xid);
+			SubordinateTransaction tx = SubordinationManager.getTransactionImporter().getImportedTransaction(xid);
 
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
@@ -87,13 +84,13 @@
 				else
 					tx.doCommit();
 
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 			}
 			else
 				throw new XAException(XAException.XA_RETRY);
 		}
         catch(RollbackException e) {
-            TxImporter.removeImportedTransaction(xid);
+            SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
             XAException xaException = new XAException(XAException.XA_RBROLLBACK);
             xaException.initCause(e);
             throw xaException;
@@ -104,7 +101,7 @@
 
 			if (ex.errorCode != XAException.XA_RETRY)
 			{
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 			}
 
 			throw ex;
@@ -119,7 +116,7 @@
 		}
 		catch (SystemException ex)
 		{
-			TxImporter.removeImportedTransaction(xid);
+			SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 
 			throw new XAException(XAException.XAER_RMERR);
 		}
@@ -140,7 +137,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.getImportedTransaction(xid);
+			SubordinateTransaction tx = SubordinationManager.getTransactionImporter().getImportedTransaction(xid);
 
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
@@ -153,7 +150,7 @@
 		}
 		finally
 		{
-			TxImporter.removeImportedTransaction(xid);
+			SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 		}
 	}
 
@@ -176,7 +173,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.getImportedTransaction(xid);
+			SubordinateTransaction tx = SubordinationManager.getTransactionImporter().getImportedTransaction(xid);
 
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
@@ -184,7 +181,7 @@
 			switch (tx.doPrepare())
 			{
 			case TwoPhaseOutcome.PREPARE_READONLY:
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 				return XAResource.XA_RDONLY;
 			case TwoPhaseOutcome.PREPARE_NOTOK:
                 // the JCA API spec limits what we can do in terms of reporting problems.
@@ -204,7 +201,7 @@
                     initCause = e;
                     xaExceptionCode = XAException.XAER_RMERR;
                 }
-                TxImporter.removeImportedTransaction(xid);
+                SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
                 XAException xaException = new XAException(xaExceptionCode);
                 if(initCause != null) {
                     xaException.initCause(initCause);
@@ -302,7 +299,7 @@
 
 					if (uid.notEquals(Uid.nullUid()))
 					{
-						TransactionImple tx = TxImporter
+						Transaction tx = SubordinationManager.getTransactionImporter()
 								.recoverTransaction(uid);
 
 						if (tx != null)
@@ -352,7 +349,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.getImportedTransaction(xid);
+			SubordinateTransaction tx = SubordinationManager.getTransactionImporter().getImportedTransaction(xid);
 
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
@@ -361,7 +358,7 @@
 			{
 				tx.doRollback();
 
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 			}
 			else
 				throw new XAException(XAException.XA_RETRY);
@@ -372,7 +369,7 @@
 
 			if (ex.errorCode != XAException.XA_RETRY)
 			{
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 			}
 
 			throw ex;
@@ -387,7 +384,7 @@
 		}
 		catch (SystemException ex)
 		{
-			TxImporter.removeImportedTransaction(xid);
+			SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 
 			throw new XAException(XAException.XAER_RMERR);
 		}

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/jca/TransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/jca/TransactionImple.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/transaction/arjunacore/subordinate/jca/TransactionImple.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -35,12 +35,13 @@
 
 import com.arjuna.ats.arjuna.common.Uid;
 import com.arjuna.ats.jta.logging.*;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction;
 
 import javax.transaction.xa.Xid;
 
 public class TransactionImple
 		extends
-		com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.TransactionImple
+		com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.TransactionImple implements SubordinateTransaction
 {
 
 	/**

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/subordinate/SubordinateTestCase.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -25,12 +25,13 @@
 import com.arjuna.ats.arjuna.coordinator.ActionManager;
 import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
 import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.TransactionImple;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TxImporter;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.XATerminatorImple;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction;
 import com.arjuna.ats.jta.xa.XidImple;
 
 import javax.transaction.RollbackException;
+import javax.transaction.Transaction;
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
 import javax.transaction.xa.XAException;
@@ -38,11 +39,18 @@
 
 public class SubordinateTestCase extends TestCase
 {
+    // This test class is subclassed by the JTAX version of the tests, so we isolate
+    // the module specific tx creation code to this function, which then gets overridden.
+    public SubordinateTransaction createTransaction() {
+        return new TransactionImple(0); // implicit begin
+    }
+
+    
 	public void testCleanupCommit () throws Exception
 	{
 		for (int i = 0; i < 1000; i++)
 		{
-			final TransactionImple tm = new TransactionImple(0); // implicit begin
+			final SubordinateTransaction tm = createTransaction();
 
 			tm.doPrepare();
 			tm.doCommit();
@@ -55,7 +63,7 @@
 	{
 		for (int i = 0; i < 1000; i++)
 		{
-			final TransactionImple tm = new TransactionImple(0); // implicit begin
+			final SubordinateTransaction tm = createTransaction();
 
 			tm.doRollback();
 		}
@@ -67,7 +75,7 @@
 	{
 		for (int i = 0; i < 1000; i++)
 		{
-			final TransactionImple tm = new TransactionImple(0); // implicit begin
+			final SubordinateTransaction tm = createTransaction();
 
 			tm.doPrepare();
 			tm.doRollback();
@@ -80,7 +88,7 @@
 	{
 		for (int i = 0; i < 1000; i++)
 		{
-			final TransactionImple tm = new TransactionImple(0); // implicit begin
+			final SubordinateTransaction tm = createTransaction();
 
 			tm.doOnePhaseCommit();
 		}
@@ -92,7 +100,7 @@
 
     public void testOnePhaseCommitSync() throws Exception
     {
-        final TransactionImple tm = new TransactionImple(0);
+        final SubordinateTransaction tm = createTransaction();
         final TestSynchronization sync = new TestSynchronization();
         tm.registerSynchronization(sync);
         tm.doOnePhaseCommit();
@@ -104,19 +112,19 @@
     public void testOnePhaseCommitSyncViaXATerminator() throws Exception
     {
         final Xid xid = new XidImple(new Uid());
-        final TransactionImple tm = TxImporter.importTransaction(xid);
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
         final TestSynchronization sync = new TestSynchronization();
-        tm.registerSynchronization(sync);
-        final XATerminator xaTerminator = new XATerminatorImple();
+        t.registerSynchronization(sync);
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
         xaTerminator.commit(xid, true);
         assertTrue(sync.isBeforeCompletionDone());
         assertTrue(sync.isAfterCompletionDone());
-        assertEquals(javax.transaction.Status.STATUS_COMMITTED, tm.getStatus());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, t.getStatus());
     }
 
     public void testOnePhaseCommitSyncWithRollbackOnly() throws Exception
     {
-        final TransactionImple tm = new TransactionImple(0);
+        final SubordinateTransaction tm = createTransaction();
         final TestSynchronization sync = new TestSynchronization();
         tm.registerSynchronization(sync);
         tm.setRollbackOnly();
@@ -134,14 +142,14 @@
     public void testOnePhaseCommitSyncWithRollbackOnlyViaXATerminator() throws Exception
     {
         final Xid xid = new XidImple(new Uid());
-        final TransactionImple tm = TxImporter.importTransaction(xid);
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
         final TestSynchronization sync = new TestSynchronization();
-        tm.registerSynchronization(sync);
-        tm.setRollbackOnly();
-        final XATerminator xaTerminator = new XATerminatorImple();
+        t.registerSynchronization(sync);
+        t.setRollbackOnly();
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
         try {
             xaTerminator.commit(xid, true);
-            tm.doOnePhaseCommit();
+            ((TransactionImple)t).doOnePhaseCommit();
             fail("did not get expected rollback exception");
         } catch(XAException e) {
             assertEquals("javax.transaction.RollbackException", e.getCause().getClass().getName());
@@ -150,12 +158,12 @@
         }
         assertFalse(sync.isBeforeCompletionDone());
         assertTrue(sync.isAfterCompletionDone());
-        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, tm.getStatus());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
     }
 
     public void testRollbackSync() throws Exception
     {
-        final TransactionImple tm = new TransactionImple(0);
+        final SubordinateTransaction tm = createTransaction();
         final TestSynchronization sync = new TestSynchronization();
         tm.registerSynchronization(sync);
         tm.doRollback();
@@ -167,19 +175,19 @@
     public void testRollbackSyncViaXATerminator() throws Exception
     {
         final Xid xid = new XidImple(new Uid());
-        final TransactionImple tm = TxImporter.importTransaction(xid);
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
         final TestSynchronization sync = new TestSynchronization();
-        tm.registerSynchronization(sync);
-        final XATerminator xaTerminator = new XATerminatorImple();
+        t.registerSynchronization(sync);
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
         xaTerminator.rollback(xid);
         assertFalse(sync.isBeforeCompletionDone());
         assertTrue(sync.isAfterCompletionDone());
-        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, tm.getStatus());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
     }
 
     public void testTwoPhaseCommitSync() throws Exception
     {
-        final TransactionImple tm = new TransactionImple(0);
+        final SubordinateTransaction tm = createTransaction();
         final TestSynchronization sync = new TestSynchronization();
         tm.registerSynchronization(sync);
         assertEquals(TwoPhaseOutcome.PREPARE_READONLY, tm.doPrepare());
@@ -192,20 +200,20 @@
     public void testTwoPhaseCommitSyncViaXATerminator() throws Exception
     {
         final Xid xid = new XidImple(new Uid());
-        final TransactionImple tm = TxImporter.importTransaction(xid);
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
         final TestSynchronization sync = new TestSynchronization();
-        tm.registerSynchronization(sync);
-        final XATerminator xaTerminator = new XATerminatorImple();
+        t.registerSynchronization(sync);
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
         assertEquals(XAResource.XA_RDONLY, xaTerminator.prepare(xid));
         // note that unlike the above test we don't call commit - the XA_RDONLY means its finished, per XA semantics.
         assertTrue(sync.isBeforeCompletionDone());
         assertTrue(sync.isAfterCompletionDone());
-        assertEquals(javax.transaction.Status.STATUS_COMMITTED, tm.getStatus());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, t.getStatus());
     }
 
     public void testTwoPhaseCommitSyncWithXAOK() throws Exception
     {
-        final TransactionImple tm = new TransactionImple(0);
+        final SubordinateTransaction tm = createTransaction();
         final TestSynchronization sync = new TestSynchronization();
         tm.registerSynchronization(sync);
         final TestXAResource xaResource = new TestXAResource();
@@ -221,23 +229,23 @@
     public void testTwoPhaseCommitSyncWithXAOKViaXATerminator() throws Exception
     {
         final Xid xid = new XidImple(new Uid());
-        final TransactionImple tm = TxImporter.importTransaction(xid);
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
         final TestSynchronization sync = new TestSynchronization();
-        tm.registerSynchronization(sync);
+        t.registerSynchronization(sync);
         final TestXAResource xaResource = new TestXAResource();
         xaResource.setPrepareReturnValue(XAResource.XA_OK);
-        tm.enlistResource(xaResource);
-        final XATerminator xaTerminator = new XATerminatorImple();
+        t.enlistResource(xaResource);
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
         assertEquals(XAResource.XA_OK, xaTerminator.prepare(xid));
         xaTerminator.commit(xid, false);
         assertTrue(sync.isBeforeCompletionDone());
         assertTrue(sync.isAfterCompletionDone());
-        assertEquals(javax.transaction.Status.STATUS_COMMITTED, tm.getStatus());
+        assertEquals(javax.transaction.Status.STATUS_COMMITTED, t.getStatus());
     }
 
     public void testTwoPhaseCommitSyncWithRollbackOnly() throws Exception
     {
-        final TransactionImple tm = new TransactionImple(0);
+        final SubordinateTransaction tm = createTransaction();
         final TestSynchronization sync = new TestSynchronization();
         tm.registerSynchronization(sync);
         tm.setRollbackOnly();
@@ -251,11 +259,11 @@
     public void testTwoPhaseCommitSyncWithRollbackOnlyViaXATerminator() throws Exception
     {
         final Xid xid = new XidImple(new Uid());
-        final TransactionImple tm = TxImporter.importTransaction(xid);
+        final Transaction t = SubordinationManager.getTransactionImporter().importTransaction(xid);
         final TestSynchronization sync = new TestSynchronization();
-        tm.registerSynchronization(sync);
-        tm.setRollbackOnly();
-        final XATerminator xaTerminator = new XATerminatorImple();
+        t.registerSynchronization(sync);
+        t.setRollbackOnly();
+        final XATerminator xaTerminator = SubordinationManager.getXATerminator();
 
         try {
             xaTerminator.prepare(xid);
@@ -263,9 +271,9 @@
             assertEquals(XAException.XA_RBROLLBACK, e.errorCode);
             // expected - we tried to prepare a rollbackonly tx.
         }
-        // no need to call rollback - the XA_RBROLLBACK code indicates it's been done.
+        // no need to call rollback - the XA_RBROLLBACK code indicates its been done.
         assertFalse(sync.isBeforeCompletionDone());
         assertTrue(sync.isAfterCompletionDone());
-        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, tm.getStatus());
+        assertEquals(javax.transaction.Status.STATUS_ROLLEDBACK, t.getStatus());
     }
 }

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/build.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/build.xml	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/build.xml	2009-03-05 17:31:21 UTC (rev 25506)
@@ -189,6 +189,7 @@
 
 	<target name="com.hp.mwlabs.ts.jtax.tests.run" depends="com.hp.mwlabs.ts.jtax.tests.compile" if="com.hp.mwlabs.ts.jtax.tests.compile">
 	    <mkdir dir="${com.hp.mwlabs.ts.jtax.reports.dest}"/>
+        
 	    <junit printsummary="yes">
 	        <formatter type="plain"/>
 	        <classpath>
@@ -196,10 +197,14 @@
 	            <path location="${com.hp.mwlabs.ts.jtax.dest}"/>
 	            <path refid="com.hp.mwlabs.ts.jacorb.classpath"/>
 	            <pathelement path="${build.classpath}"/>
+                <pathelement location="../../ArjunaJTA/jta/build/tests"/>
 	        </classpath>
 	        <batchtest haltonerror="yes" haltonfailure="yes" fork="yes"
                     todir="${com.hp.mwlabs.ts.jtax.reports.dest}">
-                    <fileset dir="${com.hp.mwlabs.ts.jtax.tests.src}" includes="**/LastResource*TestCase.java"/>
+                    <fileset dir="${com.hp.mwlabs.ts.jtax.tests.src}">
+                        <include  name="**/LastResource*TestCase.java"/>
+                        <include  name="**/SubordinateTestCase.javaXX"/>
+                    </fileset>
 	        </batchtest>
 	    </junit>
 	</target>
@@ -241,6 +246,7 @@
             <classpath>
                 <path path="${build.classpath}"/>
                 <path path="${com.hp.mwlabs.ts.jtax.dest}"/>
+                <pathelement location="../../ArjunaJTA/jta/build/tests"/>
             </classpath>
 		</javac>
 

Copied: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TransactionImporterImple.java (from rev 25489, labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxImporter.java)
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TransactionImporterImple.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TransactionImporterImple.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -0,0 +1,172 @@
+/*
+ * 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) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * Copyright (C) 2005,
+ *
+ * Arjuna Technologies Ltd,
+ * Newcastle upon Tyne,
+ * Tyne and Wear,
+ * UK.
+ *
+ * $Id: TransactionImporterImple.java 2342 2006-03-30 13:06:17Z  $
+ */
+
+package com.arjuna.ats.internal.jta.transaction.jts.jca;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.transaction.xa.*;
+import javax.transaction.Transaction;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TransactionImporter;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction;
+import com.arjuna.ats.jta.xa.XidImple;
+
+public class TransactionImporterImple implements TransactionImporter
+{
+	
+	/**
+	 * Create a subordinate transaction associated with the
+	 * global transaction inflow. No timeout is associated with the
+	 * transaction.
+	 * 
+	 * @param xid the global transaction.
+	 * 
+	 * @return the subordinate transaction.
+	 * 
+	 * @throws XAException thrown if there are any errors.
+	 */
+	
+	public SubordinateTransaction importTransaction (Xid xid) throws XAException
+	{
+		return importTransaction(xid, 0);
+	}
+
+	/**
+	 * Create a subordinate transaction associated with the
+	 * global transaction inflow and having a specified timeout.
+	 * 
+	 * @param xid the global transaction.
+	 * @param timeout the timeout associated with the global transaction.
+	 * 
+	 * @return the subordinate transaction.
+	 * 
+	 * @throws XAException thrown if there are any errors.
+	 */
+	
+	public SubordinateTransaction importTransaction (Xid xid, int timeout) throws XAException
+	{
+		if (xid == null)
+			throw new IllegalArgumentException();
+		
+		/*
+		 * Check to see if we haven't already imported this thing.
+		 */
+		
+		SubordinateTransaction imported = getImportedTransaction(xid);
+		
+		if (imported == null)
+		{	
+			imported = new TransactionImple(timeout, xid);
+			
+			_transactions.put(new XidImple(xid), imported);
+		}
+		
+		return imported;
+	}
+
+	public SubordinateTransaction recoverTransaction (Uid actId) throws XAException
+	{
+		if (actId == null)
+			throw new IllegalArgumentException();
+		
+		TransactionImple recovered = new TransactionImple(actId);
+		TransactionImple tx = (TransactionImple) _transactions.get(recovered.baseXid());
+
+		if (tx == null)
+		{
+			recovered.recordTransaction();
+
+			_transactions.put(recovered.baseXid(), recovered);
+			
+			return recovered;
+		}
+		else
+			return tx;
+	}
+    
+	/**
+	 * Get the subordinate (imported) transaction associated with the
+	 * global transaction.
+	 * 
+	 * @param xid the global transaction.
+	 * 
+	 * @return the subordinate transaction or <code>null</code> if there
+	 * is none.
+	 * 
+	 * @throws XAException thrown if there are any errors.
+	 */
+	
+	public SubordinateTransaction getImportedTransaction (Xid xid) throws XAException
+	{
+		if (xid == null)
+			throw new IllegalArgumentException();
+		
+		SubordinateTransaction tx = _transactions.get(new XidImple(xid));
+		
+		if (tx == null)
+			return null;
+
+		if (tx.baseXid() == null)
+		{
+			/*
+			 * Try recovery again. If it fails we'll throw a RETRY to the caller who
+			 * should try again later.
+			 */
+            tx.recover();
+
+			return tx;
+		}
+		else
+			return tx;
+	}
+
+	/**
+	 * Remove the subordinate (imported) transaction.
+	 * 
+	 * @param xid the global transaction.
+	 * 
+	 * @throws XAException thrown if there are any errors.
+	 */
+	
+	public void removeImportedTransaction (Xid xid) throws XAException
+	{
+		if (xid == null)
+			throw new IllegalArgumentException();
+
+		_transactions.remove(new XidImple(xid));
+	}
+	
+	private static ConcurrentHashMap<Xid, SubordinateTransaction> _transactions = new ConcurrentHashMap<Xid, SubordinateTransaction>();
+	
+}

Deleted: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxImporter.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxImporter.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxImporter.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -1,169 +0,0 @@
-/*
- * 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) 2005-2006,
- * @author JBoss Inc.
- */
-/*
- * Copyright (C) 2005,
- *
- * Arjuna Technologies Ltd,
- * Newcastle upon Tyne,
- * Tyne and Wear,
- * UK.
- *
- * $Id: TxImporter.java 2342 2006-03-30 13:06:17Z  $
- */
-
-package com.arjuna.ats.internal.jta.transaction.jts.jca;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.transaction.xa.*;
-
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
-import com.arjuna.ats.jta.xa.XidImple;
-
-public class TxImporter
-{
-	
-	/**
-	 * Create a subordinate transaction associated with the
-	 * global transaction inflow. No timeout is associated with the
-	 * transaction.
-	 * 
-	 * @param xid the global transaction.
-	 * 
-	 * @return the subordinate transaction.
-	 * 
-	 * @throws XAException thrown if there are any errors.
-	 */
-	
-	public static TransactionImple importTransaction (Xid xid) throws XAException
-	{
-		return importTransaction(xid, 0);
-	}
-
-	/**
-	 * Create a subordinate transaction associated with the
-	 * global transaction inflow and having a specified timeout.
-	 * 
-	 * @param xid the global transaction.
-	 * @param timeout the timeout associated with the global transaction.
-	 * 
-	 * @return the subordinate transaction.
-	 * 
-	 * @throws XAException thrown if there are any errors.
-	 */
-	
-	public static TransactionImple importTransaction (Xid xid, int timeout) throws XAException
-	{
-		if (xid == null)
-			throw new IllegalArgumentException();
-		
-		/*
-		 * Check to see if we haven't already imported this thing.
-		 */
-		
-		TransactionImple imported = getImportedTransaction(xid);
-		
-		if (imported == null)
-		{	
-			imported = new TransactionImple(timeout, xid);
-			
-			_transactions.put(new XidImple(xid), imported);
-		}
-		
-		return imported;
-	}
-
-	public static TransactionImple recoverTransaction (Uid actId) throws XAException
-	{
-		if (actId == null)
-			throw new IllegalArgumentException();
-		
-		TransactionImple recovered = new TransactionImple(actId);
-		TransactionImple tx = (TransactionImple) _transactions.get(recovered.baseXid());
-
-		if (tx == null)
-		{
-			recovered.recordTransaction();
-
-			_transactions.put(recovered.baseXid(), recovered);
-			
-			return recovered;
-		}
-		else
-			return tx;
-	}
-	/**
-	 * Get the subordinate (imported) transaction associated with the
-	 * global transaction.
-	 * 
-	 * @param xid the global transaction.
-	 * 
-	 * @return the subordinate transaction or <code>null</code> if there
-	 * is none.
-	 * 
-	 * @throws XAException thrown if there are any errors.
-	 */
-	
-	public static TransactionImple getImportedTransaction (Xid xid) throws XAException
-	{
-		if (xid == null)
-			throw new IllegalArgumentException();
-		
-		TransactionImple tx = (TransactionImple) _transactions.get(new XidImple(xid));
-		
-		if (tx == null)
-			return null;
-
-		if (tx.baseXid() == null)
-		{
-			/*
-			 * Try recovery again. If it fails we'll throw a RETRY to the caller who
-			 * should try again later.
-			 */
-			
-			tx.getControlWrapper().getImple().getImplHandle().activate();
-
-			return tx;
-		}
-		else
-			return tx;
-	}
-
-	/**
-	 * Remove the subordinate (imported) transaction.
-	 * 
-	 * @param xid the global transaction.
-	 * 
-	 * @throws XAException thrown if there are any errors.
-	 */
-	
-	public static void removeImportedTransaction (Xid xid) throws XAException
-	{
-		if (xid == null)
-			throw new IllegalArgumentException();
-
-		_transactions.remove(new XidImple(xid));
-	}
-	
-	private static ConcurrentHashMap<Xid, TransactionImple> _transactions = new ConcurrentHashMap<Xid, TransactionImple>();
-	
-}

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxWorkManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxWorkManager.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/TxWorkManager.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -33,10 +33,12 @@
 
 import java.util.HashMap;
 import java.util.Stack;
+import java.util.Map;
 
 import javax.resource.spi.work.Work;
 import javax.resource.spi.work.WorkCompletedException;
 import javax.resource.spi.work.WorkException;
+import javax.transaction.Transaction;
 
 import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
 
@@ -65,17 +67,17 @@
 	 *          com.arjuna.ats.internal.jta.transaction.jts.jca.busy] Work already active!
 	 */
 
-	public static void addWork (Work work, TransactionImple tx) throws WorkCompletedException
+	public static void addWork (Work work, Transaction tx) throws WorkCompletedException
 	{
-		Stack workers;
+		Stack<Work> workers;
 
 		synchronized (_transactions)
 		{
-			workers = (Stack) _transactions.get(tx);
+			workers = _transactions.get(tx);
 
 			if (workers == null)
 			{
-				workers = new Stack();
+				workers = new Stack<Work>();
 
 				_transactions.put(tx, workers);
 			}
@@ -96,13 +98,13 @@
 	 * @param tx the transaction the work should be disassociated from.
 	 */
 
-	public static void removeWork (Work work, TransactionImple tx)
+	public static void removeWork (Work work, Transaction tx)
 	{
-		Stack workers;
+		Stack<Work> workers;
 
 		synchronized (_transactions)
 		{
-			workers = (Stack) _transactions.get(tx);
+			workers = _transactions.get(tx);
 		}
 
 		if (workers != null)
@@ -137,11 +139,11 @@
 	 * <code>false</code> otherwise.
 	 */
 
-	public static boolean hasWork (TransactionImple tx)
+	public static boolean hasWork (Transaction tx)
 	{
 		synchronized (_transactions)
 		{
-			Stack workers = (Stack) _transactions.get(tx);
+			Stack workers = _transactions.get(tx);
 
 			return (boolean) (workers != null);
 		}
@@ -155,13 +157,13 @@
 	 * @return the work, or <code>null</code> if there is none.
 	 */
 
-	public static Work getWork (TransactionImple tx)
+	public static Work getWork (Transaction tx)
 	{
-		Stack workers;
+		Stack<Work> workers;
 
 		synchronized (_transactions)
 		{
-			workers = (Stack) _transactions.get(tx);
+			workers = _transactions.get(tx);
 		}
 
 		if (workers != null)
@@ -169,13 +171,13 @@
 			synchronized (workers)
 			{
 				if (!workers.empty())
-					return (Work) workers.peek();
+					return workers.peek();
 			}
 		}
 
 		return null;
 	}
 
-	private static HashMap _transactions = new HashMap();
+	private static final Map<Transaction, Stack<Work>> _transactions = new HashMap<Transaction, Stack<Work>>();
 
 }

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/WorkSynchronization.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/WorkSynchronization.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/WorkSynchronization.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -34,6 +34,8 @@
 import com.arjuna.ats.internal.jta.transaction.jts.jca.TxWorkManager;
 import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
 
+import javax.transaction.Transaction;
+
 /**
  * Register a single instance of this thing when the first JCA worker is
  * imported. Not before.
@@ -47,7 +49,7 @@
 public class WorkSynchronization implements javax.transaction.Synchronization
 {
 
-	public WorkSynchronization (TransactionImple current)
+	public WorkSynchronization (Transaction current)
 	{
 		_current = current;
 	}
@@ -94,6 +96,6 @@
 		// do nothing
 	}
 
-	private TransactionImple _current;
+	private Transaction _current;
 	
 }

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -34,10 +34,7 @@
 import java.io.IOException;
 import java.util.Stack;
 
-import javax.transaction.HeuristicCommitException;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.SystemException;
+import javax.transaction.*;
 import javax.transaction.xa.*;
 
 import com.arjuna.ats.arjuna.common.Uid;
@@ -47,8 +44,8 @@
 import com.arjuna.ats.arjuna.state.InputObjectState;
 import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
 import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.coordinator.ServerTransaction;
-import com.arjuna.ats.jta.utils.XAHelper;
-import com.arjuna.ats.jta.xa.XidImple;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction;
 
 /**
  * The XATerminator implementation.
@@ -64,7 +61,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.getImportedTransaction(xid);
+			SubordinateTransaction tx = SubordinationManager.getTransactionImporter().getImportedTransaction(xid);
 
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
@@ -76,18 +73,25 @@
 				else
 					tx.doCommit();
 
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 			}
 			else
 				throw new XAException(XAException.XA_RETRY);
 		}
+        catch(RollbackException e)
+        {
+            SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
+            XAException xaException = new XAException(XAException.XA_RBROLLBACK);
+            xaException.initCause(e);
+            throw xaException;
+        }
 		catch (XAException ex)
 		{
 			// resource hasn't had a chance to recover yet
 
 			if (ex.errorCode != XAException.XA_RETRY)
 			{
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 			}
 
 			throw ex;
@@ -102,7 +106,7 @@
 		}
 		catch (SystemException ex)
 		{
-			TxImporter.removeImportedTransaction(xid);
+			SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 
 			throw new XAException(XAException.XAER_RMERR);
 		}
@@ -112,7 +116,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.getImportedTransaction(xid);
+			SubordinateTransaction tx = SubordinationManager.getTransactionImporter().getImportedTransaction(xid);
 
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
@@ -125,7 +129,7 @@
 		}
 		finally
 		{
-			TxImporter.removeImportedTransaction(xid);
+			SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 		}
 	}
 
@@ -133,7 +137,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.getImportedTransaction(xid);
+			SubordinateTransaction tx = SubordinationManager.getTransactionImporter().getImportedTransaction(xid);
 
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
@@ -141,11 +145,11 @@
 			switch (tx.doPrepare())
 			{
 			case TwoPhaseOutcome.PREPARE_READONLY:
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 
 				return XAResource.XA_RDONLY;
 			case TwoPhaseOutcome.PREPARE_NOTOK:
-				TxImporter.removeImportedTransaction(xid);  // TODO check if rollback is going to be called first
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);  // TODO check if rollback is going to be called first
 
 				throw new XAException(XAException.XA_RBROLLBACK);
 			case TwoPhaseOutcome.PREPARE_OK:
@@ -154,10 +158,10 @@
 				throw new XAException(XAException.XA_RBOTHER);
 			}
 		}
-		catch (SystemException ex)
+		/*catch (SystemException ex)
 		{
 			throw new XAException(XAException.XAER_RMFAIL);
-		}
+		}*/
 		catch (XAException ex)
 		{
 			throw ex;
@@ -232,7 +236,7 @@
 
 					if (uid.notEquals(Uid.nullUid()))
 					{
-						TransactionImple tx = TxImporter.recoverTransaction(uid);
+						Transaction tx = SubordinationManager.getTransactionImporter().recoverTransaction(uid);
 
 						values.push(tx);
 					}
@@ -270,7 +274,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.getImportedTransaction(xid);
+			SubordinateTransaction tx = SubordinationManager.getTransactionImporter().getImportedTransaction(xid);
 
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
@@ -279,7 +283,7 @@
 			{
 				tx.doRollback();
 
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 			}
 			else
 				throw new XAException(XAException.XA_RETRY);
@@ -290,7 +294,7 @@
 
 			if (ex.errorCode != XAException.XA_RETRY)
 			{
-				TxImporter.removeImportedTransaction(xid);
+				SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 			}
 
 			throw ex;
@@ -305,7 +309,7 @@
 		}
 		catch (SystemException ex)
 		{
-			TxImporter.removeImportedTransaction(xid);
+			SubordinationManager.getTransactionImporter().removeImportedTransaction(xid);
 
 			throw new XAException(XAException.XAER_RMERR);
 		}

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/TransactionImple.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -48,6 +48,7 @@
 import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.SystemException;
+import javax.transaction.RollbackException;
 
 /**
  * @message com.arjuna.ats.internal.jta.transaction.jts.subordinate.invalidstate
@@ -139,7 +140,7 @@
 	 * @throws SystemException thrown if any error occurs.
 	 */
 
-	public int doPrepare () throws SystemException
+	public int doPrepare ()
 	{
 		try
 		{
@@ -173,12 +174,6 @@
 		{
 			return TwoPhaseOutcome.INVALID_TRANSACTION;
 		}
-		catch (Exception ex)
-		{
-			ex.printStackTrace();
-
-			throw new SystemException();
-		}
 	}
 
 	/**
@@ -303,7 +298,7 @@
 	 * rolls back.
 	 */
 
-	public void doOnePhaseCommit () throws IllegalStateException,
+	public void doOnePhaseCommit () throws IllegalStateException, javax.transaction.RollbackException,
 			javax.transaction.HeuristicRollbackException, javax.transaction.SystemException
 	{
 		try
@@ -322,7 +317,7 @@
         			}
 			}
 
-			int status = subAct.doOnePhaseCommit();
+			int status = subAct.doOnePhaseCommit(); // ActionStatus status = TwoPhaseOutcome
 
 			TransactionImple.removeTransaction(this);
 
@@ -332,6 +327,7 @@
 			case ActionStatus.H_COMMIT:
 				break;
 			case ActionStatus.ABORTED:
+                throw new RollbackException();
 			case ActionStatus.ABORTING:
 			case ActionStatus.H_HAZARD:
 			case ActionStatus.H_MIXED:

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/jca/TransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/jca/TransactionImple.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/subordinate/jca/TransactionImple.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -35,11 +35,12 @@
 
 import com.arjuna.ats.arjuna.common.Uid;
 import com.arjuna.ats.jta.logging.*;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction;
 
 import javax.transaction.xa.Xid;
 
 public class TransactionImple extends
-		com.arjuna.ats.internal.jta.transaction.jts.subordinate.TransactionImple
+		com.arjuna.ats.internal.jta.transaction.jts.subordinate.TransactionImple implements SubordinateTransaction
 {
 
 	/**
@@ -127,5 +128,13 @@
 	{
 		return ((SubordinateAtomicTransaction) _theTransaction).getXid();
 	}
+    
+    public void recover() {
+        getControlWrapper().getImple().getImplHandle().activate();
+    }
+    
+    public boolean activated() {
+        return true; // TODO: more sensible implementation.
+    }
 	
 }

Added: labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/subordinate/SubordinateTestCase.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/subordinate/SubordinateTestCase.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/subordinate/SubordinateTestCase.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, 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) 2009,
+ * @author JBoss Inc.
+ */
+package com.hp.mwtests.ts.jta.jts.subordinate;
+
+import com.arjuna.orbportability.ORB;
+import com.arjuna.orbportability.RootOA;
+import com.arjuna.orbportability.OA;
+import com.arjuna.ats.internal.jts.ORBManager;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinateTransaction;
+import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
+
+/**
+ * JTAX version of the Subordinate transaction tests.
+ */
+public class SubordinateTestCase extends com.hp.mwtests.ts.jta.subordinate.SubordinateTestCase
+{
+    // we mostly reuse the JTA version of the test class, but need to ensure correct config, orb init
+    // and use of the appropriate tx impl class:
+    
+    private ORB orb ;
+    private RootOA oa ;
+    
+    protected void setUp()
+        throws Exception
+    {
+        System.setProperty("com.arjuna.ats.jta.jtaTMImplementation", "com.arjuna.ats.internal.jta.transaction.jts.TransactionManagerImple");
+        System.setProperty("com.arjuna.ats.jta.jtaUTImplementation", "com.arjuna.ats.internal.jta.transaction.jts.UserTransactionImple");
+        
+        orb = ORB.getInstance("test");
+        oa = OA.getRootOA(orb);
+        
+        orb.initORB(new String[0], null);
+        oa.initOA();
+
+        ORBManager.setORB(orb);
+        ORBManager.setPOA(oa);
+    }
+
+    protected void tearDown()
+        throws Exception
+    {
+        if (oa != null)
+        {
+            oa.destroy();
+        }
+        if (orb != null)
+        {
+            orb.shutdown();
+        }
+    }
+    
+    @Override
+    public SubordinateTransaction createTransaction() {
+            return new TransactionImple(0); // implicit begin
+    }
+}

Modified: labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/internal/jbossatx/jta/jca/XATerminator.java
===================================================================
--- labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/internal/jbossatx/jta/jca/XATerminator.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/internal/jbossatx/jta/jca/XATerminator.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -37,22 +37,18 @@
 import javax.transaction.InvalidTransactionException;
 import javax.transaction.Status;
 import javax.transaction.SystemException;
+import javax.transaction.Transaction;
 import javax.transaction.xa.XAException;
 import javax.transaction.xa.Xid;
 
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TxImporter;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.WorkSynchronization;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.XATerminatorImple;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.subordinate.jca.TransactionImple;
+import com.arjuna.ats.jbossatx.logging.jbossatxLogger;
+import com.arjuna.ats.jta.TransactionManager;
 
 import org.jboss.tm.JBossXATerminator;
 import org.jboss.util.UnexpectedThrowable;
 
-import com.arjuna.ats.jbossatx.logging.jbossatxLogger;
-import com.arjuna.ats.jta.TransactionManager;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.*;
 
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TxWorkManager;
-
 /**
  * The implementation of JBossXATerminator using the purely local (ArjunaCore)
  * implementation of the JTA.
@@ -107,7 +103,7 @@
 			 * Remember to convert timeout to seconds.
 			 */
 
-			TransactionImple tx = TxImporter.importTransaction(xid, (int) timeout/1000);
+			Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid, (int) timeout/1000);
 
 			switch (tx.getStatus())
 			{
@@ -173,7 +169,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.importTransaction(xid);
+			Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid);
 
 			// JBoss doesn't seem to use the work parameter!
 
@@ -216,7 +212,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.importTransaction(xid);
+			Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid);
 
 			TransactionManager.transactionManager().suspend();
 
@@ -240,7 +236,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.importTransaction(xid);
+			Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid);
 
 			TxWorkManager.removeWork(work, tx);
 		}

Modified: labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/internal/jbossatx/jts/jca/XATerminator.java
===================================================================
--- labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/internal/jbossatx/jts/jca/XATerminator.java	2009-03-05 17:30:18 UTC (rev 25505)
+++ labs/jbosstm/trunk/atsintegration/classes/com/arjuna/ats/internal/jbossatx/jts/jca/XATerminator.java	2009-03-05 17:31:21 UTC (rev 25506)
@@ -37,13 +37,12 @@
 import javax.transaction.InvalidTransactionException;
 import javax.transaction.Status;
 import javax.transaction.SystemException;
+import javax.transaction.Transaction;
 import javax.transaction.xa.XAException;
 import javax.transaction.xa.Xid;
 
-import com.arjuna.ats.internal.jta.transaction.jts.jca.TxImporter;
 import com.arjuna.ats.internal.jta.transaction.jts.jca.WorkSynchronization;
 import com.arjuna.ats.internal.jta.transaction.jts.jca.XATerminatorImple;
-import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
 
 import org.jboss.tm.JBossXATerminator;
 import org.jboss.util.UnexpectedThrowable;
@@ -52,6 +51,7 @@
 import com.arjuna.ats.jta.TransactionManager;
 
 import com.arjuna.ats.internal.jta.transaction.jts.jca.TxWorkManager;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
 
 /**
  * The implementation of JBossXATerminator using the JTS implementation of the
@@ -102,7 +102,7 @@
 			 * Remember to convert timeout to seconds.
 			 */
 
-			TransactionImple tx = TxImporter.importTransaction(xid, (int) timeout/1000);
+			Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid, (int) timeout/1000);
 
 			switch (tx.getStatus())
 			{
@@ -168,7 +168,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.importTransaction(xid);
+			Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid);
 
 			// JBoss doesn't seem to use the work parameter!
 
@@ -211,7 +211,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.importTransaction(xid);
+			Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid);
 
 			TransactionManager.transactionManager().suspend();
 
@@ -235,7 +235,7 @@
 	{
 		try
 		{
-			TransactionImple tx = TxImporter.importTransaction(xid);
+			Transaction tx = SubordinationManager.getTransactionImporter().importTransaction(xid);
 
 			TxWorkManager.removeWork(work, tx);
 		}




More information about the jboss-svn-commits mailing list