geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject svn commit: rev 53780 - in geronimo/trunk/modules: assembly/src/plan client client/src/java/org/apache/geronimo/client connector/src/java/org/apache/geronimo/connector/deployment connector/src/java/org/apache/geronimo/connector/outbound connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig connector/src/java/org/apache/geronimo/connector/work connector/src/test-data/connector_1_5 connector/src/test/org/apache/geronimo/connector connector/src/test/org/apache/geronimo/connector/outbound connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking connector/src/test/org/apache/geronimo/connector/work jetty/src/java/org/apache/geronimo/jetty timer/src/java/org/apache/geronimo/timer timer/src/java/org/apache/geronimo/timer/jdbc timer/src/java/org/apache/geronimo/timer/vm timer/src/test/org/apache/geronimo/timer transaction/src/java/org/apache/geronimo/transaction transaction/src/java/org/apache/geronimo/transaction/context transaction/src/java/org/apache/geronimo/transaction/manager transaction/src/test/org/apache/geronimo/transaction
Date Tue, 05 Oct 2004 06:53:14 GMT
Author: djencks
Date: Mon Oct  4 23:53:13 2004
New Revision: 53780

Removed:
   geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/MockXATerminator.java
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/XAServices.java
Modified:
   geronimo/trunk/modules/assembly/src/plan/client-system-plan.xml
   geronimo/trunk/modules/assembly/src/plan/default-database-plan.xml
   geronimo/trunk/modules/assembly/src/plan/j2ee-client-plan.xml
   geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml
   geronimo/trunk/modules/assembly/src/plan/system-database-plan.xml
   geronimo/trunk/modules/client/project.xml
   geronimo/trunk/modules/client/src/java/org/apache/geronimo/client/AppClientContainer.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/LocalTransactions.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/NoTransactions.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/TransactionLog.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/TransactionSupport.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/XATransactions.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/work/GeronimoWorkManager.java
   geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/work/WorkerContext.java
   geronimo/trunk/modules/connector/src/test-data/connector_1_5/geronimo-ra.xml
   geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/BootstrapContextTest.java
   geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionManagerTestUtils.java
   geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java
   geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptorTest.java
   geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/DefaultComponentInterceptor.java
   geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/work/PooledWorkManagerTest.java
   geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java
   geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java
   geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/jdbc/JDBCStoreThreadPooledNonTransactionalTimer.java
   geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/jdbc/JDBCStoreThreadPooledTransactionalTimer.java
   geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/vm/VMStoreThreadPooledNonTransactionalTimer.java
   geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/vm/VMStoreThreadPooledTransactionalTimer.java
   geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java
   geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/NontransactionalThreadPooledTimerTest.java
   geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/TransactionalThreadPooledTimerTest.java
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/TransactionManagerProxy.java
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/ContainerTransactionContext.java
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java
   geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
   geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/TransactionManagerProxyTest.java
Log:
Move imported tx functionality towards TransactionContextManager.  Replace almost all uses of TransactionContext.get/setContext with methods on TransactionContextManager.  Prevent NPEs when there is no TransactionContext. This represents progress on GERONIMO-347 and GERONIMO-352

Modified: geronimo/trunk/modules/assembly/src/plan/client-system-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/client-system-plan.xml	(original)
+++ geronimo/trunk/modules/assembly/src/plan/client-system-plan.xml	Mon Oct  4 23:53:13 2004
@@ -74,4 +74,12 @@
         <attribute name="maxFileSize" type="java.lang.String">10MB</attribute>
         <reference name="ServerInfo">geronimo.client:role=ServerInfo</reference>
     </gbean>
+
+    <!-- Naming properties -->
+    <gbean name="geronimo.client:role=NamingProperties" class="org.apache.geronimo.system.properties.NamingProperties">
+        <attribute name="namingFactoryInitial" type="java.lang.String">com.sun.jndi.rmi.registry.RegistryContextFactory</attribute>
+        <attribute name="namingFactoryUrlPkgs" type="java.lang.String">org.apache.geronimo.naming</attribute>
+        <attribute name="namingProviderUrl" type="java.lang.String">rmi://localhost:1099</attribute>
+    </gbean>
+
 </configuration>

Modified: geronimo/trunk/modules/assembly/src/plan/default-database-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/default-database-plan.xml	(original)
+++ geronimo/trunk/modules/assembly/src/plan/default-database-plan.xml	Mon Oct  4 23:53:13 2004
@@ -80,6 +80,7 @@
 
     <gbean name="geronimo.server:type=ThreadPooledTimer,name=JDBCNonTransactionalThreadPooledTimer" class="org.apache.geronimo.timer.jdbc.JDBCStoreThreadPooledNonTransactionalTimer">
         <reference name="ManagedConnectionFactoryWrapper">geronimo.server:J2EEServer=geronimo,j2eeType=JCAManagedConnectionFactory,name=DefaultDatasource</reference>
+        <reference name="TransactionContextManager">geronimo.server:type=TransactionContextManager</reference>
         <reference name="ThreadPool">geronimo.server:type=ThreadPool,name=DefaultThreadPool</reference>
     </gbean>
 

Modified: geronimo/trunk/modules/assembly/src/plan/j2ee-client-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/j2ee-client-plan.xml	(original)
+++ geronimo/trunk/modules/assembly/src/plan/j2ee-client-plan.xml	Mon Oct  4 23:53:13 2004
@@ -90,7 +90,7 @@
         <attribute name="syncMaximumPoolSize" type="int">10</attribute>
         <attribute name="startMaximumPoolSize" type="int">10</attribute>
         <attribute name="scheduledMaximumPoolSize" type="int">10</attribute>
-        <reference name="XAServices">geronimo.client:type=TransactionManager</reference>
+        <reference name="TransactionContextManager">geronimo.client:type=TransactionContextManager</reference>
     </gbean>
 
     <gbean name="geronimo.client:type=TransactionManager" class="org.apache.geronimo.transaction.GeronimoTransactionManager">
@@ -102,6 +102,8 @@
 
     <gbean name="geronimo.client:type=TransactionContextManager" class="org.apache.geronimo.transaction.context.TransactionContextManager">
         <reference name="TransactionManager">geronimo.client:type=TransactionManager</reference>
+        <reference name="XidImporter">geronimo.client:type=TransactionManager</reference>
+        <reference name="Recovery">geronimo.client:type=TransactionManager</reference>
     </gbean>
 
 </configuration>

Modified: geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml	(original)
+++ geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml	Mon Oct  4 23:53:13 2004
@@ -150,7 +150,7 @@
         <attribute name="syncMaximumPoolSize" type="int">10</attribute>
         <attribute name="startMaximumPoolSize" type="int">10</attribute>
         <attribute name="scheduledMaximumPoolSize" type="int">10</attribute>
-        <reference name="XAServices">geronimo.server:type=TransactionManager</reference>
+        <reference name="TransactionContextManager">geronimo.server:type=TransactionContextManager</reference>
     </gbean>
 
     <gbean name="geronimo.server:type=HOWLTransactionLog" class="org.apache.geronimo.transaction.log.HOWLLog">
@@ -179,6 +179,8 @@
 
     <gbean name="geronimo.server:type=TransactionContextManager" class="org.apache.geronimo.transaction.context.TransactionContextManager">
         <reference name="TransactionManager">geronimo.server:type=TransactionManager</reference>
+        <reference name="XidImporter">geronimo.server:type=TransactionManager</reference>
+        <reference name="Recovery">geronimo.server:type=TransactionManager</reference>
     </gbean>
 
 

Modified: geronimo/trunk/modules/assembly/src/plan/system-database-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/system-database-plan.xml	(original)
+++ geronimo/trunk/modules/assembly/src/plan/system-database-plan.xml	Mon Oct  4 23:53:13 2004
@@ -78,6 +78,7 @@
 
     <gbean name="geronimo.server:type=ThreadPooledTimer,name=JDBCNonTransactionalThreadPooledTimer" class="org.apache.geronimo.timer.jdbc.JDBCStoreThreadPooledNonTransactionalTimer">
         <reference name="ManagedConnectionFactoryWrapper">geronimo.server:J2EEServer=geronimo,j2eeType=JCAManagedConnectionFactory,name=DefaultDatasource</reference>
+        <reference name="TransactionContextManager">geronimo.server:type=TransactionContextManager</reference>
         <reference name="ThreadPool">geronimo.server:type=ThreadPool,name=DefaultThreadPool</reference>
     </gbean>
 -->

Modified: geronimo/trunk/modules/client/project.xml
==============================================================================
--- geronimo/trunk/modules/client/project.xml	(original)
+++ geronimo/trunk/modules/client/project.xml	Mon Oct  4 23:53:13 2004
@@ -67,12 +67,18 @@
         </dependency>
 
         <dependency>
-            <groupId>geronimo</groupId>
-            <artifactId>geronimo-transaction</artifactId>
-            <version>${pom.currentVersion}</version>
+             <groupId>geronimo</groupId>
+             <artifactId>geronimo-transaction</artifactId>
+             <version>${pom.currentVersion}</version>
+         </dependency>
+
+        <dependency>
+            <groupId>geronimo-spec</groupId>
+            <artifactId>geronimo-spec-jta</artifactId>
+            <version>&geronimo-spec-jta-version;</version>
         </dependency>
 
-        <!-- Thirdparty -->
+          <!-- Thirdparty -->
 
         <dependency>
             <groupId>cglib</groupId>

Modified: geronimo/trunk/modules/client/src/java/org/apache/geronimo/client/AppClientContainer.java
==============================================================================
--- geronimo/trunk/modules/client/src/java/org/apache/geronimo/client/AppClientContainer.java	(original)
+++ geronimo/trunk/modules/client/src/java/org/apache/geronimo/client/AppClientContainer.java	Mon Oct  4 23:53:13 2004
@@ -23,7 +23,7 @@
 import org.apache.geronimo.gbean.GBeanInfo;
 import org.apache.geronimo.gbean.GBeanInfoFactory;
 import org.apache.geronimo.transaction.context.TransactionContext;
-import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * @version $Rev: 46019 $ $Date: 2004-09-14 02:56:06 -0700 (Tue, 14 Sep 2004) $
@@ -36,12 +36,14 @@
     private final ObjectName appClientModuleName;
     private final Method mainMethod;
     private final ClassLoader classLoader;
+    private final TransactionContextManager transactionContextManager;
 
