Remove dependency to JTA
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 7 Dec 2021 08:47:02 +0000 (09:47 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 7 Dec 2021 08:47:02 +0000 (09:47 +0100)
33 files changed:
dep/org.argeo.dep.cms.client/pom.xml
org.argeo.cms.e4/OSGI-INF/userAdminWrapper.xml
org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/UiAdminUtils.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java
org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java
org.argeo.cms.jcr/ext/test/org/argeo/cms/tabular/JcrTabularTest.java
org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java
org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java
org.argeo.cms/OSGI-INF/cmsUserManager.xml
org.argeo.cms/src/org/argeo/cms/CmsUserManager.java
org.argeo.cms/src/org/argeo/cms/internal/auth/CmsUserManagerImpl.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java
org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifUserAdminTest.java
org.argeo.enterprise/src/org/argeo/osgi/transaction/JtaStatusAdapter.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleRollbackException.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleTransaction.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleTransactionManager.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/TransactionStatusAdapter.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/UuidXid.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkContext.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkControl.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkTransaction.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/transaction/package-info.java [new file with mode: 0644]
org.argeo.enterprise/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java
org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransaction.java [deleted file]
org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionManager.java [deleted file]
org.argeo.enterprise/src/org/argeo/transaction/simple/UuidXid.java [deleted file]
org.argeo.enterprise/src/org/argeo/transaction/simple/package-info.java [deleted file]
pom.xml

index 2381d27b363e2b1644e4020ecd72c22acc004bfb..3c99ba16ce50bb9e3bd19483d759cb5c1fa59cb2 100644 (file)
@@ -45,6 +45,8 @@
                        <groupId>org.argeo.tp.javax</groupId>
                        <artifactId>javax.enterprise.cdi-api</artifactId>
                </dependency>
+               
+               <!-- JTA is still indirectly required by Jackrabbit -->
                <dependency>
                        <groupId>org.argeo.tp.javax</groupId>
                        <artifactId>javax.transaction-api</artifactId>
index 6fa13d402e069bdaa71aa7e5275a211689fe522c..a267aa519f8d759aff1207ddde134fbb6cc9220d 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="User Admin Wrapper">
    <implementation class="org.argeo.cms.e4.users.UserAdminWrapper"/>
-   <reference bind="setUserTransaction" cardinality="1..1" interface="javax.transaction.UserTransaction" name="UserTransaction" policy="static"/>
+   <reference bind="setUserTransaction" cardinality="1..1" interface="org.argeo.osgi.transaction.WorkTransaction" name="UserTransaction" policy="static"/>
    <reference bind="setUserAdmin" cardinality="1..1" interface="org.osgi.service.useradmin.UserAdmin" name="UserAdmin" policy="static"/>
    <service>
       <provide interface="org.argeo.cms.e4.users.UserAdminWrapper"/>
index 52756376bcd68db626b55d5c722a10c691bc71fc..fe05253c11045778fa369a702d043a0f7637b227 100644 (file)
@@ -11,13 +11,13 @@ import java.util.Arrays;
 import javax.inject.Inject;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
-import javax.transaction.UserTransaction;
 
 import org.argeo.api.security.CryptoKeyring;
 import org.argeo.cms.CmsException;
 import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.ui.dialogs.CmsMessageDialog;
 import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.core.di.annotations.Optional;
 import org.eclipse.jface.dialogs.Dialog;
@@ -38,7 +38,7 @@ public class ChangePassword {
        @Inject
        private UserAdmin userAdmin;
        @Inject
-       private UserTransaction userTransaction;
+       private WorkTransaction userTransaction;
        @Inject
        @Optional
        private CryptoKeyring keyring = null;
index 2c7504971e38f3f976d2d66fb935021b7e9797af..9ba7af72f32b698af229430d333881f500c091e3 100644 (file)
@@ -17,7 +17,6 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
-import javax.transaction.UserTransaction;
 
 import org.argeo.api.NodeConstants;
 import org.argeo.api.NodeInstance;
@@ -36,6 +35,7 @@ import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.naming.LdapAttrs;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.ToolBarManager;
@@ -514,7 +514,7 @@ public class GroupEditor extends AbstractRoleEditor {
                                userAdminWrapper.notifyListeners(new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, myGroup));
                        } else if (role.getType() == Role.USER) {
                                // TODO check if the group is already member of this group
-                               UserTransaction transaction = userAdminWrapper.beginTransactionIfNeeded();
+                               WorkTransaction transaction = userAdminWrapper.beginTransactionIfNeeded();
                                User user = (User) role;
                                myGroup.addMember(user);
                                if (UserAdminWrapper.COMMIT_ON_SAVE)
index a5fb6100e6271d01f07ebdfcf50e2b5bfffc5ffd..f856492601cf26a9fa8bc64f1412f2bc7240e8ce 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.cms.e4.users;
 
-import javax.transaction.UserTransaction;
+import org.argeo.osgi.transaction.WorkTransaction;
 
 /** First effort to centralize back end methods used by the user admin UI */
 public class UiAdminUtils {
@@ -10,7 +10,7 @@ public class UiAdminUtils {
         */
        /** Easily notify the ActiveWindow that the transaction had a state change */
        public final static void notifyTransactionStateChange(
-                       UserTransaction userTransaction) {
+                       WorkTransaction userTransaction) {
 //             try {
 //                     IWorkbenchWindow aww = PlatformUI.getWorkbench()
 //                                     .getActiveWorkbenchWindow();
index 60d232abac0a690f095753bb2b3900ad0343cc46..d1bdd775aa77c413403b15760e197faed0795159 100644 (file)
@@ -8,11 +8,9 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.transaction.Status;
-import javax.transaction.UserTransaction;
-
 import org.argeo.api.NodeConstants;
 import org.argeo.cms.CmsException;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.argeo.osgi.useradmin.UserAdminConf;
 import org.argeo.osgi.useradmin.UserDirectory;
 import org.osgi.service.useradmin.UserAdmin;
@@ -27,7 +25,7 @@ public class UserAdminWrapper {
 //     private Set<String> uris;
        private Map<UserDirectory, Hashtable<String, String>> userDirectories = Collections
                        .synchronizedMap(new LinkedHashMap<>());
-       private UserTransaction userTransaction;
+       private WorkTransaction userTransaction;
 
        // First effort to simplify UX while managing users and groups
        public final static boolean COMMIT_ON_SAVE = true;
@@ -40,10 +38,10 @@ public class UserAdminWrapper {
         * {@link UserAdminWrapper#commitOrNotifyTransactionStateChange()} once the
         * security model changes have been performed.
         */
-       public UserTransaction beginTransactionIfNeeded() {
+       public WorkTransaction beginTransactionIfNeeded() {
                try {
                        // UserTransaction userTransaction = getUserTransaction();
-                       if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) {
+                       if (userTransaction.isNoTransactionStatus()) {
                                userTransaction.begin();
                                // UiAdminUtils.notifyTransactionStateChange(userTransaction);
                        }
@@ -61,7 +59,7 @@ public class UserAdminWrapper {
        public void commitOrNotifyTransactionStateChange() {
                try {
                        // UserTransaction userTransaction = getUserTransaction();
-                       if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION)
+                       if (userTransaction.isNoTransactionStatus())
                                return;
 
                        if (UserAdminWrapper.COMMIT_ON_SAVE)
@@ -126,7 +124,7 @@ public class UserAdminWrapper {
                return userAdmin;
        }
 
-       public UserTransaction getUserTransaction() {
+       public WorkTransaction getUserTransaction() {
                return userTransaction;
        }
 
@@ -136,7 +134,7 @@ public class UserAdminWrapper {
 //             this.uris = Collections.unmodifiableSortedSet(new TreeSet<>(properties.keySet()));
        }
 
-       public void setUserTransaction(UserTransaction userTransaction) {
+       public void setUserTransaction(WorkTransaction userTransaction) {
                this.userTransaction = userTransaction;
        }
 
index 7513102fe8352a664ee00f9163d2c19e1b04231f..4073a209b25c3b7582820731c12da0b5064beae9 100644 (file)
@@ -5,9 +5,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.transaction.SystemException;
-import javax.transaction.UserTransaction;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.api.NodeConstants;
@@ -23,6 +20,7 @@ import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.eclipse.ui.parts.LdifUsersTable;
 import org.argeo.naming.LdapAttrs;
 import org.argeo.naming.LdapObjs;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.eclipse.jface.dialogs.IPageChangeProvider;
 import org.eclipse.jface.dialogs.IPageChangedListener;
 import org.eclipse.jface.dialogs.MessageDialog;
@@ -90,15 +88,10 @@ public class UserBatchUpdateWizard extends Wizard {
        public boolean performFinish() {
                if (!canFinish())
                        return false;
-               UserTransaction ut = userAdminWrapper.getUserTransaction();
-               try {
-                       if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION
-                                       && !MessageDialog.openConfirm(getShell(), "Existing Transaction",
-                                                       "A user transaction is already existing, " + "are you sure you want to proceed ?"))
-                               return false;
-               } catch (SystemException e) {
-                       throw new CmsException("Cannot get user transaction state " + "before user batch update", e);
-               }
+               WorkTransaction ut = userAdminWrapper.getUserTransaction();
+               if (!ut.isNoTransactionStatus() && !MessageDialog.openConfirm(getShell(), "Existing Transaction",
+                               "A user transaction is already existing, " + "are you sure you want to proceed ?"))
+                       return false;
 
                // We cannot use jobs, user modifications are still meant to be done in
                // the UIThread
@@ -151,14 +144,9 @@ public class UserBatchUpdateWizard extends Wizard {
                        } catch (Exception e) {
                                throw new CmsException("Cannot perform batch update on users", e);
                        } finally {
-                               UserTransaction ut = userAdminWrapper.getUserTransaction();
-                               try {
-                                       if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION)
-                                               ut.rollback();
-                               } catch (IllegalStateException | SecurityException | SystemException e) {
-                                       log.error("Unable to rollback session in 'finally', " + "the system might be in a dirty state");
-                                       e.printStackTrace();
-                               }
+                               WorkTransaction ut = userAdminWrapper.getUserTransaction();
+                               if (!ut.isNoTransactionStatus())
+                                       ut.rollback();
                        }
                }
        }
@@ -190,14 +178,9 @@ public class UserBatchUpdateWizard extends Wizard {
                        } catch (Exception e) {
                                throw new CmsException("Cannot perform batch update on users", e);
                        } finally {
-                               UserTransaction ut = userAdminWrapper.getUserTransaction();
-                               try {
-                                       if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION)
-                                               ut.rollback();
-                               } catch (IllegalStateException | SecurityException | SystemException e) {
-                                       log.error("Unable to rollback session in finally block, the system might be in a dirty state");
-                                       e.printStackTrace();
-                               }
+                               WorkTransaction ut = userAdminWrapper.getUserTransaction();
+                               if (!ut.isNoTransactionStatus())
+                                       ut.rollback();
                        }
                }
        }
@@ -457,8 +440,7 @@ public class UserBatchUpdateWizard extends Wizard {
        }
 
        /**
-        * Displays a list of users with a check box to be able to choose some of
-        * them
+        * Displays a list of users with a check box to be able to choose some of them
         */
        private class ChooseUsersWizardPage extends WizardPage implements IPageChangedListener {
                private static final long serialVersionUID = 7651807402211214274L;
index 8da6148009259b0ee41e26d52c9acab8b871599d..18150c791f702cb32b3b19c1887511fccb981a22 100644 (file)
@@ -22,10 +22,10 @@ public class JcrTabularTest extends AbstractJackrabbitTestCase {
 
        public void testWriteReadCsv() throws Exception {
                // session().setNamespacePrefix("argeo", ArgeoNames.ARGEO_NAMESPACE);
-               InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/api/ldap.cnd"));
+               InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/cms/jcr/ldap.cnd"));
                CndImporter.registerNodeTypes(reader, session());
                reader.close();
-               reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/cms/argeo.cnd"));
+               reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/cms/jcr/argeo.cnd"));
                CndImporter.registerNodeTypes(reader, session());
                reader.close();
 //             reader = new InputStreamReader(getClass().getResourceAsStream("/org/argeo/cms/cms.cnd"));
index 6003d638ddadab47a630d694903704ca62dce2c4..ae09cd4bfdbaf1fa77e4ad9bce345392e191dcf5 100644 (file)
@@ -9,7 +9,6 @@ import javax.jcr.NoSuchWorkspaceException;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import javax.transaction.UserTransaction;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -17,6 +16,7 @@ import org.argeo.api.NodeUtils;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.naming.Distinguished;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.UserAdmin;
@@ -28,7 +28,7 @@ public abstract class AbstractMaintenanceService {
        private Repository repository;
 //     private UserAdminService userAdminService;
        private UserAdmin userAdmin;
-       private UserTransaction userTransaction;
+       private WorkTransaction userTransaction;
 
        public void init() {
                makeSureRolesExists(getRequiredRoles());
@@ -202,7 +202,7 @@ public abstract class AbstractMaintenanceService {
 //             this.userAdminService = userAdminService;
 //     }
 
-       protected UserTransaction getUserTransaction() {
+       protected WorkTransaction getUserTransaction() {
                return userTransaction;
        }
 
@@ -214,7 +214,7 @@ public abstract class AbstractMaintenanceService {
                this.userAdmin = userAdmin;
        }
 
-       public void setUserTransaction(UserTransaction userTransaction) {
+       public void setUserTransaction(WorkTransaction userTransaction) {
                this.userTransaction = userTransaction;
        }
 
index a30fe9796e24df88e56ed1be68635953a88367d6..07dc3998569025c88c99e32026ee6e089e216283 100644 (file)
@@ -6,10 +6,10 @@ import java.util.Map;
 
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
-import javax.transaction.UserTransaction;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.UserAdmin;
 
@@ -23,7 +23,7 @@ public class SimpleRoleRegistration implements Runnable {
        private String role;
        private List<String> roles = new ArrayList<String>();
        private UserAdmin userAdmin;
-       private UserTransaction userTransaction;
+       private WorkTransaction userTransaction;
 
        @Override
        public void run() {
@@ -80,7 +80,7 @@ public class SimpleRoleRegistration implements Runnable {
                this.userAdmin = userAdminService;
        }
 
-       public void setUserTransaction(UserTransaction userTransaction) {
+       public void setUserTransaction(WorkTransaction userTransaction) {
                this.userTransaction = userTransaction;
        }
 
index 045c9609a2a6bf7b2e7b4441ce683cbeac261213..524c054eccf733b1a3a295cce1d9e64dc918d7d9 100644 (file)
@@ -5,6 +5,6 @@
       <provide interface="org.argeo.cms.CmsUserManager"/>
    </service>
    <reference bind="setUserAdmin" cardinality="1..1" interface="org.osgi.service.useradmin.UserAdmin" name="UserAdmin" policy="static"/>
-   <reference bind="setUserTransaction" cardinality="1..1" interface="javax.transaction.UserTransaction" name="UserTransaction" policy="static"/>
+   <reference bind="setUserTransaction" cardinality="1..1" interface="org.argeo.osgi.transaction.WorkTransaction" name="UserTransaction" policy="static"/>
    <reference bind="addUserDirectory" cardinality="0..n" interface="org.argeo.osgi.useradmin.UserDirectory" name="UserDirectory" policy="static" unbind="removeUserDirectory"/>
-</scr:component>
\ No newline at end of file
+</scr:component>
index d970855ff5066316857c38b101c52f4d43767e2d..cd76d65ef05618372e1e11c2b3159a2a9b412832 100644 (file)
@@ -5,12 +5,10 @@ import java.util.List;
 import java.util.Set;
 
 import javax.security.auth.Subject;
-import javax.transaction.UserTransaction;
 
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.useradmin.Role;
 import org.osgi.service.useradmin.User;
-import org.osgi.service.useradmin.UserAdmin;
 
 /**
  * Provide method interfaces to manage user concepts without accessing directly
@@ -81,9 +79,9 @@ public interface CmsUserManager {
 
 //     User createUserFromPerson(Node person);
 
-       @Deprecated
-       public UserAdmin getUserAdmin();
-
-       @Deprecated
-       public UserTransaction getUserTransaction();
+//     @Deprecated
+//     public UserAdmin getUserAdmin();
+//
+//     @Deprecated
+//     public UserTransaction getUserTransaction();
 }
\ No newline at end of file
index d21e8616c10e3ce5e9d513f7653357856c7ddc02..5753decf9ed2c565d5f011795371e99620b9154d 100644 (file)
@@ -22,8 +22,6 @@ import java.util.UUID;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 import javax.security.auth.Subject;
-import javax.transaction.Status;
-import javax.transaction.UserTransaction;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -34,6 +32,7 @@ import org.argeo.cms.auth.UserAdminUtils;
 import org.argeo.naming.LdapAttrs;
 import org.argeo.naming.NamingUtils;
 import org.argeo.naming.SharedSecret;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.argeo.osgi.useradmin.TokenUtils;
 import org.argeo.osgi.useradmin.UserAdminConf;
 import org.argeo.osgi.useradmin.UserDirectory;
@@ -61,7 +60,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
 
        private UserAdmin userAdmin;
 //     private Map<String, String> serviceProperties;
-       private UserTransaction userTransaction;
+       private WorkTransaction userTransaction;
 
        private Map<UserDirectory, Hashtable<String, String>> userDirectories = Collections
                        .synchronizedMap(new LinkedHashMap<>());
@@ -351,7 +350,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
                        return tokenStr;
                } catch (Exception e1) {
                        try {
-                               if (userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION)
+                               if (!userTransaction.isNoTransactionStatus())
                                        userTransaction.rollback();
                        } catch (Exception e2) {
                                if (log.isTraceEnabled())
@@ -374,7 +373,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
                                log.debug("Token " + token + " expired.");
                } catch (Exception e1) {
                        try {
-                               if (userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION)
+                               if (!userTransaction.isNoTransactionStatus())
                                        userTransaction.rollback();
                        } catch (Exception e2) {
                                if (log.isTraceEnabled())
@@ -423,7 +422,7 @@ public class CmsUserManagerImpl implements CmsUserManager {
                        userTransaction.commit();
                } catch (Exception e1) {
                        try {
-                               if (userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION)
+                               if (!userTransaction.isNoTransactionStatus())
                                        userTransaction.rollback();
                        } catch (Exception e2) {
                                if (log.isTraceEnabled())
@@ -468,9 +467,9 @@ public class CmsUserManagerImpl implements CmsUserManager {
                return userAdmin;
        }
 
-       public UserTransaction getUserTransaction() {
-               return userTransaction;
-       }
+//     public UserTransaction getUserTransaction() {
+//             return userTransaction;
+//     }
 
        /* DEPENDENCY INJECTION */
        public void setUserAdmin(UserAdmin userAdmin) {
@@ -478,10 +477,10 @@ public class CmsUserManagerImpl implements CmsUserManager {
 //             this.serviceProperties = serviceProperties;
        }
 
-       public void setUserTransaction(UserTransaction userTransaction) {
+       public void setUserTransaction(WorkTransaction userTransaction) {
                this.userTransaction = userTransaction;
        }
-       
+
        public void addUserDirectory(UserDirectory userDirectory, Map<String, String> properties) {
                userDirectories.put(userDirectory, new Hashtable<>(properties));
        }
index cb4d552739f89d46a6eb10d016b785d58750dac3..b24fb0a123b40326974a34be0eac92a97bbf94a2 100644 (file)
@@ -5,13 +5,12 @@ import java.lang.management.ManagementFactory;
 import java.net.URL;
 import java.util.Dictionary;
 
-import javax.transaction.UserTransaction;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.api.NodeConstants;
 import org.argeo.api.NodeDeployment;
 import org.argeo.api.NodeState;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.argeo.osgi.useradmin.UserAdminConf;
 import org.eclipse.equinox.http.jetty.JettyConfigurator;
 import org.osgi.framework.BundleContext;
@@ -34,7 +33,6 @@ public class CmsDeployment implements NodeDeployment {
 
        private Long availableSince;
 
-
        // Readiness
        private boolean nodeAvailable = false;
        private boolean userAdminAvailable = false;
@@ -69,7 +67,6 @@ public class CmsDeployment implements NodeDeployment {
                // httpSt.open();
                KernelUtils.asyncOpen(httpSt);
 
-
                ServiceTracker<?, ?> userAdminSt = new ServiceTracker<UserAdmin, UserAdmin>(bc, UserAdmin.class, null) {
                        @Override
                        public UserAdmin addingService(ServiceReference<UserAdmin> reference) {
@@ -96,7 +93,7 @@ public class CmsDeployment implements NodeDeployment {
                                } catch (Exception e) {
                                        throw new IllegalStateException("Cannot analyse clean state", e);
                                }
-                               deployConfig = new DeployConfig(configurationAdmin,  isClean);
+                               deployConfig = new DeployConfig(configurationAdmin, isClean);
                                Activator.registerService(NodeDeployment.class, CmsDeployment.this, null);
 //                             JcrInitUtils.addToDeployment(CmsDeployment.this);
                                httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null;
@@ -145,7 +142,7 @@ public class CmsDeployment implements NodeDeployment {
 
        private void addStandardSystemRoles(UserAdmin userAdmin) {
                // we assume UserTransaction is already available (TODO make it more robust)
-               UserTransaction userTransaction = bc.getService(bc.getServiceReference(UserTransaction.class));
+               WorkTransaction userTransaction = bc.getService(bc.getServiceReference(WorkTransaction.class));
                try {
                        userTransaction.begin();
                        Role adminRole = userAdmin.getRole(NodeConstants.ROLE_ADMIN);
@@ -180,7 +177,6 @@ public class CmsDeployment implements NodeDeployment {
 //             if (nodeHttp != null)
 //                     nodeHttp.destroy();
 
-
                try {
                        JettyConfigurator.stopServer(KernelConstants.DEFAULT_JETTY_SERVER);
                } catch (Exception e) {
@@ -236,7 +232,6 @@ public class CmsDeployment implements NodeDeployment {
                }
        }
 
-
        @Override
        public synchronized Long getAvailableSince() {
                return availableSince;
@@ -246,5 +241,4 @@ public class CmsDeployment implements NodeDeployment {
                return availableSince != null;
        }
 
-
 }
index fc9ea7dd71cbefc20b00b871b8a4fb6eecc453ae..219f2d53c059b58f4032ed11c22d3d9dc5c3812d 100644 (file)
@@ -8,15 +8,14 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 
-import javax.transaction.TransactionManager;
-import javax.transaction.UserTransaction;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.api.NodeConstants;
 import org.argeo.api.NodeState;
 import org.argeo.cms.LocaleUtils;
-import org.argeo.transaction.simple.SimpleTransactionManager;
+import org.argeo.osgi.transaction.SimpleTransactionManager;
+import org.argeo.osgi.transaction.WorkControl;
+import org.argeo.osgi.transaction.WorkTransaction;
 import org.argeo.util.LangUtils;
 import org.osgi.framework.Constants;
 import org.osgi.service.cm.ManagedServiceFactory;
@@ -117,8 +116,10 @@ public class CmsState implements NodeState {
 
        private void initSimpleTransactionManager() {
                SimpleTransactionManager transactionManager = new SimpleTransactionManager();
-               Activator.registerService(TransactionManager.class, transactionManager, null);
-               Activator.registerService(UserTransaction.class, transactionManager, null);
+               Activator.registerService(WorkControl.class, transactionManager, null);
+               Activator.registerService(WorkTransaction.class, transactionManager, null);
+//             Activator.registerService(TransactionManager.class, transactionManager, null);
+//             Activator.registerService(UserTransaction.class, transactionManager, null);
                // TODO TransactionSynchronizationRegistry
        }
 
index 1a9817450ed427deee762ed39f0866d1d6a3942c..86c6c9c31a66721cdb9acd9c2a0c373a1af2f6ce 100644 (file)
@@ -25,7 +25,6 @@ import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
-import javax.transaction.TransactionManager;
 
 import org.apache.commons.httpclient.auth.AuthPolicy;
 import org.apache.commons.httpclient.auth.CredentialsProvider;
@@ -38,6 +37,7 @@ import org.argeo.api.NodeConstants;
 import org.argeo.cms.internal.http.client.HttpCredentialProvider;
 import org.argeo.cms.internal.http.client.SpnegoAuthScheme;
 import org.argeo.naming.DnsBrowser;
+import org.argeo.osgi.transaction.WorkControl;
 import org.argeo.osgi.useradmin.AbstractUserDirectory;
 import org.argeo.osgi.useradmin.AggregatingUserAdmin;
 import org.argeo.osgi.useradmin.LdapUserAdmin;
@@ -72,7 +72,7 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor
 //     private ServiceRegistration<UserAdmin> userAdminReg;
 
        // JTA
-       private final ServiceTracker<TransactionManager, TransactionManager> tmTracker;
+       private final ServiceTracker<WorkControl, WorkControl> tmTracker;
        // private final String cacheName = UserDirectory.class.getName();
 
        // GSS API
@@ -86,7 +86,7 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor
                super(systemRolesBaseDn, tokensBaseDn);
                BundleContext bc = Activator.getBundleContext();
                if (bc != null) {
-                       tmTracker = new ServiceTracker<>(bc, TransactionManager.class, null);
+                       tmTracker = new ServiceTracker<>(bc, WorkControl.class, null);
                        tmTracker.open();
                } else {
                        tmTracker = null;
@@ -194,10 +194,10 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor
 
        protected void postAdd(AbstractUserDirectory userDirectory) {
                // JTA
-               TransactionManager tm = tmTracker != null ? tmTracker.getService() : null;
+               WorkControl tm = tmTracker != null ? tmTracker.getService() : null;
                if (tm == null)
                        throw new IllegalStateException("A JTA transaction manager must be available.");
-               userDirectory.setTransactionManager(tm);
+               userDirectory.setTransactionControl(tm);
 //             if (tmTracker.getService() instanceof BitronixTransactionManager)
 //                     EhCacheXAResourceProducer.registerXAResource(cacheName, userDirectory.getXaResource());
 
index 126125b8500f7a3c8c8b46a2e8ff783c42a196ac..8432ce999ca1d51bb07f85e383c3e972cedebf01 100644 (file)
@@ -16,10 +16,8 @@ import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
 
-import javax.transaction.TransactionManager;
-
 import org.argeo.naming.LdapAttrs;
-import org.argeo.transaction.simple.SimpleTransactionManager;
+import org.argeo.osgi.transaction.SimpleTransactionManager;
 import org.osgi.service.useradmin.Authorization;
 import org.osgi.service.useradmin.Group;
 import org.osgi.service.useradmin.Role;
@@ -36,7 +34,7 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants {
        final static int TM_BITRONIX = 1;
 
        private int tmType = TM_SIMPLE;
-       private TransactionManager tm;
+       private SimpleTransactionManager tm;
        private URI uri;
        private AbstractUserDirectory userAdmin;
        private Path tempDir;
@@ -171,7 +169,7 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants {
                }
        }
 
-       private AbstractUserDirectory initUserAdmin(URI uri, TransactionManager tm) {
+       private AbstractUserDirectory initUserAdmin(URI uri, SimpleTransactionManager tm) {
                Dictionary<String, Object> props = new Hashtable<>();
                props.put(UserAdminConf.uri.name(), uri.toString());
                props.put(UserAdminConf.baseDn.name(), BASE_DN);
@@ -186,7 +184,7 @@ public class LdifUserAdminTest extends TestCase implements BasicTestConstants {
                // JTA
 //             if (TM_BITRONIX == tmType)
 //                     EhCacheXAResourceProducer.registerXAResource(UserDirectory.class.getName(), userAdmin.getXaResource());
-               userAdmin.setTransactionManager(tm);
+               userAdmin.setTransactionControl(tm);
                return userAdmin;
        }
 
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/JtaStatusAdapter.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/JtaStatusAdapter.java
new file mode 100644 (file)
index 0000000..2dd94c6
--- /dev/null
@@ -0,0 +1,61 @@
+package org.argeo.osgi.transaction;
+
+/** JTA transaction status. */
+public class JtaStatusAdapter implements TransactionStatusAdapter<Integer> {
+       private static final Integer STATUS_ACTIVE = 0;
+       private static final Integer STATUS_COMMITTED = 3;
+       private static final Integer STATUS_COMMITTING = 8;
+       private static final Integer STATUS_MARKED_ROLLBACK = 1;
+       private static final Integer STATUS_NO_TRANSACTION = 6;
+       private static final Integer STATUS_PREPARED = 2;
+       private static final Integer STATUS_PREPARING = 7;
+       private static final Integer STATUS_ROLLEDBACK = 4;
+       private static final Integer STATUS_ROLLING_BACK = 9;
+//     private static final Integer STATUS_UNKNOWN = 5;
+
+       @Override
+       public Integer getActiveStatus() {
+               return STATUS_ACTIVE;
+       }
+
+       @Override
+       public Integer getPreparingStatus() {
+               return STATUS_PREPARING;
+       }
+
+       @Override
+       public Integer getMarkedRollbackStatus() {
+               return STATUS_MARKED_ROLLBACK;
+       }
+
+       @Override
+       public Integer getPreparedStatus() {
+               return STATUS_PREPARED;
+       }
+
+       @Override
+       public Integer getCommittingStatus() {
+               return STATUS_COMMITTING;
+       }
+
+       @Override
+       public Integer getCommittedStatus() {
+               return STATUS_COMMITTED;
+       }
+
+       @Override
+       public Integer getRollingBackStatus() {
+               return STATUS_ROLLING_BACK;
+       }
+
+       @Override
+       public Integer getRolledBackStatus() {
+               return STATUS_ROLLEDBACK;
+       }
+
+       @Override
+       public Integer getNoTransactionStatus() {
+               return STATUS_NO_TRANSACTION;
+       }
+
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleRollbackException.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleRollbackException.java
new file mode 100644 (file)
index 0000000..cf8a80b
--- /dev/null
@@ -0,0 +1,15 @@
+package org.argeo.osgi.transaction;
+
+/** Internal unchecked rollback exception. */
+class SimpleRollbackException extends RuntimeException {
+       private static final long serialVersionUID = 8055601819719780566L;
+
+       public SimpleRollbackException() {
+               super();
+       }
+
+       public SimpleRollbackException(Throwable cause) {
+               super(cause);
+       }
+
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleTransaction.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleTransaction.java
new file mode 100644 (file)
index 0000000..e668b31
--- /dev/null
@@ -0,0 +1,160 @@
+package org.argeo.osgi.transaction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+/** Simple implementation of an XA transaction. */
+class SimpleTransaction<T>
+//implements Transaction, Status 
+{
+       private final Xid xid;
+       private T status;
+       private final List<XAResource> xaResources = new ArrayList<XAResource>();
+
+       private final SimpleTransactionManager transactionManager;
+       private TransactionStatusAdapter<T> tsa;
+
+       public SimpleTransaction(SimpleTransactionManager transactionManager, TransactionStatusAdapter<T> tsa) {
+               this.tsa = tsa;
+               this.status = tsa.getActiveStatus();
+               this.xid = new UuidXid();
+               this.transactionManager = transactionManager;
+       }
+
+       public synchronized void commit()
+//                     throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
+//                     SecurityException, IllegalStateException, SystemException 
+       {
+               status = tsa.getPreparingStatus();
+               for (XAResource xaRes : xaResources) {
+                       if (status.equals(tsa.getMarkedRollbackStatus()))
+                               break;
+                       try {
+                               xaRes.prepare(xid);
+                       } catch (XAException e) {
+                               status = tsa.getMarkedRollbackStatus();
+                               error("Cannot prepare " + xaRes + " for " + xid, e);
+                       }
+               }
+               if (status.equals(tsa.getMarkedRollbackStatus())) {
+                       rollback();
+                       throw new SimpleRollbackException();
+               }
+               status = tsa.getPreparedStatus();
+
+               status = tsa.getCommittingStatus();
+               for (XAResource xaRes : xaResources) {
+                       if (status.equals(tsa.getMarkedRollbackStatus()))
+                               break;
+                       try {
+                               xaRes.commit(xid, false);
+                       } catch (XAException e) {
+                               status = tsa.getMarkedRollbackStatus();
+                               error("Cannot prepare " + xaRes + " for " + xid, e);
+                       }
+               }
+               if (status.equals(tsa.getMarkedRollbackStatus())) {
+                       rollback();
+                       throw new SimpleRollbackException();
+               }
+
+               // complete
+               status = tsa.getCommittedStatus();
+               clearResources(XAResource.TMSUCCESS);
+               transactionManager.unregister(xid);
+       }
+
+       public synchronized void rollback()
+//                     throws IllegalStateException, SystemException 
+       {
+               status = tsa.getRollingBackStatus();
+               for (XAResource xaRes : xaResources) {
+                       try {
+                               xaRes.rollback(xid);
+                       } catch (XAException e) {
+                               error("Cannot rollback " + xaRes + " for " + xid, e);
+                       }
+               }
+
+               // complete
+               status = tsa.getRolledBackStatus();
+               clearResources(XAResource.TMFAIL);
+               transactionManager.unregister(xid);
+       }
+
+       public synchronized boolean enlistResource(XAResource xaRes)
+//                     throws RollbackException, IllegalStateException, SystemException 
+       {
+               if (xaResources.add(xaRes)) {
+                       try {
+                               xaRes.start(getXid(), XAResource.TMNOFLAGS);
+                               return true;
+                       } catch (XAException e) {
+                               error("Cannot enlist " + xaRes, e);
+                               return false;
+                       }
+               } else
+                       return false;
+       }
+
+       public synchronized boolean delistResource(XAResource xaRes, int flag)
+//                     throws IllegalStateException, SystemException 
+       {
+               if (xaResources.remove(xaRes)) {
+                       try {
+                               xaRes.end(getXid(), flag);
+                       } catch (XAException e) {
+                               error("Cannot delist " + xaRes, e);
+                               return false;
+                       }
+                       return true;
+               } else
+                       return false;
+       }
+
+       protected void clearResources(int flag) {
+               for (XAResource xaRes : xaResources)
+                       try {
+                               xaRes.end(getXid(), flag);
+                       } catch (XAException e) {
+                               error("Cannot end " + xaRes, e);
+                       }
+               xaResources.clear();
+       }
+
+       protected void error(Object obj, Exception e) {
+               System.err.println(obj);
+               e.printStackTrace();
+       }
+
+       public synchronized T getStatus()
+//                     throws SystemException 
+       {
+               return status;
+       }
+
+//     public void registerSynchronization(Synchronization sync)
+//                     throws RollbackException, IllegalStateException, SystemException {
+//             throw new UnsupportedOperationException();
+//     }
+
+       public void setRollbackOnly()
+//                     throws IllegalStateException, SystemException 
+       {
+               status = tsa.getMarkedRollbackStatus();
+       }
+
+       @Override
+       public int hashCode() {
+               return xid.hashCode();
+       }
+
+       Xid getXid() {
+               return xid;
+       }
+
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleTransactionManager.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/SimpleTransactionManager.java
new file mode 100644 (file)
index 0000000..3d4edfd
--- /dev/null
@@ -0,0 +1,214 @@
+package org.argeo.osgi.transaction;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+/**
+ * Simple implementation of an XA transaction manager.
+ */
+public class SimpleTransactionManager
+// implements TransactionManager, UserTransaction 
+               implements WorkControl, WorkTransaction {
+       private ThreadLocal<SimpleTransaction<Integer>> current = new ThreadLocal<SimpleTransaction<Integer>>();
+
+       private Map<Xid, SimpleTransaction<Integer>> knownTransactions = Collections
+                       .synchronizedMap(new HashMap<Xid, SimpleTransaction<Integer>>());
+       private TransactionStatusAdapter<Integer> tsa = new JtaStatusAdapter();
+//     private SyncRegistry syncRegistry = new SyncRegistry();
+
+       /*
+        * WORK IMPLEMENTATION
+        */
+       @Override
+       public <T> T required(Callable<T> work) {
+               T res;
+               begin();
+               try {
+                       res = work.call();
+                       commit();
+               } catch (Exception e) {
+                       rollback();
+                       throw new SimpleRollbackException(e);
+               }
+               return res;
+       }
+
+       @Override
+       public WorkContext getWorkContext() {
+               return new WorkContext() {
+
+                       @Override
+                       public void registerXAResource(XAResource resource, String recoveryId) {
+                               getTransaction().enlistResource(resource);
+                       }
+               };
+       }
+
+       /*
+        * WORK TRANSACTION IMPLEMENTATION
+        */
+
+       @Override
+       public boolean isNoTransactionStatus() {
+               return tsa.getNoTransactionStatus().equals(getStatus());
+       }
+
+       /*
+        * JTA IMPLEMENTATION
+        */
+
+       public void begin()
+//                     throws NotSupportedException, SystemException 
+       {
+               if (getCurrent() != null)
+                       throw new UnsupportedOperationException("Nested transactions are not supported");
+               SimpleTransaction<Integer> transaction = new SimpleTransaction<Integer>(this, tsa);
+               knownTransactions.put(transaction.getXid(), transaction);
+               current.set(transaction);
+       }
+
+       public void commit()
+//                     throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
+//                     SecurityException, IllegalStateException, SystemException 
+       {
+               if (getCurrent() == null)
+                       throw new IllegalStateException("No transaction registered with the current thread.");
+               getCurrent().commit();
+       }
+
+       public int getStatus()
+//                     throws SystemException
+       {
+               if (getCurrent() == null)
+                       return tsa.getNoTransactionStatus();
+               return getTransaction().getStatus();
+       }
+
+       public SimpleTransaction<Integer> getTransaction()
+//                     throws SystemException 
+       {
+               return getCurrent();
+       }
+
+       protected SimpleTransaction<Integer> getCurrent()
+//                     throws SystemException 
+       {
+               SimpleTransaction<Integer> transaction = current.get();
+               if (transaction == null)
+                       return null;
+               Integer status = transaction.getStatus();
+               if (status.equals(tsa.getCommittedStatus()) || status.equals(tsa.getRolledBackStatus())) {
+                       current.remove();
+                       return null;
+               }
+               return transaction;
+       }
+
+       void unregister(Xid xid) {
+               knownTransactions.remove(xid);
+       }
+
+       public void resume(SimpleTransaction<Integer> tobj)
+//                     throws InvalidTransactionException, IllegalStateException, SystemException 
+       {
+               if (getCurrent() != null)
+                       throw new IllegalStateException("Transaction " + current.get() + " already registered");
+               current.set(tobj);
+       }
+
+       public void rollback()
+//                     throws IllegalStateException, SecurityException, SystemException 
+       {
+               if (getCurrent() == null)
+                       throw new IllegalStateException("No transaction registered with the current thread.");
+               getCurrent().rollback();
+       }
+
+       public void setRollbackOnly()
+//                     throws IllegalStateException, SystemException 
+       {
+               if (getCurrent() == null)
+                       throw new IllegalStateException("No transaction registered with the current thread.");
+               getCurrent().setRollbackOnly();
+       }
+
+       public void setTransactionTimeout(int seconds)
+//                     throws SystemException
+       {
+               throw new UnsupportedOperationException();
+       }
+
+       public SimpleTransaction<Integer> suspend()
+//                     throws SystemException
+       {
+               SimpleTransaction<Integer> transaction = getCurrent();
+               current.remove();
+               return transaction;
+       }
+
+//     public TransactionSynchronizationRegistry getTsr() {
+//             return syncRegistry;
+//     }
+//
+//     private class SyncRegistry implements TransactionSynchronizationRegistry {
+//             @Override
+//             public Object getTransactionKey() {
+//                     try {
+//                             SimpleTransaction transaction = getCurrent();
+//                             if (transaction == null)
+//                                     return null;
+//                             return getCurrent().getXid();
+//                     } catch (SystemException e) {
+//                             throw new IllegalStateException("Cannot get transaction key", e);
+//                     }
+//             }
+//
+//             @Override
+//             public void putResource(Object key, Object value) {
+//                     throw new UnsupportedOperationException();
+//             }
+//
+//             @Override
+//             public Object getResource(Object key) {
+//                     throw new UnsupportedOperationException();
+//             }
+//
+//             @Override
+//             public void registerInterposedSynchronization(Synchronization sync) {
+//                     throw new UnsupportedOperationException();
+//             }
+//
+//             @Override
+//             public int getTransactionStatus() {
+//                     try {
+//                             return getStatus();
+//                     } catch (SystemException e) {
+//                             throw new IllegalStateException("Cannot get status", e);
+//                     }
+//             }
+//
+//             @Override
+//             public boolean getRollbackOnly() {
+//                     try {
+//                             return getStatus() == Status.STATUS_MARKED_ROLLBACK;
+//                     } catch (SystemException e) {
+//                             throw new IllegalStateException("Cannot get status", e);
+//                     }
+//             }
+//
+//             @Override
+//             public void setRollbackOnly() {
+//                     try {
+//                             getCurrent().setRollbackOnly();
+//                     } catch (Exception e) {
+//                             throw new IllegalStateException("Cannot set rollback only", e);
+//                     }
+//             }
+//
+//     }
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/TransactionStatusAdapter.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/TransactionStatusAdapter.java
new file mode 100644 (file)
index 0000000..87abceb
--- /dev/null
@@ -0,0 +1,22 @@
+package org.argeo.osgi.transaction;
+
+/** Abstract the various approaches to represent transaction status. */
+public interface TransactionStatusAdapter<T> {
+       T getActiveStatus();
+
+       T getPreparingStatus();
+
+       T getMarkedRollbackStatus();
+
+       T getPreparedStatus();
+
+       T getCommittingStatus();
+
+       T getCommittedStatus();
+
+       T getRollingBackStatus();
+
+       T getRolledBackStatus();
+
+       T getNoTransactionStatus();
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/UuidXid.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/UuidXid.java
new file mode 100644 (file)
index 0000000..729aef8
--- /dev/null
@@ -0,0 +1,132 @@
+package org.argeo.osgi.transaction;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.UUID;
+
+import javax.transaction.xa.Xid;
+
+/**
+ * Implementation of {@link Xid} based on {@link UUID}, using max significant
+ * bits as global transaction id, and least significant bits as branch
+ * qualifier.
+ */
+public class UuidXid implements Xid, Serializable {
+       private static final long serialVersionUID = -5380531989917886819L;
+       public final static int FORMAT = (int) serialVersionUID;
+
+       private final static int BYTES_PER_LONG = Long.SIZE / Byte.SIZE;
+
+       private final int format;
+       private final byte[] globalTransactionId;
+       private final byte[] branchQualifier;
+       private final String uuid;
+       private final int hashCode;
+
+       public UuidXid() {
+               this(UUID.randomUUID());
+       }
+
+       public UuidXid(UUID uuid) {
+               this.format = FORMAT;
+               this.globalTransactionId = uuidToBytes(uuid.getMostSignificantBits());
+               this.branchQualifier = uuidToBytes(uuid.getLeastSignificantBits());
+               this.uuid = uuid.toString();
+               this.hashCode = uuid.hashCode();
+       }
+
+       public UuidXid(Xid xid) {
+               this(xid.getFormatId(), xid.getGlobalTransactionId(), xid
+                               .getBranchQualifier());
+       }
+
+       private UuidXid(int format, byte[] globalTransactionId,
+                       byte[] branchQualifier) {
+               this.format = format;
+               this.globalTransactionId = globalTransactionId;
+               this.branchQualifier = branchQualifier;
+               this.uuid = bytesToUUID(globalTransactionId, branchQualifier)
+                               .toString();
+               this.hashCode = uuid.hashCode();
+       }
+
+       @Override
+       public int getFormatId() {
+               return format;
+       }
+
+       @Override
+       public byte[] getGlobalTransactionId() {
+               return Arrays.copyOf(globalTransactionId, globalTransactionId.length);
+       }
+
+       @Override
+       public byte[] getBranchQualifier() {
+               return Arrays.copyOf(branchQualifier, branchQualifier.length);
+       }
+
+       @Override
+       public int hashCode() {
+               return hashCode;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj instanceof UuidXid) {
+                       UuidXid that = (UuidXid) obj;
+                       return Arrays.equals(globalTransactionId, that.globalTransactionId)
+                                       && Arrays.equals(branchQualifier, that.branchQualifier);
+               }
+               if (obj instanceof Xid) {
+                       Xid that = (Xid) obj;
+                       return Arrays.equals(globalTransactionId,
+                                       that.getGlobalTransactionId())
+                                       && Arrays
+                                                       .equals(branchQualifier, that.getBranchQualifier());
+               }
+               return uuid.equals(obj.toString());
+       }
+
+       @Override
+       protected Object clone() throws CloneNotSupportedException {
+               return new UuidXid(format, globalTransactionId, branchQualifier);
+       }
+
+       @Override
+       public String toString() {
+               return uuid;
+       }
+
+       public UUID asUuid() {
+               return bytesToUUID(globalTransactionId, branchQualifier);
+       }
+
+       public static byte[] uuidToBytes(long bits) {
+               ByteBuffer buffer = ByteBuffer.allocate(BYTES_PER_LONG);
+               buffer.putLong(0, bits);
+               return buffer.array();
+       }
+
+       public static UUID bytesToUUID(byte[] most, byte[] least) {
+               if (most.length < BYTES_PER_LONG)
+                       most = Arrays.copyOf(most, BYTES_PER_LONG);
+               if (least.length < BYTES_PER_LONG)
+                       least = Arrays.copyOf(least, BYTES_PER_LONG);
+               ByteBuffer buffer = ByteBuffer.allocate(2 * BYTES_PER_LONG);
+               buffer.put(most, 0, BYTES_PER_LONG);
+               buffer.put(least, 0, BYTES_PER_LONG);
+               buffer.flip();
+               return new UUID(buffer.getLong(), buffer.getLong());
+       }
+
+       // public static void main(String[] args) {
+       // UUID uuid = UUID.randomUUID();
+       // System.out.println(uuid);
+       // uuid = bytesToUUID(uuidToBytes(uuid.getMostSignificantBits()),
+       // uuidToBytes(uuid.getLeastSignificantBits()));
+       // System.out.println(uuid);
+       // }
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkContext.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkContext.java
new file mode 100644 (file)
index 0000000..f50f208
--- /dev/null
@@ -0,0 +1,11 @@
+package org.argeo.osgi.transaction;
+
+import javax.transaction.xa.XAResource;
+
+/**
+ * A minimalistic interface similar to OSGi transaction context in order to
+ * register XA resources.
+ */
+public interface WorkContext {
+       void registerXAResource(XAResource resource, String recoveryId);
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkControl.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkControl.java
new file mode 100644 (file)
index 0000000..7668095
--- /dev/null
@@ -0,0 +1,15 @@
+package org.argeo.osgi.transaction;
+
+import java.util.concurrent.Callable;
+
+/**
+ * A minimalistic interface inspired by OSGi transaction control in order to
+ * commit units of work externally.
+ */
+public interface WorkControl {
+       <T> T required(Callable<T> work);
+
+       void setRollbackOnly();
+
+       WorkContext getWorkContext();
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkTransaction.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/WorkTransaction.java
new file mode 100644 (file)
index 0000000..6533909
--- /dev/null
@@ -0,0 +1,15 @@
+package org.argeo.osgi.transaction;
+
+/**
+ * A minimalistic interface inspired by JTA user transaction in order to commit
+ * units of work externally.
+ */
+public interface WorkTransaction {
+       void begin();
+
+       void commit();
+
+       void rollback();
+
+       boolean isNoTransactionStatus();
+}
diff --git a/org.argeo.enterprise/src/org/argeo/osgi/transaction/package-info.java b/org.argeo.enterprise/src/org/argeo/osgi/transaction/package-info.java
new file mode 100644 (file)
index 0000000..3d37562
--- /dev/null
@@ -0,0 +1,2 @@
+/** Minimalistic and partial XA transaction manager implementation. */
+package org.argeo.osgi.transaction;
\ No newline at end of file
index f2d7c88fc232ca8d1090c065a5a2a5f9c1b5a975..7279877e0e8ec46690a7f95b72ba062b234f8a34 100644 (file)
@@ -27,11 +27,9 @@ import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.BasicAttributes;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
 
 import org.argeo.naming.LdapAttrs;
+import org.argeo.osgi.transaction.WorkControl;
 import org.osgi.framework.Filter;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.InvalidSyntaxException;
@@ -64,8 +62,9 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory
        private List<String> credentialAttributeIds = Arrays
                        .asList(new String[] { LdapAttrs.userPassword.name(), LdapAttrs.authPassword.name() });
 
-       // JTA
-       private TransactionManager transactionManager;
+       // Transaction
+//     private TransactionManager transactionManager;
+       private WorkControl transactionControl;
        private WcXaResource xaResource = new WcXaResource(this);
 
        AbstractUserDirectory(URI uriArg, Dictionary<String, ?> props, boolean scoped) {
@@ -142,17 +141,18 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory
        }
 
        protected void checkEdit() {
-               Transaction transaction;
-               try {
-                       transaction = transactionManager.getTransaction();
-               } catch (SystemException e) {
-                       throw new UserDirectoryException("Cannot get transaction", e);
-               }
-               if (transaction == null)
-                       throw new UserDirectoryException("A transaction needs to be active in order to edit");
+//             Transaction transaction;
+//             try {
+//                     transaction = transactionManager.getTransaction();
+//             } catch (SystemException e) {
+//                     throw new UserDirectoryException("Cannot get transaction", e);
+//             }
+//             if (transaction == null)
+//                     throw new UserDirectoryException("A transaction needs to be active in order to edit");
                if (xaResource.wc() == null) {
                        try {
-                               transaction.enlistResource(xaResource);
+//                             transaction.enlistResource(xaResource);
+                               transactionControl.getWorkContext().registerXAResource(xaResource, null);
                        } catch (Exception e) {
                                throw new UserDirectoryException("Cannot enlist " + xaResource, e);
                        }
@@ -490,8 +490,12 @@ public abstract class AbstractUserDirectory implements UserAdmin, UserDirectory
                this.externalRoles = externalRoles;
        }
 
-       public void setTransactionManager(TransactionManager transactionManager) {
-               this.transactionManager = transactionManager;
+//     public void setTransactionManager(TransactionManager transactionManager) {
+//             this.transactionManager = transactionManager;
+//     }
+
+       public void setTransactionControl(WorkControl transactionControl) {
+               this.transactionControl = transactionControl;
        }
 
        public WcXaResource getXaResource() {
diff --git a/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransaction.java b/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransaction.java
deleted file mode 100644 (file)
index 43d4cd9..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-package org.argeo.transaction.simple;
-
-import java.util.ArrayList;
-import java.util.List;
-
-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.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-
-/** Simple implementation of an XA {@link Transaction}. */
-class SimpleTransaction implements Transaction, Status {
-       private final Xid xid;
-       private int status = Status.STATUS_ACTIVE;
-       private final List<XAResource> xaResources = new ArrayList<XAResource>();
-
-       private final SimpleTransactionManager transactionManager;
-
-       public SimpleTransaction(SimpleTransactionManager transactionManager) {
-               this.xid = new UuidXid();
-               this.transactionManager = transactionManager;
-       }
-
-       @Override
-       public synchronized void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
-                       SecurityException, IllegalStateException, SystemException {
-               status = STATUS_PREPARING;
-               for (XAResource xaRes : xaResources) {
-                       if (status == STATUS_MARKED_ROLLBACK)
-                               break;
-                       try {
-                               xaRes.prepare(xid);
-                       } catch (XAException e) {
-                               status = STATUS_MARKED_ROLLBACK;
-                               error("Cannot prepare " + xaRes + " for " + xid, e);
-                       }
-               }
-               if (status == STATUS_MARKED_ROLLBACK) {
-                       rollback();
-                       throw new RollbackException();
-               }
-               status = STATUS_PREPARED;
-
-               status = STATUS_COMMITTING;
-               for (XAResource xaRes : xaResources) {
-                       if (status == STATUS_MARKED_ROLLBACK)
-                               break;
-                       try {
-                               xaRes.commit(xid, false);
-                       } catch (XAException e) {
-                               status = STATUS_MARKED_ROLLBACK;
-                               error("Cannot prepare " + xaRes + " for " + xid, e);
-                       }
-               }
-               if (status == STATUS_MARKED_ROLLBACK) {
-                       rollback();
-                       throw new RollbackException();
-               }
-
-               // complete
-               status = STATUS_COMMITTED;
-               clearResources(XAResource.TMSUCCESS);
-               transactionManager.unregister(xid);
-       }
-
-       @Override
-       public synchronized void rollback() throws IllegalStateException, SystemException {
-               status = STATUS_ROLLING_BACK;
-               for (XAResource xaRes : xaResources) {
-                       try {
-                               xaRes.rollback(xid);
-                       } catch (XAException e) {
-                               error("Cannot rollback " + xaRes + " for " + xid, e);
-                       }
-               }
-
-               // complete
-               status = STATUS_ROLLEDBACK;
-               clearResources(XAResource.TMFAIL);
-               transactionManager.unregister(xid);
-       }
-
-       @Override
-       public synchronized boolean enlistResource(XAResource xaRes)
-                       throws RollbackException, IllegalStateException, SystemException {
-               if (xaResources.add(xaRes)) {
-                       try {
-                               xaRes.start(getXid(), XAResource.TMNOFLAGS);
-                               return true;
-                       } catch (XAException e) {
-                               error("Cannot enlist " + xaRes, e);
-                               return false;
-                       }
-               } else
-                       return false;
-       }
-
-       @Override
-       public synchronized boolean delistResource(XAResource xaRes, int flag)
-                       throws IllegalStateException, SystemException {
-               if (xaResources.remove(xaRes)) {
-                       try {
-                               xaRes.end(getXid(), flag);
-                       } catch (XAException e) {
-                               error("Cannot delist " + xaRes, e);
-                               return false;
-                       }
-                       return true;
-               } else
-                       return false;
-       }
-
-       protected void clearResources(int flag) {
-               for (XAResource xaRes : xaResources)
-                       try {
-                               xaRes.end(getXid(), flag);
-                       } catch (XAException e) {
-                               error("Cannot end " + xaRes, e);
-                       }
-               xaResources.clear();
-       }
-
-       protected void error(Object obj, Exception e) {
-               System.err.println(obj);
-               e.printStackTrace();
-       }
-
-       @Override
-       public synchronized int getStatus() throws SystemException {
-               return status;
-       }
-
-       @Override
-       public void registerSynchronization(Synchronization sync)
-                       throws RollbackException, IllegalStateException, SystemException {
-               throw new UnsupportedOperationException();
-       }
-
-       @Override
-       public void setRollbackOnly() throws IllegalStateException, SystemException {
-               status = STATUS_MARKED_ROLLBACK;
-       }
-
-       @Override
-       public int hashCode() {
-               return xid.hashCode();
-       }
-
-       Xid getXid() {
-               return xid;
-       }
-
-}
diff --git a/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionManager.java b/org.argeo.enterprise/src/org/argeo/transaction/simple/SimpleTransactionManager.java
deleted file mode 100644 (file)
index 7dcf7d9..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-package org.argeo.transaction.simple;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-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.TransactionSynchronizationRegistry;
-import javax.transaction.UserTransaction;
-import javax.transaction.xa.Xid;
-
-/**
- * Simple implementation of an XA {@link TransactionManager} and
- * {@link UserTransaction}.
- */
-public class SimpleTransactionManager implements TransactionManager, UserTransaction {
-       private ThreadLocal<SimpleTransaction> current = new ThreadLocal<SimpleTransaction>();
-
-       private Map<Xid, SimpleTransaction> knownTransactions = Collections
-                       .synchronizedMap(new HashMap<Xid, SimpleTransaction>());
-       private SyncRegistry syncRegistry = new SyncRegistry();
-
-       @Override
-       public void begin() throws NotSupportedException, SystemException {
-               if (getCurrent() != null)
-                       throw new NotSupportedException("Nested transactions are not supported");
-               SimpleTransaction transaction = new SimpleTransaction(this);
-               knownTransactions.put(transaction.getXid(), transaction);
-               current.set(transaction);
-       }
-
-       @Override
-       public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
-                       SecurityException, IllegalStateException, SystemException {
-               if (getCurrent() == null)
-                       throw new IllegalStateException("No transaction registered with the current thread.");
-               getCurrent().commit();
-       }
-
-       @Override
-       public int getStatus() throws SystemException {
-               if (getCurrent() == null)
-                       return Status.STATUS_NO_TRANSACTION;
-               return getTransaction().getStatus();
-       }
-
-       @Override
-       public Transaction getTransaction() throws SystemException {
-               return getCurrent();
-       }
-
-       protected SimpleTransaction getCurrent() throws SystemException {
-               SimpleTransaction transaction = current.get();
-               if (transaction == null)
-                       return null;
-               int status = transaction.getStatus();
-               if (Status.STATUS_COMMITTED == status || Status.STATUS_ROLLEDBACK == status) {
-                       current.remove();
-                       return null;
-               }
-               return transaction;
-       }
-
-       void unregister(Xid xid) {
-               knownTransactions.remove(xid);
-       }
-
-       @Override
-       public void resume(Transaction tobj) throws InvalidTransactionException, IllegalStateException, SystemException {
-               if (getCurrent() != null)
-                       throw new IllegalStateException("Transaction " + current.get() + " already registered");
-               current.set((SimpleTransaction) tobj);
-       }
-
-       @Override
-       public void rollback() throws IllegalStateException, SecurityException, SystemException {
-               if (getCurrent() == null)
-                       throw new IllegalStateException("No transaction registered with the current thread.");
-               getCurrent().rollback();
-       }
-
-       @Override
-       public void setRollbackOnly() throws IllegalStateException, SystemException {
-               if (getCurrent() == null)
-                       throw new IllegalStateException("No transaction registered with the current thread.");
-               getCurrent().setRollbackOnly();
-       }
-
-       @Override
-       public void setTransactionTimeout(int seconds) throws SystemException {
-               throw new UnsupportedOperationException();
-       }
-
-       @Override
-       public Transaction suspend() throws SystemException {
-               Transaction transaction = getCurrent();
-               current.remove();
-               return transaction;
-       }
-
-       public TransactionSynchronizationRegistry getTsr() {
-               return syncRegistry;
-       }
-
-       private class SyncRegistry implements TransactionSynchronizationRegistry {
-               @Override
-               public Object getTransactionKey() {
-                       try {
-                               SimpleTransaction transaction = getCurrent();
-                               if (transaction == null)
-                                       return null;
-                               return getCurrent().getXid();
-                       } catch (SystemException e) {
-                               throw new IllegalStateException("Cannot get transaction key", e);
-                       }
-               }
-
-               @Override
-               public void putResource(Object key, Object value) {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public Object getResource(Object key) {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public void registerInterposedSynchronization(Synchronization sync) {
-                       throw new UnsupportedOperationException();
-               }
-
-               @Override
-               public int getTransactionStatus() {
-                       try {
-                               return getStatus();
-                       } catch (SystemException e) {
-                               throw new IllegalStateException("Cannot get status", e);
-                       }
-               }
-
-               @Override
-               public boolean getRollbackOnly() {
-                       try {
-                               return getStatus() == Status.STATUS_MARKED_ROLLBACK;
-                       } catch (SystemException e) {
-                               throw new IllegalStateException("Cannot get status", e);
-                       }
-               }
-
-               @Override
-               public void setRollbackOnly() {
-                       try {
-                               getCurrent().setRollbackOnly();
-                       } catch (Exception e) {
-                               throw new IllegalStateException("Cannot set rollback only", e);
-                       }
-               }
-
-       }
-}
diff --git a/org.argeo.enterprise/src/org/argeo/transaction/simple/UuidXid.java b/org.argeo.enterprise/src/org/argeo/transaction/simple/UuidXid.java
deleted file mode 100644 (file)
index 1009c82..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.argeo.transaction.simple;
-
-import java.io.Serializable;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.UUID;
-
-import javax.transaction.xa.Xid;
-
-/**
- * Implementation of {@link Xid} based on {@link UUID}, using max significant
- * bits as global transaction id, and least significant bits as branch
- * qualifier.
- */
-public class UuidXid implements Xid, Serializable {
-       private static final long serialVersionUID = -5380531989917886819L;
-       public final static int FORMAT = (int) serialVersionUID;
-
-       private final static int BYTES_PER_LONG = Long.SIZE / Byte.SIZE;
-
-       private final int format;
-       private final byte[] globalTransactionId;
-       private final byte[] branchQualifier;
-       private final String uuid;
-       private final int hashCode;
-
-       public UuidXid() {
-               this(UUID.randomUUID());
-       }
-
-       public UuidXid(UUID uuid) {
-               this.format = FORMAT;
-               this.globalTransactionId = uuidToBytes(uuid.getMostSignificantBits());
-               this.branchQualifier = uuidToBytes(uuid.getLeastSignificantBits());
-               this.uuid = uuid.toString();
-               this.hashCode = uuid.hashCode();
-       }
-
-       public UuidXid(Xid xid) {
-               this(xid.getFormatId(), xid.getGlobalTransactionId(), xid
-                               .getBranchQualifier());
-       }
-
-       private UuidXid(int format, byte[] globalTransactionId,
-                       byte[] branchQualifier) {
-               this.format = format;
-               this.globalTransactionId = globalTransactionId;
-               this.branchQualifier = branchQualifier;
-               this.uuid = bytesToUUID(globalTransactionId, branchQualifier)
-                               .toString();
-               this.hashCode = uuid.hashCode();
-       }
-
-       @Override
-       public int getFormatId() {
-               return format;
-       }
-
-       @Override
-       public byte[] getGlobalTransactionId() {
-               return Arrays.copyOf(globalTransactionId, globalTransactionId.length);
-       }
-
-       @Override
-       public byte[] getBranchQualifier() {
-               return Arrays.copyOf(branchQualifier, branchQualifier.length);
-       }
-
-       @Override
-       public int hashCode() {
-               return hashCode;
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (this == obj)
-                       return true;
-               if (obj instanceof UuidXid) {
-                       UuidXid that = (UuidXid) obj;
-                       return Arrays.equals(globalTransactionId, that.globalTransactionId)
-                                       && Arrays.equals(branchQualifier, that.branchQualifier);
-               }
-               if (obj instanceof Xid) {
-                       Xid that = (Xid) obj;
-                       return Arrays.equals(globalTransactionId,
-                                       that.getGlobalTransactionId())
-                                       && Arrays
-                                                       .equals(branchQualifier, that.getBranchQualifier());
-               }
-               return uuid.equals(obj.toString());
-       }
-
-       @Override
-       protected Object clone() throws CloneNotSupportedException {
-               return new UuidXid(format, globalTransactionId, branchQualifier);
-       }
-
-       @Override
-       public String toString() {
-               return uuid;
-       }
-
-       public UUID asUuid() {
-               return bytesToUUID(globalTransactionId, branchQualifier);
-       }
-
-       public static byte[] uuidToBytes(long bits) {
-               ByteBuffer buffer = ByteBuffer.allocate(BYTES_PER_LONG);
-               buffer.putLong(0, bits);
-               return buffer.array();
-       }
-
-       public static UUID bytesToUUID(byte[] most, byte[] least) {
-               if (most.length < BYTES_PER_LONG)
-                       most = Arrays.copyOf(most, BYTES_PER_LONG);
-               if (least.length < BYTES_PER_LONG)
-                       least = Arrays.copyOf(least, BYTES_PER_LONG);
-               ByteBuffer buffer = ByteBuffer.allocate(2 * BYTES_PER_LONG);
-               buffer.put(most, 0, BYTES_PER_LONG);
-               buffer.put(least, 0, BYTES_PER_LONG);
-               buffer.flip();
-               return new UUID(buffer.getLong(), buffer.getLong());
-       }
-
-       // public static void main(String[] args) {
-       // UUID uuid = UUID.randomUUID();
-       // System.out.println(uuid);
-       // uuid = bytesToUUID(uuidToBytes(uuid.getMostSignificantBits()),
-       // uuidToBytes(uuid.getLeastSignificantBits()));
-       // System.out.println(uuid);
-       // }
-}
diff --git a/org.argeo.enterprise/src/org/argeo/transaction/simple/package-info.java b/org.argeo.enterprise/src/org/argeo/transaction/simple/package-info.java
deleted file mode 100644 (file)
index 19adecc..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Minimalistic and partial XA transaction manager implementation. */
-package org.argeo.transaction.simple;
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c4d70f610cf27acff274a65a56c4839e9418cd19..88ab72780601b5aed44ef4370609c916fe9de93e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
                <groupId>org.argeo.maven</groupId>
@@ -19,7 +21,7 @@
        <modules>
                <!-- Base -->
                <module>org.argeo.enterprise</module>
-<!--           <module>org.argeo.jcr</module> -->
+               <!-- <module>org.argeo.jcr</module> -->
                <module>org.argeo.osgi.boot</module>
                <module>org.argeo.core</module>
                <!-- Eclipse -->
@@ -27,7 +29,7 @@
                <module>org.argeo.eclipse.ui.rap</module>
                <!-- CMS -->
                <module>org.argeo.api</module>
-<!--           <module>org.argeo.maintenance</module> -->
+               <!-- <module>org.argeo.maintenance</module> -->
                <module>org.argeo.cms</module>
                <module>org.argeo.cms.jcr</module>
                <module>org.argeo.cms.ui.theme</module>
                                        <groupId>org.argeo.tp.misc</groupId>
                                        <artifactId>slf4j.osgi</artifactId>
                                </exclusion>
+                               <!-- Make sure JTA is not used anymore -->
+                               <exclusion>
+                                       <groupId>org.argeo.tp.javax</groupId>
+                                       <artifactId>javax.transaction-api</artifactId>
+                               </exclusion>
                        </exclusions>
                </dependency>
        </dependencies>