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

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Thu Jul 15 08:52:35 EDT 2010


Author: swd847
Date: 2010-07-15 08:52:34 -0400 (Thu, 15 Jul 2010)
New Revision: 13405

Added:
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/AbstractUserTransaction.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/CMTTransaction.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EJB.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EjbSynchronizations.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/LocalEjbSynchronizations.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Naming.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/NoTransaction.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/SeSynchronizations.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/SynchronizationRegistry.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Synchronizations.java
   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/java/org/jboss/seam/transaction/TransactionInterceptor.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/UTTransaction.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/UserTransaction.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Work.java
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/Hotel.java
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/SimpleTest.java
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/ArtifactNames.java
   modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/MavenArtifactResolver.java
   modules/persistence/trunk/src/test/resources-glassfish/
   modules/persistence/trunk/src/test/resources-glassfish/sun-resources.xml
   modules/persistence/trunk/src/test/resources-jbossas/
   modules/persistence/trunk/src/test/resources-jbossas/jndi.properties
   modules/persistence/trunk/src/test/resources-jbossas/seam-transactions-test-ds.xml
   modules/persistence/trunk/src/test/resources/META-INF/
   modules/persistence/trunk/src/test/resources/META-INF/persistence.xml
   modules/persistence/trunk/src/test/resources/META-INF/seam-beans.xml
   modules/persistence/trunk/src/test/resources/arquillian.xml
Modified:
   modules/persistence/trunk/pom.xml
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionPropagation.java
   modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transactional.java
Log:

initial port of seam 2 transaction management



Modified: modules/persistence/trunk/pom.xml
===================================================================
--- modules/persistence/trunk/pom.xml	2010-07-15 12:28:14 UTC (rev 13404)
+++ modules/persistence/trunk/pom.xml	2010-07-15 12:52:34 UTC (rev 13405)
@@ -15,8 +15,16 @@
 
    <properties>
       <seam.version>3.0.0.b01</seam.version>
+      <arquillian.version>1.0.0-SNAPSHOT</arquillian.version>
+      <junit.version>4.8.1</junit.version>
+      <jboss.home>${env.JBOSS_HOME}</jboss.home>
+      <jboss.domain>default</jboss.domain>
+      <glassfish.version>3.0.1-b19</glassfish.version>
+      <jboss-as-client.version>6.0.0-SNAPSHOT</jboss-as-client.version>
+      <jboss-javaee6-spec.version>1.0.0.Beta4</jboss-javaee6-spec.version>
+      <jboss-server-manager.version>1.0.3.GA</jboss-server-manager.version>
    </properties>
-   
+
    <prerequisites>
       <maven>3.0</maven>
    </prerequisites>
@@ -30,12 +38,32 @@
             <type>pom</type>
             <scope>import</scope>
          </dependency>
+
+         <dependency>
+            <groupId>org.jboss.arquillian</groupId>
+            <artifactId>arquillian-junit</artifactId>
+            <version>${arquillian.version}</version>
+            <scope>test</scope>
+         </dependency>
+
+         <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+         </dependency>
+
       </dependencies>
+
+
    </dependencyManagement>
 
    <dependencies>
-
       <dependency>
+         <groupId>junit</groupId>
+         <artifactId>junit</artifactId>
+      </dependency>
+      
+      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-core</artifactId>
       </dependency>
@@ -67,9 +95,142 @@
          <scope>provided</scope>
       </dependency>
 
+       <dependency>
+          <groupId>org.jboss.spec</groupId>
+          <artifactId>jboss-javaee-6.0</artifactId>
+          <version>${jboss-javaee6-spec.version}</version>
+          <type>pom</type>
+          <scope>provided</scope>
+       </dependency>
+
+      <dependency>
+         <groupId>org.jboss.weld</groupId>
+         <artifactId>weld-extensions</artifactId>
+         <version>1.0.0-SNAPSHOT</version>
+         <type>jar</type>
+         <scope>compile</scope>
+      </dependency>
+
+      <dependency>
+         <groupId>org.jboss.arquillian</groupId>
+         <artifactId>arquillian-junit</artifactId>
+         <scope>test</scope>
+      </dependency>
    </dependencies>
 
 
+   <profiles>
+      <profile>
+         <id>default</id>
+         <activation>
+            <activeByDefault>true</activeByDefault>
+         </activation>
+         <build>
+            <plugins>
+               <plugin>
+                  <artifactId>maven-surefire-plugin</artifactId>
+                  <configuration>
+                     <skip>true</skip>
+                  </configuration>
+               </plugin>            
+           </plugins>
+         </build>
+      </profile>
+   
+      <profile>
+         <id>jbossas-remote-60</id>
+         <dependencies>
+            <dependency>
+               <groupId>org.jboss.arquillian.container</groupId>
+               <artifactId>arquillian-jbossas-remote-6</artifactId>
+               <version>${arquillian.version}</version>
+               <scope>test</scope>
+            </dependency>
+            <dependency>
+               <groupId>org.jboss.spec</groupId>
+               <artifactId>jboss-javaee-6.0</artifactId>
+               <version>${jboss-javaee6-spec.version}</version>
+               <type>pom</type>
+               <scope>provided</scope>
+            </dependency>
+            <!-- need for org.jnp.interfaces.NamingContextFactory -->
+            <dependency>
+               <groupId>org.jboss.jbossas</groupId>
+               <artifactId>jboss-as-client</artifactId>
+               <version>${jboss-as-client.version}</version>
+               <type>pom</type>
+               <scope>test</scope>
+            </dependency>
+         </dependencies>
+         <build>
+            <testResources>
+               <testResource>
+                  <directory>src/test/resources</directory>
+               </testResource>
+               <testResource>
+                  <directory>src/test/resources-jbossas</directory>
+               </testResource>
+            </testResources>
+         </build>
+      </profile>
+
+      <profile>
+         <id>glassfish-embedded-30</id>
+         <dependencies>
+            <dependency>
+               <groupId>org.jboss.arquillian.container</groupId>
+               <artifactId>arquillian-glassfish-embedded-30</artifactId>
+               <version>${arquillian.version}</version>
+               <scope>test</scope>
+            </dependency>
+            <dependency>
+               <groupId>org.glassfish.extras</groupId>
+               <artifactId>glassfish-embedded-all</artifactId>
+               <version>${glassfish.version}</version>
+               <scope>provided</scope>
+            </dependency>
+         </dependencies>
+         <build>
+            <testResources>
+               <testResource>
+                  <directory>src/test/resources</directory>
+               </testResource>
+               <testResource>
+                  <directory>src/test/resources-glassfish</directory>
+               </testResource>
+            </testResources>
+         </build>
+      </profile>
+
+      <profile>
+         <id>glassfish-remote-30</id>
+         <dependencies>
+            <dependency>
+               <groupId>org.jboss.arquillian.container</groupId>
+               <artifactId>arquillian-glassfish-remote-30</artifactId>
+               <version>${arquillian.version}</version>
+               <scope>test</scope>
+            </dependency>
+            <dependency>
+               <groupId>org.glassfish.extras</groupId>
+               <artifactId>glassfish-embedded-all</artifactId>
+               <version>${glassfish.version}</version>
+               <scope>provided</scope>
+            </dependency>
+         </dependencies>
+         <build>
+            <testResources>
+               <testResource>
+                  <directory>src/test/resources</directory>
+               </testResource>
+               <testResource>
+                  <directory>src/test/resources-glassfish</directory>
+               </testResource>
+            </testResources>
+         </build>
+      </profile>
+   </profiles>
+
    <scm>
       <connection>scm:svn:http://anonsvn.jboss.org/repos/seam/modules/persistence/trunk</connection>
       <developerConnection>scm:svn:https://svn.jboss.org/repos/seam/modules/persistence/trunk</developerConnection>
