Author: timothyjward
Date: Wed Apr 13 16:31:07 2016
New Revision: 1738967

URL: http://svn.apache.org/viewvc?rev=1738967&view=rev
Log:
[tx-control] Initial support for XA transactions with EclipseLink and OpenJPA

Added:
    
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/openjpa/
    
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/openjpa/impl/
    
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/openjpa/impl/OpenJPATxControlPlatform.java
Modified:
    
aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleEclipseLink_2_6_0_Test.java
    aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml
    
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/eclipse/impl/EclipseTxControlPlatform.java
    
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java

Modified: 
aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleEclipseLink_2_6_0_Test.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleEclipseLink_2_6_0_Test.java?rev=1738967&r1=1738966&r2=1738967&view=diff
==============================================================================
--- 
aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleEclipseLink_2_6_0_Test.java
 (original)
+++ 
aries/trunk/tx-control/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleEclipseLink_2_6_0_Test.java
 Wed Apr 13 16:31:07 2016
@@ -26,7 +26,7 @@ public class SimpleEclipseLink_2_6_0_Tes
                                mavenBundle("org.eclipse.persistence", 
"org.eclipse.persistence.asm", "2.6.0"),
                                mavenBundle("org.eclipse.persistence", 
"org.eclipse.persistence.antlr", "2.6.0"),
                                mavenBundle("org.eclipse.persistence", 
"org.eclipse.persistence.jpa.jpql", "2.6.0"),
-                               mavenBundle("org.apache.aries.jpa", 
"org.apache.aries.jpa.eclipselink.adapter", "2.3.0"));
+                               mavenBundle("org.apache.aries.jpa", 
"org.apache.aries.jpa.eclipselink.adapter", "2.4.0-SNAPSHOT"));
        }
 
 }

Modified: aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml
URL: 
http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml?rev=1738967&r1=1738966&r2=1738967&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml (original)
+++ aries/trunk/tx-control/tx-control-provider-jpa-xa/pom.xml Wed Apr 13 
16:31:07 2016
@@ -66,11 +66,14 @@
                        !javassist.*,
                        !javax.transaction,
                        !org.apache.geronimo.osgi.registry.api,
+                       !org.apache.openjpa.*,
+                       !org.eclipse.*,
                        !org.hibernate.*,
                        javax.persistence;version="0.0.0",
                        javax.persistence.criteria;version="0.0.0",
                        javax.persistence.metamodel;version="0.0.0",
                        javax.persistence.spi;version="0.0.0",
+                       javax.transaction.xa;version="0.0.0",
                        
org.osgi.service.transaction.control;version="[0.0.1,0.0.2)",
                        
org.osgi.service.transaction.control.jpa;version="[0.0.1,0.0.2)",
                        org.osgi.service.cm,
@@ -99,12 +102,24 @@
                        <scope>provided</scope>
                </dependency>
                <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>org.eclipse.persistence.jpa</artifactId>
+                       <version>2.0.0</version>
+                       <scope>provided</scope>
+               </dependency>
+               <dependency>
                        <groupId>org.hibernate</groupId>
                        <artifactId>hibernate-core</artifactId>
                        <version>5.0.0.Final</version>
                        <scope>provided</scope>
                </dependency>
                <dependency>
+                       <groupId>org.apache.openjpa</groupId>
+                       <artifactId>openjpa-kernel</artifactId>
+                       <version>2.0.0</version>
+                       <scope>provided</scope>
+               </dependency>
+               <dependency>
                        <groupId>org.apache.aries.tx-control</groupId>
                        <artifactId>tx-control-provider-jdbc-common</artifactId>
                        <version>0.0.1-SNAPSHOT</version>

Modified: 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/eclipse/impl/EclipseTxControlPlatform.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/eclipse/impl/EclipseTxControlPlatform.java?rev=1738967&r1=1738966&r2=1738967&view=diff
==============================================================================
--- 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/eclipse/impl/EclipseTxControlPlatform.java
 (original)
+++ 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/eclipse/impl/EclipseTxControlPlatform.java
 Wed Apr 13 16:31:07 2016