-    public AppClientContainer(String mainClassName, ObjectName appClientModuleName, AppClientPlugin jndiContext, ClassLoader classLoader) throws Exception {
+    public AppClientContainer(String mainClassName, ObjectName appClientModuleName, ClassLoader classLoader, AppClientPlugin jndiContext, TransactionContextManager transactionContextManager) throws Exception {
         this.mainClassName = mainClassName;
-        this.jndiContext = jndiContext;
         this.appClientModuleName = appClientModuleName;
         this.classLoader = classLoader;
+        this.jndiContext = jndiContext;
+        this.transactionContextManager = transactionContextManager;
 
         try {
             Class mainClass = classLoader.loadClass(mainClassName);
@@ -66,11 +68,11 @@
 
         ClassLoader contextClassLoader = thread.getContextClassLoader();
         thread.setContextClassLoader(classLoader);
-        TransactionContext oldTransactionContext = TransactionContext.getContext();
-
+        TransactionContext oldTransactionContext = transactionContextManager.getContext();
+        TransactionContext currentTransactionContext = null;
         try {
             jndiContext.startClient(appClientModuleName);
-            TransactionContext.setContext(new UnspecifiedTransactionContext());
+            currentTransactionContext = transactionContextManager.newUnspecifiedTransactionContext();
             mainMethod.invoke(null, new Object[]{args});
 
         } catch (InvocationTargetException e) {
@@ -85,8 +87,8 @@
             jndiContext.stopClient(appClientModuleName);
 
             thread.setContextClassLoader(contextClassLoader);
-            TransactionContext.setContext(oldTransactionContext);
-
+            transactionContextManager.setContext(oldTransactionContext);
+            currentTransactionContext.commit();
         }
     }
 
@@ -98,10 +100,11 @@
         infoFactory.addOperation("main", new Class[]{String[].class});
         infoFactory.addAttribute("mainClassName", String.class, true);
         infoFactory.addAttribute("appClientModuleName", ObjectName.class, true);
-        infoFactory.addReference("JNDIContext", AppClientPlugin.class);
         infoFactory.addAttribute("classLoader", ClassLoader.class, false);
+        infoFactory.addReference("JNDIContext", AppClientPlugin.class);
+        infoFactory.addReference("TransactionContextManager", TransactionContextManager.class);
 
-        infoFactory.setConstructor(new String[]{"mainClassName", "appClientModuleName", "JNDIContext", "classLoader"});
+        infoFactory.setConstructor(new String[]{"mainClassName", "appClientModuleName", "classLoader", "JNDIContext", "TransactionContextManager"});
 
         GBEAN_INFO = infoFactory.getBeanInfo();
     }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java	Mon Oct  4 23:53:13 2004
@@ -220,7 +220,7 @@
     }
 
     public String addGBeans(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException {
-        ObjectName resourceAdapterModuleName = addResourceAdapterModuleGBean(earContext, module, cl);
+        addResourceAdapterModuleGBean(earContext, module, cl);
 
         GerConnectorType geronimoConnector = (GerConnectorType) module.getVendorDD();
         XmlObject specDD = module.getSpecDD();
@@ -626,6 +626,7 @@
             if (connectionManager.getRealmBridge() != null) {
                 connectionManagerGBean.setReferencePattern("RealmBridge", ObjectName.getInstance(BASE_REALM_BRIDGE_NAME + connectionManager.getRealmBridge()));
             }
+            connectionManagerGBean.setReferencePattern("TransactionContextManager", earContext.getTransactionContextManagerObjectName());
         } catch (Exception e) {
             throw new DeploymentException("Problem setting up ConnectionManager", e);
         }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java	Mon Oct  4 23:53:13 2004
@@ -24,6 +24,7 @@
 import org.apache.geronimo.gbean.GBeanInfo;
 import org.apache.geronimo.gbean.GBeanInfoFactory;
 import org.apache.geronimo.security.bridge.RealmBridge;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * GenericConnectionManager sets up a connection manager stack according to the
@@ -40,23 +41,30 @@
     private PoolingSupport pooling;
     //dependencies
 
-    protected RealmBridge realmBridge;
-    protected ConnectionTracker connectionTracker;
+    private final RealmBridge realmBridge;
+    private final ConnectionTracker connectionTracker;
+    private final TransactionContextManager transactionContextManager;
 
     //default constructor for use as endpoint
     public GenericConnectionManager() {
+        this.realmBridge = null;
+        this.connectionTracker = null;
+        this.transactionContextManager = null;
     }
 
     public GenericConnectionManager(TransactionSupport transactionSupport,
-            PoolingSupport pooling,
-            String objectName,
-            RealmBridge realmBridge,
-            ConnectionTracker connectionTracker) {
+                                    PoolingSupport pooling,
+                                    String objectName,
+                                    RealmBridge realmBridge,
+                                    ConnectionTracker connectionTracker,
+                                    TransactionContextManager transactionContextManager) {
         this.transactionSupport = transactionSupport;
         this.pooling = pooling;
         this.objectName = objectName;
         this.realmBridge = realmBridge;
         this.connectionTracker = connectionTracker;
+        assert transactionContextManager != null;
+        this.transactionContextManager = transactionContextManager;
     }
 
     /**
@@ -88,7 +96,7 @@
 //        if (transactionSupport instanceof XATransactions && ((XATransactions)transactionSupport).isUseThreadCaching()) {
 //            stack = new ThreadLocalCachingConnectionInterceptor(stack, false);
 //        }
-        stack = transactionSupport.addTransactionInterceptors(stack);
+        stack = transactionSupport.addTransactionInterceptors(stack, transactionContextManager);
 
         if (realmBridge != null) {
             stack = new SubjectInterceptor(stack, realmBridge);
@@ -103,7 +111,7 @@
                     connectionTracker);
         }
         tail.setStack(stack);
-        return new ConnectionInterceptor[] {stack, recoveryStack};
+        return new ConnectionInterceptor[]{stack, recoveryStack};
     }
 
     public TransactionSupport getTransactionSupport() {
@@ -126,18 +134,10 @@
         return realmBridge;
     }
 
-    public void setRealmBridge(RealmBridge realmBridge) {
-        this.realmBridge = realmBridge;
-    }
-
     public ConnectionTracker getConnectionTracker() {
         return connectionTracker;
     }
 
-    public void setConnectionTracker(ConnectionTracker connectionTracker) {
-        this.connectionTracker = connectionTracker;
-    }
-
     public static final GBeanInfo GBEAN_INFO;
 
     static {
@@ -151,13 +151,15 @@
 
         infoFactory.addReference("ConnectionTracker", ConnectionTracker.class);
         infoFactory.addReference("RealmBridge", RealmBridge.class);
+        infoFactory.addReference("TransactionContextManager", TransactionContextManager.class);
 
         infoFactory.setConstructor(new String[]{
             "transactionSupport",
             "pooling",
             "objectName",
             "RealmBridge",
-            "ConnectionTracker"});
+            "ConnectionTracker",
+            "TransactionContextManager"});
 
         GBEAN_INFO = infoFactory.getBeanInfo();
     }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java	Mon Oct  4 23:53:13 2004
@@ -26,6 +26,7 @@
 
 import org.apache.geronimo.transaction.ConnectionReleaser;
 import org.apache.geronimo.transaction.context.TransactionContext;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * TransactionCachingInterceptor.java
@@ -50,13 +51,18 @@
 public class TransactionCachingInterceptor implements ConnectionInterceptor, ConnectionReleaser {
 
     private final ConnectionInterceptor next;
+    private final TransactionContextManager transactionContextManager;
 
-    public TransactionCachingInterceptor(final ConnectionInterceptor next) {
+    public TransactionCachingInterceptor(ConnectionInterceptor next, TransactionContextManager transactionContextManager) {
         this.next = next;
+        this.transactionContextManager = transactionContextManager;
     }
 
     public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
-        TransactionContext transactionContext = TransactionContext.getContext();
+        TransactionContext transactionContext = transactionContextManager.getContext();
+        if (transactionContext == null) {
+            next.getConnection(connectionInfo);
+        } else {
         ManagedConnectionInfos managedConnectionInfos = (ManagedConnectionInfos) transactionContext.getManagedConnectionInfo(this);
         if (managedConnectionInfos == null) {
             managedConnectionInfos = new ManagedConnectionInfos();
@@ -77,6 +83,7 @@
                 managedConnectionInfos.setShared(connectionInfo.getManagedConnectionInfo());
             }
         }
+        }
     }
 
     public void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
@@ -86,8 +93,8 @@
             return;
         }
 
-        TransactionContext transactionContext = TransactionContext.getContext();
-        if (transactionContext.isActive()) {
+        TransactionContext transactionContext = transactionContextManager.getContext();
+        if (transactionContext != null && transactionContext.isActive()) {
             return;
         }
         if (connectionInfo.getManagedConnectionInfo().hasConnectionHandles()) {

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java	Mon Oct  4 23:53:13 2004
@@ -23,11 +23,12 @@
 import javax.transaction.xa.XAResource;
 
 import org.apache.geronimo.transaction.context.TransactionContext;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * TransactionEnlistingInterceptor.java
- *
- *
+ * <p/>
+ * <p/>
  * Created: Fri Sep 26 14:52:24 2003
  *
  * @version 1.0
@@ -35,19 +36,19 @@
 public class TransactionEnlistingInterceptor implements ConnectionInterceptor {
 
     private final ConnectionInterceptor next;
+    private final TransactionContextManager transactionContextManager;
 
-    public TransactionEnlistingInterceptor(
-            ConnectionInterceptor next
-            ) {
+    public TransactionEnlistingInterceptor(ConnectionInterceptor next, TransactionContextManager transactionContextManager) {
         this.next = next;
+        this.transactionContextManager = transactionContextManager;
     }
 
     public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
         next.getConnection(connectionInfo);
         try {
             ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
-            TransactionContext transactionContext = TransactionContext.getContext();
-            if (transactionContext.isActive()) {
+            TransactionContext transactionContext = transactionContextManager.getContext();
+            if (transactionContext != null && transactionContext.isActive()) {
                 XAResource xares = mci.getXAResource();
                 transactionContext.getTransaction().enlistResource(xares);
             }
@@ -55,8 +56,7 @@
         } catch (SystemException e) {
             throw new ResourceException("Could not get transaction", e);
         } catch (RollbackException e) {
-            throw new ResourceException(
-                    "Could not enlist resource in rolled back transaction",
+            throw new ResourceException("Could not enlist resource in rolled back transaction",
                     e);
         }
 
@@ -64,19 +64,19 @@
 
     /**
      * The <code>returnConnection</code> method
-     *
+     * <p/>
      * todo Probably the logic needs improvement if a connection
      * error occurred and we are destroying the handle.
-     * @param connectionInfo a <code>ConnectionInfo</code> value
+     *
+     * @param connectionInfo         a <code>ConnectionInfo</code> value
      * @param connectionReturnAction a <code>ConnectionReturnAction</code> value
      */
-    public void returnConnection(
-            ConnectionInfo connectionInfo,
-            ConnectionReturnAction connectionReturnAction) {
+    public void returnConnection(ConnectionInfo connectionInfo,
+                                 ConnectionReturnAction connectionReturnAction) {
         try {
             ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
-            TransactionContext transactionContext = TransactionContext.getContext();
-            if (transactionContext.isActive()) {
+            TransactionContext transactionContext = transactionContextManager.getContext();
+            if (transactionContext != null && transactionContext.isActive()) {
                 XAResource xares = mci.getXAResource();
                 transactionContext.getTransaction().delistResource(xares, XAResource.TMSUSPEND);
             }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/LocalTransactions.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/LocalTransactions.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/LocalTransactions.java	Mon Oct  4 23:53:13 2004
@@ -21,6 +21,7 @@
 import org.apache.geronimo.connector.outbound.LocalXAResourceInsertionInterceptor;
 import org.apache.geronimo.connector.outbound.TransactionCachingInterceptor;
 import org.apache.geronimo.connector.outbound.TransactionEnlistingInterceptor;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  *
@@ -38,8 +39,8 @@
         return new LocalXAResourceInsertionInterceptor(stack, name);
     }
 
-    public ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack) {
-        stack = new TransactionEnlistingInterceptor(stack);
-        return new TransactionCachingInterceptor(stack);
+    public ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack, TransactionContextManager transactionContextManager) {
+        stack = new TransactionEnlistingInterceptor(stack, transactionContextManager);
+        return new TransactionCachingInterceptor(stack, transactionContextManager);
     }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/NoTransactions.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/NoTransactions.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/NoTransactions.java	Mon Oct  4 23:53:13 2004
@@ -18,6 +18,7 @@
 package org.apache.geronimo.connector.outbound.connectionmanagerconfig;
 
 import org.apache.geronimo.connector.outbound.ConnectionInterceptor;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  *
@@ -35,7 +36,7 @@
         return stack;
     }
 
-    public ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack) {
+    public ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack, TransactionContextManager transactionContextManager) {
         return stack;
     }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/TransactionLog.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/TransactionLog.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/TransactionLog.java	Mon Oct  4 23:53:13 2004
@@ -21,6 +21,7 @@
 import org.apache.geronimo.connector.outbound.TransactionCachingInterceptor;
 import org.apache.geronimo.connector.outbound.TransactionEnlistingInterceptor;
 import org.apache.geronimo.connector.outbound.transactionlog.LogXAResourceInsertionInterceptor;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  *
@@ -39,8 +40,8 @@
         return new LogXAResourceInsertionInterceptor(stack, name);
     }
 