@@ -77,3 +238,4 @@
    </scm>
 
 </project>
+

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/AbstractUserTransaction.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/AbstractUserTransaction.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/AbstractUserTransaction.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,86 @@
+package org.jboss.seam.transaction;
+
+import static javax.transaction.Status.STATUS_ACTIVE;
+import static javax.transaction.Status.STATUS_COMMITTED;
+import static javax.transaction.Status.STATUS_MARKED_ROLLBACK;
+import static javax.transaction.Status.STATUS_NO_TRANSACTION;
+import static javax.transaction.Status.STATUS_ROLLEDBACK;
+
+import javax.persistence.EntityManager;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+/**
+ * Base implementation of UserTransaction
+ * 
+ * @author Gavin King
+ * 
+ */
+public abstract class AbstractUserTransaction implements UserTransaction
+{
+
+   private final Synchronizations synchronizations;
+
+   public AbstractUserTransaction(Synchronizations synchronizations)
+   {
+      this.synchronizations = synchronizations;
+   }
+
+   public boolean isActive() throws SystemException
+   {
+      return getStatus() == STATUS_ACTIVE;
+   }
+
+   public boolean isActiveOrMarkedRollback() throws SystemException
+   {
+      int status = getStatus();
+      return status == STATUS_ACTIVE || status == STATUS_MARKED_ROLLBACK;
+   }
+
+   public boolean isRolledBackOrMarkedRollback() throws SystemException
+   {
+      int status = getStatus();
+      return status == STATUS_ROLLEDBACK || status == STATUS_MARKED_ROLLBACK;
+   }
+
+   public boolean isMarkedRollback() throws SystemException
+   {
+      return getStatus() == STATUS_MARKED_ROLLBACK;
+   }
+
+   public boolean isNoTransaction() throws SystemException
+   {
+      return getStatus() == STATUS_NO_TRANSACTION;
+   }
+
+   public boolean isRolledBack() throws SystemException
+   {
+      return getStatus() == STATUS_ROLLEDBACK;
+   }
+
+   public boolean isCommitted() throws SystemException
+   {
+      return getStatus() == STATUS_COMMITTED;
+   }
+
+   public boolean isConversationContextRequired()
+   {
+      return false;
+   }
+
+   public abstract void registerSynchronization(Synchronization sync);
+
+   public void enlist(EntityManager entityManager) throws SystemException
+   {
+      if (isActiveOrMarkedRollback())
+      {
+         entityManager.joinTransaction();
+      }
+   }
+
+   public Synchronizations getSynchronizations()
+   {
+      return synchronizations;
+   }
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/CMTTransaction.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/CMTTransaction.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/CMTTransaction.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,128 @@
+package org.jboss.seam.transaction;
+
+import javax.ejb.EJBContext;
+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 javax.transaction.UserTransaction;
+
+import org.jboss.weld.extensions.core.Veto;
+
+/**
+ * Wraps EJBContext transaction management in a UserTransaction interface. Note
+ * that container managed transactions cannot be controlled by the application,
+ * so begin(), commit() and rollback() are disallowed in a CMT.
+ * 
+ * @author Mike Youngstrom
+ * @author Gavin King
+ * @author Stuart Douglas
+ * 
+ */
+ at Veto
+public class CMTTransaction extends AbstractUserTransaction
+{
+
+   private final EJBContext ejbContext;
+
+   public CMTTransaction(EJBContext ejbContext, Synchronizations sync)
+   {
+      super(sync);
+      this.ejbContext = ejbContext;
+      if (ejbContext == null)
+      {
+         throw new IllegalArgumentException("null EJBContext");
+      }
+   }
+
+   public void begin() throws NotSupportedException, SystemException
+   {
+      ejbContext.getUserTransaction().begin();
+      getSynchronizations().afterTransactionBegin();
+   }
+
+   public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+   {
+      UserTransaction userTransaction = ejbContext.getUserTransaction();
+      boolean success = false;
+      Synchronizations synchronizations = getSynchronizations();
+      synchronizations.beforeTransactionCommit();
+      try
+      {
+         userTransaction.commit();
+         success = true;
+      }
+      finally
+      {
+         synchronizations.afterTransactionCommit(success);
+      }
+   }
+
+   public void rollback() throws IllegalStateException, SecurityException, SystemException
+   {
+      UserTransaction userTransaction = ejbContext.getUserTransaction();
+      try
+      {
+         userTransaction.rollback();
+      }
+      finally
+      {
+         getSynchronizations().afterTransactionRollback();
+      }
+   }
+
+   public int getStatus() throws SystemException
+   {
+      try
+      {
+         // TODO: not correct for SUPPORTS or NEVER!
+         if (!ejbContext.getRollbackOnly())
+         {
+            return Status.STATUS_ACTIVE;
+         }
+         else
+         {
+            return Status.STATUS_MARKED_ROLLBACK;
+         }
+      }
+      catch (IllegalStateException ise)
+      {
+         try
+         {
+            return ejbContext.getUserTransaction().getStatus();
+         }
+         catch (IllegalStateException is)
+         {
+            return Status.STATUS_NO_TRANSACTION;
+         }
+      }
+   }
+
+   public void setRollbackOnly() throws IllegalStateException, SystemException
+   {
+      ejbContext.setRollbackOnly();
+   }
+
+   public void setTransactionTimeout(int timeout) throws SystemException
+   {
+      ejbContext.getUserTransaction().setTransactionTimeout(timeout);
+   }
+
+   @Override
+   public void registerSynchronization(Synchronization sync)
+   {
+      Synchronizations synchronizations = getSynchronizations();
+      if (synchronizations.isAwareOfContainerTransactions())
+      {
+         synchronizations.registerSynchronization(sync);
+      }
+      else
+      {
+         throw new UnsupportedOperationException("cannot register synchronization with container transaction, use <transaction:ejb-transaction/>");
+      }
+   }
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EJB.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EJB.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EJB.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,39 @@
+package org.jboss.seam.transaction;
+
+import javax.ejb.EJBContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+
+/**
+ * utility class to look up the EJBContext
+ * 
+ * 
+ */
+public class EJB
+{
+   public static String ejbContextName = "java:comp.ejb3/EJBContext";
+   public static final String STANDARD_EJB_CONTEXT_NAME = "java:comp/EJBContext";
+
+   public static EJBContext getEJBContext() throws NamingException
+   {
+      try
+      {
+         return (EJBContext) Naming.getInitialContext().lookup(ejbContextName);
+      }
+      catch (NameNotFoundException nnfe)
+      {
+         return (EJBContext) Naming.getInitialContext().lookup(STANDARD_EJB_CONTEXT_NAME);
+      }
+   }
+
+   protected static String getEjbContextName()
+   {
+      return ejbContextName;
+   }
+
+   protected static void setEjbContextName(String ejbContextName)
+   {
+      EJB.ejbContextName = ejbContextName;
+   }
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EjbSynchronizations.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EjbSynchronizations.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/EjbSynchronizations.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,109 @@
+package org.jboss.seam.transaction;
+
+import java.rmi.RemoteException;
+import java.util.LinkedList;
+
+import javax.ejb.EJBException;
+import javax.ejb.Remove;
+import javax.ejb.SessionSynchronization;
+import javax.ejb.Stateful;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import javax.enterprise.context.RequestScoped;
+import javax.transaction.Synchronization;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Receives JTA transaction completion notifications from the EJB container, and
+ * passes them on to the registered Synchronizations. This implementation is
+ * fully aware of container managed transactions and is able to register
+ * Synchronizations for the container transaction.
+ * 
+ * @author Gavin King
+ * 
+ */
+ at Stateful
+ at RequestScoped
+ at TransactionAttribute(TransactionAttributeType.SUPPORTS)
+public class EjbSynchronizations implements LocalEjbSynchronizations, SessionSynchronization
+{
+   private static final Logger log = LoggerFactory.getLogger(EjbSynchronizations.class);
+
+   // maintain two lists to work around a bug in JBoss EJB3 where a new
+   // SessionSynchronization
+   // gets registered each time the bean is called
+   protected LinkedList<SynchronizationRegistry> synchronizations = new LinkedList<SynchronizationRegistry>();
+   protected LinkedList<SynchronizationRegistry> committing = new LinkedList<SynchronizationRegistry>();
+
+   public void afterBegin()
+   {
+      log.debug("afterBegin");
+      synchronizations.addLast(new SynchronizationRegistry());
+   }
+
+   public void beforeCompletion() throws EJBException, RemoteException
+   {
+      log.debug("beforeCompletion");
+      SynchronizationRegistry sync = synchronizations.removeLast();
+      sync.beforeTransactionCompletion();
+      committing.addLast(sync);
+   }
+
+   public void afterCompletion(boolean success) throws EJBException, RemoteException
+   {
+      log.debug("afterCompletion");
+      if (committing.isEmpty())
+      {
+         if (success)
+         {
+            throw new IllegalStateException("beforeCompletion was never called");
+         }
+         else
+         {
+            synchronizations.removeLast().afterTransactionCompletion(false);
+         }
+      }
+      else
+      {
+         committing.removeFirst().afterTransactionCompletion(success);
+      }
+   }
+
+   public boolean isAwareOfContainerTransactions()
+   {
+      return true;
+   }
+
+   public void afterTransactionBegin()
+   {
+      // noop, let JTA notify us
+   }
+
+   public void afterTransactionCommit(boolean success)
+   {
+      // noop, let JTA notify us
+   }
+
+   public void afterTransactionRollback()
+   {
+      // noop, let JTA notify us
+   }
+
+   public void beforeTransactionCommit()
+   {
+      // noop, let JTA notify us
+   }
+
+   public void registerSynchronization(Synchronization sync)
+   {
+      synchronizations.getLast().registerSynchronization(sync);
+   }
+
+   @Remove
+   public void destroy()
+   {
+   }
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/LocalEjbSynchronizations.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/LocalEjbSynchronizations.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/LocalEjbSynchronizations.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,15 @@
+package org.jboss.seam.transaction;
+
+import javax.ejb.Local;
+
+/**
+ * Local interface for EjbTransaction
+ * 
+ * @author Gavin King
+ * 
+ */
+ at Local
+public interface LocalEjbSynchronizations extends Synchronizations
+{
+   public void destroy();
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Naming.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Naming.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Naming.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.seam.transaction;
+
+import java.util.Hashtable;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * this has been ported to seam and hacked to make it work
+ * 
+ * we need to figure out what we are doing with JNDI in seam 3 and make this go
+ * away
+ * 
+ * @author stuart
+ * 
+ */
+public final class Naming
+{
+   private static final Logger log = LoggerFactory.getLogger(Naming.class);
+   private static Hashtable initialContextProperties;
+
+   private static InitialContext initialContext;
+
+   public static InitialContext getInitialContext(Hashtable<String, String> props) throws NamingException
+   {
+      if (props == null)
+      {
+         // throw new
+         // IllegalStateException("JNDI properties not initialized, Seam was not started correctly");
+      }
+      props = new Hashtable<String, String>();
+
+      if (log.isDebugEnabled())
+      {
+         log.debug("JNDI InitialContext properties:" + props);
+      }
+
+      try
+      {
+         return props.size() == 0 ? new InitialContext() : new InitialContext(props);
+      }
+      catch (NamingException e)
+      {
+         log.debug("Could not obtain initial context");
+         throw e;
+      }
+
+   }
+
+   public static InitialContext getInitialContext() throws NamingException
+   {
+      if (initialContext == null)
+         initInitialContext();
+
+      return initialContext;
+   }
+
+   private static synchronized void initInitialContext() throws NamingException
+   {
+      if (initialContext == null)
+      {
+         initialContext = getInitialContext(initialContextProperties);
+      }
+   }
+
+   private Naming()
+   {
+   }
+
+   public static void setInitialContextProperties(Hashtable initialContextProperties)
+   {
+      Naming.initialContextProperties = initialContextProperties;
+      initialContext = null;
+   }
+
+   public static Hashtable getInitialContextProperties()
+   {
+      return initialContextProperties;
+   }
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/NoTransaction.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/NoTransaction.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/NoTransaction.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,72 @@
+package org.jboss.seam.transaction;
+
+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;
+
+/**
+ * When no kind of transaction management exists.
+ * 
+ * @author Mike Youngstrom
+ * @author Gavin King
+ * 
+ */
+ at Veto
+public class NoTransaction extends AbstractUserTransaction
+{
+
+   public NoTransaction()
+   {
+      super(null);
+   }
+
+   public void begin() throws NotSupportedException, SystemException
+   {
+      throw new UnsupportedOperationException("no transaction");
+   }
+
+   public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+   {
+      throw new UnsupportedOperationException("no transaction");
+   }
+
+   public int getStatus() throws SystemException
+   {
+      return Status.STATUS_NO_TRANSACTION;
+   }
+
+   public void rollback() throws IllegalStateException, SecurityException, SystemException
+   {
+      throw new UnsupportedOperationException("no transaction");
+   }
+
+   public void setRollbackOnly() throws IllegalStateException, SystemException
+   {
+      throw new UnsupportedOperationException("no transaction");
+   }
+
+   public void setTransactionTimeout(int timeout) throws SystemException
+   {
+      throw new UnsupportedOperationException("no transaction");
+   }
+
+   @Override
+   public void registerSynchronization(Synchronization sync)
+   {
+      throw new UnsupportedOperationException("no transaction");
+   }
+
+   @Override
+   public void enlist(EntityManager entityManager) throws SystemException
+   {
+      // no-op
+   }
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/SeSynchronizations.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/SeSynchronizations.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/SeSynchronizations.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,71 @@
+package org.jboss.seam.transaction;
+
+import java.util.Stack;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Alternative;
+import javax.transaction.Synchronization;
+
+/**
+ * This implementation does not have access to the JTA TransactionManager, so it
+ * is not fully aware of container managed transaction lifecycle, and is not
+ * able to register Synchronizations with a container managed transaction.
+ * 
+ * This is an alternative, and as such must be enabled in beans.xml.
+ * 
+ * @author Gavin King
+ * @author Stuart Douglas
+ */
+ at RequestScoped
+ at Alternative
+public class SeSynchronizations implements Synchronizations
+{
+   protected Stack<SynchronizationRegistry> synchronizations = new Stack<SynchronizationRegistry>();
+
+   public void afterTransactionBegin()
+   {
+      synchronizations.push(new SynchronizationRegistry());
+   }
+
+   public void afterTransactionCommit(boolean success)
+   {
+      if (!synchronizations.isEmpty())
+      {
+         synchronizations.pop().afterTransactionCompletion(success);
+      }
+   }
+
+   public void afterTransactionRollback()
+   {
+      if (!synchronizations.isEmpty())
+      {
+         synchronizations.pop().afterTransactionCompletion(false);
+      }
+   }
+
+   public void beforeTransactionCommit()
+   {
+      if (!synchronizations.isEmpty())
+      {
+         synchronizations.peek().beforeTransactionCompletion();
+      }
+   }
+
+   public void registerSynchronization(Synchronization sync)
+   {
+      if (synchronizations.isEmpty())
+      {
+         throw new IllegalStateException("Transaction begin not detected, try installing transaction:ejb-transaction in components.xml");
+      }
+      else
+      {
+         synchronizations.peek().registerSynchronization(sync);
+      }
+   }
+
+   public boolean isAwareOfContainerTransactions()
+   {
+      return false;
+   }
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/SynchronizationRegistry.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/SynchronizationRegistry.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/SynchronizationRegistry.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,71 @@
+package org.jboss.seam.transaction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A list of Synchronizations to be invoked before and after transaction
+ * completion. This class is used when we can't register a synchronization
+ * directly with JTA.
+ * 
+ * @author Gavin King
+ * 
+ */
+class SynchronizationRegistry
+{
+   private static final Logger log = LoggerFactory.getLogger(SynchronizationRegistry.class);
+
+   private List<Synchronization> synchronizations = new ArrayList<Synchronization>();
+
+   void registerSynchronization(Synchronization sync)
+   {
+      synchronizations.add(sync);
+   }
+
+   void afterTransactionCompletion(boolean success)
+   {
+      // if ( Events.exists() )
+      // {
+      // Events.instance().raiseEvent("org.jboss.seam.afterTransactionCompletion",
+      // success);
+      // }
+      for (Synchronization sync : synchronizations)
+      {
+         try
+         {
+            sync.afterCompletion(success ? Status.STATUS_COMMITTED : Status.STATUS_ROLLEDBACK);
+         }
+         catch (Exception e)
+         {
+            log.error("Exception processing transaction Synchronization after completion", e);
+         }
+      }
+      synchronizations.clear();
+   }
+
+   void beforeTransactionCompletion()
+   {
+      // if ( Events.exists() )
+      // {
+      // Events.instance().raiseEvent("org.jboss.seam.beforeTransactionCompletion");
+      // }
+      for (Synchronization sync : synchronizations)
+      {
+         try
+         {
+            sync.beforeCompletion();
+         }
+         catch (Exception e)
+         {
+            log.error("Exception processing transaction Synchronization before completion", e);
+         }
+      }
+   }
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Synchronizations.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Synchronizations.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Synchronizations.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,24 @@
+package org.jboss.seam.transaction;
+
+import javax.transaction.Synchronization;
+
+/**
+ * Interface for registering transaction synchronizations
+ * 
+ * @author Gavin King
+ * 
+ */
+public interface Synchronizations
+{
+   public void afterTransactionBegin();
+
+   public void afterTransactionCommit(boolean success);
+
+   public void afterTransactionRollback();
+
+   public void beforeTransactionCommit();
+
+   public void registerSynchronization(Synchronization sync);
+
+   public boolean isAwareOfContainerTransactions();
+}
\ No newline at end of file

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transaction.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transaction.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transaction.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,85 @@
+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;
+import javax.naming.NamingException;
+
+/**
+ * Supports injection of a Seam UserTransaction object that wraps the current
+ * JTA transaction or EJB container managed transaction.
+ * 
+ * @author Mike Youngstrom
+ * @author Gavin King
+ * 
+ */
+ at ApplicationScoped
+public class Transaction
+{
+
+   @Inject
+   Synchronizations synchronizations;
+
+   @Produces
+   public UserTransaction getTransaction() throws NamingException
+   {
+      try
+      {
+         return createUTTransaction();
+      }
+      catch (NameNotFoundException nnfe)
+      {
+         try
+         {
+            return createCMTTransaction();
+         }
+         catch (NameNotFoundException nnfe2)
+         {
+            return createNoTransaction();
+         }
+      }
+   }
+
+   protected UserTransaction createNoTransaction()
+   {
+      return new NoTransaction();
+   }
+
+   protected UserTransaction createCMTTransaction() throws NamingException
+   {
+      return new CMTTransaction(EJB.getEJBContext(), synchronizations);
+   }
+
+   protected UserTransaction createUTTransaction() throws NamingException
+   {
+      return new UTTransaction(getUserTransaction(), synchronizations);
+   }
+
+   protected javax.transaction.UserTransaction getUserTransaction() throws NamingException
+   {
+      InitialContext context = Naming.getInitialContext();
+      try
+      {
+         return (javax.transaction.UserTransaction) context.lookup("java:comp/UserTransaction");
+      }
+      catch (NameNotFoundException nnfe)
+      {
+         try
+         {
+            // Embedded JBoss has no java:comp/UserTransaction
+            javax.transaction.UserTransaction ut = (javax.transaction.UserTransaction) context.lookup("UserTransaction");
+            ut.getStatus(); // for glassfish, which can return an unusable UT
+            return ut;
+         }
+         catch (Exception e)
+         {
+            throw nnfe;
+         }
+      }
+   }
+
+}
+
+

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionExtension.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionExtension.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionExtension.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,12 @@
+package org.jboss.seam.transaction;
+
+/**
+ * Extension than provides a {@link UserTransaction}
+ * 
+ * @author stuart
+ * 
+ */
+public class TransactionExtension
+{
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionInterceptor.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionInterceptor.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionInterceptor.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,118 @@
+package org.jboss.seam.transaction;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.InvocationContext;
+
+/**
+ * Implements transaction propagation rules for Seam JavaBean components.
+ * 
+ * @author Gavin King
+ * @author Shane Bryzak
+ */
+ at Transactional
+public class TransactionInterceptor
+{
+   private static final long serialVersionUID = -4364203056333738988L;
+
+   transient private Map<AnnotatedElement, TransactionMetadata> transactionMetadata = new HashMap<AnnotatedElement, TransactionMetadata>();
+
+   @Inject
+   UserTransaction transaction;
+
+   private class TransactionMetadata
+   {
+      private boolean annotationPresent;
+      TransactionPropagation propType;
+
+      public TransactionMetadata(AnnotatedElement element)
+      {
+         annotationPresent = element.isAnnotationPresent(Transactional.class);
+
+         if (annotationPresent)
+         {
+            propType = element.getAnnotation(Transactional.class).value();
+         }
+      }
+
+      public boolean isAnnotationPresent()
+      {
+         return annotationPresent;
+      }
+
+      public boolean isNewTransactionRequired(boolean transactionActive)
+      {
+         return propType != null && propType.isNewTransactionRequired(transactionActive);
+      }
+   }
+
+   private TransactionMetadata lookupTransactionMetadata(AnnotatedElement element)
+   {
+      if (transactionMetadata == null)
+      {
+         transactionMetadata = new HashMap<AnnotatedElement, TransactionMetadata>();
+      }
+
+      TransactionMetadata metadata = transactionMetadata.get(element);
+
+      if (metadata == null)
+      {
+         metadata = loadMetadata(element);
+      }
+
+      return metadata;
+   }
+
+   private synchronized TransactionMetadata loadMetadata(AnnotatedElement element)
+   {
+      if (!transactionMetadata.containsKey(element))
+      {
+         TransactionMetadata metadata = new TransactionMetadata(element);
+         transactionMetadata.put(element, metadata);
+         return metadata;
+      }
+
+      return transactionMetadata.get(element);
+   }
+
+   @AroundInvoke
+   public Object aroundInvoke(final InvocationContext invocation) throws Exception
+   {
+      return new Work()
+      {
+
+         @Override
+         protected Object work() throws Exception
+         {
+            return invocation.proceed();
+         }
+
+         @Override
+         protected boolean isNewTransactionRequired(boolean transactionActive)
+         {
+            return isNewTransactionRequired(invocation.getMethod(), invocation.getTarget().getClass(), transactionActive);
+         }
+
+         private boolean isNewTransactionRequired(Method method, Class<?> beanClass, boolean transactionActive)
+         {
+            TransactionMetadata metadata = lookupTransactionMetadata(method);
+            if (metadata.isAnnotationPresent())
+            {
+               return metadata.isNewTransactionRequired(transactionActive);
+            }
+            else
+            {
+               metadata = lookupTransactionMetadata(beanClass);
+               return metadata.isNewTransactionRequired(transactionActive);
+            }
+         }
+
+      }.workInTransaction(transaction);
+   }
+
+}

Modified: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionPropagation.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionPropagation.java	2010-07-15 12:28:14 UTC (rev 13404)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/TransactionPropagation.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -3,6 +3,38 @@
 /**
  * @author Dan Allen
  */
-public enum TransactionPropagation {
+public enum TransactionPropagation
+{
    REQUIRED, SUPPORTS, MANDATORY, NEVER;
+
+   public boolean isNewTransactionRequired(boolean transactionActive)
+   {
+      switch (this)
+      {
+      case REQUIRED:
+         return !transactionActive;
+      case SUPPORTS:
+         return false;
+      case MANDATORY:
+         if (!transactionActive)
+         {
+            throw new IllegalStateException("No transaction active on call to MANDATORY method");
+         }
+         else
+         {
+            return false;
+         }
+      case NEVER:
+         if (transactionActive)
+         {
+            throw new IllegalStateException("Transaction active on call to NEVER method");
+         }
+         else
+         {
+            return false;
+         }
+      default:
+         throw new IllegalArgumentException();
+      }
+   }
 }
\ No newline at end of file

Modified: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transactional.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transactional.java	2010-07-15 12:28:14 UTC (rev 13404)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Transactional.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -14,12 +14,14 @@
 @Inherited
 @InterceptorBinding
 @Retention(RetentionPolicy.RUNTIME)
- at Target({ElementType.METHOD, ElementType.TYPE})
-public @interface Transactional {
+ at Target( { ElementType.METHOD, ElementType.TYPE })
+public @interface Transactional
+{
    /**
     * The transaction propagation type.
-    *
+    * 
     * @return REQUIRED by default
     */
-   @Nonbinding TransactionPropagation value() default TransactionPropagation.REQUIRED;
+   @Nonbinding
+   TransactionPropagation value() default TransactionPropagation.REQUIRED;
 }
\ No newline at end of file

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/UTTransaction.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/UTTransaction.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/UTTransaction.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,96 @@
+package org.jboss.seam.transaction;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.jboss.weld.extensions.core.Veto;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Wraps JTA transaction management in a Seam UserTransaction interface.
+ * 
+ * @author Mike Youngstrom
+ * @author Gavin King
+ * 
+ */
+ at Veto
+public class UTTransaction extends AbstractUserTransaction
+{
+   private static final Logger log = LoggerFactory.getLogger(UTTransaction.class);
+
+   private final javax.transaction.UserTransaction delegate;
+
+   UTTransaction(javax.transaction.UserTransaction delegate, Synchronizations sync)
+   {
+      super(sync);
+      this.delegate = delegate;
+      if (delegate == null)
+      {
+         throw new IllegalArgumentException("null UserTransaction");
+      }
+   }
+
+   public void begin() throws NotSupportedException, SystemException
+   {
+      log.debug("beginning JTA transaction");
+      delegate.begin();
+      getSynchronizations().afterTransactionBegin();
+   }
+
+   public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException
+   {
+      log.debug("committing JTA transaction");
+      boolean success = false;
+      Synchronizations synchronizations = getSynchronizations();
+      synchronizations.beforeTransactionCommit();
+      try
+      {
+         delegate.commit();
+         success = true;
+      }
+      finally
+      {
+         synchronizations.afterTransactionCommit(success);
+      }
+   }
+
+   public void rollback() throws IllegalStateException, SecurityException, SystemException
+   {
+      log.debug("rolling back JTA transaction");
+      try
+      {
+         delegate.rollback();
+      }
+      finally
+      {
+         getSynchronizations().afterTransactionRollback();
+      }
+   }
+
+   public int getStatus() throws SystemException
+   {
+      return delegate.getStatus();
+   }
+
+   public void setRollbackOnly() throws IllegalStateException, SystemException
+   {
+      delegate.setRollbackOnly();
+   }
+
+   public void setTransactionTimeout(int timeout) throws SystemException
+   {
+      delegate.setTransactionTimeout(timeout);
+   }
+
+   @Override
+   public void registerSynchronization(Synchronization sync)
+   {
+      getSynchronizations().registerSynchronization(sync);
+   }
+
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/UserTransaction.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/UserTransaction.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/UserTransaction.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,36 @@
+package org.jboss.seam.transaction;
+
+import javax.persistence.EntityManager;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+/**
+ * Extends the standard UserTransaction interface with a couple of helpful
+ * methods.
+ * 
+ * @author Gavin King
+ * 
+ */
+public interface UserTransaction extends javax.transaction.UserTransaction
+{
+
+   public boolean isActive() throws SystemException;
+
+   public boolean isActiveOrMarkedRollback() throws SystemException;
+
+   public boolean isRolledBackOrMarkedRollback() throws SystemException;
+
+   public boolean isMarkedRollback() throws SystemException;
+
+   public boolean isNoTransaction() throws SystemException;
+
+   public boolean isRolledBack() throws SystemException;
+
+   public boolean isCommitted() throws SystemException;
+
+   public boolean isConversationContextRequired();
+
+   public abstract void registerSynchronization(Synchronization sync);
+
+   public void enlist(EntityManager entityManager) throws SystemException;
+}

Added: modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Work.java
===================================================================
--- modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Work.java	                        (rev 0)
+++ modules/persistence/trunk/src/main/java/org/jboss/seam/transaction/Work.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,84 @@
+package org.jboss.seam.transaction;
+
+import javax.ejb.ApplicationException;
+import javax.transaction.Status;
+import javax.transaction.UserTransaction;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Performs work in a JTA transaction.
+ * 
+ * @author Gavin King
+ */
+public abstract class Work<T>
+{
+   private static final Logger log = LoggerFactory.getLogger(Work.class);
+
+   protected abstract T work() throws Exception;
+
+   protected boolean isNewTransactionRequired(boolean transactionActive)
+   {
+      return !transactionActive;
+   }
+
+   public final T workInTransaction(org.jboss.seam.transaction.UserTransaction transaction) throws Exception
+   {
+      boolean transactionActive = transaction.isActiveOrMarkedRollback() || transaction.isRolledBack();
+      // TODO: temp workaround, what should we really do in this case??
+      boolean newTransactionRequired = isNewTransactionRequired(transactionActive);
+      UserTransaction userTransaction = newTransactionRequired ? transaction : null;
+
+      try
+      {
+         if (newTransactionRequired)
+         {
+            log.debug("beginning transaction");
+            userTransaction.begin();
+         }
+
+         T result = work();
+         if (newTransactionRequired)
+         {
+            if (transaction.isMarkedRollback())
+            {
+               log.debug("rolling back transaction");
+               userTransaction.rollback();
+            }
+            else
+            {
+               log.debug("committing transaction");
+               userTransaction.commit();
+            }
+         }
+         return result;
+      }
+      catch (Exception e)
+      {
+         if (newTransactionRequired && userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION && isRollbackRequired(e, true))
+         {
+            log.debug("rolling back transaction");
+            userTransaction.rollback();
+         }
+         throw e;
+      }
+
+   }
+
+   public static boolean isRollbackRequired(Exception e, boolean isJavaBean)
+   {
+      Class<? extends Exception> clazz = e.getClass();
+      return (isSystemException(e, isJavaBean, clazz)) || (clazz.isAnnotationPresent(ApplicationException.class) && clazz.getAnnotation(ApplicationException.class).rollback());
+   }
+
+   private static boolean isSystemException(Exception e, boolean isJavaBean, Class<? extends Exception> clazz)
+   {
+      return isJavaBean && (e instanceof RuntimeException) && !clazz.isAnnotationPresent(ApplicationException.class);
+      // &&
+      // TODO: this is hackish, maybe just turn off RollackInterceptor for
+      // @Converter/@Validator components
+      // !JSF.VALIDATOR_EXCEPTION.isInstance(e) &&
+      // !JSF.CONVERTER_EXCEPTION.isInstance(e);
+   }
+}

Added: modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/Hotel.java
===================================================================
--- modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/Hotel.java	                        (rev 0)
+++ modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/Hotel.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,205 @@
+/* 
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, 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.transactions.test;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import org.jboss.weld.extensions.core.Veto;
+
+/**
+ * <p>
+ * <strong>Hotel</strong> is the model/entity class that represents a hotel.
+ * </p>
+ * 
+ * @author Gavin King
+ * @author Dan Allen
+ */
+ at Entity
+ at Table(name = "hotel")
+ at Veto
+public class Hotel implements Serializable
+{
+   private Long id;
+   private String name;
+   private String address;
+   private String city;
+   private String state;
+   private String zip;
+   private String country;
+   private Integer stars;
+   private BigDecimal price;
+
+   public Hotel()
+   {
+   }
+
+   public Hotel(final String name, final String address, final String city, final String state, final String zip, final String country)
+   {
+      this.name = name;
+      this.address = address;
+      this.city = city;
+      this.state = state;
+      this.zip = zip;
+      this.country = country;
+   }
+
+   public Hotel(final int price, final int stars, final String name, final String address, final String city, final String state, final String zip, final String country)
+   {
+      this.price = new BigDecimal(price);
+      this.stars = stars;
+      this.name = name;
+      this.address = address;
+      this.city = city;
+      this.state = state;
+      this.zip = zip;
+      this.country = country;
+   }
+
+   @Id
+   @GeneratedValue
+   public Long getId()
+   {
+      return id;
+   }
+
+   public void setId(final Long id)
+   {
+      this.id = id;
+   }
+
+   @Size(max = 50)
+   @NotNull
+   public String getName()
+   {
+      return name;
+   }
+
+   public void setName(final String name)
+   {
+      this.name = name;
+   }
+
+   @Size(max = 100)
+   @NotNull
+   public String getAddress()
+   {
+      return address;
+   }
+
+   public void setAddress(final String address)
+   {
+      this.address = address;
+   }
+
+   @Size(max = 40)
+   @NotNull
+   public String getCity()
+   {
+      return city;
+   }
+
+   public void setCity(final String city)
+   {
+      this.city = city;
+   }
+
+   @Size(min = 3, max = 6)
+   @NotNull
+   public String getZip()
+   {
+      return zip;
+   }
+
+   public void setZip(final String zip)
+   {
+      this.zip = zip;
+   }
+
+   @Size(min = 2, max = 10)
+   public String getState()
+   {
+      return state;
+   }
+
+   public void setState(final String state)
+   {
+      this.state = state;
+   }
+
+   @Size(min = 2, max = 40)
+   @NotNull
+   public String getCountry()
+   {
+      return country;
+   }
+
+   public void setCountry(final String country)
+   {
+      this.country = country;
+   }
+
+   @Min(1)
+   @Max(5)
+   public Integer getStars()
+   {
+      return stars;
+   }
+
+   public void setStars(final Integer stars)
+   {
+      this.stars = stars;
+   }
+
+   @Column(precision = 6, scale = 2)
+   public BigDecimal getPrice()
+   {
+      return price;
+   }
+
+   public void setPrice(final BigDecimal price)
+   {
+      this.price = price;
+   }
+
+   @Transient
+   public String getLocation()
+   {
+      return city + ", " + state + ", " + country;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "Hotel(" + name + "," + address + "," + city + "," + zip + ")";
+   }
+}

Added: modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/SimpleTest.java
===================================================================
--- modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/SimpleTest.java	                        (rev 0)
+++ modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/SimpleTest.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,75 @@
+package org.jboss.seam.transactions.test;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnit;
+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.transaction.Transaction;
+import org.jboss.seam.transaction.UserTransaction;
+import org.jboss.seam.transactions.test.util.ArtifactNames;
+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;
+
+ at RunWith(Arquillian.class)
+public class SimpleTest
+{
+   @Deployment
+   public static Archive<?> createTestArchive()
+   {
+
+      WebArchive war = ShrinkWrap.create("test.war", WebArchive.class).addLibraries(MavenArtifactResolver.resolve(ArtifactNames.WELD_EXTENSIONS)).addPackage(Transaction.class.getPackage()).addPackage(SimpleTest.class.getPackage()).addWebResource("META-INF/persistence.xml", "classes/META-INF/persistence.xml").addWebResource(new ByteArrayAsset(new byte[0]), "beans.xml");
+      
+      return war;
+   }
+
+   @Inject
+   UserTransaction transaction;
+
+   @PersistenceUnit
+   EntityManagerFactory emf;
+
+   @Test
+   public void simpleTest() throws NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException
+   {
+      transaction.begin();
+      EntityManager em = emf.createEntityManager();
+      em.joinTransaction();
+      Hotel h = new Hotel("test", "Fake St", "Wollongong", "NSW", "2518", "Australia");
+      em.persist(h);
+      em.flush();
+      transaction.commit();
+
+      transaction.begin();
+      em = emf.createEntityManager();
+      em.joinTransaction();
+      h = new Hotel("test2", "Fake St", "Wollongong", "NSW", "2518", "Australia");
+      em.persist(h);
+      em.flush();
+      transaction.rollback();
+
+      transaction.begin();
+      em = emf.createEntityManager();
+      em.joinTransaction();
+      List<Hotel> hotels = em.createQuery("select h from Hotel h").getResultList();
+      Assert.assertTrue(hotels.size() == 1);
+      transaction.rollback();
+
+   }
+}

Added: modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/ArtifactNames.java
===================================================================
--- modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/ArtifactNames.java	                        (rev 0)
+++ modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/ArtifactNames.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,7 @@
+package org.jboss.seam.transactions.test.util;
+
+public class ArtifactNames
+{
+   public static final String WELD_EXTENSIONS = "org.jboss.weld:weld-extensions:1.0.0-SNAPSHOT";
+
+}

Added: modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/MavenArtifactResolver.java
===================================================================
--- modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/MavenArtifactResolver.java	                        (rev 0)
+++ modules/persistence/trunk/src/test/java/org/jboss/seam/transactions/test/util/MavenArtifactResolver.java	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,25 @@
+package org.jboss.seam.transactions.test.util;
+
+import java.io.File;
+
+public class MavenArtifactResolver
+{
+   private static final String LOCAL_MAVEN_REPO =
+         System.getProperty("user.home") + File.separatorChar +
+         ".m2" + File.separatorChar + "repository";
+
+   public static File resolve(String groupId, String artifactId, String version)
+   {
+      return new File(LOCAL_MAVEN_REPO + File.separatorChar +
+            groupId.replace(".", File.separator) + File.separatorChar +
+            artifactId + File.separatorChar +
+            version + File.separatorChar +
+            artifactId + "-" + version + ".jar");
+   }
+
+   public static File resolve(String qualifiedArtifactId)
+   {
+      String[] segments = qualifiedArtifactId.split(":");
+      return resolve(segments[0], segments[1], segments[2]);
+   }
+}

Added: modules/persistence/trunk/src/test/resources/META-INF/persistence.xml
===================================================================
--- modules/persistence/trunk/src/test/resources/META-INF/persistence.xml	                        (rev 0)
+++ modules/persistence/trunk/src/test/resources/META-INF/persistence.xml	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
+   version="2.0">
+   <persistence-unit name="transactionPu">
+      <!--
+      <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+      -->
+      <provider>org.hibernate.ejb.HibernatePersistence</provider>
+      <jta-data-source>java:/DefaultDS</jta-data-source>
+      <class>org.jboss.seam.transactions.test.Hotel</class>
+      <exclude-unlisted-classes/>
+      <properties>
+         <!-- Properties for Hibernate (default provider for JBoss AS) -->
+         <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
+         <property name="hibernate.show_sql" value="true"/>
+         <!-- Only format when you need to debug, because it slows things down -->
+         <property name="hibernate.format_sql" value="false"/>
+
+         <!-- Properties for EclipseLink (default provider for GlassFish) -->
+         <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
+         <property name="eclipselink.logging.level" value="FINE"/>
+      </properties>
+   </persistence-unit>
+</persistence>

Added: modules/persistence/trunk/src/test/resources/META-INF/seam-beans.xml
===================================================================
--- modules/persistence/trunk/src/test/resources/META-INF/seam-beans.xml	                        (rev 0)
+++ modules/persistence/trunk/src/test/resources/META-INF/seam-beans.xml	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,30 @@
+<!--
+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.
+-->
+<beans xmlns="http://java.sun.com/xml/ns/javaee"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xmlns:s="urn:java:seam:core" 
+   xmlns:i18n="urn:java:org.jboss.seam.international.locale"
+   xsi:schemaLocation="
+      http://java.sun.com/xml/ns/javaee 
+      http://docs.jboss.org/cdi/beans_1_0.xsd">
+
+</beans>

Added: modules/persistence/trunk/src/test/resources/arquillian.xml
===================================================================
--- modules/persistence/trunk/src/test/resources/arquillian.xml	                        (rev 0)
+++ modules/persistence/trunk/src/test/resources/arquillian.xml	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<arquillian xmlns="http://jboss.com/arquillian"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xmlns:gfembedded="urn:arq:org.jboss.arquillian.glassfish.embedded30"
+   xmlns:gfremote="urn:arq:org.jboss.arquillian.container.glassfish.remote30">
+
+   <engine>
+      <deploymentExportPath>/tmp/</deploymentExportPath>
+   </engine>
+   
+   <gfremote:container>
+      <gfremote:remoteServerHttpPort>7070</gfremote:remoteServerHttpPort>
+   </gfremote:container>
+
+   <gfembedded:container>
+      <gfembedded:sunResourcesXml>src/test/resources-glassfish/sun-resources.xml</gfembedded:sunResourcesXml>
+   </gfembedded:container>  
+
+</arquillian>

Added: modules/persistence/trunk/src/test/resources-glassfish/sun-resources.xml
===================================================================
--- modules/persistence/trunk/src/test/resources-glassfish/sun-resources.xml	                        (rev 0)
+++ modules/persistence/trunk/src/test/resources-glassfish/sun-resources.xml	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE resources PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Resource Definitions //EN"
+   "http://www.sun.com/software/appserver/dtds/sun-resources_1_4.dtd">
+<resources>
+   <jdbc-resource pool-name="ArquillianEmbeddedDerbyPool"
+      jndi-name="jdbc/__arquillian"/>
+   <jdbc-connection-pool name="ArquillianEmbeddedDerbyPool"
+      res-type="javax.sql.DataSource"
+      datasource-classname="org.apache.derby.jdbc.EmbeddedDataSource"
+      is-isolation-level-guaranteed="false">
+      <property name="databaseName" value="target/databases/derby"/>
+      <property name="createDatabase" value="create"/>
+   </jdbc-connection-pool>
+   <!--
+   <jdbc-resource pool-name="ArquillianEmbeddedH2Pool"
+      jndi-name="jdbc/__arquillian"/>
+   <jdbc-connection-pool name="ArquillianEmbeddedH2Pool"
+      res-type="javax.sql.DataSource"
+      datasource-classname="org.h2.jdbcx.JdbcDataSource">
+      <property name="user" value="sa"/>
+      <property name="password" value=""/>
+      <property name="url" value="jdbc:h2:file:target/databases/h2/db"/>
+   </jdbc-connection-pool>
+   -->
+</resources>

Added: modules/persistence/trunk/src/test/resources-jbossas/jndi.properties
===================================================================
--- modules/persistence/trunk/src/test/resources-jbossas/jndi.properties	                        (rev 0)
+++ modules/persistence/trunk/src/test/resources-jbossas/jndi.properties	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,3 @@
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces 
+java.naming.provider.url=jnp://localhost:1099 

Added: modules/persistence/trunk/src/test/resources-jbossas/seam-transactions-test-ds.xml
===================================================================
--- modules/persistence/trunk/src/test/resources-jbossas/seam-transactions-test-ds.xml	                        (rev 0)
+++ modules/persistence/trunk/src/test/resources-jbossas/seam-transactions-test-ds.xml	2010-07-15 12:52:34 UTC (rev 13405)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE datasources
+   PUBLIC "-//JBoss//DTD JBOSS JCA Config 1.5//EN"
+   "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">
+<datasources>
+   <local-tx-datasource>
+      <jndi-name>jdbc/__default</jndi-name>
+      <use-java-context>false</use-java-context>
+      <connection-url>jdbc:hsqldb:.</connection-url>
+      <driver-class>org.hsqldb.jdbcDriver</driver-class>
+      <user-name>sa</user-name>
+      <password></password>
+      <min-pool-size>5</min-pool-size>
+      <max-pool-size>20</max-pool-size>
+   </local-tx-datasource>
+</datasources>



More information about the seam-commits mailing list