@@ -1,13 +1,252 @@
-//package org.apache.aries.tx.control.jpa.xa.eclipse.impl;
-//
-//import org.eclipse.persistence.platform.server.ServerPlatformBase;
-//
-//public class EclipseTxControlPlatform extends ServerPlatformBase {
-//
-//     @Override
-//     public Class getExternalTransactionControllerClass() {
-//             // TODO Auto-generated method stub
-//             return null;
-//     }
-//
-//}
+package org.apache.aries.tx.control.jpa.xa.eclipse.impl;
+
+import static javax.transaction.Status.STATUS_ACTIVE;
+import static javax.transaction.Status.STATUS_COMMITTED;
+import static javax.transaction.Status.STATUS_COMMITTING;
+import static javax.transaction.Status.STATUS_MARKED_ROLLBACK;
+import static javax.transaction.Status.STATUS_NO_TRANSACTION;
+import static javax.transaction.Status.STATUS_PREPARING;
+import static javax.transaction.Status.STATUS_ROLLEDBACK;
+import static javax.transaction.Status.STATUS_ROLLING_BACK;
+import static javax.transaction.Status.STATUS_UNKNOWN;
+import static org.osgi.service.transaction.control.TransactionStatus.ACTIVE;
+import static org.osgi.service.transaction.control.TransactionStatus.COMMITTED;
+import static 
org.osgi.service.transaction.control.TransactionStatus.NO_TRANSACTION;
+import static org.osgi.service.transaction.control.TransactionStatus.PREPARING;
+import static 
org.osgi.service.transaction.control.TransactionStatus.ROLLED_BACK;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.xa.XAResource;
+
+import org.eclipse.persistence.internal.sessions.AbstractSession;
+import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
+import org.eclipse.persistence.platform.server.ServerPlatformBase;
+import org.eclipse.persistence.sessions.DatabaseSession;
+import org.eclipse.persistence.transaction.AbstractSynchronizationListener;
+import org.eclipse.persistence.transaction.AbstractTransactionController;
+import org.eclipse.persistence.transaction.SynchronizationListenerFactory;
+import org.osgi.service.transaction.control.TransactionContext;
+import org.osgi.service.transaction.control.TransactionControl;
+import org.osgi.service.transaction.control.TransactionException;
+import org.osgi.service.transaction.control.TransactionStatus;
+
+public class EclipseTxControlPlatform extends ServerPlatformBase {
+
+       public static void setTransactionControl(TransactionControl txControl) {
+               TxControlAdapter.txControl = txControl;
+       }
+       
+       public EclipseTxControlPlatform(DatabaseSession newDatabaseSession) {
+               super(newDatabaseSession);
+       }
+
+       @Override
+       public Class<?> getExternalTransactionControllerClass() {
+               return TxControlAdapter.class;
+       }
+
+       public static class TxControlAdapter extends 
AbstractTransactionController {
+
+               /**
+                *  This has to be static because EclipseLink doesn't allow 
plugins
+                *  to be configured and passed in as instances. It is safe 
because
+                *  we use a separate ClassLoader every time we create the 
resource.
+                */
+               private static TransactionControl txControl;
+               
+               public TxControlAdapter() {
+                       this.listenerFactory = new TxControlListenerFactory();
+               }
+               
+               @Override
+               public boolean isRolledBack_impl(Object status) {
+                       return status == ROLLED_BACK;
+               }
+
+               @Override
+               protected void 
registerSynchronization_impl(AbstractSynchronizationListener listener, Object 
txn)
+                               throws Exception {
+                       TransactionContext ctx = ((TransactionWrapper) 
txn).getContext();
+                       ctx.preCompletion(listener::beforeCompletion);
+                       ctx.postCompletion(listener::afterCompletion);
+               }
+
+               @Override
+               protected Object getTransaction_impl() throws Exception {
+                       TransactionContext currentContext = 
txControl.getCurrentContext();
+                       if(currentContext == null || 
currentContext.getTransactionStatus() == NO_TRANSACTION) {
+                               return null;
+                       } else {
+                               return new TransactionWrapper(currentContext);
+                       }
+               }
+
+               @Override
+               protected Object getTransactionKey_impl(Object transaction) 
throws Exception {
+                       
+                       return transaction == null ? null :
+                               ((TransactionWrapper) 
transaction).getContext().getTransactionKey();
+               }
+
+               @Override
+               protected Object getTransactionStatus_impl() throws Exception {
+                       TransactionContext currentContext = 
txControl.getCurrentContext();
+                       return currentContext == null ? null : 
currentContext.getTransactionStatus();
+               }
+
+               @Override
+               protected void beginTransaction_impl() throws Exception {
+                       throw new TransactionException("Open scoped 
transactions are not supported");
+               }
+
+               @Override
+               protected void commitTransaction_impl() throws Exception {
+                       throw new TransactionException("Open scoped 
transactions are not supported");
+               }
+
+               @Override
+               protected void rollbackTransaction_impl() throws Exception {
+                       throw new TransactionException("Open scoped 
transactions are not supported");
+               }
+
+               @Override
+               protected void markTransactionForRollback_impl() throws 
Exception {
+                       txControl.setRollbackOnly();
+               }
+
+               @Override
+               protected boolean canBeginTransaction_impl(Object status) {
+                       return false;
+               }
+
+               @Override
+               protected boolean canCommitTransaction_impl(Object status) {
+                       return false;
+               }
+
+               @Override
+               protected boolean canRollbackTransaction_impl(Object status) {
+                       return false;
+               }
+
+               @Override
+               protected boolean canIssueSQLToDatabase_impl(Object status) {
+                       return status == ACTIVE || status == PREPARING;
+               }
+
+               @Override
+               protected boolean canMergeUnitOfWork_impl(Object status) {
+                       return status == COMMITTED;
+               }
+
+               @Override
+               protected String statusToString_impl(Object status) {
+                       return status == null ? "No scope is active" : 
status.toString();
+               }
+       }
+       
+       /** 
+        * We have to do this as despite its claims, EclipseLink JPA needs the
+        * transaction impl to be a javax.tranasaction.Transaction :(
+        */
+       private static class TransactionWrapper implements Transaction {
+               private final TransactionContext context;
+
+               public TransactionWrapper(TransactionContext context) {
+                       this.context = context;
+               }
+
+               public TransactionContext getContext() {
+                       return context;
+               }
+               
+               @Override
+               public void registerSynchronization(Synchronization synch)
+                               throws IllegalStateException, 
RollbackException, SystemException {
+                       context.preCompletion(synch::beforeCompletion);
+                       context.postCompletion(status -> 
synch.afterCompletion(toIntStatus(status)));
+               }
+
+               @Override
+               public void setRollbackOnly() throws IllegalStateException, 
SystemException {
+                       context.setRollbackOnly();
+               }
+
+               @Override
+               public boolean delistResource(XAResource xaRes, int flag) 
throws IllegalStateException, SystemException {
+                       throw new TransactionException("Resources may not be 
delisted");
+               }
+
+               @Override
+               public boolean enlistResource(XAResource xaRes)
+                               throws IllegalStateException, 
RollbackException, SystemException {
+                       context.registerXAResource(xaRes);
+                       return true;
+               }
+
+               @Override
+               public int getStatus() throws SystemException {
+                       return toIntStatus(context.getTransactionStatus());
+               }
+               
+               private int toIntStatus(TransactionStatus status) {
+                       switch(status) {
+                               case NO_TRANSACTION:
+                                       return STATUS_NO_TRANSACTION;
+                               case ACTIVE:
+                                       return STATUS_ACTIVE;
+                               case PREPARING:
+                                       return STATUS_PREPARING;
+                               case PREPARED:
+                                       return Status.STATUS_PREPARED;
+                               case COMMITTING:
+                                       return STATUS_COMMITTING;
+                               case COMMITTED:
+                                       return STATUS_COMMITTED;
+                               case MARKED_ROLLBACK:
+                                       return STATUS_MARKED_ROLLBACK;
+                               case ROLLING_BACK:
+                                       return STATUS_ROLLING_BACK;
+                               case ROLLED_BACK:
+                                       return STATUS_ROLLEDBACK;
+                               default:
+                                       return STATUS_UNKNOWN;
+                       }
+               }
+
+               @Override
+               public void commit() throws HeuristicMixedException, 
HeuristicRollbackException, RollbackException,
+                               SecurityException, SystemException {
+                       throw new TransactionException("Open scoped 
transactions are not supported");
+               }
+
+               @Override
+               public void rollback() throws IllegalStateException, 
SystemException {
+                       throw new TransactionException("Open scoped 
transactions are not supported");
+               }
+       }
+       
+       public static class TxControlListenerFactory implements 
SynchronizationListenerFactory {
+
+               @Override
+               public AbstractSynchronizationListener 
newSynchronizationListener(UnitOfWorkImpl unitOfWork,
+                               AbstractSession session, Object transaction, 
AbstractTransactionController controller) {
+                       return new TxControlListener(unitOfWork, session, 
transaction, controller);
+               }
+               
+       }
+       
+       public static class TxControlListener extends 
AbstractSynchronizationListener {
+
+               public TxControlListener(UnitOfWorkImpl unitOfWork, 
AbstractSession session, Object transaction,
+                               AbstractTransactionController controller) {
+                       super(unitOfWork, session, transaction, controller);
+               }
+       }
+}

Modified: 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java?rev=1738967&r1=1738966&r2=1738967&view=diff
==============================================================================
--- 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java
 (original)
+++ 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/ManagedJPAEMFLocator.java
 Wed Apr 13 16:31:07 2016
@@ -13,6 +13,8 @@ import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicReference;
 
 import javax.persistence.spi.PersistenceProvider;
@@ -93,12 +95,13 @@ public class ManagedJPAEMFLocator implem
                        try {
                                JPAEntityManagerProvider jpaEM = new 
DelayedJPAEntityManagerProvider(t -> {
                                        
-                                       Map<String, Object> props = new 
HashMap<String, Object>(jpaProperties);
+                                       Map<String, Object> jpaProps = new 
HashMap<String, Object>(jpaProperties);
+                                       Map<String, Object> providerProps = new 
HashMap<String, Object>(providerProperties);
                                        
-                                       setupTransactionManager(props, t, 
reference);
+                                       setupTransactionManager(jpaProps, 
providerProps, t, reference);
                                        
                                        return new 
JPAEntityManagerProviderFactoryImpl().getProviderFor(service,
-                                                       props, 
providerProperties);
+                                                       jpaProps, 
providerProps);
                                });
                                ServiceRegistration<JPAEntityManagerProvider> 
reg = context
                                                
.registerService(JPAEntityManagerProvider.class, jpaEM, getServiceProperties());
@@ -112,8 +115,8 @@ public class ManagedJPAEMFLocator implem
                }
        }
 
-       private void setupTransactionManager(Map<String, Object> props, 
TransactionControl txControl,
-                       ServiceReference<EntityManagerFactoryBuilder> 
reference) {
+       private void setupTransactionManager(Map<String, Object> props, 
Map<String, Object> providerProps, 
+                       TransactionControl txControl, 
ServiceReference<EntityManagerFactoryBuilder> reference) {
                String provider = (String) 
reference.getProperty(JPA_UNIT_PROVIDER);
                
                ServiceReference<PersistenceProvider> providerRef = 
getPersistenceProvider(provider);
@@ -148,6 +151,28 @@ public class ManagedJPAEMFLocator implem
                                
                                
props.put("hibernate.transaction.coordinator_class", plugin);
                                
+                       } else 
if("org.apache.openjpa.persistence.PersistenceProviderImpl".equals(provider)) {
+                                       
+                               ClassLoader pluginLoader = 
getPluginLoader(providerBundle, txControlProviderBundle);
+                                       
+                               Class<?> pluginClazz = 
pluginLoader.loadClass("org.apache.aries.tx.control.jpa.xa.openjpa.impl.OpenJPATxControlPlatform");
+                               Object plugin = 
pluginClazz.getConstructor(TransactionControl.class)
+                                               .newInstance(txControl);
+                                       
+                               props.put("openjpa.ManagedRuntime", plugin);
+                                       
+                       } else 
if("org.eclipse.persistence.jpa.PersistenceProvider".equals(provider)) {
+                               
+                               ClassLoader pluginLoader = 
getPluginLoader(providerBundle, txControlProviderBundle);
+                               
+                               Class<?> pluginClazz = 
pluginLoader.loadClass("org.apache.aries.tx.control.jpa.xa.eclipse.impl.EclipseTxControlPlatform");
+                               
+                               pluginClazz.getMethod("setTransactionControl", 
TransactionControl.class)
+                                               .invoke(null, txControl);
+                               
+                               props.put("eclipselink.target-server", 
pluginClazz.getName());
+                               
props.put("org.apache.aries.jpa.eclipselink.plugin.types", pluginClazz);
+                               
                        } else {
                                // TODO log a warning and give up
                                return;
@@ -161,9 +186,20 @@ public class ManagedJPAEMFLocator implem
        private ClassLoader getPluginLoader(Bundle providerBundle, Bundle 
txControlProviderBundle) {
                return new ClassLoader() {
 
+                       ConcurrentMap<String, Class<?>> loaded = new 
ConcurrentHashMap<>();
+                       
                        @Override
                        public Class<?> loadClass(String name) throws 
ClassNotFoundException {
-                               
if(name.startsWith("org.apache.aries.tx.control.jpa.xa.hibernate")) {
+                               
if(name.startsWith("org.apache.aries.tx.control.jpa.xa.hibernate") ||
+                                       
name.startsWith("org.apache.aries.tx.control.jpa.xa.openjpa") ||
+                                       
name.startsWith("org.apache.aries.tx.control.jpa.xa.eclipse")) {
+                                       
+                                       Class<?> c = loaded.get(name);
+                                       
+                                       if(c != null) {
+                                               return c;
+                                       }
+                                       
                                        String resource = name.replace('.', 
'/') + ".class";
                                        
                                        try (InputStream is = 
txControlProviderBundle.getResource(resource).openStream()) {
@@ -174,8 +210,10 @@ public class ManagedJPAEMFLocator implem
                                                        baos.write(b, 0, read);
                                                }
                                                byte[] clazzBytes = 
baos.toByteArray();
-                                               return defineClass(name, 
clazzBytes, 0, clazzBytes.length, 
+                                               c = defineClass(name, 
clazzBytes, 0, clazzBytes.length, 
                                                                
ManagedJPAEMFLocator.class.getProtectionDomain());
+                                               loaded.putIfAbsent(name, c);
+                                               return c;
                                        } catch (IOException e) {
                                                throw new 
ClassNotFoundException("Unable to load class " + name, e);
                                        }

Added: 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/openjpa/impl/OpenJPATxControlPlatform.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/openjpa/impl/OpenJPATxControlPlatform.java?rev=1738967&view=auto
==============================================================================
--- 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/openjpa/impl/OpenJPATxControlPlatform.java
 (added)
+++ 
aries/trunk/tx-control/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/openjpa/impl/OpenJPATxControlPlatform.java
 Wed Apr 13 16:31:07 2016
@@ -0,0 +1,160 @@
+package org.apache.aries.tx.control.jpa.xa.openjpa.impl;
+
+import static javax.transaction.Status.STATUS_ACTIVE;
+import static javax.transaction.Status.STATUS_COMMITTED;
+import static javax.transaction.Status.STATUS_COMMITTING;
+import static javax.transaction.Status.STATUS_MARKED_ROLLBACK;
+import static javax.transaction.Status.STATUS_NO_TRANSACTION;
+import static javax.transaction.Status.STATUS_PREPARING;
+import static javax.transaction.Status.STATUS_ROLLEDBACK;
+import static javax.transaction.Status.STATUS_ROLLING_BACK;
+import static javax.transaction.Status.STATUS_UNKNOWN;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+
+import org.apache.openjpa.ee.ManagedRuntime;
+import org.osgi.service.transaction.control.TransactionContext;
+import org.osgi.service.transaction.control.TransactionControl;
+import org.osgi.service.transaction.control.TransactionStatus;
+
+public class OpenJPATxControlPlatform implements ManagedRuntime, 
TransactionManager, Transaction {
+
+       private final TransactionControl txControl;
+       
+       public OpenJPATxControlPlatform(TransactionControl txControl) {
+               this.txControl = txControl;
+       }
+
+       @Override
+       public void doNonTransactionalWork(Runnable arg0) throws 
NotSupportedException {
+               txControl.notSupported(() -> {
+                       arg0.run();
+                       return null;
+               });
+       }
+
+       @Override
+       public Throwable getRollbackCause() throws Exception {
+               return null;
+       }
+
+       @Override
+       public Object getTransactionKey() throws Exception, SystemException {
+               return txControl.getCurrentContext().getTransactionKey();
+       }
+
+       @Override
+       public TransactionManager getTransactionManager() throws Exception {
+               return this;
+       }
+
+       @Override
+       public void setRollbackOnly(Throwable arg0) throws Exception {
+               txControl.setRollbackOnly();
+       }
+
+       @Override
+       public void setRollbackOnly() throws IllegalStateException, 
SystemException {
+               txControl.setRollbackOnly();
+       }
+
+       @Override
+       public int getStatus() throws SystemException {
+               TransactionContext currentContext = 
txControl.getCurrentContext();
+               if(currentContext != null) {
+                       return 
toIntStatus(currentContext.getTransactionStatus());
+               }
+               return STATUS_NO_TRANSACTION;
+       }
+
+       private int toIntStatus(TransactionStatus status) {
+               switch(status) {
+                       case NO_TRANSACTION:
+                               return STATUS_NO_TRANSACTION;
+                       case ACTIVE:
+                               return STATUS_ACTIVE;
+                       case PREPARING:
+                               return STATUS_PREPARING;
+                       case PREPARED:
+                               return Status.STATUS_PREPARED;
+                       case COMMITTING:
+                               return STATUS_COMMITTING;
+                       case COMMITTED:
+                               return STATUS_COMMITTED;
+                       case MARKED_ROLLBACK:
+                               return STATUS_MARKED_ROLLBACK;
+                       case ROLLING_BACK:
+                               return STATUS_ROLLING_BACK;
+                       case ROLLED_BACK:
+                               return STATUS_ROLLEDBACK;
+                       default:
+                               return STATUS_UNKNOWN;
+               }
+       }
+
+       @Override
+       public Transaction getTransaction() throws SystemException {
+               return this;
+       }
+
+       @Override
+       public boolean delistResource(XAResource xaRes, int flag) throws 
IllegalStateException, SystemException {
+               return false;
+       }
+
+       @Override
+       public boolean enlistResource(XAResource xaRes) throws 
IllegalStateException, RollbackException, SystemException {
+               txControl.getCurrentContext().registerXAResource(xaRes);
+               return true;
+       }
+
+       @Override
+       public void registerSynchronization(Synchronization synch)
+                       throws IllegalStateException, RollbackException, 
SystemException {
+               TransactionContext currentContext = 
txControl.getCurrentContext();
+               currentContext.preCompletion(synch::beforeCompletion);
+               currentContext.postCompletion(status -> 
synch.afterCompletion(toIntStatus(status)));
+       }
+
+       @Override
+       public void begin() throws NotSupportedException, SystemException {
+               throw new NotSupportedException("The Transaction contol service 
does not support open scoped work");
+       }
+
+       @Override
+       public void commit() throws HeuristicMixedException, 
HeuristicRollbackException, IllegalStateException,
+                       RollbackException, SecurityException, SystemException {
+               throw new SystemException("The Transaction contol service does 
not support open scoped work");
+       }
+
+       @Override
+       public void resume(Transaction tobj) throws IllegalStateException, 
InvalidTransactionException, SystemException {
+               throw new SystemException("The Transaction contol service does 
not support open scoped work");
+       }
+
+       @Override
+       public void rollback() throws IllegalStateException, SecurityException, 
SystemException {
+               throw new SystemException("The Transaction contol service does 
not support open scoped work");
+       }
+
+       @Override
+       public void setTransactionTimeout(int seconds) throws SystemException {
+               throw new SystemException("The Transaction contol service does 
not support open scoped work");
+       }
+
+       @Override
+       public Transaction suspend() throws SystemException {
+               throw new SystemException("The Transaction contol service does 
not support open scoped work");
+       }
+
+}


Reply via email to