[seam-commits] Seam SVN: r13516 - in modules/persistence/trunk/impl/src: main/java/org/jboss/seam/persistence/transaction and 2 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Tue Jul 27 05:07:38 EDT 2010


Author: swd847
Date: 2010-07-27 05:07:36 -0400 (Tue, 27 Jul 2010)
New Revision: 13516

Added:
   modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
   modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java
   modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeManagedBean.java
Modified:
   modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionExtension.java
   modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionInterceptor.java
   modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/Work.java
   modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/util/EjbApi.java
   modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java
Log:
@TransactionAttribute now works on managed beans



Added: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java	                        (rev 0)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java	2010-07-27 09:07:36 UTC (rev 13516)
@@ -0,0 +1,86 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.persistence;
+
+import javax.naming.NamingException;
+import javax.persistence.EntityManagerFactory;
+
+import org.jboss.seam.persistence.util.NamingUtils;
+import org.jboss.weld.extensions.core.Veto;
+
+/**
+ * Class that enabled the seam managed persitence context to be configured via
+ * xml.
+ * 
+ * There are two ways to do this. Either the persistenceUnintJndi name can be
+ * set, in which case the entityManagerFactory is looked up from JNDI.
+ * 
+ * Alternativly the @Inject annotation can be applied to the
+ * entityManagerFactory propery along with any qualifiers needed and the
+ * entityManagerFactory will be injected
+ * 
+ * Any qualifiers that are applied to this class are also applied to the managed
+ * persistence context in question
+ * 
+ * @author Stuart Douglas
+ * 
+ */
+ at Veto
+public class ManagedPersistenceContext
+{
+
+   public String getPersistenceUnitJndiName()
+   {
+      return persistenceUnitJndiName;
+   }
+
+   public void setPersistenceUnitJndiName(String persistenceUnitJndiName)
+   {
+      this.persistenceUnitJndiName = persistenceUnitJndiName;
+   }
+
+   public EntityManagerFactory getEntityManagerFactory()
+   {
+      if (entityManagerFactory != null)
+      {
+         return entityManagerFactory;
+      }
+      try
+      {
+         return (EntityManagerFactory) NamingUtils.getInitialContext().lookup(persistenceUnitJndiName);
+      }
+      catch (NamingException ne)
+      {
+         throw new IllegalArgumentException("EntityManagerFactory not found in JNDI : " + persistenceUnitJndiName, ne);
+      }
+   }
+
+   public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory)
+   {
+      this.entityManagerFactory = entityManagerFactory;
+   }
+
+   String persistenceUnitJndiName;
+
+   EntityManagerFactory entityManagerFactory;
+
+}

Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionExtension.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionExtension.java	2010-07-27 08:58:14 UTC (rev 13515)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionExtension.java	2010-07-27 09:07:36 UTC (rev 13516)
@@ -22,6 +22,7 @@
 package org.jboss.seam.persistence.transaction;
 
 import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.Annotated;
 import javax.enterprise.inject.spi.AnnotatedMethod;
 import javax.enterprise.inject.spi.AnnotatedType;
 import javax.enterprise.inject.spi.BeanManager;
@@ -76,29 +77,35 @@
     */
    public <X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> event)
    {
-      if (event.getAnnotatedType().isAnnotationPresent(Transactional.class))
+      boolean addInterceptor = false;
+      AnnotatedType<X> type = event.getAnnotatedType();
+      if (type.isAnnotationPresent(Transactional.class))
       {
-         event.setAnnotatedType(addInterceptorBinding(event.getAnnotatedType()));
-         return;
+
+         addInterceptor = true;
       }
-      if (event.getAnnotatedType().isAnnotationPresent(EjbApi.TRANSACTION_ATTRIBUTE) && !EjbApi.isEjb(event.getAnnotatedType()))
+      else if (type.isAnnotationPresent(EjbApi.TRANSACTION_ATTRIBUTE) && !EjbApi.isEjb(event.getAnnotatedType()))
       {
-         event.setAnnotatedType(addInterceptorBinding(event.getAnnotatedType()));
-         return;
+         checkTransactionAttributeIsValue(type, type);
+         addInterceptor = true;
       }
-      for (AnnotatedMethod<? super X> m : event.getAnnotatedType().getMethods())
+
+      for (AnnotatedMethod<? super X> m : type.getMethods())
       {
          if (m.isAnnotationPresent(Transactional.class))
          {
-            event.setAnnotatedType(addInterceptorBinding(event.getAnnotatedType()));
-            return;
+            addInterceptor = true;
          }
          else if (m.isAnnotationPresent(EjbApi.TRANSACTION_ATTRIBUTE) && !EjbApi.isEjb(event.getAnnotatedType()))
          {
-            event.setAnnotatedType(addInterceptorBinding(event.getAnnotatedType()));
-            return;
+            checkTransactionAttributeIsValue(type, m);
+            addInterceptor = true;
          }
       }
+      if (addInterceptor)
+      {
+         event.setAnnotatedType(addInterceptorBinding(type));
+      }
    }
 
    public <X> AnnotatedType addInterceptorBinding(AnnotatedType<X> type)
