[seam-commits] Seam SVN: r13415 - in modules/persistence/trunk/src: main/resources/META-INF/services and 1 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Fri Jul 16 18:31:48 EDT 2010


Author: swd847
Date: 2010-07-16 18:31:47 -0400 (Fri, 16 Jul 2010)
New Revision: 13415

Added:
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EntityTransaction.java
Modified:
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transaction.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionExtension.java
   modules/persistence/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/TransactionInterceptorTest.java
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/UserTransactionTest.java
Log:
make default UserTransaction registered via portable extension



Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EntityTransaction.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EntityTransaction.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EntityTransaction.java	2010-07-16 22:31:47 UTC (rev 13415)
@@ -0,0 +1,160 @@
+package org.jboss.seam.transaction;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.jboss.weld.extensions.core.Veto;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Support for the JPA EntityTransaction API.
+ * 
+ * Adapts JPA transaction management to a Seam UserTransaction 
+ * interface.For use in non-JTA-capable environments.
+ * 
+ * @author Gavin King
+ * 
+ */
+ at RequestScoped
+ at Veto
+public class EntityTransaction extends AbstractUserTransaction
+{
+   private static final Logger log = LoggerFactory.getLogger(EntityTransaction.class);
+   
+   @Inject
+   private EntityManager entityManager;
+   
+   
+   @Inject
+   public EntityTransaction(Synchronizations sync)
+   {
+      super(sync);
+   }
+
+   private javax.persistence.EntityTransaction getDelegate()
+   {
+      return entityManager.getTransaction();
+   }
+
+   public void begin() throws NotSupportedException, SystemException
+   {
+      log.debug("beginning JPA resource-local transaction");
+      //TODO: translate exceptions that occur into the correct JTA exception
+      try
+      {
+         getDelegate().begin();
+         getSynchronizations().afterTransactionBegin();
+      }
+      catch (RuntimeException re)
+      {
+         throw re;
+      }
+   }
+
+   public void commit() throws RollbackException, HeuristicMixedException,
+            HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+   {
+      log.debug("committing JPA resource-local transaction");
+      javax.persistence.EntityTransaction delegate = getDelegate();
+      boolean success = false;
+      try
+      {
+         if ( delegate.getRollbackOnly() )
+         {
+            delegate.rollback();
+            throw new RollbackException();
+         }
+         else
+         {
+            getSynchronizations().beforeTransactionCommit();
+            delegate.commit();
+            success = true;
+         }
+      }
+      finally
+      {
+         getSynchronizations().afterTransactionCommit(success);
+      }
+   }
+
+   public void rollback() throws IllegalStateException, SecurityException, SystemException
+   {
+      log.debug("rolling back JPA resource-local transaction");
+      //TODO: translate exceptions that occur into the correct JTA exception
+      javax.persistence.EntityTransaction delegate = getDelegate();
+      try
+      {
+         delegate.rollback();
+      }
+      finally
+      {
+         getSynchronizations().afterTransactionRollback();
+      }
+   }
+
+   public void setRollbackOnly() throws IllegalStateException, SystemException
+   {
+      log.debug("marking JPA resource-local transaction for rollback");
+      getDelegate().setRollbackOnly();
+   }
+
+   public int getStatus() throws SystemException
+   {
+      if (getDelegate().getRollbackOnly())
+      {
+         return Status.STATUS_MARKED_ROLLBACK;
+      }
+      else if (getDelegate().isActive())
+      {
+         return Status.STATUS_ACTIVE;
+      }
+      else
+      {
+         return Status.STATUS_NO_TRANSACTION;
+      }
+   }
+
+   public void setTransactionTimeout(int timeout) throws SystemException
+   {
+      throw new UnsupportedOperationException();
+   }
+
+   @Override
+   public void registerSynchronization(Synchronization sync)
+   {
+      if ( log.isDebugEnabled() )
+      {
+         log.debug("registering synchronization: " + sync);
+      }
+      //try to register the synchronization directly with the
+      //persistence provider, but if this fails, just hold
+      //on to it myself
+      // if ( !PersistenceProvider.instance().registerSynchronization(sync,
+      // currentEntityManager) )
+      // {
+      // getSynchronizations().registerSynchronization(sync);
+      // }
+   }
+
+   @Override
+   public boolean isConversationContextRequired()
+   {
+      return true;
+   }
+
+   @Override
+   public void enlist(EntityManager entityManager)
+   {
+      //no-op
+   }
+
+}