-    public ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack) {
-        stack = new TransactionEnlistingInterceptor(stack);
-        return new TransactionCachingInterceptor(stack);
+    public ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack, TransactionContextManager transactionContextManager) {
+        stack = new TransactionEnlistingInterceptor(stack, transactionContextManager);
+        return new TransactionCachingInterceptor(stack, transactionContextManager);
     }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/TransactionSupport.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/TransactionSupport.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/TransactionSupport.java	Mon Oct  4 23:53:13 2004
@@ -20,6 +20,7 @@
 import java.io.Serializable;
 
 import org.apache.geronimo.connector.outbound.ConnectionInterceptor;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  *
@@ -29,6 +30,6 @@
  * */
 public abstract class TransactionSupport implements Serializable {
     public abstract ConnectionInterceptor addXAResourceInsertionInterceptor(ConnectionInterceptor stack, String name);
-    public abstract ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack);
+    public abstract ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack, TransactionContextManager transactionContextManager);
 
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/XATransactions.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/XATransactions.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/XATransactions.java	Mon Oct  4 23:53:13 2004
@@ -22,6 +22,7 @@
 import org.apache.geronimo.connector.outbound.TransactionCachingInterceptor;
 import org.apache.geronimo.connector.outbound.TransactionEnlistingInterceptor;
 import org.apache.geronimo.connector.outbound.XAResourceInsertionInterceptor;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  *
@@ -58,15 +59,15 @@
         return new XAResourceInsertionInterceptor(stack, name);
     }
 
-    public ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack) {
+    public ConnectionInterceptor addTransactionInterceptors(ConnectionInterceptor stack, TransactionContextManager transactionContextManager) {
         //experimental thread local caching
         if (isUseThreadCaching()) {
             //useMatching should be configurable
             stack = new ThreadLocalCachingConnectionInterceptor(stack, false);
         }
-        stack = new TransactionEnlistingInterceptor(stack);
+        stack = new TransactionEnlistingInterceptor(stack, transactionContextManager);
         if (isUseTransactionCaching()) {
-            stack = new TransactionCachingInterceptor(stack);
+            stack = new TransactionCachingInterceptor(stack, transactionContextManager);
         }
         return stack;
     }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/work/GeronimoWorkManager.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/work/GeronimoWorkManager.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/work/GeronimoWorkManager.java	Mon Oct  4 23:53:13 2004
@@ -36,7 +36,7 @@
 import org.apache.geronimo.gbean.GBeanInfoFactory;
 import org.apache.geronimo.gbean.GBeanLifecycle;
 import org.apache.geronimo.gbean.WaitingException;
-import org.apache.geronimo.transaction.XAServices;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * WorkManager implementation which uses under the cover three WorkExecutorPool
@@ -70,7 +70,7 @@
      */
     private WorkExecutorPool scheduledWorkExecutorPool;
 
-    private final XAServices xaServices;
+    private final TransactionContextManager transactionContextManager;
 
     private final WorkExecutor scheduleWorkExecutor = new ScheduleWorkExecutor();
     private final WorkExecutor startWorkExecutor = new StartWorkExecutor();
@@ -83,15 +83,15 @@
         this(DEFAULT_POOL_SIZE, null);
     }
 