@@ -109,4 +116,17 @@
       });
       return builder.create();
    }
+
+   private void checkTransactionAttributeIsValue(AnnotatedType type, Annotated element)
+   {
+      Object attribute = element.getAnnotation(EjbApi.TRANSACTION_ATTRIBUTE);
+      if (attribute == EjbApi.REQUIRES_NEW)
+      {
+         throw new RuntimeException("TransactionAttributeType.REQUIRED_NEW is not supported on Managed Beans that are not EJB's. Annotation was found on type " + type);
+      }
+      if (attribute == EjbApi.NOT_SUPPORTED)
+      {
+         throw new RuntimeException("TransactionAttributeType.NOT_SUPPORTED is not supported on Managed Beans that are not EJB's. Annotation was found on type " + type);
+      }
+   }
 }

Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionInterceptor.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionInterceptor.java	2010-07-27 08:58:14 UTC (rev 13515)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/TransactionInterceptor.java	2010-07-27 09:07:36 UTC (rev 13516)
@@ -33,6 +33,8 @@
 import javax.interceptor.Interceptor;
 import javax.interceptor.InvocationContext;
 
+import org.jboss.seam.persistence.util.EjbApi;
+
 /**
  * Implements transaction propagation rules for Seam JavaBean components.
  * 
@@ -60,11 +62,52 @@
       public TransactionMetadata(AnnotatedElement element)
       {
          annotationPresent = element.isAnnotationPresent(Transactional.class);
-
          if (annotationPresent)
          {
             propType = element.getAnnotation(Transactional.class).value();
          }
+         else if (element.isAnnotationPresent(EjbApi.TRANSACTION_ATTRIBUTE))
+         {
+            annotationPresent = true;
+            Object annotation = element.getAnnotation(EjbApi.TRANSACTION_ATTRIBUTE);
+            try
+            {
+               Object value = annotation.getClass().getMethod("value").invoke(annotation);
+
+               if (value == EjbApi.REQUIRED)
+               {
+                  propType = TransactionPropagation.REQUIRED;
+               }
+               else if (value == EjbApi.MANDATORY)
+               {
+                  propType = TransactionPropagation.MANDATORY;
+               }
+               else if (value == EjbApi.NEVER)
+               {
+                  propType = TransactionPropagation.NEVER;
+               }
+               else if (value == EjbApi.SUPPORTS)
+               {
+                  propType = TransactionPropagation.SUPPORTS;
+               }
+               else if (value == EjbApi.NOT_SUPPORTED)
+               {
+                  throw new RuntimeException("TransactionAttributeType.NOT_SUPPORTED is not allowed on managed beans that are not EJB's. Element: " + element);
+               }
+               else if (value == EjbApi.REQUIRES_NEW)
+               {
+                  throw new RuntimeException("TransactionAttributeType.REQUIRES_NEW is not allowed on managed beans that are not EJB's Element: " + element);
+               }
+               else
+               {
+                  throw new RuntimeException("Unkown TransactionAttributeType: " + value);
+               }
+            }
+            catch (Exception e)
+            {
+               throw new RuntimeException(e);
+            }
+         }
       }
 
       public boolean isAnnotationPresent()

Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/Work.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/Work.java	2010-07-27 08:58:14 UTC (rev 13515)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/Work.java	2010-07-27 09:07:36 UTC (rev 13516)
@@ -92,10 +92,8 @@
          {
             transaction.setRollbackOnly();
          }
-
          throw e;
       }
-
    }
 
    public static boolean isRollbackRequired(Exception e, boolean isJavaBean)

Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/util/EjbApi.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/util/EjbApi.java	2010-07-27 08:58:14 UTC (rev 13515)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/util/EjbApi.java	2010-07-27 09:07:36 UTC (rev 13516)
@@ -50,17 +50,17 @@
    public static final Class<? extends Annotation> MESSAGE_DRIVEN;
    public static final Class<? extends Annotation> SINGLETON;
 
-   private static final Object MANDATORY;
+   public static final Object MANDATORY;
 
-   private static final Object REQUIRED;
+   public static final Object REQUIRED;
 
-   private static final Object REQUIRES_NEW;
+   public static final Object REQUIRES_NEW;
 
-   private static final Object SUPPORTS;
+   public static final Object SUPPORTS;
 
-   private static final Object NOT_SUPPORTED;
+   public static final Object NOT_SUPPORTED;
 
-   private static final Object NEVER;
+   public static final Object NEVER;
 
    public static final boolean INVOCATION_CONTEXT_AVAILABLE;
 

Added: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java	                        (rev 0)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java	2010-07-27 09:07:36 UTC (rev 13516)
@@ -0,0 +1,131 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.persistence.transactions.test;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TransactionRequiredException;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+
+import junit.framework.Assert;
+
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.seam.persistence.transaction.DefaultTransaction;
+import org.jboss.seam.persistence.transaction.SeamTransaction;
+import org.jboss.seam.persistence.transaction.TransactionExtension;
+import org.jboss.seam.persistence.transaction.TransactionInterceptor;
+import org.jboss.seam.persistence.util.NamingUtils;
+import org.jboss.seam.transactions.test.util.ArtifactNames;
+import org.jboss.seam.transactions.test.util.DontRollBackException;
+import org.jboss.seam.transactions.test.util.EntityManagerProvider;
+import org.jboss.seam.transactions.test.util.Hotel;
+import org.jboss.seam.transactions.test.util.MavenArtifactResolver;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.ByteArrayAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests the @TransactionAttribute interceptor for non ee beans.
+ * 
+ * TODO: refactor the tests to share a common superclass
+ * 
+ * @author stuart
+ * 
+ */
+ at RunWith(Arquillian.class)
+public class TransactionAttributeInterceptorTest
+{
+   @Deployment
+   public static Archive<?> createTestArchive()
+   {
+
+      WebArchive war = ShrinkWrap.createDomain().getArchiveFactory().create(WebArchive.class, "test.war");
+      war.addLibraries(MavenArtifactResolver.resolve(ArtifactNames.WELD_EXTENSIONS));
+      war.addLibraries(MavenArtifactResolver.resolve(ArtifactNames.SEAM_PERSISTENCE_API));
+      war.addPackage(TransactionExtension.class.getPackage());
+      war.addPackage(NamingUtils.class.getPackage());
+      war.addClasses(TransactionAttributeInterceptorTest.class, TransactionAttributeManagedBean.class, Hotel.class, EntityManagerProvider.class, DontRollBackException.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;
+   }
+
+   @Inject
+   TransactionAttributeManagedBean bean;
+
+   @Inject
+   @DefaultTransaction
+   SeamTransaction transaction;
+
+   @PersistenceContext
+   EntityManager em;
+
+   @Test
+   public void testTransactionInterceptor() throws NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException
+   {
+      bean.addHotel();
+      assertHotels(1);
+      try
+      {
+         bean.failToAddHotel();
+      }
+      catch (Exception e)
+      {
+      }
+      assertHotels(1);
+      try
+      {
+         bean.addHotelWithApplicationException();
+      }
+      catch (DontRollBackException e)
+      {
+      }
+      assertHotels(2);
+   }
+
+   @Test(expected = TransactionRequiredException.class)
+   public void testTransactionInterceptorMethodOverrides()
+   {
+      bean.tryAndAddHotelWithNoTransaction();
+   }
+
+   public void assertHotels(int count) throws NotSupportedException, SystemException
+   {
+      transaction.begin();
+      em.joinTransaction();
+      List<Hotel> hotels = em.createQuery("select h from Hotel h").getResultList();
+      Assert.assertTrue("Wrong number of hotels: " + hotels.size(), hotels.size() == count);
+      transaction.rollback();
+   }
+}

Added: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeManagedBean.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeManagedBean.java	                        (rev 0)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeManagedBean.java	2010-07-27 09:07:36 UTC (rev 13516)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.persistence.transactions.test;
+
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+
+import org.jboss.seam.transactions.test.util.DontRollBackException;
+import org.jboss.seam.transactions.test.util.Hotel;
+
+ at TransactionAttribute(TransactionAttributeType.REQUIRED)
+public class TransactionAttributeManagedBean
+{
+
+   @Inject
+   EntityManager entityManager;
+
+   public void addHotel()
+   {
+      entityManager.joinTransaction();
+      Hotel h = new Hotel("test", "Fake St", "Wollongong", "NSW", "2518", "Australia");
+      entityManager.persist(h);
+      entityManager.flush();
+   }
+
+   public void failToAddHotel()
+   {
+      entityManager.joinTransaction();
+      Hotel h = new Hotel("test2", "Fake St", "Wollongong", "NSW", "2518", "Australia");
+      entityManager.persist(h);
+      entityManager.flush();
+      throw new RuntimeException("Roll back transaction");
+   }
+
+   public void addHotelWithApplicationException() throws DontRollBackException
+   {
+      entityManager.joinTransaction();
+      Hotel h = new Hotel("test3", "Fake St", "Wollongong", "NSW", "2518", "Australia");
+      entityManager.persist(h);
+      entityManager.flush();
+      throw new DontRollBackException();
+   }
+
+   @TransactionAttribute(TransactionAttributeType.NEVER)
+   public void tryAndAddHotelWithNoTransaction()
+   {
+      entityManager.joinTransaction();
+      Hotel h = new Hotel("test3", "Fake St", "Wollongong", "NSW", "2518", "Australia");
+      entityManager.persist(h);
+      entityManager.flush();
+   }
+
+}

Modified: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java	2010-07-27 08:58:14 UTC (rev 13515)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java	2010-07-27 09:07:36 UTC (rev 13516)
@@ -57,6 +57,8 @@
 /**
  * Tests the @Transactional interceptor
  * 
+ * TODO: refactor the tests to share a common superclass
+ * 
  * @author stuart
  * 
  */
@@ -92,7 +94,6 @@
    @Test
    public void testTransactionInterceptor() throws NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException
    {
-
       bean.addHotel();
       assertHotels(1);
       try



More information about the seam-commits mailing list