Modified: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transaction.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transaction.java	2010-07-16 21:51:51 UTC (rev 13414)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transaction.java	2010-07-16 22:31:47 UTC (rev 13415)
@@ -1,7 +1,6 @@
 package org.jboss.seam.transaction;
 
 import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.inject.Produces;
 import javax.inject.Inject;
 import javax.naming.InitialContext;
 import javax.naming.NameNotFoundException;
@@ -22,7 +21,6 @@
    @Inject
    Synchronizations synchronizations;
 
-   @Produces
    public UserTransaction getTransaction() throws NamingException
    {
       try

Modified: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionExtension.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionExtension.java	2010-07-16 21:51:51 UTC (rev 13414)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionExtension.java	2010-07-16 22:31:47 UTC (rev 13415)
@@ -1,12 +1,162 @@
 package org.jboss.seam.transaction;
 
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.enterprise.inject.spi.ProcessBean;
+import javax.naming.NamingException;
+
+import org.jboss.weld.extensions.annotated.AnnotatedTypeBuilder;
+import org.jboss.weld.extensions.bean.BeanBuilder;
+import org.jboss.weld.extensions.bean.BeanImpl;
+import org.jboss.weld.extensions.bean.BeanLifecycle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
- * Extension than provides a {@link UserTransaction}
+ * Extension than provides a {@link UserTransaction} if no other UserTransaction
+ * has been registered.
  * 
- * @author stuart
+ * This allows the user to register a transaction via seam XML and have it
+ * automatically replace the default UserTransaction implementation
  * 
+ * This is not done with alternatives, because that would require specifying the
+ * transaction manager on a per module basis, and some of the UserTransaction
+ * implementations need to be configured via seam xml anyway, so they would have
+ * to be configured twice
+ * 
+ * @author Stuart Douglas
+ * 
  */
-public class TransactionExtension
+public class TransactionExtension implements Extension
 {
+   private boolean transactionRegistered = false;
 
+   private static final Logger log = LoggerFactory.getLogger(TransactionExtension.class);
+
+   public void processBean(@Observes ProcessBean<?> event)
+   {
+      Bean<?> bean = event.getBean();
+      if (bean.getTypes().contains(UserTransaction.class))
+      {
+         if (bean.getQualifiers().isEmpty()) // not sure about this
+         {
+            transactionRegistered = true;
+         }
+         else
+         {
+            for (Annotation a : event.getBean().getQualifiers())
+            {
+               if (a.annotationType() == Default.class)
+               {
+                  transactionRegistered = true;
+                  break;
+               }
+            }
+         }
+      }
+   }
+
+   public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager)
+   {
+      if (!transactionRegistered)
+      {
+         AnnotatedTypeBuilder<UserTransaction> utbuilder = AnnotatedTypeBuilder.newInstance(UserTransaction.class);
+         BeanBuilder<UserTransaction> builder = new BeanBuilder<UserTransaction>(utbuilder.create(), manager);
+         builder.defineBeanFromAnnotatedType();
+
+         Set<Bean<?>> beans = manager.getBeans(Transaction.class);
+         if (beans.isEmpty())
+         {
+            log.error("No bean with type " + Transaction.class.getName() + " registered, SEAM TRANSACTIONS ARE DISABLED");
+         }
+         else if (beans.size() > 1)
+         {
+            log.error("More than 1 bean with type " + Transaction.class.getName() + " registered, SEAM TRANSACTIONS ARE DISABLED");
+         }
+         Bean<?> bean = beans.iterator().next();
+         builder.setBeanLifecycle(new TransactionLifecycle(manager, (Bean) bean));
+         builder.setInjectionTarget(new NoOpInjectionTarget());
+         event.addBean(builder.create());
+      }
+   }
+
+   private static class TransactionLifecycle implements BeanLifecycle<UserTransaction>
+   {
+
+      private final BeanManager manager;
+
+      private final Bean<Transaction> transactionBean;
+
+      public TransactionLifecycle(BeanManager manager, Bean<Transaction> transactionBean)
+      {
+         this.manager = manager;
+         this.transactionBean = transactionBean;
+
+      }
+
+      public UserTransaction create(BeanImpl<UserTransaction> bean, CreationalContext<UserTransaction> ctx)
+      {
+         Transaction t = (Transaction) manager.getReference(transactionBean, Transaction.class, ctx);
+         try
+         {
+            return t.getTransaction();
+         }
+         catch (NamingException e)
+         {
+            throw new RuntimeException(e);
+         }
+      }
+
+      public void destroy(BeanImpl<UserTransaction> bean, UserTransaction arg0, CreationalContext<UserTransaction> arg1)
+      {
+         arg1.release();
+      }
+
+   }
+
+   private static class NoOpInjectionTarget implements InjectionTarget<UserTransaction>
+   {
+
+      public UserTransaction produce(CreationalContext<UserTransaction> ctx)
+      {
+         return null;
+      }
+
+      public Set<InjectionPoint> getInjectionPoints()
+      {
+         return Collections.EMPTY_SET;
+      }
+
+      public void dispose(UserTransaction instance)
+      {
+
+      }
+
+      public void preDestroy(UserTransaction instance)
+      {
+
+      }
+
+      public void postConstruct(UserTransaction instance)
+      {
+
+      }
+
+      public void inject(UserTransaction instance, CreationalContext<UserTransaction> ctx)
+      {
+
+      }
+
+   }
 }

