You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2008/08/25 04:39:08 UTC

svn commit: r688602 [1/5] - in /openejb/trunk/openejb3: assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/ container/openejb-core/src/main/java/org/apache/openejb/ container/openejb-core/src/main/java/o...

Author: dain
Date: Sun Aug 24 19:39:06 2008
New Revision: 688602

URL: http://svn.apache.org/viewvc?rev=688602&view=rev
Log:
Moved TransactionManager usages in EJB containers behind the TransactionPolicy interface.
Added a factory for TransactionPolicy instances.
Created a prototype TransactionPolicy implementation based in the Spring PlatformTransactionManager.

Added:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/BeanTransactionPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/EjbTransactionUtil.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/EjbUserTransaction.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/JtaTransactionPolicy.java   (contents, props changed)
      - copied, changed from r686452, openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/JtaTransactionPolicyFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionPolicyFactory.java   (contents, props changed)
      - copied, changed from r686452, openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/TransactionService.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionType.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TxBeanManaged.java
      - copied, changed from r686452, openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessBeanManagedTxPolicy.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringBeanTransactionPolicy.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicy.java
    openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicyFactory.java
Removed:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MessageDrivenBeanManagedTxPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonBeanManagedTxPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SessionSynchronizationTxPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulBeanManagedTxPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerManagedTxPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessBeanManagedTxPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionContext.java
Modified:
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseSessionContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/entity/EntityInstanceManager.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/EndpointFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/BeanEntry.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SessionSynchronizationCoordinator.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContext.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EjbTimerServiceImpl.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionPolicy.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TxMandatory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TxNever.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TxNotSupported.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TxRequired.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TxRequiresNew.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TxSupports.java
    openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml
    openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulSecurityPermissionsTest.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulTransactionAttributesTest.java

Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml Sun Aug 24 19:39:06 2008
@@ -66,7 +66,7 @@
           id="Default BMP Container"
           service="Container"
           types="BMP_ENTITY"
-          constructor="id, transactionManager, securityService, PoolSize"
+          constructor="id, securityService, PoolSize"
           class-name="org.apache.openejb.core.entity.EntityContainer">
 
     # Specifies the size of the bean pools for this
@@ -87,7 +87,7 @@
           id="Default Stateless Container"
           service="Container"
           types="STATELESS"
-          constructor="id, transactionManager, securityService, TimeOut, PoolSize, StrictPooling"
+          constructor="id, securityService, TimeOut, PoolSize, StrictPooling"
           class-name="org.apache.openejb.core.stateless.StatelessContainer">
 
     # Specifies the time to wait between invocations. This
@@ -129,7 +129,7 @@
           id="Default Singleton Container"
           service="Container"
           types="SINGLETON"
-          constructor="id, transactionManager, securityService"
+          constructor="id, securityService"
           class-name="org.apache.openejb.core.singleton.SingletonContainer">
 
     AccessTimeout = 30 seconds
@@ -146,7 +146,7 @@
           id="Default Stateful Container"
           service="Container"
           types="STATEFUL"
-          constructor="id, transactionManager, securityService, Passivator, TimeOut, PoolSize, BulkPassivate"
+          constructor="id, securityService, Passivator, TimeOut, PoolSize, BulkPassivate"
           class-name="org.apache.openejb.core.stateful.StatefulContainer">
 
     # The passivator is responsible for writing beans to disk
@@ -190,7 +190,7 @@
           id="Default MDB Container"
           service="Container"
           types="MESSAGE"
-          constructor="id, transactionManager, securityService, ResourceAdapter, MessageListenerInterface, ActivationSpecClass, InstanceLimit"
+          constructor="id, securityService, ResourceAdapter, MessageListenerInterface, ActivationSpecClass, InstanceLimit"
           class-name="org.apache.openejb.core.mdb.MdbContainer">
 
     # The resource adapter delivers messages to the container

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java Sun Aug 24 19:39:06 2008
@@ -19,6 +19,7 @@
 import org.apache.openejb.core.interceptor.InterceptorData;
 import org.apache.openejb.core.timer.EjbTimerService;
 import org.apache.openejb.core.ExceptionType;
+import org.apache.openejb.core.transaction.TransactionType;
 
 import java.lang.reflect.Method;
 import java.util.Collection;
@@ -29,20 +30,6 @@
 
 public interface DeploymentInfo {
 
-    final public static byte TX_NEVER = (byte) 0;
-
-    final public static byte TX_NOT_SUPPORTED = (byte) 1;
-
-    final public static byte TX_SUPPORTS = (byte) 2;
-
-    final public static byte TX_MANDITORY = (byte) 3;
-
-    final public static byte TX_REQUIRED = (byte) 4;
-
-    final public static byte TX_REQUIRES_NEW = (byte) 5;
-
-    final public static byte TX_MAX = (byte) 5;
-
     final public static byte READ_LOCK = (byte) 6;
 
     final public static byte WRITE_LOCK = (byte) 7;
@@ -53,7 +40,7 @@
 
     public InterfaceType getInterfaceType(Class clazz);
     
-    public byte getTransactionAttribute(Method method);
+    public TransactionType getTransactionType(Method method);
 
     public Collection<String> getAuthorizedRoles(Method method);
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Sun Aug 24 19:39:06 2008
@@ -68,12 +68,16 @@
 import org.apache.openejb.OpenEJB;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.UndeployException;
+import org.apache.openejb.finder.ResourceFinder;
 import org.apache.openejb.core.ConnectorReference;
 import org.apache.openejb.core.CoreContainerSystem;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.SimpleTransactionSynchronizationRegistry;
 import org.apache.openejb.core.transaction.SimpleWorkManager;
 import org.apache.openejb.core.transaction.SimpleBootstrapContext;
+import org.apache.openejb.core.transaction.TransactionType;
+import org.apache.openejb.core.transaction.JtaTransactionPolicyFactory;
+import org.apache.openejb.core.transaction.TransactionPolicyFactory;
 import org.apache.openejb.core.ivm.naming.IvmContext;
 import org.apache.openejb.core.timer.EjbTimerServiceImpl;
 import org.apache.openejb.core.timer.NullEjbTimerServiceImpl;
@@ -518,6 +522,12 @@
                     jaccPermissionsBuilder.install(policyContext);
                 }
 
+                TransactionPolicyFactory transactionPolicyFactory = createTransactionPolicyFactory(ejbJar, classLoader);
+                for (DeploymentInfo deploymentInfo : deployments.values()) {
+                    CoreDeploymentInfo coreDeploymentInfo = (CoreDeploymentInfo) deploymentInfo;
+                    coreDeploymentInfo.setTransactionPolicyFactory(transactionPolicyFactory);
+                }
+
                 MethodTransactionBuilder methodTransactionBuilder = new MethodTransactionBuilder();
                 methodTransactionBuilder.build(deployments, ejbJar.methodTransactions);
 