-    public GeronimoWorkManager(int size, XAServices xaServices) {
-        this(size, size, size, xaServices);
+    public GeronimoWorkManager(int size, TransactionContextManager transactionContextManager) {
+        this(size, size, size, transactionContextManager);
     }
 
-    public GeronimoWorkManager(int syncSize, int startSize, int schedSize, XAServices xaServices) {
+    public GeronimoWorkManager(int syncSize, int startSize, int schedSize, TransactionContextManager transactionContextManager) {
         syncWorkExecutorPool = new NullWorkExecutorPool(syncSize);
         startWorkExecutorPool = new NullWorkExecutorPool(startSize);
         scheduledWorkExecutorPool = new NullWorkExecutorPool(schedSize);
-        this.xaServices = xaServices;
+        this.transactionContextManager = transactionContextManager;
     }
 
     public void doStart() throws WaitingException, Exception {
@@ -115,7 +115,7 @@
     }
 
     public XATerminator getXATerminator() {
-        return xaServices;
+        return transactionContextManager;
     }
 
     public int getSyncThreadCount() {
@@ -158,7 +158,7 @@
      * @see javax.resource.spi.work.WorkManager#doWork(javax.resource.spi.work.Work)
      */
     public void doWork(Work work) throws WorkException {
-        executeWork(new WorkerContext(work), syncWorkExecutor, syncWorkExecutorPool);
+        executeWork(new WorkerContext(work, transactionContextManager), syncWorkExecutor, syncWorkExecutorPool);
     }
 
     /* (non-Javadoc)
@@ -171,7 +171,7 @@
             WorkListener workListener)
             throws WorkException {
         WorkerContext workWrapper =
-                new WorkerContext(work, startTimeout, execContext, xaServices, workListener);
+                new WorkerContext(work, startTimeout, execContext, transactionContextManager, workListener);
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
         executeWork(workWrapper, syncWorkExecutor, syncWorkExecutorPool);
     }
@@ -180,7 +180,7 @@
      * @see javax.resource.spi.work.WorkManager#startWork(javax.resource.spi.work.Work)
      */
     public long startWork(Work work) throws WorkException {
-        WorkerContext workWrapper = new WorkerContext(work);
+        WorkerContext workWrapper = new WorkerContext(work, transactionContextManager);
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
         executeWork(workWrapper, startWorkExecutor, startWorkExecutorPool);
         return System.currentTimeMillis() - workWrapper.getAcceptedTime();
@@ -196,7 +196,7 @@
             WorkListener workListener)
             throws WorkException {
         WorkerContext workWrapper =
-                new WorkerContext(work, startTimeout, execContext, xaServices, workListener);
+                new WorkerContext(work, startTimeout, execContext, transactionContextManager, workListener);
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
         executeWork(workWrapper, startWorkExecutor, startWorkExecutorPool);
         return System.currentTimeMillis() - workWrapper.getAcceptedTime();
@@ -206,7 +206,7 @@
      * @see javax.resource.spi.work.WorkManager#scheduleWork(javax.resource.spi.work.Work)
      */
     public void scheduleWork(Work work) throws WorkException {
-        WorkerContext workWrapper = new WorkerContext(work);
+        WorkerContext workWrapper = new WorkerContext(work, transactionContextManager);
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
         executeWork(workWrapper, scheduleWorkExecutor, scheduledWorkExecutorPool);
     }
@@ -221,7 +221,7 @@
             WorkListener workListener)
             throws WorkException {
         WorkerContext workWrapper =
-                new WorkerContext(work, startTimeout, execContext, xaServices, workListener);
+                new WorkerContext(work, startTimeout, execContext, transactionContextManager, workListener);
         workWrapper.setThreadPriority(Thread.currentThread().getPriority());
         executeWork(workWrapper, scheduleWorkExecutor, scheduledWorkExecutorPool);
     }
@@ -262,13 +262,13 @@
 
         infoFactory.addOperation("getXATerminator");
 
-        infoFactory.addReference("XAServices", XAServices.class);
+        infoFactory.addReference("TransactionContextManager", TransactionContextManager.class);
 
         infoFactory.setConstructor(new String[]{
             "syncMaximumPoolSize",
             "startMaximumPoolSize",
             "scheduledMaximumPoolSize",
-            "XAServices"});
+            "TransactionContextManager"});
 
         GBEAN_INFO = infoFactory.getBeanInfo();
     }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/work/WorkerContext.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/work/WorkerContext.java	(original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/work/WorkerContext.java	Mon Oct  4 23:53:13 2004
@@ -24,13 +24,13 @@
 import javax.resource.spi.work.WorkEvent;
 import javax.resource.spi.work.WorkException;
 import javax.resource.spi.work.WorkListener;
-import javax.resource.spi.work.WorkRejectedException;
 import javax.resource.spi.work.WorkManager;
+import javax.resource.spi.work.WorkRejectedException;
 
 import EDU.oswego.cs.dl.util.concurrent.Latch;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.transaction.XAWork;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * Work wrapper providing an execution context to a Work instance.
@@ -82,7 +82,7 @@
      */
     private final ExecutionContext executionContext;
 
-    private final XAWork xaWork;
+    private final TransactionContextManager transactionContextManager;
 
     /**
      * Listener to be notified during the life-cycle of the work treatment.
@@ -107,12 +107,13 @@
     /**
      * Create a WorkWrapper.
      *
-     * @param aWork Work to be wrapped.
+     * @param work Work to be wrapped.
+     * @param transactionContextManager
      */
-    public WorkerContext(Work aWork) {
-        adaptee = aWork;
+    public WorkerContext(Work work, TransactionContextManager transactionContextManager) {
+        adaptee = work;
         executionContext = null;
-        xaWork = null;
+        this.transactionContextManager = transactionContextManager;
     }
 
     /**
@@ -125,16 +126,15 @@
      * the submitted Work instance must be executed.
      * @param workListener an object which would be notified when the various
      * Work processing events (work accepted, work rejected, work started,
-     * work completed) occur.
      */
     public WorkerContext(Work aWork, long aStartTimeout,
                          ExecutionContext execContext,
-                         XAWork xaWork,
+                         TransactionContextManager transactionContextManager,
                          WorkListener workListener) {
         adaptee = aWork;
         startTimeOut = aStartTimeout;
         executionContext = execContext;
-        this.xaWork = xaWork;
+        this.transactionContextManager = transactionContextManager;
         if (null != workListener) {
             this.workListener = workListener;
         }
@@ -271,15 +271,19 @@
         workListener.workStarted(
                 new WorkEvent(this, WorkEvent.WORK_STARTED, adaptee, null));
         startLatch.release();
+        //Implementation note: we assume this is being called without an interesting TransactionContext,
+        //and ignore/replace whatever is associated with the current thread.
         try {
             if (executionContext == null || executionContext.getXid() == null) {
+                transactionContextManager.newUnspecifiedTransactionContext();
                 adaptee.run();
+                //TODO should we commit the txContext to flush any leftover state???
             } else {
                 try {
-                    xaWork.begin(executionContext.getXid(), executionContext.getTransactionTimeout());
+                    transactionContextManager.begin(executionContext.getXid(), executionContext.getTransactionTimeout());
                     adaptee.run();
                 } finally {
-                    xaWork.end(executionContext.getXid());
+                    transactionContextManager.end(executionContext.getXid());
                 }
 
             }

Modified: geronimo/trunk/modules/connector/src/test-data/connector_1_5/geronimo-ra.xml
==============================================================================
--- geronimo/trunk/modules/connector/src/test-data/connector_1_5/geronimo-ra.xml	(original)
+++ geronimo/trunk/modules/connector/src/test-data/connector_1_5/geronimo-ra.xml	Mon Oct  4 23:53:13 2004
@@ -108,7 +108,7 @@
         <attribute name="syncMaximumPoolSize" type="int">10</attribute>
         <attribute name="startMaximumPoolSize" type="int">10</attribute>
         <attribute name="scheduledMaximumPoolSize" type="int">10</attribute>
-        <reference name="XAServices">geronimo.server:type=TransactionManager</reference>
+        <reference name="TransactionContextManager">geronimo.server:type=TransactionContextManager</reference>
     </gbean>
 
     <gbean name="geronimo.server:type=TransactionManager" class="org.apache.geronimo.transaction.GeronimoTransactionManager">
@@ -116,6 +116,12 @@
             <pattern>geronimo.server:j2eeType=JCAManagedConnectionFactory,*</pattern>
             <pattern>geronimo.server:j2eeType=MessageDrivenBean,*</pattern>
         </references>
+    </gbean>
+
+    <gbean name="geronimo.server:type=TransactionContextManager" class="org.apache.geronimo.transaction.context.TransactionContextManager">
+        <reference name="TransactionManager">geronimo.server:type=TransactionManager</reference>
+        <reference name="XidImporter">geronimo.server:type=TransactionManager</reference>
+        <reference name="Recovery">geronimo.server:type=TransactionManager</reference>
     </gbean>
 
     <gbean name="geronimo.security:service=RealmBridge,name=TargetRealm" class="org.apache.geronimo.security.bridge.ConfiguredIdentityUserPasswordRealmBridge">

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/BootstrapContextTest.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/BootstrapContextTest.java	(original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/BootstrapContextTest.java	Mon Oct  4 23:53:13 2004
@@ -18,13 +18,12 @@
 package org.apache.geronimo.connector;
 
 import java.util.Timer;
-
 import javax.resource.spi.XATerminator;
 import javax.resource.spi.work.WorkManager;
 
 import junit.framework.TestCase;
 import org.apache.geronimo.connector.work.GeronimoWorkManager;
-import org.apache.geronimo.transaction.XAServices;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * Unit tests for {@link BootstrapContextImpl}
@@ -36,8 +35,8 @@
      * Tests get and set work manager
      */
     public void testGetSetWorkManager() {
-        XAServices xaServices = new MockXATerminator("MockXATerminator");
-        GeronimoWorkManager manager = new GeronimoWorkManager(1, xaServices);
+        TransactionContextManager transactionContextManager = new TransactionContextManager();
+        GeronimoWorkManager manager = new GeronimoWorkManager(1, transactionContextManager);
         BootstrapContextImpl context = new BootstrapContextImpl(manager);
         WorkManager wm = context.getWorkManager();
 
@@ -48,12 +47,12 @@
      * Tests get and set XATerminator
      */
     public void testGetSetXATerminator() {
-        XAServices xaServices = new MockXATerminator("MockXATerminator");
-        GeronimoWorkManager manager = new GeronimoWorkManager(1, xaServices);
+        TransactionContextManager transactionContextManager = new TransactionContextManager();
+        GeronimoWorkManager manager = new GeronimoWorkManager(1, transactionContextManager);
         BootstrapContextImpl context = new BootstrapContextImpl(manager);
         XATerminator xat = context.getXATerminator();
 
-        assertSame("Make sure it is the same object", xaServices, xat);
+        assertSame("Make sure it is the same object", transactionContextManager, xat);
     }
 
     /**

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionManagerTestUtils.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionManagerTestUtils.java	(original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionManagerTestUtils.java	Mon Oct  4 23:53:13 2004
@@ -20,7 +20,6 @@
 import java.util.HashSet;
 import java.util.Set;
 import javax.security.auth.Subject;
-import javax.transaction.TransactionManager;
 
 import junit.framework.TestCase;
 import org.apache.geronimo.connector.mock.MockConnection;
@@ -89,8 +88,8 @@
 
     protected void setUp() throws Exception {
         connectionTrackingCoordinator = new ConnectionTrackingCoordinator();
-        TransactionManager transactionManager = new TransactionManagerImpl();
-        transactionContextManager = new TransactionContextManager(transactionManager);
+        TransactionManagerImpl transactionManager = new TransactionManagerImpl();
+        transactionContextManager = new TransactionContextManager(transactionManager, transactionManager, null);
         mockManagedConnectionFactory = new MockManagedConnectionFactory();
         subject = new Subject();
         ContextManager.setCurrentCaller(subject);
@@ -99,11 +98,12 @@
                 poolingSupport,
                 name,
                 realmBridge,
-                connectionTrackingCoordinator);
+                connectionTrackingCoordinator,
+                transactionContextManager);
         connectionManagerDeployment.doStart();
         connectionFactory = (MockConnectionFactory) connectionManagerDeployment.createConnectionFactory(mockManagedConnectionFactory);
         defaultComponentContext = new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources);
-        defaultComponentInterceptor = new DefaultComponentInterceptor(this, connectionTrackingCoordinator);
+        defaultComponentInterceptor = new DefaultComponentInterceptor(this, connectionTrackingCoordinator, transactionContextManager);
     }
 
     protected void tearDown() throws Exception {

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java	(original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionCachingInterceptorTest.java	Mon Oct  4 23:53:13 2004
@@ -18,10 +18,10 @@
 package org.apache.geronimo.connector.outbound;
 
 import javax.resource.ResourceException;
-import javax.transaction.TransactionManager;
 
 import org.apache.geronimo.transaction.context.ContainerTransactionContext;
 import org.apache.geronimo.transaction.context.TransactionContext;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
 import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
 
@@ -33,25 +33,26 @@
  * */
 public class TransactionCachingInterceptorTest extends ConnectionInterceptorTestUtils {
 
-    private TransactionManager transactionManager;
+    private TransactionManagerImpl transactionManager;
+    private TransactionContextManager transactionContextManager;
     private TransactionCachingInterceptor transactionCachingInterceptor;
 
     protected void setUp() throws Exception {
         super.setUp();
         transactionManager = new TransactionManagerImpl();
-        transactionCachingInterceptor = new TransactionCachingInterceptor(this);
+        transactionContextManager = new TransactionContextManager(transactionManager, transactionManager, null);
+        transactionCachingInterceptor = new TransactionCachingInterceptor(this, transactionContextManager);
     }
 
     protected void tearDown() throws Exception {
         super.tearDown();
         transactionManager = null;
+        transactionContextManager = null;
         transactionCachingInterceptor = null;
     }
 
     public void testGetConnectionInTransaction() throws Exception {
-        ContainerTransactionContext transactionContext = new ContainerTransactionContext(transactionManager);
-        TransactionContext.setContext(transactionContext);
-        transactionContext.begin();
+        ContainerTransactionContext transactionContext = transactionContextManager.newContainerTransactionContext();
         ConnectionInfo connectionInfo1 = makeConnectionInfo();
         transactionCachingInterceptor.getConnection(connectionInfo1);
         assertTrue("Expected to get an initial connection", obtainedConnectionInfo != null);
@@ -78,9 +79,7 @@
     }
 
     public void testGetUnshareableConnectionsInTransaction() throws Exception {
-        ContainerTransactionContext transactionContext = new ContainerTransactionContext(transactionManager);
-        TransactionContext.setContext(transactionContext);
-        transactionContext.begin();
+        ContainerTransactionContext transactionContext = transactionContextManager.newContainerTransactionContext();
         ConnectionInfo connectionInfo1 = makeConnectionInfo();
         connectionInfo1.setUnshareable(true);
         transactionCachingInterceptor.getConnection(connectionInfo1);
@@ -129,7 +128,7 @@
         assertTrue("Expected to get an initial connection", obtainedConnectionInfo != null);
         assertTrue("Expected nothing returned yet", returnedConnectionInfo == null);
         assertTrue("Expected no ManagedConnectionInfo in the TransactionContext",
-                null == TransactionContext.getContext().getManagedConnectionInfo(transactionCachingInterceptor));
+                null == transactionContextManager.getContext().getManagedConnectionInfo(transactionCachingInterceptor));
         obtainedConnectionInfo = null;
         ConnectionInfo connectionInfo2 = makeConnectionInfo();
         transactionCachingInterceptor.getConnection(connectionInfo2);
@@ -138,32 +137,28 @@
         assertTrue("Expected different ManagedConnectionInfo in both ConnectionInfos",
                 connectionInfo1.getManagedConnectionInfo() != connectionInfo2.getManagedConnectionInfo());
         assertTrue("Expected no ManagedConnectionInfo in the TransactionContext",
-                null == TransactionContext.getContext().getManagedConnectionInfo(transactionCachingInterceptor));
+                null == transactionContextManager.getContext().getManagedConnectionInfo(transactionCachingInterceptor));
         //we didn't create any handles, so the "ManagedConnection" should be returned.
-        assertTrue("Expected TransactionContext to report inactive", !TransactionContext.getContext().isActive());
+        assertTrue("Expected TransactionContext to report inactive", !transactionContextManager.getContext().isActive());
         transactionCachingInterceptor.returnConnection(connectionInfo1, ConnectionReturnAction.RETURN_HANDLE);
         assertTrue("Expected connection to be returned", returnedConnectionInfo != null);
         returnedConnectionInfo = null;
         transactionCachingInterceptor.returnConnection(connectionInfo2, ConnectionReturnAction.RETURN_HANDLE);
         assertTrue("Expected connection to be returned", returnedConnectionInfo != null);
 
-        assertTrue("Expected TransactionContext to report inactive", !TransactionContext.getContext().isActive());
+        assertTrue("Expected TransactionContext to report inactive", !transactionContextManager.getContext().isActive());
 
     }
 
     public void testTransactionIndependence() throws Exception {
-        ContainerTransactionContext transactionContext1 = new ContainerTransactionContext(transactionManager);
-        TransactionContext.setContext(transactionContext1);
-        transactionContext1.begin();
+        ContainerTransactionContext transactionContext1 = transactionContextManager.newContainerTransactionContext();
         ConnectionInfo connectionInfo1 = makeConnectionInfo();
         transactionCachingInterceptor.getConnection(connectionInfo1);
         obtainedConnectionInfo = null;
 
         //start a second transaction
         transactionContext1.suspend();
-        ContainerTransactionContext transactionContext2 = new ContainerTransactionContext(transactionManager);
-        TransactionContext.setContext(transactionContext2);
-        transactionContext2.begin();
+        ContainerTransactionContext transactionContext2 = transactionContextManager.newContainerTransactionContext();
         ConnectionInfo connectionInfo2 = makeConnectionInfo();
         transactionCachingInterceptor.getConnection(connectionInfo2);
         assertTrue("Expected to get a second connection", obtainedConnectionInfo != null);

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptorTest.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptorTest.java	(original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptorTest.java	Mon Oct  4 23:53:13 2004
@@ -18,16 +18,14 @@
 package org.apache.geronimo.connector.outbound;
 
 import javax.resource.ResourceException;
-import javax.transaction.TransactionManager;
 import javax.transaction.xa.XAException;
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
 
 import org.apache.geronimo.transaction.context.ContainerTransactionContext;
-import org.apache.geronimo.transaction.context.TransactionContext;
-import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
-import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 import org.apache.geronimo.transaction.manager.NamedXAResource;
+import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
 
 /**
  *
@@ -43,10 +41,13 @@
     private boolean ended;
     private boolean returned;
     private boolean committed;
+    private TransactionContextManager transactionContextManager;
 
     protected void setUp() throws Exception {
         super.setUp();
-        transactionEnlistingInterceptor = new TransactionEnlistingInterceptor(this);
+        TransactionManagerImpl transactionManager = new TransactionManagerImpl();
+        transactionContextManager = new TransactionContextManager(transactionManager, transactionManager, null);
+        transactionEnlistingInterceptor = new TransactionEnlistingInterceptor(this, transactionContextManager);
     }
 
     protected void tearDown() throws Exception {
@@ -60,7 +61,7 @@
 
     public void testNoTransaction() throws Exception {
         ConnectionInfo connectionInfo = makeConnectionInfo();
-        TransactionContext.setContext(new UnspecifiedTransactionContext());
+        transactionContextManager.newUnspecifiedTransactionContext();
         transactionEnlistingInterceptor.getConnection(connectionInfo);
         assertTrue("Expected not started", !started);
         assertTrue("Expected not ended", !ended);
@@ -70,10 +71,7 @@
     }
 
     public void testTransactionShareableConnection() throws Exception {
-        TransactionManager transactionManager = new TransactionManagerImpl();
-        ContainerTransactionContext transactionContext = new ContainerTransactionContext(transactionManager);
-        TransactionContext.setContext(transactionContext);
-        transactionContext.begin();
+        ContainerTransactionContext transactionContext = transactionContextManager.newContainerTransactionContext();
         ConnectionInfo connectionInfo = makeConnectionInfo();
         transactionEnlistingInterceptor.getConnection(connectionInfo);
         assertTrue("Expected started", started);
@@ -83,15 +81,12 @@
         assertTrue("Expected not started", !started);
         assertTrue("Expected ended", ended);
         assertTrue("Expected returned", returned);
-        transactionManager.commit();
+        transactionContext.commit();
         assertTrue("Expected committed", committed);
     }
 
     public void testTransactionUnshareableConnection() throws Exception {
-        TransactionManager transactionManager = new TransactionManagerImpl();
-        ContainerTransactionContext transactionContext = new ContainerTransactionContext(transactionManager);
-        TransactionContext.setContext(transactionContext);
-        transactionContext.begin();
+        ContainerTransactionContext transactionContext = transactionContextManager.newContainerTransactionContext();
         ConnectionInfo connectionInfo = makeConnectionInfo();
         connectionInfo.setUnshareable(true);
         transactionEnlistingInterceptor.getConnection(connectionInfo);
@@ -102,7 +97,7 @@
         assertTrue("Expected not started", !started);
         assertTrue("Expected ended", ended);
         assertTrue("Expected returned", returned);
-        transactionManager.commit();
+        transactionContext.commit();
         assertTrue("Expected committed", committed);
     }
 

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/DefaultComponentInterceptor.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/DefaultComponentInterceptor.java	(original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/DefaultComponentInterceptor.java	Mon Oct  4 23:53:13 2004
@@ -21,34 +21,46 @@
 import org.apache.geronimo.transaction.TrackedConnectionAssociator;
 import org.apache.geronimo.transaction.context.TransactionContext;
 import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * Sample functionality for an interceptor that enables connection caching and obtaining
  * connections outside a UserTransaction.
  *
  * @version $Rev$ $Date$
- *
- * */
+ */
 public class DefaultComponentInterceptor implements DefaultInterceptor {
 
     private final DefaultInterceptor next;
     private final TrackedConnectionAssociator trackedConnectionAssociator;
+    private final TransactionContextManager transactionContextManager;
 
     public DefaultComponentInterceptor(DefaultInterceptor next,
-            TrackedConnectionAssociator trackedConnectionAssociator) {
+                                       TrackedConnectionAssociator trackedConnectionAssociator,
+                                       TransactionContextManager transactionContextManager) {
         this.next = next;
         this.trackedConnectionAssociator = trackedConnectionAssociator;
+        this.transactionContextManager = transactionContextManager;
     }
 
     public Object invoke(InstanceContext newInstanceContext) throws Throwable {
-        if (TransactionContext.getContext() == null) {
-            TransactionContext.setContext(new UnspecifiedTransactionContext());
+        TransactionContext transactionContext = transactionContextManager.getContext();
+        if (transactionContext == null) {
+            transactionContextManager.newUnspecifiedTransactionContext();
         }
-        InstanceContext oldInstanceContext = trackedConnectionAssociator.enter(newInstanceContext);
         try {
-            return next.invoke(newInstanceContext);
+            InstanceContext oldInstanceContext = trackedConnectionAssociator.enter(newInstanceContext);
+            try {
+                return next.invoke(newInstanceContext);
+            } finally {
+                trackedConnectionAssociator.exit(oldInstanceContext);
+            }
         } finally {
-            trackedConnectionAssociator.exit(oldInstanceContext);
+            if (transactionContext == null) {
+                transactionContext = transactionContextManager.getContext();
+                transactionContext.commit();
+                transactionContextManager.setContext(null);
+            }
         }
     }
 }

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/work/PooledWorkManagerTest.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/work/PooledWorkManagerTest.java	(original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/work/PooledWorkManagerTest.java	Mon Oct  4 23:53:13 2004
@@ -25,6 +25,7 @@
 import javax.resource.spi.work.WorkListener;
 
 import junit.framework.TestCase;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  * Timing is crucial for this test case, which focuses on the synchronization
@@ -37,7 +38,8 @@
     private GeronimoWorkManager workManager;
 
     protected void setUp() throws Exception {
-        workManager = new GeronimoWorkManager(1, null);
+        TransactionContextManager transactionContextManager = new TransactionContextManager();
+        workManager = new GeronimoWorkManager(1, transactionContextManager);
         workManager.doStart();
     }
 

Modified: geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java
==============================================================================
--- geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java	(original)
+++ geronimo/trunk/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java	Mon Oct  4 23:53:13 2004
@@ -22,7 +22,6 @@
 import java.net.URI;
 import java.net.URL;
 import java.util.Set;
-
 import javax.resource.ResourceException;
 
 import org.apache.commons.logging.Log;
@@ -38,6 +37,7 @@
 import org.apache.geronimo.transaction.InstanceContext;
 import org.apache.geronimo.transaction.TrackedConnectionAssociator;
 import org.apache.geronimo.transaction.UserTransactionImpl;
+import org.apache.geronimo.transaction.context.TransactionContext;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
 import org.mortbay.http.HttpException;
 import org.mortbay.http.HttpRequest;
@@ -161,16 +161,32 @@
             // Turn on the UserTransaction
             userTransaction.setOnline(true);
 
-            if (transactionContextManager.getContext() == null) {
-                transactionContextManager.newUnspecifiedTransactionContext();
+            TransactionContext transactionContext = transactionContextManager.getContext();
+            if (transactionContext == null) {
+                transactionContext = transactionContextManager.newUnspecifiedTransactionContext();
+            } else {
+                transactionContext = null;
             }
+
             try {
-                oldInstanceContext = associator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
-            } catch (ResourceException e) {
-                throw new RuntimeException(e);
-            }
+                try {
+                    oldInstanceContext = associator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
+                } catch (ResourceException e) {
+                    throw new RuntimeException(e);
+                }
 
-            super.handle(pathInContext, pathParams, httpRequest, httpResponse);
+                super.handle(pathInContext, pathParams, httpRequest, httpResponse);
+            } finally {
+                if (transactionContext != null) {
+                    transactionContextManager.setContext(null);
+                    try {
+                        transactionContext.commit();
+                    } catch (Exception e) {
+                        //TODO this is undoubtedly the wrong error code!
+                        throw (HttpException) new HttpException(500, "Problem committing unspecified transaction context").initCause(e);
+                    }
+                }
+            }
         } finally {
             try {
                 associator.exit(oldInstanceContext);
@@ -187,12 +203,11 @@
     public void doStart() throws WaitingException, Exception {
 
         // merge Geronimo and Jetty Lifecycles
-        if (!isStarting())
-        {
+        if (!isStarting()) {
             super.start();
             return;
         }
-        
+
         if (uri.isAbsolute()) {
             setWAR(uri.toString());
         } else {
@@ -212,18 +227,33 @@
                 // Turn on the UserTransaction
                 userTransaction.setOnline(true);
 
-                //TODO should this always create an unspecified context, or might this be executed in a tx?
-                if (transactionContextManager.getContext() == null) {
-                    transactionContextManager.newUnspecifiedTransactionContext();
+                TransactionContext transactionContext = transactionContextManager.getContext();
+                if (transactionContext == null) {
+                    transactionContext = transactionContextManager.newUnspecifiedTransactionContext();
+                } else {
+                    transactionContext = null;
                 }
 
                 try {
-                    oldInstanceContext = associator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
-                } catch (ResourceException e) {
-                    throw new RuntimeException(e);
-                }
 
-                super.doStart();
+                    try {
+                        oldInstanceContext = associator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
+                    } catch (ResourceException e) {
+                        throw new RuntimeException(e);
+                    }
+
+                    super.doStart();
+                } finally {
+                    if (transactionContext != null) {
+                        transactionContextManager.setContext(null);
+                        try {
+                            transactionContext.commit();
+                        } catch (Exception e) {
+                            //TODO this is undoubtedly the wrong error code!
+                            throw (HttpException) new HttpException(500, "Problem committing unspecified transaction context").initCause(e);
+                        }
+                    }
+                }
             } finally {
                 try {
                     associator.exit(oldInstanceContext);
@@ -245,12 +275,11 @@
     public void doStop() throws Exception {
 
         // merge Geronimo and Jetty Lifecycles
-        if (!isStopping())
-        {
+        if (!isStopping()) {
             super.stop();
             return;
         }
-        
+
         ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
         try {
             Thread.currentThread().setContextClassLoader(classLoader);
@@ -261,23 +290,37 @@
                 // Turn on the UserTransaction
                 userTransaction.setOnline(true);
 
-                //TODO should this always create an unspecified context, or might this be executed in a tx?
-                if (transactionContextManager.getContext() == null) {
-                    transactionContextManager.newUnspecifiedTransactionContext();
+                TransactionContext transactionContext = transactionContextManager.getContext();
+                if (transactionContext == null) {
+                    transactionContext = transactionContextManager.newUnspecifiedTransactionContext();
+                } else {
+                    transactionContext = null;
                 }
-
                 try {
-                    oldInstanceContext = associator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
-                } catch (ResourceException e) {
-                    throw new RuntimeException(e);
-                }
 
-                while (true) {
                     try {
-                        super.doStop();
-                        break;
-                    } catch (InterruptedException e) {
-                        continue;
+                        oldInstanceContext = associator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
+                    } catch (ResourceException e) {
+                        throw new RuntimeException(e);
+                    }
+
+                    while (true) {
+                        try {
+                            super.doStop();
+                            break;
+                        } catch (InterruptedException e) {
+                            continue;
+                        }
+                    }
+                } finally {
+                    if (transactionContext != null) {
+                        transactionContextManager.setContext(null);
+                        try {
+                            transactionContext.commit();
+                        } catch (Exception e) {
+                            //TODO this is undoubtedly the wrong error code!
+                            throw (HttpException) new HttpException(500, "Problem committing unspecified transaction context").initCause(e);
+                        }
                     }
                 }
             } finally {

Modified: geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java
==============================================================================
--- geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java	(original)
+++ geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/ThreadPooledTimer.java	Mon Oct  4 23:53:13 2004
@@ -37,6 +37,7 @@
 import org.apache.geronimo.gbean.GBeanLifecycle;
 import org.apache.geronimo.gbean.WaitingException;
 import org.apache.geronimo.transaction.context.TransactionContext;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  *
@@ -49,6 +50,7 @@
     private final ExecutorTaskFactory executorTaskFactory;
     private final WorkerPersistence workerPersistence;
     private final Executor executor;
+    private final TransactionContextManager transactionContextManager;
 
     private Timer delegate;
 
@@ -56,13 +58,14 @@
 
     //default constructor for use as reference endpoint.
     public ThreadPooledTimer() {
-        this(null, null, null);
+        this(null, null, null, null);
     }
 
-    public ThreadPooledTimer(ExecutorTaskFactory executorTaskFactory, WorkerPersistence workerPersistence, Executor executor) {
+    public ThreadPooledTimer(ExecutorTaskFactory executorTaskFactory, WorkerPersistence workerPersistence, Executor executor, TransactionContextManager transactionContextManager) {
         this.executorTaskFactory = executorTaskFactory;
         this.workerPersistence = workerPersistence;
         this.executor = executor;
+        this.transactionContextManager = transactionContextManager;
     }
 
     public void doStart() throws WaitingException, Exception {
@@ -194,8 +197,9 @@
     }
 
     void registerSynchronization(Synchronization sync) throws RollbackException, SystemException {
-        TransactionContext transactionContext = TransactionContext.getContext();
-        Transaction transaction = transactionContext == null ? null : transactionContext.getTransaction();
+        TransactionContext transactionContext = transactionContextManager.getContext();
+        //TODO move the registerSynchronization to the TransactionContext
+        Transaction transaction = transactionContext == null? null: transactionContext.getTransaction();
         if (transaction == null) {
             sync.beforeCompletion();
             sync.afterCompletion(Status.STATUS_COMMITTED);

Modified: geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/jdbc/JDBCStoreThreadPooledNonTransactionalTimer.java
==============================================================================
--- geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/jdbc/JDBCStoreThreadPooledNonTransactionalTimer.java	(original)
+++ geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/jdbc/JDBCStoreThreadPooledNonTransactionalTimer.java	Mon Oct  4 23:53:13 2004
@@ -25,20 +25,19 @@
 import org.apache.geronimo.timer.NontransactionalExecutorTaskFactory;
 import org.apache.geronimo.timer.PersistentTimer;
 import org.apache.geronimo.timer.ThreadPooledTimer;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
- *
- *
  * @version $Rev$ $Date$
- *
- * */
+ */
 public class JDBCStoreThreadPooledNonTransactionalTimer extends ThreadPooledTimer {
 
     public JDBCStoreThreadPooledNonTransactionalTimer(ManagedConnectionFactoryWrapper managedConnectionFactoryWrapper,
-            Executor threadPool,
-            Kernel kernel) {
+                                                      TransactionContextManager transactionContextManager,
+                                                      Executor threadPool,
+                                                      Kernel kernel) {
         super(new NontransactionalExecutorTaskFactory(),
-                new JDBCWorkerPersistence(kernel, managedConnectionFactoryWrapper), threadPool);
+                new JDBCWorkerPersistence(kernel, managedConnectionFactoryWrapper), threadPool, transactionContextManager);
     }
 
 
@@ -50,9 +49,11 @@
 
         infoFactory.addReference("ManagedConnectionFactoryWrapper", ManagedConnectionFactoryWrapper.class);
         infoFactory.addReference("ThreadPool", Executor.class);
+        infoFactory.addReference("TransactionContextManager", TransactionContextManager.class);
+
         infoFactory.addAttribute("kernel", Kernel.class, false);
 
-        infoFactory.setConstructor(new String[] {"ManagedConnectionFactoryWrapper", "ThreadPool", "kernel"});
+        infoFactory.setConstructor(new String[]{"ManagedConnectionFactoryWrapper", "TransactionContextManager", "ThreadPool", "kernel"});
         GBEAN_INFO = infoFactory.getBeanInfo();
     }
 

Modified: geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/jdbc/JDBCStoreThreadPooledTransactionalTimer.java
==============================================================================
--- geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/jdbc/JDBCStoreThreadPooledTransactionalTimer.java	(original)
+++ geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/jdbc/JDBCStoreThreadPooledTransactionalTimer.java	Mon Oct  4 23:53:13 2004
@@ -41,7 +41,7 @@
             Executor threadPool,
             Kernel kernel) {
         super(new TransactionalExecutorTaskFactory(transactionContextManager, repeatCount),
-                new JDBCWorkerPersistence(kernel, managedConnectionFactoryWrapper), threadPool);
+                new JDBCWorkerPersistence(kernel, managedConnectionFactoryWrapper), threadPool, transactionContextManager);
     }
 
 

Modified: geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/vm/VMStoreThreadPooledNonTransactionalTimer.java
==============================================================================
--- geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/vm/VMStoreThreadPooledNonTransactionalTimer.java	(original)
+++ geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/vm/VMStoreThreadPooledNonTransactionalTimer.java	Mon Oct  4 23:53:13 2004
@@ -23,6 +23,7 @@
 import org.apache.geronimo.timer.NontransactionalExecutorTaskFactory;
 import org.apache.geronimo.timer.PersistentTimer;
 import org.apache.geronimo.timer.ThreadPooledTimer;
+import org.apache.geronimo.transaction.context.TransactionContextManager;
 
 /**
  *
@@ -32,9 +33,9 @@
  * */
 public class VMStoreThreadPooledNonTransactionalTimer extends ThreadPooledTimer {
 
-    public VMStoreThreadPooledNonTransactionalTimer(Executor threadPool) {
+    public VMStoreThreadPooledNonTransactionalTimer(TransactionContextManager transactionContextManager, Executor threadPool) {
         super(new NontransactionalExecutorTaskFactory(),
-                new VMWorkerPersistence(), threadPool);
+                new VMWorkerPersistence(), threadPool, transactionContextManager);
     }
 
 
@@ -45,8 +46,9 @@
         infoFactory.addInterface(PersistentTimer.class);
 
         infoFactory.addReference("ThreadPool", Executor.class);
+        infoFactory.addReference("TransactionContextManager", TransactionContextManager.class);
 
-        infoFactory.setConstructor(new String[] {"ThreadPool"});
+        infoFactory.setConstructor(new String[] {"TransactionContextManager", "ThreadPool"});
         GBEAN_INFO = infoFactory.getBeanInfo();
     }
 

Modified: geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/vm/VMStoreThreadPooledTransactionalTimer.java
==============================================================================
--- geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/vm/VMStoreThreadPooledTransactionalTimer.java	(original)
+++ geronimo/trunk/modules/timer/src/java/org/apache/geronimo/timer/vm/VMStoreThreadPooledTransactionalTimer.java	Mon Oct  4 23:53:13 2004
@@ -37,7 +37,7 @@
             TransactionContextManager transactionContextManager,
             Executor threadPool) {
         super(new TransactionalExecutorTaskFactory(transactionContextManager, repeatCount),
-                new VMWorkerPersistence(), threadPool);
+                new VMWorkerPersistence(), threadPool, transactionContextManager);
     }
 
 

Modified: geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java
==============================================================================
--- geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java	(original)
+++ geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/AbstractThreadPooledTimerTest.java	Mon Oct  4 23:53:13 2004
@@ -61,7 +61,7 @@
         threadPool.setPoolName("TestPool");
         threadPool.doStart();
         WorkerPersistence workerPersistence = new VMWorkerPersistence();
-        timer = new ThreadPooledTimer(executableWorkFactory, workerPersistence, threadPool);
+        timer = new ThreadPooledTimer(executableWorkFactory, workerPersistence, threadPool, transactionContextManager);
         timer.doStart();
 
         counter.set(0);

Modified: geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/NontransactionalThreadPooledTimerTest.java
==============================================================================
--- geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/NontransactionalThreadPooledTimerTest.java	(original)
+++ geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/NontransactionalThreadPooledTimerTest.java	Mon Oct  4 23:53:13 2004
@@ -17,12 +17,8 @@
 
 package org.apache.geronimo.timer;
 
-import javax.transaction.TransactionManager;
-
-import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
-import org.apache.geronimo.timer.NontransactionalExecutorTaskFactory;
-import org.apache.geronimo.timer.AbstractThreadPooledTimerTest;
+import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
 
 /**
  *
@@ -33,8 +29,8 @@
 public class NontransactionalThreadPooledTimerTest extends AbstractThreadPooledTimerTest {
 
     protected void setUp() throws Exception {
-        TransactionManager transactionManager = new TransactionManagerImpl();
-        transactionContextManager = new TransactionContextManager(transactionManager);
+        TransactionManagerImpl transactionManager = new TransactionManagerImpl();
+        transactionContextManager = new TransactionContextManager(transactionManager, transactionManager, null);
         executableWorkFactory = new NontransactionalExecutorTaskFactory();
         super.setUp();
     }

Modified: geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/TransactionalThreadPooledTimerTest.java
==============================================================================
--- geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/TransactionalThreadPooledTimerTest.java	(original)
+++ geronimo/trunk/modules/timer/src/test/org/apache/geronimo/timer/TransactionalThreadPooledTimerTest.java	Mon Oct  4 23:53:13 2004
@@ -17,12 +17,8 @@
 
 package org.apache.geronimo.timer;
 
-import javax.transaction.TransactionManager;
-
-import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
-import org.apache.geronimo.timer.TransactionalExecutorTaskFactory;
-import org.apache.geronimo.timer.AbstractThreadPooledTimerTest;
+import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
 
 /**
  *
@@ -33,8 +29,8 @@
 public class TransactionalThreadPooledTimerTest extends AbstractThreadPooledTimerTest {
 
     protected void setUp() throws Exception {
-        TransactionManager transactionManager = new TransactionManagerImpl();
-        transactionContextManager = new TransactionContextManager(transactionManager);
+        TransactionManagerImpl transactionManager = new TransactionManagerImpl();
+        transactionContextManager = new TransactionContextManager(transactionManager, transactionManager, null);
         executableWorkFactory = new TransactionalExecutorTaskFactory(transactionContextManager, 1);
         super.setUp();
     }

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/TransactionManagerProxy.java
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/TransactionManagerProxy.java	(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/TransactionManagerProxy.java	Mon Oct  4 23:53:13 2004
@@ -19,12 +19,10 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-
-import javax.resource.spi.XATerminator;
+import java.util.HashMap;
 import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.InvalidTransactionException;
@@ -35,7 +33,6 @@
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
 import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
 
 import org.apache.commons.logging.Log;
@@ -47,12 +44,12 @@
 import org.apache.geronimo.gbean.ReferenceCollectionEvent;
 import org.apache.geronimo.gbean.ReferenceCollectionListener;
 import org.apache.geronimo.gbean.WaitingException;
+import org.apache.geronimo.transaction.context.TransactionContext;
+import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
 import org.apache.geronimo.transaction.manager.NamedXAResource;
 import org.apache.geronimo.transaction.manager.Recovery;
 import org.apache.geronimo.transaction.manager.ResourceManager;
 import org.apache.geronimo.transaction.manager.XidImporter;
-import org.apache.geronimo.transaction.context.TransactionContext;
-import org.apache.geronimo.transaction.context.UnspecifiedTransactionContext;
 
 /**
  * A wrapper for a TransactionManager that wraps all Transactions in a TransactionProxy
@@ -62,23 +59,19 @@
  *
  * @version $Rev$ $Date$
  */
-public class TransactionManagerProxy implements TransactionManager, XATerminator, XAWork, GBeanLifecycle {
-    private static final boolean NOT_IN_RECOVERY = false;
-    private static final boolean IN_RECOVERY = true;
-
+public class TransactionManagerProxy implements TransactionManager, XidImporter, Recovery, GBeanLifecycle {
     private static final Log recoveryLog = LogFactory.getLog("RecoveryController");
 
     private final TransactionManager delegate;
     private final XidImporter importer;
     private final ThreadLocal threadTx = new ThreadLocal();
-    private final Map importedTransactions = new HashMap();
-    private boolean recoveryState = NOT_IN_RECOVERY;
     private final Recovery recovery;
     private final ReferenceCollection resourceManagers;
     private List recoveryErrors = new ArrayList();
 
     /**
      * Constructor taking the TransactionManager to wrap.
+     *
      * @param delegate the TransactionManager that should be wrapped
      */
     public TransactionManagerProxy(TransactionManager delegate, XidImporter importer, Recovery recovery, Collection resourceManagers) {
@@ -103,6 +96,7 @@
         this(params.delegate, params.xidImporter, params.recovery, params.resourceManagers);
     }
 
+    //TODO NOTE!!! this should be called in an unspecified transaction context, but we cannot enforce this restriction!
     public void doStart() throws WaitingException, Exception {
         recovery.recoverLog();
         List copy = null;
@@ -127,29 +121,23 @@
     }
 
     private void recoverResourceManager(ResourceManager resourceManager) {
-        TransactionContext oldTransactionContext = TransactionContext.getContext();
+        NamedXAResource namedXAResource = null;
         try {
-            TransactionContext.setContext(new UnspecifiedTransactionContext());
-            NamedXAResource namedXAResource = null;
+            namedXAResource = resourceManager.getRecoveryXAResources();
+        } catch (SystemException e) {
+            recoveryLog.error(e);
+            recoveryErrors.add(e);
+            return;
+        }
+        if (namedXAResource != null) {
             try {
-                namedXAResource = resourceManager.getRecoveryXAResources();
-            } catch (SystemException e) {
+                recovery.recoverResourceManager(namedXAResource);
+            } catch (XAException e) {
                 recoveryLog.error(e);
                 recoveryErrors.add(e);
-                return;
-            }
-            if (namedXAResource != null) {
-                try {
-                    recovery.recoverResourceManager(namedXAResource);
-                } catch (XAException e) {
-                    recoveryLog.error(e);
-                    recoveryErrors.add(e);
-                } finally {
-                    resourceManager.returnResource(namedXAResource);
-                }
+            } finally {
+                resourceManager.returnResource(namedXAResource);
             }
-        } finally {
-            TransactionContext.setContext(oldTransactionContext);
         }
     }
 
@@ -225,187 +213,74 @@
         tx.setRollbackOnly();
     }
 
-    /**
-     * @see javax.resource.spi.XATerminator#commit(javax.transaction.xa.Xid, boolean)
-     */
-    public void commit(Xid xid, boolean onePhase) throws XAException {
-        ImportedTransactionInfo txInfo;
-        synchronized (importedTransactions) {
-            txInfo = (ImportedTransactionInfo) importedTransactions.remove(xid);
-        }
-        if (txInfo == null) {
-            throw new XAException("No imported transaction for xid: " + xid);
-        }
-        TransactionProxy tx = txInfo.getTransactionProxy();
 
-        try {
-            int status = tx.getStatus();
-            assert status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARED;
-        } catch (SystemException e) {
-            throw new XAException();
+    //XidImporter implementation. Wrap and unwrap TransactionProxy.
+    public Transaction importXid(Xid xid) throws XAException, SystemException {
+        if (threadTx.get() != null) {
+            throw new IllegalStateException("Transaction already associated with current thread");
         }
-        importer.commit(tx.getDelegate(), onePhase);
+        TransactionProxy transactionProxy = new TransactionProxy(importer.importXid(xid));
+        threadTx.set(transactionProxy);
+        return transactionProxy;
     }
 
-    /**
-     * @see javax.resource.spi.XATerminator#forget(javax.transaction.xa.Xid)
-     */
-    public void forget(Xid xid) throws XAException {
-        ImportedTransactionInfo txInfo;
-        synchronized (importedTransactions) {
-            txInfo = (ImportedTransactionInfo) importedTransactions.remove(xid);
-        }
-        if (txInfo == null) {
-            throw new XAException("No imported transaction for xid: " + xid);
-        }
-        TransactionProxy tx = txInfo.getTransactionProxy();
-        //todo is there a correct status test here?
-//        try {
-//            int status = tx.getStatus();
-//            assert status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARED;
-//        } catch (SystemException e) {
-//            throw new XAException();
-//        }
-        importer.forget(tx.getDelegate());
+    //TODO how do these relate to threadTx???? probably not at all...
+    public void commit(Transaction tx, boolean onePhase) throws XAException {
+        importer.commit(((TransactionProxy) tx).getDelegate(), onePhase);
     }
 
-    /**
-     * @see javax.resource.spi.XATerminator#prepare(javax.transaction.xa.Xid)
-     */
-    public int prepare(Xid xid) throws XAException {
-        ImportedTransactionInfo txInfo;
-        synchronized (importedTransactions) {
-            txInfo = (ImportedTransactionInfo) importedTransactions.get(xid);
-        }
-        if (txInfo == null) {
-            throw new XAException("No imported transaction for xid: " + xid);
-        }
-        TransactionProxy tx = txInfo.getTransactionProxy();
-        try {
-            int status = tx.getStatus();
-            assert status == Status.STATUS_ACTIVE;
-        } catch (SystemException e) {
-            throw new XAException();
-        }
-        return importer.prepare(tx.getDelegate());
+    public void forget(Transaction tx) throws XAException {
+        importer.forget(((TransactionProxy) tx).getDelegate());
     }
 
-    /**
-     * @see javax.resource.spi.XATerminator#recover(int)
-     */
-    public Xid[] recover(int flag) throws XAException {
-        if (recoveryState == NOT_IN_RECOVERY) {
-            if ((flag & XAResource.TMSTARTRSCAN) == 0) {
-                throw new XAException(XAException.XAER_PROTO);
-            }
-            recoveryState = IN_RECOVERY;
-        }
-        if ((flag & XAResource.TMENDRSCAN) != 0) {
-            recoveryState = NOT_IN_RECOVERY;
-        }
-        //we always return all xids in first call.
-        //calling "startrscan" repeatedly starts at beginning of list again.
-        if ((flag & XAResource.TMSTARTRSCAN) != 0) {
-            Map recoveredXidMap = recovery.getExternalXids();
-            Xid[] recoveredXids = new Xid[recoveredXidMap.size()];
-            int i = 0;
-            synchronized (importedTransactions) {
-                for (Iterator iterator = recoveredXidMap.entrySet().iterator(); iterator.hasNext();) {
-                    Map.Entry entry = (Map.Entry) iterator.next();
-                    Xid xid = (Xid) entry.getKey();
-                    recoveredXids[i++] = xid;
-                    ImportedTransactionInfo txInfo = new ImportedTransactionInfo(new TransactionProxy((Transaction)entry.getValue()));
-                    importedTransactions.put(xid, txInfo);
-                }
-            }
-            return recoveredXids;
-        } else {
-            return new Xid[0];
-        }
+    public int prepare(Transaction tx) throws XAException {
+        return importer.prepare(((TransactionProxy) tx).getDelegate());
     }
 
-    /**
-     * @see javax.resource.spi.XATerminator#rollback(javax.transaction.xa.Xid)
-     */
-    public void rollback(Xid xid) throws XAException {
-        ImportedTransactionInfo txInfo;
-        synchronized (importedTransactions) {
-            txInfo = (ImportedTransactionInfo) importedTransactions.remove(xid);
-        }
-        if (txInfo == null) {
-            throw new XAException("No imported transaction for xid: " + xid);
-        }
-        TransactionProxy tx = txInfo.getTransactionProxy();
+    public void rollback(Transaction tx) throws XAException {
+        importer.rollback(((TransactionProxy) tx).getDelegate());
+    }
 
-        try {
-            int status = tx.getStatus();
-            assert status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARED;
-        } catch (SystemException e) {
-            throw new XAException();
-        }
-        importer.rollback(tx.getDelegate());
+    public void setTransactionTimeout(long milliseconds) {
+        importer.setTransactionTimeout(milliseconds);
     }
 
-    public void begin(Xid xid, long txTimeoutMillis) throws XAException, InvalidTransactionException, SystemException {
-        ImportedTransactionInfo txInfo;
-        boolean old = true;
-        synchronized (importedTransactions) {
-             txInfo = (ImportedTransactionInfo) importedTransactions.get(xid);
-            if (txInfo == null) {
-                try {
-                    txInfo = new ImportedTransactionInfo(new TransactionProxy(importer.importXid(xid)));
-                    old = false;
-                } catch (SystemException e) {
-                    throw (XAException) new XAException("Could not import xid").initCause(e);
-                }
-                importedTransactions.put(xid, txInfo);
-            }
-            if (txInfo.isActive()) {
-                throw new XAException("Xid already active");
-            }
-            txInfo.setActive(true);
-        }
-        threadTx.set(txInfo.getTransactionProxy());
-        if (old) {
-            delegate.resume(txInfo.getTransactionProxy().getDelegate());
-        }
-        importer.setTransactionTimeout(txTimeoutMillis);
+    //Recovery implementation
+    //TODO make an interface of only getExternalIds since other methods don't work.
+    //Or, decide to expose the other methods.
+    public void recoverLog() throws XAException {
+        throw new IllegalStateException("Don't call this");
     }
 
-    public void end(Xid xid) throws XAException, SystemException {
-        synchronized (importedTransactions) {
-            ImportedTransactionInfo txInfo = (ImportedTransactionInfo) importedTransactions.get(xid);
-            if (txInfo == null) {
-                throw new XAException("No imported transaction for xid: " + xid);
-            }
-            if (!txInfo.isActive()) {
-                throw new XAException("tx not active for xid: " + xid);
-            }
-            txInfo.setActive(false);
-        }
-        threadTx.set(null);
-        delegate.suspend();
+    public void recoverResourceManager(NamedXAResource xaResource) throws XAException {
+        throw new IllegalStateException("Don't call this");
     }
 
-    private static class ImportedTransactionInfo {
-        private final TransactionProxy transactionProxy;
-        private boolean active;
+    public boolean hasRecoveryErrors() {
+        throw new IllegalStateException("Don't call this");
+    }
 
-        public ImportedTransactionInfo(TransactionProxy transactionProxy) {
-            this.transactionProxy = transactionProxy;
-        }
+    public List getRecoveryErrors() {
+        throw new IllegalStateException("Don't call this");
+    }
 
-        public TransactionProxy getTransactionProxy() {
-            return transactionProxy;
-        }
+    public boolean localRecoveryComplete() {
+        throw new IllegalStateException("Don't call this");
+    }
 
-        public boolean isActive() {
-            return active;
-        }
+    public int localUnrecoveredCount() {
+        throw new IllegalStateException("Don't call this");
+    }
 
-        public void setActive(boolean active) {
-            this.active = active;
+    public Map getExternalXids() {
+        Map internal = recovery.getExternalXids();
+        Map external = new HashMap(internal.size());
+        for (Iterator iterator = internal.entrySet().iterator(); iterator.hasNext();) {
+            Map.Entry entry = (Map.Entry) iterator.next();
+            Transaction tx = (Transaction) entry.getValue();
+            external.put(entry.getKey(), new TransactionProxy(tx));
         }
+        return external;
     }
 
     public static final GBeanInfo GBEAN_INFO;

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/ContainerTransactionContext.java
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/ContainerTransactionContext.java	(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/ContainerTransactionContext.java	Mon Oct  4 23:53:13 2004
@@ -28,23 +28,23 @@
 import javax.transaction.TransactionManager;
 
 /**
- *
- *
  * @version $Rev$ $Date$
  */
 public class ContainerTransactionContext extends InheritableTransactionContext {
     private final TransactionManager txnManager;
     private Transaction transaction;
 
-    public ContainerTransactionContext(TransactionManager txnManager) {
+    public ContainerTransactionContext(TransactionManager txnManager) throws SystemException, NotSupportedException {
         this.txnManager = txnManager;
-    }
-
-    public void begin() throws SystemException, NotSupportedException {
         txnManager.begin();
         transaction = txnManager.getTransaction();
     }
 
+    public ContainerTransactionContext(TransactionManager txnManager, Transaction transaction) {
+        this.txnManager = txnManager;
+        this.transaction = transaction;
+    }
+
     public void suspend() throws SystemException {
         Transaction suspendedTransaction = txnManager.suspend();
         assert (transaction == suspendedTransaction) : "suspend did not return our transaction";
@@ -59,9 +59,13 @@
      * a successful commit...??
      *
      * @throws javax.transaction.HeuristicMixedException
+     *
      * @throws javax.transaction.HeuristicRollbackException
+     *
      * @throws javax.transaction.RollbackException
+     *
      * @throws javax.transaction.SystemException
+     *
      */
     public void commit() throws HeuristicMixedException, HeuristicRollbackException, RollbackException, SystemException {
         try {
@@ -139,6 +143,6 @@
         int status = transaction.getStatus();
         return (status == Status.STATUS_MARKED_ROLLBACK ||
                 status == Status.STATUS_ROLLEDBACK ||
-                status == Status.STATUS_ROLLING_BACK );
+                status == Status.STATUS_ROLLING_BACK);
     }
 }

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java	(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java	Mon Oct  4 23:53:13 2004
@@ -62,7 +62,7 @@
     private Map managedConnections;
     private InTxCache inTxCache;
 
-    public abstract void begin() throws SystemException, NotSupportedException;
+//    public abstract void begin() throws SystemException, NotSupportedException;
 
     public abstract void suspend() throws SystemException;
 

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java	(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContextManager.java	Mon Oct  4 23:53:13 2004
@@ -17,12 +17,25 @@
 
 package org.apache.geronimo.transaction.context;
 
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import javax.resource.spi.XATerminator;
+import javax.transaction.InvalidTransactionException;
 import javax.transaction.NotSupportedException;
+import javax.transaction.Status;
 import javax.transaction.SystemException;
+import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
 
 import org.apache.geronimo.gbean.GBeanInfo;
 import org.apache.geronimo.gbean.GBeanInfoFactory;
+import org.apache.geronimo.transaction.XAWork;
+import org.apache.geronimo.transaction.manager.Recovery;
+import org.apache.geronimo.transaction.manager.XidImporter;
 
 /**
  *
@@ -30,17 +43,27 @@
  * @version $Rev$ $Date$
  *
  * */
-public class TransactionContextManager {
+public class TransactionContextManager implements XATerminator, XAWork {
+    private static final boolean NOT_IN_RECOVERY = false;
+    private static final boolean IN_RECOVERY = true;
+
 
     private final TransactionManager transactionManager;
+    private final XidImporter importer;
+    private final Recovery recovery;
+    private final Map importedTransactions = new HashMap();
+
+    private boolean recoveryState = NOT_IN_RECOVERY;
 
     //use as reference endpoint.
     public TransactionContextManager() {
-        transactionManager = null;
+        this(null, null, null);
     }
 
-    public TransactionContextManager(TransactionManager transactionManager) {
+    public TransactionContextManager(TransactionManager transactionManager, XidImporter importer, Recovery recovery) {
         this.transactionManager = transactionManager;
+        this.importer = importer;
+        this.recovery = recovery;
     }
 
     public TransactionContext getContext() {
@@ -54,7 +77,6 @@
     public ContainerTransactionContext newContainerTransactionContext() throws NotSupportedException, SystemException {
         ContainerTransactionContext transactionContext = new ContainerTransactionContext(transactionManager);
         TransactionContext.setContext(transactionContext);
-        transactionContext.begin();
         return transactionContext;
     }
 
@@ -97,6 +119,194 @@
         transactionManager.setTransactionTimeout(seconds);
     }
 
+
+    /**
+     * TODO write and use ImportedTransactionContext for this!
+      * @see javax.resource.spi.XATerminator#commit(javax.transaction.xa.Xid, boolean)
+      */
+     public void commit(Xid xid, boolean onePhase) throws XAException {
+         ImportedTransactionInfo txInfo;
+         synchronized (importedTransactions) {
+             txInfo = (ImportedTransactionInfo) importedTransactions.remove(xid);
+         }
+         if (txInfo == null) {
+             throw new XAException("No imported transaction for xid: " + xid);
+         }
+         ContainerTransactionContext containerTransactionContext = txInfo.getContainerTransactionContext();
+
+         try {
+             int status = containerTransactionContext.getTransaction().getStatus();
+             assert status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARED;
+         } catch (SystemException e) {
+             throw new XAException();
+         }
+         importer.commit(containerTransactionContext.getTransaction(), onePhase);
+     }
+
+     /**
+      * @see javax.resource.spi.XATerminator#forget(javax.transaction.xa.Xid)
+      */
+     public void forget(Xid xid) throws XAException {
+         ImportedTransactionInfo txInfo;
+         synchronized (importedTransactions) {
+             txInfo = (ImportedTransactionInfo) importedTransactions.remove(xid);
+         }
+         if (txInfo == null) {
+             throw new XAException("No imported transaction for xid: " + xid);
+         }
+         Transaction tx = txInfo.getContainerTransactionContext().getTransaction();
+         //todo is there a correct status test here?
+//        try {
+//            int status = tx.getStatus();
+//            assert status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARED;
+//        } catch (SystemException e) {
+//            throw new XAException();
+//        }
+         importer.forget(tx);
+     }
+
+     /**
+      * @see javax.resource.spi.XATerminator#prepare(javax.transaction.xa.Xid)
+      */
+     public int prepare(Xid xid) throws XAException {
+         ImportedTransactionInfo txInfo;
+         synchronized (importedTransactions) {
+             txInfo = (ImportedTransactionInfo) importedTransactions.get(xid);
+         }
+         if (txInfo == null) {
+             throw new XAException("No imported transaction for xid: " + xid);
+         }
+         Transaction tx = txInfo.getContainerTransactionContext().getTransaction();
+         try {
+             int status = tx.getStatus();
+             assert status == Status.STATUS_ACTIVE;
+         } catch (SystemException e) {
+             throw new XAException();
+         }
+         return importer.prepare(tx);
+     }
+
+     /**
+      * @see javax.resource.spi.XATerminator#recover(int)
+      */
+     public Xid[] recover(int flag) throws XAException {
+         if (recoveryState == NOT_IN_RECOVERY) {
+             if ((flag & XAResource.TMSTARTRSCAN) == 0) {
+                 throw new XAException(XAException.XAER_PROTO);
+             }
+             recoveryState = IN_RECOVERY;
+         }
+         if ((flag & XAResource.TMENDRSCAN) != 0) {
+             recoveryState = NOT_IN_RECOVERY;
+         }
+         //we always return all xids in first call.
+         //calling "startrscan" repeatedly starts at beginning of list again.
+         if ((flag & XAResource.TMSTARTRSCAN) != 0) {
+             Map recoveredXidMap = recovery.getExternalXids();
+             Xid[] recoveredXids = new Xid[recoveredXidMap.size()];
+             int i = 0;
+             synchronized (importedTransactions) {
+                 for (Iterator iterator = recoveredXidMap.entrySet().iterator(); iterator.hasNext();) {
+                     Map.Entry entry = (Map.Entry) iterator.next();
+                     Xid xid = (Xid) entry.getKey();
+                     recoveredXids[i++] = xid;
+                     ImportedTransactionInfo txInfo = new ImportedTransactionInfo(new ContainerTransactionContext(transactionManager, (Transaction)entry.getValue()));
+                     importedTransactions.put(xid, txInfo);
+                 }
+             }
+             return recoveredXids;
+         } else {
+             return new Xid[0];
+         }
+     }
+
+     /**
+      * @see javax.resource.spi.XATerminator#rollback(javax.transaction.xa.Xid)
+      */
+     public void rollback(Xid xid) throws XAException {
+         ImportedTransactionInfo txInfo;
+         synchronized (importedTransactions) {
+             txInfo = (ImportedTransactionInfo) importedTransactions.remove(xid);
+         }
+         if (txInfo == null) {
+             throw new XAException("No imported transaction for xid: " + xid);
+         }
+         Transaction tx = txInfo.getContainerTransactionContext().getTransaction();
+
+         try {
+             int status = tx.getStatus();
+             assert status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARED;
+         } catch (SystemException e) {
+             throw new XAException();
+         }
+         importer.rollback(tx);
+     }
+
+
+    //XAWork implementation
+    public void begin(Xid xid, long txTimeoutMillis) throws XAException, InvalidTransactionException, SystemException {
+        ImportedTransactionInfo txInfo;
+        boolean old = true;
+        synchronized (importedTransactions) {
+             txInfo = (ImportedTransactionInfo) importedTransactions.get(xid);
+            if (txInfo == null) {
+                try {
+                    Transaction transaction = importer.importXid(xid);
+                    ContainerTransactionContext containerTransactionContext = new ContainerTransactionContext(transactionManager, transaction);
+                    txInfo = new ImportedTransactionInfo(containerTransactionContext);
+                    old = false;
+                } catch (SystemException e) {
+                    throw (XAException) new XAException("Could not import xid").initCause(e);
+                }
+                importedTransactions.put(xid, txInfo);
+            }
+            if (txInfo.isActive()) {
+                throw new XAException("Xid already active");
+            }
+            txInfo.setActive(true);
+        }
+        if (old) {
+            txInfo.getContainerTransactionContext().resume();
+        }
+        importer.setTransactionTimeout(txTimeoutMillis);
+    }
+
+    public void end(Xid xid) throws XAException, SystemException {
+        synchronized (importedTransactions) {
+            ImportedTransactionInfo txInfo = (ImportedTransactionInfo) importedTransactions.get(xid);
+            if (txInfo == null) {
+                throw new XAException("No imported transaction for xid: " + xid);
+            }
+            if (!txInfo.isActive()) {
+                throw new XAException("tx not active for xid: " + xid);
+            }
+            txInfo.getContainerTransactionContext().suspend();
+            txInfo.setActive(false);
+        }
+    }
+
+    //todo make an imported transaction context with this info.
+    private static class ImportedTransactionInfo {
+        private final ContainerTransactionContext containerTransactionContext;
+        private boolean active;
+
+        public ImportedTransactionInfo(ContainerTransactionContext containerTransactionContext) {
+            this.containerTransactionContext = containerTransactionContext;
+        }
+
+        public ContainerTransactionContext getContainerTransactionContext() {
+            return containerTransactionContext;
+        }
+
+        public boolean isActive() {
+            return active;
+        }
+
+        public void setActive(boolean active) {
+            this.active = active;
+        }
+    }
+
     public static final GBeanInfo GBEAN_INFO;
 
     static {
@@ -108,8 +318,10 @@
         infoFactory.addOperation("newUnspecifiedTransactionContext");
 
         infoFactory.addReference("TransactionManager", TransactionManager.class);
+        infoFactory.addReference("XidImporter", XidImporter.class);
+        infoFactory.addReference("Recovery", Recovery.class);
 
-        infoFactory.setConstructor(new String[] {"TransactionManager"});
+        infoFactory.setConstructor(new String[] {"TransactionManager", "XidImporter", "Recovery"});
         GBEAN_INFO = infoFactory.getBeanInfo();
     }
 

Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
==============================================================================
--- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java	(original)
+++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java	Mon Oct  4 23:53:13 2004
@@ -88,6 +88,7 @@
     }
 
     public synchronized void setRollbackOnly() throws IllegalStateException, SystemException {
+        log.info("in setRollbackOnly, txImpl", new Exception("stack trace"));
         switch (status) {
             case Status.STATUS_ACTIVE:
             case Status.STATUS_PREPARING:

Modified: geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/TransactionManagerProxyTest.java
==============================================================================
--- geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/TransactionManagerProxyTest.java	(original)
+++ geronimo/trunk/modules/transaction/src/test/org/apache/geronimo/transaction/TransactionManagerProxyTest.java	Mon Oct  4 23:53:13 2004
@@ -18,6 +18,7 @@
 package org.apache.geronimo.transaction;
 
 import java.util.ArrayList;
+import java.util.Map;
 
 import javax.transaction.RollbackException;
 import javax.transaction.Status;
@@ -86,7 +87,7 @@
         assertEquals(Status.STATUS_MARKED_ROLLBACK, tm.getStatus());
         try {
             tm.commit();
-            fail("tx should roll back");
+            fail("tx should not commit");
         } catch (RollbackException e) {
             //expected
         }
@@ -100,7 +101,7 @@
         assertEquals(Status.STATUS_MARKED_ROLLBACK, tx.getStatus());
         try {
             tx.commit();
-            fail("tx should roll back");
+            fail("tx should not commit");
         } catch (RollbackException e) {
             //expected
         }
@@ -252,14 +253,15 @@
     //BE VERY CAREFUL!! the ResourceManager only "recovers" the LAST resource it creates.
     //This test depends on using the resource that will be recovered by the resource manager.
     public void testSimpleRecovery() throws Exception {
+        //create a transaction in our own transaction manager
         Xid xid = xidFactory.createXid();
-        tm.begin(xid, 1000);
+        tm.importXid(xid);
         Transaction tx = tm.getTransaction();
         tx.enlistResource(r1_2);
         tx.enlistResource(r2_2);
         tx.delistResource(r1_2, XAResource.TMSUCCESS);
         tx.delistResource(r2_2, XAResource.TMSUCCESS);
-        tm.prepare(xid);
+        tm.prepare(tx);
         //recover
         resourceManagers.add(rm1);
         tm.doStart();
@@ -271,15 +273,16 @@
     }
 
     public void testImportedXidRecovery() throws Exception {
+        //create a transaction from an external transaction manager.
         XidFactory xidFactory2 = new XidFactoryImpl("tm2".getBytes());
         Xid xid = xidFactory2.createXid();
-        tm.begin(xid, 1000);
+        tm.importXid(xid);
         Transaction tx = tm.getTransaction();
         tx.enlistResource(r1_2);
         tx.enlistResource(r2_2);
         tx.delistResource(r1_2, XAResource.TMSUCCESS);
         tx.delistResource(r2_2, XAResource.TMSUCCESS);
-        tm.prepare(xid);
+        tm.prepare(tx);
         //recover
         resourceManagers.add(rm1);
         tm.doStart();
@@ -289,9 +292,9 @@
         assertTrue(!r2_2.isCommitted());
         //there are no transactions started here, so local recovery is complete
         assertTrue(recovery.localRecoveryComplete());
-        Xid[] recovered = tm.recover(XAResource.TMSTARTRSCAN);
-        assertEquals(1, recovered.length);
-        assertEquals(xid, recovered[0]);
+        Map recovered = tm.getExternalXids();
+        assertEquals(1, recovered.size());
+        assertEquals(xid, recovered.keySet().iterator().next());
     }
 
     public void testResourceManagerContract() throws Exception {

Mime
View raw message