Modified: modules/persistence/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
===================================================================
--- modules/persistence/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension	2010-07-16 21:51:51 UTC (rev 13414)
+++ modules/persistence/trunk/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension	2010-07-16 22:31:47 UTC (rev 13415)
@@ -1 +1,2 @@
 org.jboss.seam.persistence.PersistenceContextExtension
+org.jboss.seam.transaction.TransactionExtension
\ No newline at end of file

Modified: modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/TransactionInterceptorTest.java
===================================================================
--- modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/TransactionInterceptorTest.java	2010-07-16 21:51:51 UTC (rev 13414)
+++ modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/TransactionInterceptorTest.java	2010-07-16 22:31:47 UTC (rev 13415)
@@ -42,7 +42,7 @@
       war.addClasses(TransactionInterceptorTest.class, TransactionManagedBean.class, Hotel.class, EntityManagerProvider.class, DontRollBackException.class, TransactionObserver.class);
       war.addWebResource("META-INF/persistence.xml", "classes/META-INF/persistence.xml");
       war.addWebResource(new ByteArrayAsset(("<beans><interceptors><class>" + TransactionInterceptor.class.getName() + "</class></interceptors></beans>").getBytes()), "beans.xml");
-      
+      war.addWebResource("META-INF/services/javax.enterprise.inject.spi.Extension", "classes/META-INF/services/javax.enterprise.inject.spi.Extension");
       return war;
    }
 

Modified: modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/UserTransactionTest.java
===================================================================
--- modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/UserTransactionTest.java	2010-07-16 21:51:51 UTC (rev 13414)
+++ modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/UserTransactionTest.java	2010-07-16 22:31:47 UTC (rev 13415)
@@ -39,7 +39,7 @@
       war.addPackage(Transaction.class.getPackage()).addClasses(UserTransactionTest.class, Hotel.class);
       war.addWebResource("META-INF/persistence.xml", "classes/META-INF/persistence.xml");
       war.addWebResource(new ByteArrayAsset(new byte[0]), "beans.xml");
-      
+      war.addWebResource("META-INF/services/javax.enterprise.inject.spi.Extension", "classes/META-INF/services/javax.enterprise.inject.spi.Extension");
       return war;
    }
 



More information about the seam-commits mailing list