@@ -537,7 +547,7 @@
                         Method ejbTimeout = coreDeploymentInfo.getEjbTimeout();
                         if (ejbTimeout != null) {
                             // If user set the tx attribute to RequiresNew change it to Required so a new transaction is not started
-                            if (coreDeploymentInfo.getTransactionAttribute(ejbTimeout) == CoreDeploymentInfo.TX_REQUIRES_NEW) {
+                            if (coreDeploymentInfo.getTransactionType(ejbTimeout) == TransactionType.RequiresNew) {
                                 coreDeploymentInfo.setMethodTransactionAttribute(ejbTimeout, "Required");
                             }
 
@@ -634,6 +644,37 @@
         }
     }
 
+    private TransactionPolicyFactory createTransactionPolicyFactory(EjbJarInfo ejbJar, ClassLoader classLoader) {
+        TransactionPolicyFactory factory = null;
+
+        Object value = ejbJar.properties.get(TransactionPolicyFactory.class.getName());
+        if (value instanceof TransactionPolicyFactory) {
+            factory = (TransactionPolicyFactory) value;
+        } else if (value instanceof String) {
+            try {
+                String[] parts = ((String)value).split(":", 2);
+
+                ResourceFinder finder = new ResourceFinder("META-INF", classLoader);
+                Map<String,Class> plugins = finder.mapAvailableImplementations(TransactionPolicyFactory.class);
+                Class<? extends TransactionPolicyFactory> clazz = plugins.get(parts[0]).asSubclass(TransactionPolicyFactory.class);
+                if (clazz != null) {
+                    if (parts.length == 1) {
+                        factory = clazz.getConstructor(String.class).newInstance(parts[1]);
+                    } else {
+                        factory = clazz.newInstance();
+                    }
+                }
+            } catch (Exception ignored) {
+                // couldn't determine the plugins, which isn't fatal
+            }
+        }
+
+        if (factory == null) {
+             factory = new JtaTransactionPolicyFactory(transactionManager);
+        }
+        return factory;
+    }
+
     private static List<DeploymentInfo> sort(List<DeploymentInfo> deployments) {
         // Sort all the singletons to the back of the list.  We want to make sure
         // all non-singletons are created first so that if a singleton refers to them

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseContext.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseContext.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseContext.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseContext.java Sun Aug 24 19:39:06 2008
@@ -27,9 +27,7 @@
 import javax.ejb.TimerService;
 import javax.naming.NamingException;
 import javax.naming.Context;
-import javax.transaction.Status;
 import javax.transaction.SystemException;
-import javax.transaction.TransactionManager;
 import javax.transaction.UserTransaction;
 import javax.transaction.NotSupportedException;
 import javax.transaction.HeuristicMixedException;
@@ -40,6 +38,8 @@
 import org.apache.openejb.core.timer.EjbTimerService;
 import org.apache.openejb.core.timer.TimerServiceImpl;
 import org.apache.openejb.core.ivm.IntraVmArtifact;
+import org.apache.openejb.core.transaction.EjbUserTransaction;
+import org.apache.openejb.core.transaction.TransactionPolicy;
 import org.apache.openejb.spi.SecurityService;
 
 
@@ -48,18 +48,14 @@
  */
 public abstract class BaseContext implements EJBContext, Serializable {
 
-    private final UserTransaction userTransaction;
     private final SecurityService securityService;
-    private final TransactionManager transactionManager;
+    private final UserTransaction userTransaction;
 
-    public BaseContext(TransactionManager transactionManager, SecurityService securityService) {
-        this.transactionManager = transactionManager;
-        this.securityService = securityService;
-        this.userTransaction = new UserTransactionWrapper(new CoreUserTransaction(transactionManager));
+    protected BaseContext(SecurityService securityService) {
+        this(securityService, new EjbUserTransaction());
     }
 
-    protected BaseContext(TransactionManager transactionManager, SecurityService securityService, UserTransaction userTransaction) {
-        this.transactionManager = transactionManager;
+    protected BaseContext(SecurityService securityService, UserTransaction userTransaction) {
         this.securityService = securityService;
         this.userTransaction = new UserTransactionWrapper(userTransaction);
     }
@@ -107,11 +103,11 @@
     }
 
     public void setRollbackOnly() throws IllegalStateException {
-        getState().setRollbackOnly(transactionManager);
+        getState().setRollbackOnly();
     }
 
     public boolean getRollbackOnly() throws IllegalStateException {
-        return getState().getRollbackOnly(transactionManager);
+        return getState().getRollbackOnly();
     }
 
     public TimerService getTimerService() throws IllegalStateException {
@@ -258,7 +254,7 @@
             }
         }
 
-        public void setRollbackOnly(TransactionManager transactionManager) throws IllegalStateException {
+        public void setRollbackOnly() throws IllegalStateException {
             ThreadContext threadContext = ThreadContext.getThreadContext();
             DeploymentInfo di = threadContext.getDeploymentInfo();
 
@@ -266,14 +262,18 @@
                 throw new IllegalStateException("bean-managed transaction beans can not access the setRollbackOnly() method");
             }
 
-            try {
-                transactionManager.setRollbackOnly();
-            } catch (SystemException se) {
-                throw new RuntimeException("Transaction service has thrown a SystemException", se);
+            TransactionPolicy txPolicy = threadContext.getTransactionPolicy();
+            if (txPolicy == null) {
+                throw new IllegalStateException("ThreadContext does not contain a TransactionEnvironment");
+            }
+            if (!txPolicy.isTransactionActive()) {
+                // this would be true for Supports tx attribute where no tx was propagated
+                throw new IllegalStateException("No current transaction");
             }
+            txPolicy.setRollbackOnly();
         }
 
-        public boolean getRollbackOnly(TransactionManager transactionManager) throws IllegalStateException {
+        public boolean getRollbackOnly() throws IllegalStateException {
             ThreadContext threadContext = ThreadContext.getThreadContext();
             DeploymentInfo di = threadContext.getDeploymentInfo();
 
@@ -281,19 +281,15 @@
                 throw new IllegalStateException("bean-managed transaction beans can not access the getRollbackOnly() method: deploymentId=" + di.getDeploymentID());
             }
 
-            try {
-                int status = transactionManager.getStatus();
-                if (status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLEDBACK) {
-                    return true;
-                } else if (status == Status.STATUS_NO_TRANSACTION) {
-                    // this would be true for Supports tx attribute where no tx was propagated
-                    throw new IllegalStateException("No current transaction");
-                } else {
-                    return false;
-                }
-            } catch (SystemException se) {
-                throw new RuntimeException("Transaction service has thrown a SystemException", se);
+            TransactionPolicy transactionPolicy = threadContext.getTransactionPolicy();
+            if (transactionPolicy == null) {
+                throw new IllegalStateException("ThreadContext does not contain a TransactionEnvironment");
+            }
+            if (!transactionPolicy.isTransactionActive()) {
+                // this would be true for Supports tx attribute where no tx was propagated
+                throw new IllegalStateException("No current transaction");
             }
+            return transactionPolicy.isRollbackOnly();
         }
 
         public TimerService getTimerService() throws IllegalStateException {

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseSessionContext.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseSessionContext.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseSessionContext.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/BaseSessionContext.java Sun Aug 24 19:39:06 2008
@@ -16,7 +16,6 @@
  */
 package org.apache.openejb.core;
 
-import java.lang.reflect.Method;
 import java.security.Principal;
 import java.util.List;
 import java.util.ArrayList;
@@ -24,19 +23,12 @@
 import javax.ejb.EJBObject;
 import javax.ejb.SessionContext;
 import javax.ejb.TimerService;
-import javax.transaction.TransactionManager;
 import javax.transaction.UserTransaction;
-import javax.transaction.NotSupportedException;
-import javax.transaction.SystemException;
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.RollbackException;
 import javax.xml.rpc.handler.MessageContext;
 
 import org.apache.openejb.DeploymentInfo;
 import org.apache.openejb.InterfaceType;
 import org.apache.openejb.InternalErrorException;
-import org.apache.openejb.RpcContainer;
 import org.apache.openejb.core.ivm.EjbObjectProxyHandler;
 import org.apache.openejb.core.ivm.IntraVmProxy;
 import org.apache.openejb.core.stateless.StatelessEjbObjectHandler;
@@ -45,18 +37,16 @@
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.proxy.ProxyManager;
 
-
 /**
  * @version $Rev$ $Date$
  */
 public abstract class BaseSessionContext extends BaseContext implements SessionContext {
-
-    public BaseSessionContext(TransactionManager transactionManager, SecurityService securityService) {
-        super(transactionManager, securityService);
+    protected BaseSessionContext(SecurityService securityService) {
+        super(securityService);
     }
 
-    public BaseSessionContext(TransactionManager transactionManager, SecurityService securityService, UserTransaction userTransaction) {
-        super(transactionManager, securityService, userTransaction);
+    public BaseSessionContext(SecurityService securityService, UserTransaction userTransaction) {
+        super(securityService, userTransaction);
     }
 
     public EJBLocalObject getEJBLocalObject() throws IllegalStateException {
@@ -143,7 +133,7 @@
                 List<Class> interfaces = new ArrayList<Class>();
                 interfaces.addAll(di.getInterfaces(interfaceType));
                 interfaces.add(IntraVmProxy.class);
-                return ProxyManager.newProxyInstance(interfaces.toArray(new Class[]{}), handler);
+                return ProxyManager.newProxyInstance(interfaces.toArray(new Class[interfaces.size()]), handler);
             } catch (IllegalAccessException iae) {
                 throw new InternalErrorException("Could not create IVM proxy for " + interfce.getName() + " interface", iae);
             }
@@ -199,11 +189,11 @@
             throw new IllegalStateException();
         }
 
-        public void setRollbackOnly(TransactionManager transactionManager) throws IllegalStateException {
+        public void setRollbackOnly() throws IllegalStateException {
             throw new IllegalStateException();
         }
 
-        public boolean getRollbackOnly(TransactionManager transactionManager) throws IllegalStateException {
+        public boolean getRollbackOnly() throws IllegalStateException {
             throw new IllegalStateException();
         }
 
@@ -257,11 +247,11 @@
             throw new IllegalStateException();
         }
 
-        public void setRollbackOnly(TransactionManager transactionManager) throws IllegalStateException {
+        public void setRollbackOnly() throws IllegalStateException {
             throw new IllegalStateException();
         }
 
-        public boolean getRollbackOnly(TransactionManager transactionManager) throws IllegalStateException {
+        public boolean getRollbackOnly() throws IllegalStateException {
             throw new IllegalStateException();
         }
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java Sun Aug 24 19:39:06 2008
@@ -17,51 +17,39 @@
 package org.apache.openejb.core;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.Set;
-import java.util.ArrayList;
 import java.util.TreeSet;
-import java.util.LinkedHashSet;
 import javax.ejb.EJBHome;
 import javax.ejb.EJBLocalHome;
 import javax.ejb.EJBLocalObject;
-import javax.ejb.SessionSynchronization;
+import javax.ejb.EJBObject;
 import javax.ejb.MessageDrivenBean;
 import javax.ejb.TimedObject;
 import javax.ejb.Timer;
-import javax.persistence.EntityManagerFactory;
 import javax.naming.Context;
+import javax.persistence.EntityManagerFactory;
 
+import org.apache.openejb.BeanType;
 import org.apache.openejb.Container;
-import org.apache.openejb.SystemException;
-import org.apache.openejb.InterfaceType;
 import org.apache.openejb.DeploymentInfo;
-import org.apache.openejb.BeanType;
 import org.apache.openejb.Injection;
+import org.apache.openejb.InterfaceType;
 import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.SystemException;
 import org.apache.openejb.core.cmp.KeyGenerator;
-import org.apache.openejb.core.ivm.EjbHomeProxyHandler;
-import org.apache.openejb.core.stateful.SessionSynchronizationTxPolicy;
-import org.apache.openejb.core.stateful.StatefulBeanManagedTxPolicy;
-import org.apache.openejb.core.stateful.StatefulContainerManagedTxPolicy;
-import org.apache.openejb.core.stateless.StatelessBeanManagedTxPolicy;
-import org.apache.openejb.core.transaction.TransactionContainer;
-import org.apache.openejb.core.transaction.TransactionPolicy;
-import org.apache.openejb.core.transaction.TxMandatory;
-import org.apache.openejb.core.transaction.TxNever;
-import org.apache.openejb.core.transaction.TxNotSupported;
-import org.apache.openejb.core.transaction.TxRequired;
-import org.apache.openejb.core.transaction.TxRequiresNew;
-import org.apache.openejb.core.transaction.TxSupports;
 import org.apache.openejb.core.interceptor.InterceptorData;
-import org.apache.openejb.core.mdb.MessageDrivenBeanManagedTxPolicy;
+import org.apache.openejb.core.ivm.EjbHomeProxyHandler;
 import org.apache.openejb.core.timer.EjbTimerService;
-import org.apache.openejb.core.singleton.SingletonBeanManagedTxPolicy;
+import org.apache.openejb.core.transaction.TransactionType;
+import org.apache.openejb.core.transaction.TransactionPolicyFactory;
 import org.apache.openejb.util.Index;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
@@ -104,8 +92,6 @@
     private Container container;
     private EJBHome ejbHomeRef;
     private EJBLocalHome ejbLocalHomeRef;
-    private BusinessLocalHome businessLocalHomeRef;
-    private BusinessRemoteHome businessRemoteHomeRef;
     private String destinationId;
     private final Map<Class, Object> data = new HashMap<Class, Object>();
 
@@ -123,9 +109,11 @@
     private final BeanType componentType;
 
     private final Map<Method, Collection<String>> methodPermissions = new HashMap<Method, Collection<String>>();
-    private final Map<Method, Byte> methodTransactionAttributes = new HashMap<Method, Byte>();
     private final Map<Method, Byte> methodConcurrencyAttributes = new HashMap<Method, Byte>();
-    private final Map<Method, TransactionPolicy> methodTransactionPolicies = new HashMap<Method, TransactionPolicy>();
+
+    private final Map<Method, TransactionType> methodTransactionType = new HashMap<Method, TransactionType>();
+    private TransactionPolicyFactory transactionPolicyFactory;
+
     private final Map<Method, List<InterceptorData>> methodInterceptors = new HashMap<Method, List<InterceptorData>>();
     private final List<InterceptorData> callbackInterceptors = new ArrayList<InterceptorData>();
     private final Map<Method, Method> methodMap = new HashMap<Method, Method>();
@@ -358,21 +346,6 @@
         return componentType;
     }
 
-    public byte getTransactionAttribute(Method method) {
-        Byte byteWrapper = methodTransactionAttributes.get(method);
-
-        if (byteWrapper == null){
-            Method beanMethod = getMatchingBeanMethod(method);
-            byteWrapper = methodTransactionAttributes.get(beanMethod);
-        }
-
-        if (byteWrapper == null) {
-            return TX_NOT_SUPPORTED;// non remote or home interface method
-        } else {
-            return byteWrapper;
-        }
-    }
-
     public byte getConcurrencyAttribute(Method method) {
         Byte byteWrapper = methodConcurrencyAttributes.get(method);
 
@@ -388,46 +361,45 @@
         }
     }
 
-    public TransactionPolicy getTransactionPolicy(Method method) {
-        TransactionPolicy policy = methodTransactionPolicies.get(method);
-        if (policy == null && !isBeanManagedTransaction) {
-            Method beanMethod = getMatchingBeanMethod(method);
-            if (beanMethod != null){
-                policy = methodTransactionPolicies.get(beanMethod);
-            }
+    public TransactionType getTransactionType(Method method) {
+        // Check the cache
+        TransactionType type = methodTransactionType.get(method);
+        if (type != null) {
+            return type;
         }
-        if (policy == null && !isBeanManagedTransaction) {
-            Logger log = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
-            log.debug("The following method doesn't have a transaction policy assigned: " + method);
-        }
-        if (policy == null && container instanceof TransactionContainer) {
-            if (isBeanManagedTransaction) {
-                if (componentType == BeanType.STATEFUL) {
-                    policy = new StatefulBeanManagedTxPolicy((TransactionContainer) container);
-                } else if (componentType == BeanType.STATELESS) {
-                    policy = new StatelessBeanManagedTxPolicy((TransactionContainer) container);
-                } else if (componentType == BeanType.SINGLETON) {
-                    policy = new SingletonBeanManagedTxPolicy((TransactionContainer) container);
-                } else if (componentType == BeanType.MESSAGE_DRIVEN) {
-                    policy = new MessageDrivenBeanManagedTxPolicy((TransactionContainer) container);
-                }
-            } else if (componentType == BeanType.STATEFUL) {
-                policy = new TxRequired((TransactionContainer) container);
-                if (!isBeanManagedTransaction && SessionSynchronization.class.isAssignableFrom(beanClass)) {
-                    policy = new SessionSynchronizationTxPolicy(policy);
-                } else {
-                    policy = new StatefulContainerManagedTxPolicy(policy);
-                }
-            } else {
-                // default transaction policy is required
-                policy = new TxRequired((TransactionContainer) container);
-            }
-            methodTransactionPolicies.put(method, policy);
+
+        // Bean managed EJBs always get the BeanManaged policy
+        if (isBeanManagedTransaction) {
+            return TransactionType.BeanManaged;
         }
-        if (policy == null) {
-            policy = new TxSupports((TransactionContainer) container);
+
+        // Check the matching bean method for the supplied method
+        Method beanMethod = getMatchingBeanMethod(method);
+        if (beanMethod != null){
+            type = methodTransactionType.get(beanMethod);
+            if (type != null) {
+                return type;
+            }
         }
-        return policy ;
+
+        // All transaction attributes should have been set during deployment, so log a message
+        Logger log = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
+        log.debug("The following method doesn't have a transaction policy assigned: " + method);
+
+        // default transaction policy is required
+        type = TransactionType.Required;
+
+        // cache this default to avoid extra log messages
+        methodTransactionType.put(method, type);
+        return type;
+    }
+
+    public TransactionPolicyFactory getTransactionPolicyFactory() {
+        return transactionPolicyFactory;
+    }
+
+    public void setTransactionPolicyFactory(TransactionPolicyFactory transactionPolicyFactory) {
+        this.transactionPolicyFactory = transactionPolicyFactory;
     }
 
     public Collection<String> getAuthorizedRoles(Method method) {
@@ -644,85 +616,46 @@
 
 
     public void setMethodTransactionAttribute(Method method, String transAttribute) throws OpenEJBException {
-        Byte byteValue = null;
-        TransactionPolicy policy = null;
-
+        TransactionType transactionType;
         if (transAttribute.equalsIgnoreCase("Supports")) {
-            if (container instanceof TransactionContainer) {
-                policy = new TxSupports((TransactionContainer) container);
-            }
-            byteValue = new Byte(TX_SUPPORTS);
+            transactionType = TransactionType.Supports;
 
         } else if (transAttribute.equalsIgnoreCase("RequiresNew")) {
-            if (container instanceof TransactionContainer) {
-                policy = new TxRequiresNew((TransactionContainer) container);
-            }
-            byteValue = new Byte(TX_REQUIRES_NEW);
+            transactionType = TransactionType.RequiresNew;
 
         } else if (transAttribute.equalsIgnoreCase("Mandatory")) {
-            if (container instanceof TransactionContainer) {
-                policy = new TxMandatory((TransactionContainer) container);
-            }
-            byteValue = new Byte(TX_MANDITORY);
+            transactionType = TransactionType.Mandatory;
 
         } else if (transAttribute.equalsIgnoreCase("NotSupported")) {
-            if (container instanceof TransactionContainer) {
-                policy = new TxNotSupported((TransactionContainer) container);
-            }
-            byteValue = new Byte(TX_NOT_SUPPORTED);
+            transactionType = TransactionType.NotSupported;
 
         } else if (transAttribute.equalsIgnoreCase("Required")) {
-            if (container instanceof TransactionContainer) {
-                policy = new TxRequired((TransactionContainer) container);
-            }
-            byteValue = new Byte(TX_REQUIRED);
+            transactionType = TransactionType.Required;
 
         } else if (transAttribute.equalsIgnoreCase("Never")) {
-            if (container instanceof TransactionContainer) {
-                policy = new TxNever((TransactionContainer) container);
-            }
-            byteValue = new Byte(TX_NEVER);
+            transactionType = TransactionType.Never;
+
         } else {
             throw new IllegalArgumentException("Invalid transaction attribute \"" + transAttribute + "\" declared for method " + method.getName() + ". Please check your configuration.");
         }
 
-        /* EJB 1.1 page 55
-         Only a stateful Session bean with container-managed transaction demarcation may implement the
-         SessionSynchronization interface. A stateless Session bean must not implement the SessionSynchronization
-         interface.
-         */
-
-        if (componentType == BeanType.STATEFUL && !isBeanManagedTransaction && container instanceof TransactionContainer) {
-
-            if (SessionSynchronization.class.isAssignableFrom(beanClass)) {
-                if (!transAttribute.equals("Never") && !transAttribute.equals("NotSupported")) {
-                    policy = new SessionSynchronizationTxPolicy(policy);
-                }
-            } else {
-                policy = new StatefulContainerManagedTxPolicy(policy);
-            }
-        }
-
-        /**
-           Only the NOT_SUPPORTED and REQUIRED transaction attributes may be used for message-driven
-           bean message listener methods. The use of the other transaction attributes is not meaningful
-           for message-driven bean message listener methods because there is no pre-existing client transaction
-           context(REQUIRES_NEW, SUPPORTS) and no client to handle exceptions (MANDATORY, NEVER).
-         */
-        if (componentType.isMessageDriven() && !isBeanManagedTransaction && container instanceof TransactionContainer) {
-            if (policy.getPolicyType() != TransactionPolicy.Type.NotSupported && policy.getPolicyType() != TransactionPolicy.Type.Required) {
+        // Only the NOT_SUPPORTED and REQUIRED transaction attributes may be used for message-driven
+        // bean message listener methods. The use of the other transaction attributes is not meaningful
+        // for message-driven bean message listener methods because there is no pre-existing client transaction
+        // context(REQUIRES_NEW, SUPPORTS) and no client to handle exceptions (MANDATORY, NEVER).
+        if (componentType.isMessageDriven() && !isBeanManagedTransaction) {
+            if (transactionType != TransactionType.NotSupported && transactionType != TransactionType.Required) {
 
-                if (method.equals(this.ejbTimeout) && policy.getPolicyType() == TransactionPolicy.Type.RequiresNew) {
+                if (method.equals(this.ejbTimeout) && transactionType == TransactionType.RequiresNew) {
                     // do nothing. This is allowed as the timer callback method for a message driven bean
                     // can also have a transaction policy of RequiresNew Sec 5.4.12 of Ejb 3.0 Core Spec
                 } else {
-                    throw new OpenEJBException("The transaction attribute " + policy.policyToString() + "is not supported for the method "
+                    throw new OpenEJBException("The transaction attribute " + transactionType + " is not supported for the method "
                                                + method.getName() + " of the Message Driven Bean " + beanClass.getName());
                 }
             }
         }
-        methodTransactionAttributes.put(method, byteValue);
-        methodTransactionPolicies.put(method, policy);
+        methodTransactionType.put(method, transactionType);
     }
 
     public List<Method> getAroundInvoke() {
@@ -872,10 +805,9 @@
 
     private void mapHomeInterface(Class intrface) {
         Method [] homeMethods = intrface.getMethods();
-        for (int i = 0; i < homeMethods.length; i++) {
-            Method method = homeMethods[i];
+        for (Method method : homeMethods) {
             Class owner = method.getDeclaringClass();
-            if (owner == javax.ejb.EJBHome.class || owner == EJBLocalHome.class) {
+            if (owner == EJBHome.class || owner == EJBLocalHome.class) {
                 continue;
             }
 
@@ -883,7 +815,7 @@
                 Method beanMethod = null;
                 if (method.getName().startsWith("create")) {
                     StringBuilder ejbCreateName = new StringBuilder(method.getName());
-                    ejbCreateName.replace(0,1, "ejbC");
+                    ejbCreateName.replace(0, 1, "ejbC");
                     beanMethod = beanClass.getMethod(ejbCreateName.toString(), method.getParameterTypes());
                     createMethod = beanMethod;
                     /*
@@ -913,7 +845,7 @@
                     beanMethod = beanClass.getMethod(beanMethodName, method.getParameterTypes());
                 }
                 if (beanMethod != null) {
-                    mapMethods(homeMethods[i], beanMethod);
+                    mapMethods(method, beanMethod);
                 }
             } catch (NoSuchMethodException nsme) {
 //                throw new RuntimeException("Invalid method [" + method + "] Not declared by " + beanClass.getName() + " class");
@@ -931,10 +863,9 @@
         }
 
         Method [] interfaceMethods = intrface.getMethods();
-        for (int i = 0; i < interfaceMethods.length; i++) {
-            Method method = interfaceMethods[i];
+        for (Method method : interfaceMethods) {
             Class declaringClass = method.getDeclaringClass();
-            if (declaringClass == javax.ejb.EJBObject.class || declaringClass == EJBLocalObject.class) {
+            if (declaringClass == EJBObject.class || declaringClass == EJBLocalObject.class) {
                 continue;
             }
             try {

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/RpcContainerWrapper.java Sun Aug 24 19:39:06 2008
@@ -19,11 +19,10 @@
 import org.apache.openejb.RpcContainer;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.ContainerType;
-import org.apache.openejb.core.transaction.TransactionContainer;
 
 import java.lang.reflect.Method;
 
-public class RpcContainerWrapper implements RpcContainer, TransactionContainer {
+public class RpcContainerWrapper implements RpcContainer {
 
     private final RpcContainer container;
 
@@ -63,12 +62,7 @@
         container.undeploy(info);
     }
 
-    public void discardInstance(Object instance, ThreadContext context) {
-        ((TransactionContainer) container).discardInstance(instance, context);
-    }
-
     public RpcContainer getContainer() {
         return container;
     }
-
 }

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/ThreadContext.java Sun Aug 24 19:39:06 2008
@@ -22,6 +22,7 @@
 
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
+import org.apache.openejb.core.transaction.TransactionPolicy;
 
 public class ThreadContext {
     private static final Logger log = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
@@ -97,6 +98,7 @@
     private Operation currentOperation;
     private BaseContext.State[] currentAllowedStates;
     private Class invokedInterface;
+    private TransactionPolicy transactionPolicy;
 
     public ThreadContext(CoreDeploymentInfo deploymentInfo, Object primaryKey) {
         this(deploymentInfo, primaryKey, null);
@@ -142,6 +144,14 @@
         this.invokedInterface = invokedInterface;
     }
 
+    public TransactionPolicy getTransactionPolicy() {
+        return transactionPolicy;
+    }
+
+    public void setTransactionPolicy(TransactionPolicy transactionPolicy) {
+        this.transactionPolicy = transactionPolicy;
+    }
+
     public BaseContext.State[] getCurrentAllowedStates() {
         return currentAllowedStates;
     }

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/CmpContainer.java Sun Aug 24 19:39:06 2008
@@ -30,7 +30,6 @@
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.Set;
-import javax.ejb.CreateException;
 import javax.ejb.EJBException;
 import javax.ejb.EJBHome;
 import javax.ejb.EJBLocalHome;
@@ -61,18 +60,19 @@
 import org.apache.openejb.core.timer.EjbTimerServiceImpl;
 import org.apache.openejb.core.entity.EntityContext;
 import org.apache.openejb.core.entity.EntrancyTracker;
-import org.apache.openejb.core.transaction.TransactionContainer;
-import org.apache.openejb.core.transaction.TransactionContext;
 import org.apache.openejb.core.transaction.TransactionPolicy;
+import static org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException;
+import static org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException;
+import static org.apache.openejb.core.transaction.EjbTransactionUtil.afterInvoke;
+import static org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.Enumerator;
 
 /**
  * @org.apache.xbean.XBean element="cmpContainer"
  */
-public class CmpContainer implements RpcContainer, TransactionContainer {
+public class CmpContainer implements RpcContainer {
     protected final Object containerID;
-    protected final TransactionManager transactionManager;
     protected final SecurityService securityService;
 
     /**
@@ -104,9 +104,8 @@
     };
 
     public CmpContainer(Object id, TransactionManager transactionManager, SecurityService securityService, String cmpEngineFactory) throws OpenEJBException {
-        this.transactionManager = transactionManager;
-        this.securityService = securityService;
         this.containerID = id;
+        this.securityService = securityService;
         synchronizationRegistry = SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class);
         entrancyTracker = new EntrancyTracker(synchronizationRegistry);
 
@@ -279,9 +278,6 @@
         }
     }
 
-    public void discardInstance(Object bean, ThreadContext threadContext) {
-    }
-
     private EntityBean createNewInstance(ThreadContext callContext) {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
         try {
@@ -315,7 +311,7 @@
 
         ThreadContext oldCallContext = ThreadContext.enter(callContext);
         try {
-            entityBean.setEntityContext(new EntityContext(transactionManager, securityService));
+            entityBean.setEntityContext(new EntityContext(securityService));
         } catch (RemoteException e) {
             throw new EJBException(e);
         } finally {
@@ -471,12 +467,10 @@
 
     private Object businessMethod(Method callMethod, Method runMethod, Object[] args, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
-        TransactionContext txContext = new TransactionContext(callContext, transactionManager);
 
-        txPolicy.beforeInvoke(null, txContext);
+        TransactionPolicy txPolicy = createTransactionPolicy(deploymentInfo.getTransactionType(callMethod), callContext);
 
-        EntityBean bean = null;
+        EntityBean bean;
         Object returnValue = null;
 
         entrancyTracker.enter(deploymentInfo, callContext.getPrimaryKey());
@@ -490,24 +484,24 @@
 
             // when there is not transaction, merge the data from the bean back into the cmp engine
             cmpEngine.storeBeanIfNoTx(callContext, bean);
-        } catch (InvocationTargetException ite) {
-            ExceptionType type = callContext.getDeploymentInfo().getExceptionType(ite.getTargetException());
+        } catch (NoSuchObjectException e) {
+            handleApplicationException(txPolicy, e, false);
+        } catch (Throwable e) {
+            if (e instanceof InvocationTargetException) {
+                e = ((InvocationTargetException) e).getTargetException();
+            }
+
+            ExceptionType type = callContext.getDeploymentInfo().getExceptionType(e);
             if (type == ExceptionType.SYSTEM) {
                 /* System Exception ****************************/
-                txPolicy.handleSystemException(ite.getTargetException(), bean, txContext);
-
+                handleSystemException(txPolicy, e, callContext);
             } else {
                 /* Application Exception ***********************/
-                txPolicy.handleApplicationException(ite.getTargetException(), type == ExceptionType.APPLICATION_ROLLBACK, txContext);
+                handleApplicationException(txPolicy, e, type == ExceptionType.APPLICATION_ROLLBACK);
             }
-        } catch (NoSuchObjectException e) {
-            txPolicy.handleApplicationException(e, false, txContext);
-        } catch (Throwable e) {
-            /* System Exception ****************************/
-            txPolicy.handleSystemException(e, bean, txContext);
         } finally {
             entrancyTracker.exit(deploymentInfo, callContext.getPrimaryKey());
-            txPolicy.afterInvoke(bean, txContext);
+            afterInvoke(txPolicy, callContext);
         }
 
         return returnValue;
@@ -515,12 +509,10 @@
 
     private Object homeMethod(Method callMethod, Object[] args, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
-        TransactionContext txContext = new TransactionContext(callContext, transactionManager);
 
-        txPolicy.beforeInvoke(null, txContext);
+        TransactionPolicy txPolicy = createTransactionPolicy(deploymentInfo.getTransactionType(callMethod), callContext);
 
-        EntityBean bean = null;
+        EntityBean bean;
         Object returnValue = null;
         try {
             /*
@@ -550,24 +542,22 @@
             } finally {
                 unsetEntityContext(bean);
             }
+        } catch (Throwable e) {
+            if (e instanceof InvocationTargetException) {
+                e = ((InvocationTargetException) e).getTargetException();
+            }
 
-            bean = null; // poof
-
-        } catch (InvocationTargetException ite) {
-            ExceptionType type = callContext.getDeploymentInfo().getExceptionType(ite.getTargetException());
+            ExceptionType type = callContext.getDeploymentInfo().getExceptionType(e);
             if (type == ExceptionType.SYSTEM) {
                 /* System Exception ****************************/
-                txPolicy.handleSystemException(ite.getTargetException(), bean, txContext);
+                handleSystemException(txPolicy, e, callContext);
 
             } else {
                 /* Application Exception ***********************/
-                txPolicy.handleApplicationException(ite.getTargetException(), type == ExceptionType.APPLICATION_ROLLBACK, txContext);
+                handleApplicationException(txPolicy, e, type == ExceptionType.APPLICATION_ROLLBACK);
             }
-        } catch (Throwable e) {
-            /* System Exception ****************************/
-            txPolicy.handleSystemException(e, bean, txContext);
         } finally {
-            txPolicy.afterInvoke(bean, txContext);
+            afterInvoke(txPolicy, callContext);
         }
 
         return returnValue;
@@ -576,13 +566,10 @@
     private ProxyInfo createEJBObject(Method callMethod, Object[] args, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
 
-        EntityBean bean = null;
-        Object primaryKey = null;
-
-        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
-        TransactionContext txContext = new TransactionContext(callContext, transactionManager);
+        TransactionPolicy txPolicy = createTransactionPolicy(deploymentInfo.getTransactionType(callMethod), callContext);
 
-        txPolicy.beforeInvoke(bean, txContext);
+        EntityBean bean;
+        Object primaryKey = null;
 
         try {
             // Obtain a bean instance from the method ready pool
@@ -629,21 +616,21 @@
 
             // when there is not transaction, merge the data from the bean back into the cmp engine
             cmpEngine.storeBeanIfNoTx(callContext, bean);
-        } catch (InvocationTargetException ite) {// handle enterprise bean exceptions
-            ExceptionType type = callContext.getDeploymentInfo().getExceptionType(ite.getTargetException());
+        } catch (Throwable e) {
+            if (e instanceof InvocationTargetException) {
+                e = ((InvocationTargetException) e).getTargetException();
+            }
+
+            ExceptionType type = callContext.getDeploymentInfo().getExceptionType(e);
             if (type == ExceptionType.SYSTEM) {
                 /* System Exception ****************************/
-                txPolicy.handleSystemException(ite.getTargetException(), bean, txContext);
+                handleSystemException(txPolicy, e, callContext);
             } else {
                 /* Application Exception ***********************/
-                txPolicy.handleApplicationException(ite.getTargetException(), type == ExceptionType.APPLICATION_ROLLBACK, txContext);
+                handleApplicationException(txPolicy, e, type == ExceptionType.APPLICATION_ROLLBACK);
             }
-        } catch (CreateException e) {
-            txPolicy.handleSystemException(e, bean, txContext);
-        } catch (Throwable e) {
-            txPolicy.handleSystemException(e, bean, txContext);
         } finally {
-            txPolicy.afterInvoke(bean, txContext);
+            afterInvoke(txPolicy, callContext);
         }
 
         return new ProxyInfo(deploymentInfo, primaryKey);
@@ -652,11 +639,8 @@
     private Object findByPrimaryKey(Method callMethod, Object[] args, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
 
-        // Get the transaction policy assigned to this method
-        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
-        TransactionContext txContext = new TransactionContext(callContext, transactionManager);
+        TransactionPolicy txPolicy = createTransactionPolicy(deploymentInfo.getTransactionType(callMethod), callContext);
 
-        txPolicy.beforeInvoke(null, txContext);
         try {
             EntityBean bean = (EntityBean) cmpEngine.loadBean(callContext, args[0]);
             if (bean == null) {
@@ -670,11 +654,11 @@
             // create a new ProxyInfo based on the deployment info and primary key
             return new ProxyInfo(deploymentInfo, primaryKey);
         } catch (javax.ejb.FinderException fe) {
-            txPolicy.handleApplicationException(fe, false, txContext);
+            handleApplicationException(txPolicy, fe, false);
         } catch (Throwable e) {// handle reflection exception
-            txPolicy.handleSystemException(e, null, txContext);
+            handleSystemException(txPolicy, e, callContext);
         } finally {
-            txPolicy.afterInvoke(null, txContext);
+            afterInvoke(txPolicy, callContext);
         }
         throw new AssertionError("Should not get here");
     }
@@ -682,11 +666,8 @@
     private Object findEJBObject(Method callMethod, Object[] args, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
 
-        // Get the transaction policy assigned to this method
-        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
-        TransactionContext txContext = new TransactionContext(callContext, transactionManager);
+        TransactionPolicy txPolicy = createTransactionPolicy(deploymentInfo.getTransactionType(callMethod), callContext);
 
-        txPolicy.beforeInvoke(null, txContext);
         try {
             List<Object> results = cmpEngine.queryBeans(callContext, callMethod, args);
 
@@ -731,11 +712,11 @@
                 }
             }
         } catch (javax.ejb.FinderException fe) {
-            txPolicy.handleApplicationException(fe, false, txContext);
+            handleApplicationException(txPolicy, fe, false);
         } catch (Throwable e) {// handle reflection exception
-            txPolicy.handleSystemException(e, null, txContext);
+            handleSystemException(txPolicy, e, callContext);
         } finally {
-            txPolicy.afterInvoke(null, txContext);
+            afterInvoke(txPolicy, callContext);
         }
         throw new AssertionError("Should not get here");
     }
@@ -820,10 +801,9 @@
 
     private void removeEJBObject(Method callMethod, ThreadContext callContext) throws OpenEJBException {
         CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-        TransactionContext txContext = new TransactionContext(callContext, transactionManager);
-        TransactionPolicy txPolicy = deploymentInfo.getTransactionPolicy(callMethod);
 
-        txPolicy.beforeInvoke(null, txContext);
+        TransactionPolicy txPolicy = createTransactionPolicy(deploymentInfo.getTransactionType(callMethod), callContext);
+
         try {
             EntityBean entityBean = (EntityBean) cmpEngine.loadBean(callContext, callContext.getPrimaryKey());
             if (entityBean == null) {
@@ -832,11 +812,11 @@
             ejbRemove(entityBean);
             cmpEngine.removeBean(callContext);
         } catch (NoSuchObjectException e) {
-            txPolicy.handleApplicationException(e, false, txContext);
+            handleApplicationException(txPolicy, e, false);
         } catch (Throwable e) {// handle reflection exception
-            txPolicy.handleSystemException(e, null, txContext);
+            handleSystemException(txPolicy, e, callContext);
         } finally {
-            txPolicy.afterInvoke(null, txContext);
+            afterInvoke(txPolicy, callContext);
         }
     }
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngine.java Sun Aug 24 19:39:06 2008
@@ -17,6 +17,22 @@
  */
 package org.apache.openejb.core.cmp.jpa;
 
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.ejb.CreateException;
+import javax.ejb.EJBException;
+import javax.ejb.EJBLocalObject;
+import javax.ejb.EJBObject;
+import javax.ejb.EntityBean;
+import javax.ejb.FinderException;
+import javax.ejb.RemoveException;
+import javax.naming.NamingException;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceException;
+import javax.persistence.Query;
+
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.ThreadContext;
@@ -27,31 +43,14 @@
 import org.apache.openejb.core.cmp.SimpleKeyGenerator;
 import org.apache.openejb.core.cmp.cmp2.Cmp2KeyGenerator;
 import org.apache.openejb.core.cmp.cmp2.Cmp2Util;
+import org.apache.openejb.core.transaction.TransactionType;
+import org.apache.openejb.core.transaction.TransactionPolicy;
+import static org.apache.openejb.core.transaction.EjbTransactionUtil.afterInvoke;
+import static org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy;
 import org.apache.openjpa.event.AbstractLifecycleListener;
 import org.apache.openjpa.event.LifecycleEvent;
-import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
-
-import javax.ejb.CreateException;
-import javax.ejb.EJBException;
-import javax.ejb.EJBLocalObject;
-import javax.ejb.EJBObject;
-import javax.ejb.EntityBean;
-import javax.ejb.FinderException;
-import javax.ejb.RemoveException;
-import javax.naming.NamingException;
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceException;
-import javax.persistence.Query;
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
 
 public class JpaCmpEngine implements CmpEngine {
     private static final Object[] NO_ARGS = new Object[0];
@@ -62,9 +61,6 @@
      */
     private final CmpCallback cmpCallback;
 
-    private final TransactionManager transactionManager;
-    private final TransactionSynchronizationRegistry synchronizationRegistry;
-
     /**
      * Thread local to track the beans we are creating to avoid an extra ejbStore callback
      */
@@ -79,10 +75,8 @@
      */
     protected Object entityManagerListener;
 
-    public JpaCmpEngine(CmpCallback cmpCallback, TransactionManager transactionManager, TransactionSynchronizationRegistry synchronizationRegistry) {
+    public JpaCmpEngine(CmpCallback cmpCallback) {
         this.cmpCallback = cmpCallback;
-        this.transactionManager = transactionManager;
-        this.synchronizationRegistry = synchronizationRegistry;
     }
 
     public synchronized void deploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
@@ -129,7 +123,7 @@
 
     public Object createBean(EntityBean bean, ThreadContext callContext) throws CreateException {
         // TODO verify that extract primary key requires a flush followed by a merge
-        boolean startedTx = startTransaction("persist");
+        TransactionPolicy txPolicy = startTransaction("persist", callContext);
         creating.get().add(bean);
         try {
             CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
@@ -146,12 +140,12 @@
             return primaryKey;
         } finally {
             creating.get().remove(bean);
-            commitTransaction(startedTx, "persist");
+            commitTransaction("persist", callContext, txPolicy);
         }
     }
 
     public Object loadBean(ThreadContext callContext, Object primaryKey) {
-        boolean startedTx = startTransaction("load");
+        TransactionPolicy txPolicy = startTransaction("load", callContext);
         try {
             CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
             Class<?> beanClass = deploymentInfo.getCmpImplClass();
@@ -160,26 +154,30 @@
             EntityManager entityManager = getEntityManager(deploymentInfo);
             return entityManager.find(beanClass, primaryKey);
         } finally {
-            commitTransaction(startedTx, "load");
+            commitTransaction("load", callContext, txPolicy);
         }
     }
 
     public void storeBeanIfNoTx(ThreadContext callContext, Object bean) {
-        boolean startedTx = startTransaction("store");
-        if (startedTx) {
-            CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
+        TransactionPolicy callerTxPolicy = callContext.getTransactionPolicy();
+        if (callerTxPolicy != null && callerTxPolicy.isTransactionActive()) {
+            return;
+        }
 
-            try {
-                EntityManager entityManager = getEntityManager(deploymentInfo);
+        TransactionPolicy txPolicy = startTransaction("store", callContext);
+        try {
+            // only store if we started a new transaction
+            if (txPolicy.isNewTransaction()) {
+                EntityManager entityManager = getEntityManager(callContext.getDeploymentInfo());
                 entityManager.merge(bean);
-            } finally {
-                commitTransaction(startedTx, "store");
             }
+        } finally {
+            commitTransaction("store", callContext, txPolicy);
         }
     }
 
     public void removeBean(ThreadContext callContext) {
-        boolean startedTx = startTransaction("remove");
+        TransactionPolicy txPolicy = startTransaction("remove", callContext);
         try {
             CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
             Class<?> beanClass = deploymentInfo.getCmpImplClass();
@@ -192,7 +190,7 @@
             // remove the bean
             entityManager.remove(bean);
         } finally {
-            commitTransaction(startedTx, "remove");
+            commitTransaction("remove", callContext, txPolicy);
         }
     }
 
@@ -320,23 +318,18 @@
         }
     }
 
-    private boolean startTransaction(String operation) {
+    private TransactionPolicy startTransaction(String operation, ThreadContext callContext) {
         try {
-            if (Status.STATUS_NO_TRANSACTION == transactionManager.getStatus()) {
-                transactionManager.begin();
-                return true;
-            }
-            return false;
+            TransactionPolicy txPolicy = createTransactionPolicy(TransactionType.Required, callContext);
+            return txPolicy;
         } catch (Exception e) {
             throw new EJBException("Unable to start transaction for " + operation + " operation", e);
         }
     }
 
-    private void commitTransaction(boolean startedTx, String operation) {
+    private void commitTransaction(String operation, ThreadContext callContext, TransactionPolicy txPolicy) {
         try {
-            if (startedTx) {
-                transactionManager.commit();
-            }
+            afterInvoke(txPolicy, callContext);
         } catch (Exception e) {
             throw new EJBException("Unable to complete transaction for " + operation + " operation", e);
         }
@@ -358,31 +351,6 @@
         }
     }
 
-    private static class TransactionCache {
-        private final Map<Class,Map<Object,Object>> cache = new HashMap<Class,Map<Object,Object>>();
-
-        public Object get(Class clazz, Object primaryKey) {
-            Map<Object, Object> instances = cache.get(clazz);
-            if (instances == null) return null;
-            return instances.get(primaryKey);
-        }
-
-        public void put(Class clazz, Object primaryKey, Object value) {
-            Map<Object, Object> instances = cache.get(clazz);
-            if (instances == null) {
-                instances = new HashMap<Object, Object>();
-                cache.put(clazz, instances);
-            }
-            instances.put(primaryKey, value);
-        }
-
-        public Object remove(Class clazz, Object primaryKey) {
-            Map<Object, Object> instances = cache.get(clazz);
-            if (instances == null) return null;
-            return instances.remove(primaryKey);
-        }
-    }
-
     private class OpenJPALifecycleListener extends AbstractLifecycleListener {
 //        protected void eventOccurred(LifecycleEvent event) {
 //            int type = event.getType();

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/cmp/jpa/JpaCmpEngineFactory.java Sun Aug 24 19:39:06 2008
@@ -55,6 +55,6 @@
     }
 
     public CmpEngine create() throws OpenEJBException {
-        return new JpaCmpEngine(cmpCallback, transactionManager, transactionSynchronizationRegistry);
+        return new JpaCmpEngine(cmpCallback);
     }
 }