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 [5/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...
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml Sun Aug 24 19:39:06 2008
@@ -61,7 +61,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
@@ -82,7 +82,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
@@ -124,7 +124,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
@@ -141,7 +141,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
@@ -186,7 +186,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/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java Sun Aug 24 19:39:06 2008
@@ -17,17 +17,11 @@
*/
package org.apache.openejb.core.stateful;
-import junit.framework.TestCase;
-import org.apache.openejb.assembler.classic.Assembler;
-import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
-import org.apache.openejb.assembler.classic.SecurityServiceInfo;
-import org.apache.openejb.assembler.classic.StatefulSessionContainerInfo;
-import org.apache.openejb.assembler.classic.TransactionServiceInfo;
-import org.apache.openejb.config.ConfigurationFactory;
-import org.apache.openejb.core.ivm.naming.InitContextFactory;
-import org.apache.openejb.jee.EjbJar;
-import org.apache.openejb.jee.StatefulBean;
-
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Stack;
+import java.util.ArrayList;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
@@ -38,18 +32,42 @@
import javax.ejb.Remove;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Stack;
-import java.util.ArrayList;
+import javax.transaction.TransactionManager;
+
+import junit.framework.TestCase;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.StatefulSessionContainerInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.core.ivm.naming.InitContextFactory;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatefulBean;
+import org.apache.openejb.loader.SystemInstance;
/**
* @version $Revision$ $Date$
*/
public class StatefulContainerTest extends TestCase {
+ private List<Lifecycle> inTxExpectedLifecycle;
+ private List expectedLifecycle;
public void testBusinessLocalInterface() throws Exception {
+ testBusinessLocalInterface(expectedLifecycle);
+ }
+
+ public void testBusinessRemoteInterfaceInTx() throws Exception {
+ TransactionManager transactionManager = SystemInstance.get().getComponent(TransactionManager.class);
+ transactionManager.begin();
+ try {
+ testBusinessRemoteInterface(inTxExpectedLifecycle);
+ } finally {
+ transactionManager.commit();
+ }
+ }
+
+ protected void testBusinessLocalInterface(List expectedLifecycle) throws Exception {
// Do a create...
@@ -61,19 +79,42 @@
Widget widget = (Widget) object;
// Do a business method...
- Stack<Lifecycle> lifecycle = widget.getLifecycle();
- assertNotNull("lifecycle",lifecycle);
+ Stack<Object> actual = widget.getLifecycle();
+ assertNotNull("lifecycle", actual);
+
+ // test app exception
+ try {
+ widget.throwAppException();
+ fail("Expected application exception");
+ } catch (SQLException e) {
+ assertEquals("test", e.getMessage());
+ }
+
+ // Do another business method...
+ widget.afterAppException();
// Do a remove...
widget.destroy();
// Check the lifecycle of the bean
- List expected = Arrays.asList(StatefulContainerTest.Lifecycle.values());
-
- assertEquals(StatefulContainerTest.join("\n", expected) , join("\n", WidgetBean.lifecycle));
+ assertEquals(StatefulContainerTest.join("\n", expectedLifecycle) , join("\n", WidgetBean.lifecycle));
}
public void testBusinessRemoteInterface() throws Exception {
+ testBusinessRemoteInterface(expectedLifecycle);
+ }
+
+ public void testBusinessLocalInterfaceInTx() throws Exception {
+ TransactionManager transactionManager = SystemInstance.get().getComponent(TransactionManager.class);
+ transactionManager.begin();
+ try {
+ testBusinessLocalInterface(inTxExpectedLifecycle);
+ } finally {
+ transactionManager.commit();
+ }
+ }
+
+ protected void testBusinessRemoteInterface(List expectedLifecycle) throws Exception {
WidgetBean.lifecycle.clear();
// Do a create...
@@ -86,10 +127,21 @@
RemoteWidget widget = (RemoteWidget) object;
// Do a business method...
- Stack<Lifecycle> lifecycle = widget.getLifecycle();
+ Stack<Object> lifecycle = widget.getLifecycle();
assertNotNull("lifecycle",lifecycle);
assertNotSame("is copy", lifecycle, WidgetBean.lifecycle);
+ // test app exception
+ try {
+ widget.throwAppException();
+ fail("Expected application exception");
+ } catch (SQLException e) {
+ assertEquals("test", e.getMessage());
+ }
+
+ // Do another business method...
+ widget.afterAppException();
+
// Do a remove...
widget.destroy();
@@ -100,9 +152,7 @@
}
// Check the lifecycle of the bean
- List expected = Arrays.asList(StatefulContainerTest.Lifecycle.values());
-
- assertEquals(StatefulContainerTest.join("\n", expected) , join("\n", WidgetBean.lifecycle));
+ assertEquals(StatefulContainerTest.join("\n", expectedLifecycle) , join("\n", WidgetBean.lifecycle));
}
protected void setUp() throws Exception {
@@ -132,6 +182,14 @@
WidgetBean.lifecycle.clear();
+ expectedLifecycle = Arrays.asList(Lifecycle.values());
+ inTxExpectedLifecycle = new ArrayList<Lifecycle>();
+ for (Lifecycle lifecycle : Lifecycle.values()) {
+ if (!lifecycle.name().startsWith("PRE_PASSIVATE") &&
+ !lifecycle.name().startsWith("POST_ACTIVATE")) {
+ inTxExpectedLifecycle.add(lifecycle);
+ }
+ }
}
private static String join(String delimeter, List items){
@@ -144,7 +202,9 @@
@Local
public static interface Widget {
- Stack<Lifecycle> getLifecycle();
+ Stack<Object> getLifecycle();
+ void throwAppException() throws SQLException;
+ void afterAppException();
void destroy();
}
@@ -154,39 +214,63 @@
}
public static enum Lifecycle {
- CONSTRUCTOR, INJECTION, POST_CONSTRUCT, PRE_PASSIVATE1, POST_ACTIVATE1, BUSINESS_METHOD, PRE_PASSIVATE2, POST_ACTIVATE2,REMOVE, PRE_DESTROY,
+ // construction
+ CONSTRUCTOR, INJECTION, POST_CONSTRUCT, PRE_PASSIVATE1,
+ // business method
+ POST_ACTIVATE1, BUSINESS_METHOD, PRE_PASSIVATE2,
+ // throw app exception
+ POST_ACTIVATE2, PRE_PASSIVATE3,
+ // business method after app exception
+ POST_ACTIVATE3, PRE_PASSIVATE4,
+ // remove
+ POST_ACTIVATE4, REMOVE, PRE_DESTROY,
}
public static class WidgetBean implements Widget, RemoteWidget {
- private static final long serialVersionUID = -8499745487520955081L;
-
private int activates = 0;
private int passivates = 0;
- public static Stack<Lifecycle> lifecycle = new Stack<Lifecycle>();
+ public static Stack<Object> lifecycle = new Stack<Object>();
public WidgetBean() {
lifecycle.push(Lifecycle.CONSTRUCTOR);
}
+ public void throwAppException() throws SQLException {
+ throw new SQLException("test");
+ }
+
+ public void afterAppException() {
+ }
+
@Resource
public void setContext(SessionContext context){
lifecycle.push(Lifecycle.INJECTION);
}
- public Stack<Lifecycle> getLifecycle() {
+ public Stack<Object> getLifecycle() {
lifecycle.push(Lifecycle.BUSINESS_METHOD);
return lifecycle;
}
@PostActivate
public void activate(){
- lifecycle.push(Enum.valueOf(Lifecycle.class, "POST_ACTIVATE" + (++activates)));
+ String name = "POST_ACTIVATE" + (++activates);
+ try {
+ lifecycle.push(Enum.valueOf(Lifecycle.class, name));
+ } catch (Exception e) {
+ lifecycle.push(name);
+ }
}
@PrePassivate
public void passivate(){
- lifecycle.push(Enum.valueOf(Lifecycle.class, "PRE_PASSIVATE" + (++passivates)));
+ String name = "PRE_PASSIVATE" + (++passivates);
+ try {
+ lifecycle.push(Enum.valueOf(Lifecycle.class, name));
+ } catch (Exception e) {
+ lifecycle.push(name);
+ }
}
@PostConstruct
Modified: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulSecurityPermissionsTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulSecurityPermissionsTest.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulSecurityPermissionsTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulSecurityPermissionsTest.java Sun Aug 24 19:39:06 2008
@@ -16,63 +16,54 @@
*/
package org.apache.openejb.core.stateful;
+import java.rmi.RemoteException;
+import java.security.Permission;
+import java.security.Permissions;
+import java.security.Principal;
+import java.security.ProtectionDomain;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import javax.annotation.security.DenyAll;
+import javax.annotation.security.PermitAll;
+import javax.annotation.security.RolesAllowed;
+import javax.ejb.CreateException;
+import javax.ejb.EJBAccessException;
+import javax.ejb.EJBHome;
+import javax.ejb.EJBLocalHome;
+import javax.ejb.EJBLocalObject;
+import javax.ejb.EJBObject;
+import javax.ejb.Init;
+import javax.ejb.Local;
+import javax.ejb.LocalHome;
+import javax.ejb.Remote;
+import javax.ejb.RemoteHome;
+import javax.ejb.Remove;
+import javax.naming.InitialContext;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
import junit.framework.TestCase;
-import org.apache.openejb.core.ivm.naming.InitContextFactory;
-import org.apache.openejb.core.ThreadContext;
-import org.apache.openejb.core.security.jacc.BasicJaccProvider;
-import org.apache.openejb.core.security.jacc.BasicPolicyConfiguration;
-import org.apache.openejb.core.security.AbstractSecurityService;
-import org.apache.openejb.core.security.jaas.UserPrincipal;
-import org.apache.openejb.core.security.jaas.GroupPrincipal;
-import org.apache.openejb.core.transaction.TransactionPolicy;
import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
-import org.apache.openejb.assembler.classic.TransactionServiceInfo;
import org.apache.openejb.assembler.classic.SecurityServiceInfo;
-import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.core.ivm.naming.InitContextFactory;
+import org.apache.openejb.core.security.AbstractSecurityService;
+import org.apache.openejb.core.security.jaas.GroupPrincipal;
+import org.apache.openejb.core.security.jaas.UserPrincipal;
+import org.apache.openejb.core.security.jacc.BasicJaccProvider;
+import org.apache.openejb.core.security.jacc.BasicPolicyConfiguration;
import org.apache.openejb.jee.EjbJar;
-import org.apache.openejb.jee.StatefulBean;
-import org.apache.openejb.jee.ContainerTransaction;
-import org.apache.openejb.jee.TransAttribute;
-import org.apache.openejb.jee.MethodIntf;
import org.apache.openejb.jee.MethodPermission;
+import org.apache.openejb.jee.StatefulBean;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.spi.SecurityService;
-import javax.naming.InitialContext;
-import javax.ejb.LocalHome;
-import javax.ejb.RemoteHome;
-import javax.ejb.TransactionAttribute;
-import javax.ejb.TransactionAttributeType;
-import javax.ejb.Init;
-import javax.ejb.Remove;
-import javax.ejb.Local;
-import javax.ejb.Remote;
-import javax.ejb.EJBHome;
-import javax.ejb.CreateException;
-import javax.ejb.EJBObject;
-import javax.ejb.EJBLocalHome;
-import javax.ejb.EJBLocalObject;
-import javax.ejb.EJBAccessException;
-import javax.annotation.security.RolesAllowed;
-import javax.annotation.security.PermitAll;
-import javax.annotation.security.DenyAll;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.Subject;
-import javax.security.jacc.PolicyContextException;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.HashSet;
-import java.util.Collections;
-import java.rmi.RemoteException;
-import java.security.ProtectionDomain;
-import java.security.Permission;
-import java.security.Principal;
-import java.security.Permissions;
-import java.security.PermissionCollection;
-
/**
* @version $Rev$ $Date$
*/
Modified: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulTransactionAttributesTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulTransactionAttributesTest.java?rev=688602&r1=688601&r2=688602&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulTransactionAttributesTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulTransactionAttributesTest.java Sun Aug 24 19:39:06 2008
@@ -19,17 +19,14 @@
import junit.framework.TestCase;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.EjbJarInfo;
-import org.apache.openejb.assembler.classic.MethodAttributeInfo;
import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
import org.apache.openejb.assembler.classic.SecurityServiceInfo;
import org.apache.openejb.assembler.classic.TransactionServiceInfo;
import org.apache.openejb.config.ConfigurationFactory;
import org.apache.openejb.core.ThreadContext;
-import org.apache.openejb.core.transaction.TransactionPolicy;
import org.apache.openejb.core.ivm.naming.InitContextFactory;
import org.apache.openejb.jee.ContainerTransaction;
import org.apache.openejb.jee.EjbJar;
-import org.apache.openejb.jee.StatelessBean;
import org.apache.openejb.jee.TransAttribute;
import org.apache.openejb.jee.MethodIntf;
import org.apache.openejb.jee.StatefulBean;
@@ -48,10 +45,8 @@
import javax.ejb.Init;
import javax.ejb.Remove;
import javax.naming.InitialContext;
-import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.util.List;
-import java.util.Map;
/**
* @version $Rev$ $Date$
@@ -326,7 +321,7 @@
public String attribute() {
ThreadContext context = ThreadContext.getThreadContext();
- return context.get(TransactionPolicy.Type.class).toString();
+ return context.getTransactionPolicy().toString();
}
@Init
Added: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringBeanTransactionPolicy.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringBeanTransactionPolicy.java?rev=688602&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringBeanTransactionPolicy.java (added)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringBeanTransactionPolicy.java Sun Aug 24 19:39:06 2008
@@ -0,0 +1,245 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.spring;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.UserTransaction;
+import static javax.transaction.Status.STATUS_NO_TRANSACTION;
+import static javax.transaction.Status.STATUS_MARKED_ROLLBACK;
+import static javax.transaction.Status.STATUS_ACTIVE;
+
+import org.apache.openejb.SystemException;
+import org.apache.openejb.core.transaction.BeanTransactionPolicy;
+import org.apache.openejb.core.transaction.TransactionType;
+import org.springframework.transaction.HeuristicCompletionException;
+import org.springframework.transaction.NestedTransactionNotSupportedException;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionException;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.UnexpectedRollbackException;
+import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRES_NEW;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
+import org.springframework.transaction.support.DefaultTransactionStatus;
+
+public class SpringBeanTransactionPolicy extends SpringTransactionPolicy implements BeanTransactionPolicy {
+ private final UserTransaction userTransaction;
+ private DefaultTransactionStatus beanTransaction;
+ private int timeout;
+
+ public SpringBeanTransactionPolicy(PlatformTransactionManager transactionManager) {
+ super(transactionManager, TransactionType.BeanManaged);
+ userTransaction = new SpringUserTransaction();
+ }
+
+ protected DefaultTransactionStatus getTransactionStatus() {
+ return beanTransaction != null ? beanTransaction : super.getTransactionStatus();
+ }
+
+ public SuspendedTransaction suspendUserTransaction() throws SystemException {
+ throw new SystemException(new UnsupportedOperationException("SpringTransactionPolicy does not support transaction suspension"));
+ }
+
+ public void resumeUserTransaction(SuspendedTransaction suspendedTransaction) throws SystemException {
+ throw new SystemException(new UnsupportedOperationException("SpringTransactionPolicy does not support transaction resumption"));
+ }
+
+ public UserTransaction getUserTransaction() {
+ if (getTransactionStatus().isCompleted()) {
+ throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
+ }
+ return userTransaction;
+ }
+
+ private class SpringUserTransaction implements UserTransaction {
+ public int getStatus() {
+ if (getTransactionStatus().isCompleted() || beanTransaction == null) {
+ return STATUS_NO_TRANSACTION;
+ } else if (isRollbackOnly()) {
+ return STATUS_MARKED_ROLLBACK;
+ } else {
+ return STATUS_ACTIVE;
+ }
+ }
+
+ public void begin() throws NotSupportedException, javax.transaction.SystemException {
+ if (getTransactionStatus().isCompleted()) {
+ throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
+ }
+
+ if (beanTransaction != null) {
+ // we could support nested transactions
+ throw new NotSupportedException("Current thread is already associated with a transaction");
+ }
+
+ try {
+ // create transaction definition
+ DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
+ definition.setPropagationBehavior(PROPAGATION_REQUIRES_NEW);
+ if (timeout > 0) {
+ definition.setTimeout(timeout);
+ }
+
+ // start the transaction
+ TransactionStatus transactionStatus = transactionManager.getTransaction(definition);
+
+ // TransactionStatus must be a DefaultTransactionStatus so we can implement isTransactionActive()
+ if (!(transactionManager instanceof DefaultTransactionStatus)) {
+ transactionManager.rollback(transactionStatus);
+ throw new IllegalArgumentException("SpringBeanTransactionPolicy only works with a PlatformTransactionManager that uses DefaultTransactionStatus");
+ }
+ beanTransaction = (DefaultTransactionStatus) transactionStatus;
+ } catch (TransactionException e) {
+ // check if exception is simply wrapping a JTA exception
+ Throwable cause = e.getCause();
+ if (cause instanceof NotSupportedException) {
+ throw (NotSupportedException) cause;
+ } else if (cause instanceof javax.transaction.SystemException) {
+ throw (javax.transaction.SystemException) cause;
+ }
+
+ // convert to JTA exception
+ if (e instanceof NestedTransactionNotSupportedException) {
+ throw createJtaException(NotSupportedException.class, e);
+ }
+ throw createJtaException(javax.transaction.SystemException.class, e);
+ }
+ }
+
+ public void commit() throws HeuristicMixedException, HeuristicRollbackException, IllegalStateException, RollbackException, SecurityException, javax.transaction.SystemException {
+ if (getTransactionStatus().isCompleted()) {
+ throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
+ }
+
+ if (beanTransaction == null) {
+ throw new IllegalStateException("Current thread is not associated with a transaction");
+ }
+
+ try {
+ transactionManager.commit(beanTransaction);
+ } catch (TransactionException e) {
+ // check if exception is simply wrapping a JTA exception
+ Throwable cause = e.getCause();
+ if (cause instanceof HeuristicMixedException) {
+ throw (HeuristicMixedException) cause;
+ } else if (cause instanceof HeuristicRollbackException) {
+ throw (HeuristicRollbackException) cause;
+ } else if (cause instanceof IllegalStateException) {
+ throw (IllegalStateException) cause;
+ } else if (cause instanceof RollbackException) {
+ throw (RollbackException) cause;
+ } else if (cause instanceof SecurityException) {
+ throw (SecurityException) cause;
+ } else if (cause instanceof javax.transaction.SystemException) {
+ throw (javax.transaction.SystemException) cause;
+ }
+
+ // convert to JTA exception
+ if (e instanceof HeuristicCompletionException) {
+ HeuristicCompletionException heuristicCompletionException = (HeuristicCompletionException) e;
+ if (heuristicCompletionException.getOutcomeState() == HeuristicCompletionException.STATE_MIXED) {
+ throw createJtaException(HeuristicMixedException.class, e);
+ } else if (heuristicCompletionException.getOutcomeState() == HeuristicCompletionException.STATE_ROLLED_BACK) {
+ throw createJtaException(HeuristicRollbackException.class, e);
+ }
+ } else if (e instanceof UnexpectedRollbackException) {
+ throw createJtaException(RollbackException.class, e);
+ }
+ throw createJtaException(javax.transaction.SystemException.class, e);
+ }
+ }
+
+ public void rollback() throws IllegalStateException, javax.transaction.SystemException {
+ if (getTransactionStatus().isCompleted()) {
+ throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
+ }
+
+ if (beanTransaction == null) {
+ throw new IllegalStateException("Current thread is not associated with a transaction");
+ }
+
+ try {
+ transactionManager.rollback(beanTransaction);
+ } catch (TransactionException e) {
+ // check if exception is simply wrapping a JTA exception
+ Throwable cause = e.getCause();
+ if (cause instanceof IllegalStateException) {
+ throw (IllegalStateException) cause;
+ } else if (cause instanceof SecurityException) {
+ throw (SecurityException) cause;
+ } else if (cause instanceof javax.transaction.SystemException) {
+ throw (javax.transaction.SystemException) cause;
+ }
+
+ // convert to JTA exception
+ throw createJtaException(javax.transaction.SystemException.class, e);
+ }
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, javax.transaction.SystemException {
+ if (getTransactionStatus().isCompleted()) {
+ throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
+ }
+
+ if (beanTransaction == null) {
+ throw new IllegalStateException("Current thread is not associated with a transaction");
+ }
+
+ try {
+ beanTransaction.setRollbackOnly();
+ } catch (Exception e) {
+ // check if exception is simply wrapping a JTA exception
+ Throwable cause = e.getCause();
+ if (cause instanceof IllegalStateException) {
+ throw (IllegalStateException) cause;
+ } else if (cause instanceof javax.transaction.SystemException) {
+ throw (javax.transaction.SystemException) cause;
+ }
+
+ // convert to JTA exception
+ throw createJtaException(javax.transaction.SystemException.class, e);
+ }
+ }
+
+ public void setTransactionTimeout(int timeout) throws javax.transaction.SystemException {
+ if (getTransactionStatus().isCompleted()) {
+ throw new IllegalStateException("SpringBeanTransactionPolicy transaction has been completed");
+ }
+
+ if (timeout < 0) {
+ throw new javax.transaction.SystemException("timeout is negative");
+ }
+ SpringBeanTransactionPolicy.this.timeout = timeout;
+ }
+
+ private <T extends Exception> T createJtaException(Class<T> type, Throwable cause) throws javax.transaction.SystemException {
+ T exception;
+ try {
+ exception = type.getConstructor(String.class).newInstance("Spring PlatformTransactionManager threw an exception");
+ } catch (Exception e) {
+ javax.transaction.SystemException systemException = new javax.transaction.SystemException("Spring PlatformTransactionManager threw an exception");
+ systemException.initCause(cause);
+ throw systemException;
+ }
+ exception.initCause(cause);
+ return exception;
+ }
+ }
+}
Added: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicy.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicy.java?rev=688602&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicy.java (added)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicy.java Sun Aug 24 19:39:06 2008
@@ -0,0 +1,172 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.spring;
+
+import javax.transaction.RollbackException;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.xa.XAResource;
+
+import org.apache.openejb.core.transaction.TransactionPolicy;
+import org.apache.openejb.core.transaction.TransactionType;
+import org.apache.openejb.core.transaction.TransactionPolicy.TransactionSynchronization.Status;
+import org.apache.openejb.ApplicationException;
+import org.apache.openejb.SystemException;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.TransactionException;
+import org.springframework.transaction.HeuristicCompletionException;
+import org.springframework.transaction.UnexpectedRollbackException;
+import org.springframework.transaction.support.DefaultTransactionStatus;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+import org.springframework.transaction.support.TransactionSynchronizationAdapter;
+
+public class SpringTransactionPolicy implements TransactionPolicy {
+ protected final PlatformTransactionManager transactionManager;
+ protected final TransactionType type;
+ private final DefaultTransactionStatus transactionStatus;
+
+ public SpringTransactionPolicy(PlatformTransactionManager transactionManager, TransactionType type) {
+ this.transactionManager = transactionManager;
+ this.type = type;
+
+ DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
+ switch (type) {
+ case BeanManaged:
+ transactionDefinition.setPropagationBehavior(org.springframework.transaction.TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
+ break;
+ case Mandatory:
+ transactionDefinition.setPropagationBehavior(org.springframework.transaction.TransactionDefinition.PROPAGATION_MANDATORY);
+ break;
+ case Never:
+ transactionDefinition.setPropagationBehavior(org.springframework.transaction.TransactionDefinition.PROPAGATION_NEVER);
+ break;
+ case NotSupported:
+ transactionDefinition.setPropagationBehavior(org.springframework.transaction.TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
+ break;
+ case Required:
+ transactionDefinition.setPropagationBehavior(org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRED);
+ break;
+ case RequiresNew:
+ transactionDefinition.setPropagationBehavior(org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRES_NEW);
+ break;
+ case Supports:
+ transactionDefinition.setPropagationBehavior(org.springframework.transaction.TransactionDefinition.PROPAGATION_SUPPORTS);
+ break;
+ }
+
+ TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
+ if (!(transactionManager instanceof DefaultTransactionStatus)) {
+ throw new IllegalArgumentException("SpringTransactionPolicy only works with a PlatformTransactionManager that uses DefaultTransactionStatus");
+ }
+ this.transactionStatus = (DefaultTransactionStatus) transactionStatus;
+ }
+
+ public TransactionType getTransactionType() {
+ return type;
+ }
+
+ public boolean isNewTransaction() {
+ return getTransactionStatus().isNewTransaction();
+ }
+
+ public boolean isTransactionActive() {
+ return !getTransactionStatus().isCompleted() && getTransactionStatus().hasTransaction();
+ }
+
+ public boolean isRollbackOnly() {
+ return getTransactionStatus().isRollbackOnly();
+ }
+
+ public void setRollbackOnly() {
+ getTransactionStatus().setRollbackOnly();
+ }
+
+ public void commit() throws ApplicationException, SystemException {
+ try {
+ transactionManager.commit(getTransactionStatus());
+ } catch (TransactionException e) {
+ // check if exception is simply wrapping a supported JTA exception
+ Throwable cause = e.getCause();
+ if (cause instanceof RollbackException) {
+ throw new ApplicationException(cause);
+ } else if (cause instanceof HeuristicMixedException) {
+ throw new ApplicationException(cause);
+ } else if (cause instanceof HeuristicRollbackException) {
+ throw new ApplicationException(cause);
+ } else if (cause instanceof IllegalStateException) {
+ throw new SystemException(cause);
+ } else if (cause instanceof SecurityException) {
+ throw new SystemException(cause);
+ } else if (cause instanceof javax.transaction.SystemException) {
+ throw new SystemException(cause);
+ }
+
+ // wrap with application or system exception based on type
+ if (e instanceof HeuristicCompletionException) {
+ throw new ApplicationException(e);
+ } else if (e instanceof UnexpectedRollbackException) {
+ throw new ApplicationException(e);
+ }
+ throw new SystemException(e);
+ }
+ }
+
+ public Object getResource(Object key) {
+ Object resource = TransactionSynchronizationManager.getResource(key);
+ return resource;
+ }
+
+ public void putResource(Object key, Object value) {
+ TransactionSynchronizationManager.bindResource(key, value);
+ }
+
+ public Object removeResource(Object key) {
+ Object resource = TransactionSynchronizationManager.unbindResource(key);
+ return resource;
+ }
+
+ public void registerSynchronization(final TransactionSynchronization synchronization) {
+ TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
+ public void beforeCompletion() {
+ synchronization.beforeCompletion();
+ }
+
+ public void afterCompletion(int status) {
+ Status s = null;
+ if (status == STATUS_COMMITTED) {
+ s = Status.COMMITTED;
+ } else if (status == STATUS_ROLLED_BACK) {
+ s = Status.ROLLEDBACK;
+ } else if (status == STATUS_UNKNOWN) {
+ s = Status.UNKNOWN;
+ }
+ synchronization.afterCompletion(s);
+ }
+ });
+ }
+
+ public void enlistResource(XAResource xaResource) throws SystemException {
+ throw new SystemException(new UnsupportedOperationException("SpringTransactionPolicy does not support XAResource enlistment"));
+ }
+
+ protected DefaultTransactionStatus getTransactionStatus() {
+ return transactionStatus;
+ }
+}
Added: openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicyFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicyFactory.java?rev=688602&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicyFactory.java (added)
+++ openejb/trunk/openejb3/container/openejb-spring/src/main/java/org/apache/openejb/spring/SpringTransactionPolicyFactory.java Sun Aug 24 19:39:06 2008
@@ -0,0 +1,44 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.spring;
+
+import org.apache.openejb.core.transaction.TransactionPolicyFactory;
+import org.apache.openejb.core.transaction.TransactionPolicy;
+import org.apache.openejb.core.transaction.TransactionType;
+import org.apache.openejb.SystemException;
+import org.apache.openejb.ApplicationException;
+import org.springframework.transaction.PlatformTransactionManager;
+
+public class SpringTransactionPolicyFactory implements TransactionPolicyFactory {
+ private final PlatformTransactionManager transactionManager;
+
+ public SpringTransactionPolicyFactory(PlatformTransactionManager transactionManager) {
+ if (transactionManager == null) throw new NullPointerException("transactionManager is null");
+ this.transactionManager = transactionManager;
+ }
+
+ public TransactionPolicy createTransactionPolicy(TransactionType type) throws SystemException, ApplicationException {
+ SpringTransactionPolicy policy;
+ if (type == TransactionType.BeanManaged) {
+ policy = new SpringBeanTransactionPolicy(transactionManager);
+ } else {
+ policy = new SpringTransactionPolicy(transactionManager, type);
+ }
+ return policy;
+ }
+}