Repository: tapestry-5 Updated Branches: refs/heads/master 820d7d087 -> 3c28f94a4
TAP5-2588: JPA patches provided by Dmitris Zenios Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/3c28f94a Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/3c28f94a Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/3c28f94a Branch: refs/heads/master Commit: 3c28f94a4814f3294ff4e8179109c72ffa7f0722 Parents: 820d7d0 Author: Thiago H. de Paula Figueiredo <thi...@arsmachina.com.br> Authored: Wed Dec 5 21:47:17 2018 -0200 Committer: Thiago H. de Paula Figueiredo <thi...@arsmachina.com.br> Committed: Wed Dec 5 21:47:17 2018 -0200 ---------------------------------------------------------------------- .../ioc/internal/AnnotationAccessImpl.java | 27 ++- .../internal/services/AspectDecoratorImpl.java | 2 +- .../internal/jpa/CommitAfterWorker.java | 21 +-- .../jpa/EntityTransactionManagerImpl.java | 26 +-- .../internal/jpa/JpaAdvisorProvider.java | 9 + .../internal/jpa/JpaAdvisorProviderImpl.java | 20 +++ .../internal/jpa/JpaInternalUtils.java | 9 +- .../internal/jpa/JpaTransactionAdvisorImpl.java | 25 +-- ...ContextSpecificEntityTransactionManager.java | 14 +- .../apache/tapestry5/jpa/modules/JpaModule.java | 13 +- tapestry-jpa/src/test/conf/testng.xml | 70 ++++---- .../jpa/JpaTransactionAdvisorImplTest.java | 163 +++++++++++++------ .../org/example/app5/services/AppModule.java | 1 + tapestry-runner/build.gradle | 1 + .../org/apache/tapestry5/test/TomcatRunner.java | 23 ++- 15 files changed, 244 insertions(+), 180 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java index b088cb9..f8c6155 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java @@ -14,34 +14,45 @@ package org.apache.tapestry5.ioc.internal; +import org.apache.tapestry5.func.F; +import org.apache.tapestry5.func.Flow; +import org.apache.tapestry5.func.Mapper; import org.apache.tapestry5.ioc.AnnotationAccess; import org.apache.tapestry5.ioc.AnnotationProvider; +import org.apache.tapestry5.ioc.internal.services.AnnotationProviderChain; import org.apache.tapestry5.ioc.internal.util.InternalUtils; +import java.lang.reflect.Method; + /** - * Standard AnnotationAccess for a specific type. + * Standard AnnotationAccess for an array of classes * * @since 5.3 */ public class AnnotationAccessImpl implements AnnotationAccess { - private final Class type; + private final Class[] classes; - public AnnotationAccessImpl(Class type) + public AnnotationAccessImpl(Class ...types) { - this.type = type; + this.classes = types; } @Override public AnnotationProvider getClassAnnotationProvider() { - return InternalUtils.toAnnotationProvider(type); + return AnnotationProviderChain.create(F.flow(classes).removeNulls().map(InternalUtils.CLASS_TO_AP_MAPPER).toList()); } @Override - public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes) - { - return InternalUtils.toAnnotationProvider(InternalUtils.findMethod(type, methodName, parameterTypes)); + public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes) { + Flow<Class> searchClasses = F.flow(classes).removeNulls(); + return AnnotationProviderChain.create(searchClasses.map(new Mapper<Class, Method>() { + @Override + public Method map(Class element) { + return InternalUtils.findMethod(element, methodName, parameterTypes); + } + }).map(InternalUtils.METHOD_TO_AP_MAPPER).toList()); } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java index 18aa888..f37770e 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java @@ -39,7 +39,7 @@ public class AspectDecoratorImpl implements AspectDecorator @Override public <T> AspectInterceptorBuilder<T> createBuilder(Class<T> serviceInterface, final T delegate, String description) { - return createBuilder(serviceInterface, delegate, new AnnotationAccessImpl(delegate.getClass()), description); + return createBuilder(serviceInterface, delegate, new AnnotationAccessImpl(delegate.getClass(),serviceInterface), description); } @Override http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/CommitAfterWorker.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/CommitAfterWorker.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/CommitAfterWorker.java index 30046e8..7c1d63c 100644 --- a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/CommitAfterWorker.java +++ b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/CommitAfterWorker.java @@ -14,17 +14,11 @@ package org.apache.tapestry5.internal.jpa; -import java.util.HashMap; -import java.util.Map; -import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; -import org.apache.tapestry5.jpa.EntityManagerManager; -import org.apache.tapestry5.jpa.EntityTransactionManager; import org.apache.tapestry5.jpa.annotations.CommitAfter; import org.apache.tapestry5.model.MutableComponentModel; -import org.apache.tapestry5.plastic.MethodAdvice; import org.apache.tapestry5.plastic.PlasticClass; import org.apache.tapestry5.plastic.PlasticMethod; import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2; @@ -32,27 +26,22 @@ import org.apache.tapestry5.services.transform.TransformationSupport; public class CommitAfterWorker implements ComponentClassTransformWorker2 { - private final Map<String, MethodAdvice> methodAdvices; + private final JpaAdvisorProvider jpaAdvisorProvider; - public CommitAfterWorker(EntityManagerManager manager, - EntityTransactionManager transactionManager) + public CommitAfterWorker(JpaAdvisorProvider jpaAdvisorProvider) { - methodAdvices = new HashMap<>(manager.getEntityManagers().size()); - for (Map.Entry<String, EntityManager> entry : manager.getEntityManagers().entrySet()) - methodAdvices.put(entry.getKey(), - new CommitAfterMethodAdvice(transactionManager, entry.getKey())); - methodAdvices.put(null, new CommitAfterMethodAdvice(transactionManager, null)); + this.jpaAdvisorProvider = jpaAdvisorProvider; } @Override public void transform(PlasticClass plasticClass, TransformationSupport support, - MutableComponentModel model) + MutableComponentModel model) { for (final PlasticMethod method : plasticClass.getMethodsWithAnnotation(CommitAfter.class)) { PersistenceContext annotation = method.getAnnotation(PersistenceContext.class); - method.addAdvice(methodAdvices.get(annotation == null ? null : annotation.unitName())); + method.addAdvice(jpaAdvisorProvider.getAdvice(annotation)); } } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityTransactionManagerImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityTransactionManagerImpl.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityTransactionManagerImpl.java index c0c639d..28500c4 100644 --- a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityTransactionManagerImpl.java +++ b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityTransactionManagerImpl.java @@ -16,8 +16,6 @@ package org.apache.tapestry5.internal.jpa; import java.util.HashMap; import java.util.Map; -import javax.persistence.EntityManager; - import org.apache.tapestry5.ioc.Invokable; import org.apache.tapestry5.ioc.ScopeConstants; import org.apache.tapestry5.ioc.annotations.Scope; @@ -38,28 +36,8 @@ public class EntityTransactionManagerImpl implements EntityTransactionManager { this.logger = logger; this.entityManagerManager = entityManagerManager; - transactionManagerMap = new HashMap<>(entityManagerManager.getEntityManagers().size()); - } - - private EntityManager getEntityManager(String unitName) - { - // EntityManager em = JpaInternalUtils.getEntityManager(entityManagerManager, unitName); - // FIXME we should simply incorporate the logic in JpaInternalUtils.getEntityManager to - // EntityManagerManager.getEntityManager(unitName) - if (unitName != null) - return entityManagerManager.getEntityManager(unitName); - else - { - Map<String, EntityManager> entityManagers = entityManagerManager.getEntityManagers(); - if (entityManagers.size() == 1) - return entityManagers.values().iterator().next(); - else - throw new RuntimeException( - "Unable to locate a single EntityManager. " - + "You must provide the persistence unit name as defined in the persistence.xml using the @PersistenceContext annotation."); - } + this.transactionManagerMap = new HashMap<>(entityManagerManager.getEntityManagers().size()); } - /* * (non-Javadoc) * @see net.satago.tapestry5.jpa.EntityTransactionManager#runInTransaction(java.lang.String, @@ -91,7 +69,7 @@ public class EntityTransactionManagerImpl implements EntityTransactionManager if (!transactionManagerMap.containsKey(unitName)) { PersistenceContextSpecificEntityTransactionManager transactionManager = new PersistenceContextSpecificEntityTransactionManager( - logger, getEntityManager(unitName)); + logger, JpaInternalUtils.getEntityManager(entityManagerManager,unitName)); transactionManagerMap.put(unitName, transactionManager); return transactionManager; } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProvider.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProvider.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProvider.java new file mode 100644 index 0000000..108d55f --- /dev/null +++ b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProvider.java @@ -0,0 +1,9 @@ +package org.apache.tapestry5.internal.jpa; + +import org.apache.tapestry5.plastic.MethodAdvice; + +import javax.persistence.PersistenceContext; + +public interface JpaAdvisorProvider { + MethodAdvice getAdvice(PersistenceContext context); +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProviderImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProviderImpl.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProviderImpl.java new file mode 100644 index 0000000..51b50b4 --- /dev/null +++ b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProviderImpl.java @@ -0,0 +1,20 @@ +package org.apache.tapestry5.internal.jpa; + +import org.apache.tapestry5.jpa.EntityTransactionManager; +import org.apache.tapestry5.plastic.MethodAdvice; + +import javax.persistence.PersistenceContext; + +public class JpaAdvisorProviderImpl implements JpaAdvisorProvider { + private final MethodAdvice shared; + private final EntityTransactionManager transactionManager; + + public JpaAdvisorProviderImpl(EntityTransactionManager transactionManager) { + this.shared = new CommitAfterMethodAdvice(transactionManager, null); + this.transactionManager = transactionManager; + } + @Override + public MethodAdvice getAdvice(PersistenceContext context) { + return context == null ? shared : new CommitAfterMethodAdvice(transactionManager,context.unitName()); + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java index d612e74..aff8e21 100644 --- a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java +++ b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java @@ -78,10 +78,15 @@ public class JpaInternalUtils } public static EntityManager getEntityManager(EntityManagerManager entityManagerManager, - PersistenceContext annotation) - { + PersistenceContext annotation) { String unitName = annotation == null ? null : annotation.unitName(); + return getEntityManager(entityManagerManager, unitName); + } + + public static EntityManager getEntityManager(EntityManagerManager entityManagerManager, + String unitName) + { if (InternalUtils.isNonBlank(unitName)) return entityManagerManager.getEntityManager(unitName); http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImpl.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImpl.java index 1803722..7d7437c 100644 --- a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImpl.java +++ b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImpl.java @@ -15,31 +15,21 @@ package org.apache.tapestry5.internal.jpa; import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.apache.tapestry5.ioc.MethodAdviceReceiver; -import org.apache.tapestry5.jpa.EntityManagerManager; -import org.apache.tapestry5.jpa.EntityTransactionManager; + import org.apache.tapestry5.jpa.JpaTransactionAdvisor; import org.apache.tapestry5.jpa.annotations.CommitAfter; -import org.apache.tapestry5.plastic.MethodAdvice; public class JpaTransactionAdvisorImpl implements JpaTransactionAdvisor { - private final Map<String, MethodAdvice> methodAdvices; + private final JpaAdvisorProvider jpaAdvisorProvider; - public JpaTransactionAdvisorImpl(EntityManagerManager manager, - EntityTransactionManager transactionManager) + public JpaTransactionAdvisorImpl(JpaAdvisorProvider jpaAdvisorProvider) { - methodAdvices = new HashMap<>(manager.getEntityManagers().size()); - for (Map.Entry<String, EntityManager> entry : manager.getEntityManagers().entrySet()) - methodAdvices.put(entry.getKey(), - new CommitAfterMethodAdvice(transactionManager, entry.getKey())); - methodAdvices.put(null, new CommitAfterMethodAdvice(transactionManager, null)); + this.jpaAdvisorProvider = jpaAdvisorProvider; } @Override @@ -49,11 +39,8 @@ public class JpaTransactionAdvisorImpl implements JpaTransactionAdvisor { if (m.getAnnotation(CommitAfter.class) != null) { - PersistenceContext annotation = receiver.getMethodAnnotation(m, - PersistenceContext.class); - - receiver.adviseMethod(m, - methodAdvices.get(annotation == null ? null : annotation.unitName())); + PersistenceContext annotation = receiver.getMethodAnnotation(m, PersistenceContext.class); + receiver.adviseMethod(m, jpaAdvisorProvider.getAdvice(annotation)); } } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/PersistenceContextSpecificEntityTransactionManager.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/PersistenceContextSpecificEntityTransactionManager.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/PersistenceContextSpecificEntityTransactionManager.java index ed53f2b..43405f2 100644 --- a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/PersistenceContextSpecificEntityTransactionManager.java +++ b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/PersistenceContextSpecificEntityTransactionManager.java @@ -67,6 +67,7 @@ public class PersistenceContextSpecificEntityTransactionManager public <T> T invokeInTransaction(Invokable<T> invokable) { + final EntityTransaction transaction = getTransaction(); if (transactionBeingCommitted) { // happens for example if you try to run a transaction in @PostCommit hook. We can only @@ -79,7 +80,7 @@ public class PersistenceContextSpecificEntityTransactionManager } else { - rollbackTransaction(getTransaction()); + rollbackTransaction(transaction); throw new RuntimeException( "Current transaction is already being committed. Transactions started @PostCommit are not allowed to return a value"); } @@ -95,7 +96,6 @@ public class PersistenceContextSpecificEntityTransactionManager } } - final EntityTransaction transaction = getTransaction(); try { T result = invokable.invoke(); @@ -104,15 +104,11 @@ public class PersistenceContextSpecificEntityTransactionManager { // Success or checked exception: - if (transaction.isActive()) + boolean isActive = transaction.isActive(); + if (isActive) { invokeBeforeCommit(transaction); - } - - // FIXME check if we are still on top - - if (transaction.isActive()) - { + // FIXME check if we are still on top transactionBeingCommitted = true; transaction.commit(); transactionBeingCommitted = false; http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/modules/JpaModule.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/modules/JpaModule.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/modules/JpaModule.java index 723b38a..f78b71c 100644 --- a/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/modules/JpaModule.java +++ b/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/modules/JpaModule.java @@ -23,17 +23,7 @@ import javax.persistence.spi.PersistenceUnitInfo; import org.apache.tapestry5.ValueEncoder; import org.apache.tapestry5.internal.InternalConstants; -import org.apache.tapestry5.internal.jpa.CommitAfterWorker; -import org.apache.tapestry5.internal.jpa.EntityApplicationStatePersistenceStrategy; -import org.apache.tapestry5.internal.jpa.EntityManagerManagerImpl; -import org.apache.tapestry5.internal.jpa.EntityManagerObjectProvider; -import org.apache.tapestry5.internal.jpa.EntityManagerSourceImpl; -import org.apache.tapestry5.internal.jpa.EntityPersistentFieldStrategy; -import org.apache.tapestry5.internal.jpa.EntityTransactionManagerImpl; -import org.apache.tapestry5.internal.jpa.JpaTransactionAdvisorImpl; -import org.apache.tapestry5.internal.jpa.JpaValueEncoder; -import org.apache.tapestry5.internal.jpa.PackageNamePersistenceUnitConfigurer; -import org.apache.tapestry5.internal.jpa.PersistenceContextWorker; +import org.apache.tapestry5.internal.jpa.*; import org.apache.tapestry5.internal.services.PersistentFieldManager; import org.apache.tapestry5.ioc.Configuration; import org.apache.tapestry5.ioc.LoggerSource; @@ -84,6 +74,7 @@ public class JpaModule binder.bind(PersistenceUnitConfigurer.class, PackageNamePersistenceUnitConfigurer.class).withSimpleId(); binder.bind(EntityManagerSource.class, EntityManagerSourceImpl.class); binder.bind(EntityTransactionManager.class, EntityTransactionManagerImpl.class); + binder.bind(JpaAdvisorProvider.class,JpaAdvisorProviderImpl.class); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/test/conf/testng.xml ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/test/conf/testng.xml b/tapestry-jpa/src/test/conf/testng.xml index 025f946..9267615 100644 --- a/tapestry-jpa/src/test/conf/testng.xml +++ b/tapestry-jpa/src/test/conf/testng.xml @@ -8,47 +8,49 @@ the specific language governing permissions and limitations under the License. --> <suite name="Tapestry JPA" parallel="false" thread-count="10" - annotations="1.5" verbose="2"> -<!-- <test name="Tapestry JPA Integration Tests" enabled="true"> --> -<!-- <parameter name="tapestry.web-app-folder" value="src/test/app1" /> --> -<!-- <packages> --> -<!-- <package name="org.apache.tapestry5.jpa.integration.app1" /> --> -<!-- </packages> --> -<!-- </test> --> - -<!-- <test name="Single Persistence Unit Integration Tests" enabled="true"> --> -<!-- <parameter name="tapestry.web-app-folder" value="src/test/app2" /> --> -<!-- <packages> --> -<!-- <package name="org.apache.tapestry5.jpa.integration.app2" /> --> -<!-- </packages> --> -<!-- </test> --> + annotations="1.5" verbose="2"> + <test name="Tapestry JPA Integration Tests" enabled="true"> + <parameter name="tapestry.web-app-folder" value="src/test/app1" /> + <packages> + <package name="org.apache.tapestry5.jpa.integration.app1" /> + </packages> + </test> -<!-- <test name="JNDI DataSource Integration Tests" enabled="true"> --> -<!-- <parameter name="tapestry.web-app-folder" value="src/test/app3" /> --> -<!-- <parameter name="tapestry.servlet-container" value="tomcat6" /> --> -<!-- <packages> --> -<!-- <package name="org.apache.tapestry5.jpa.integration.app3" /> --> -<!-- </packages> --> -<!-- </test> --> + <test name="Single Persistence Unit Integration Tests" enabled="true"> + <parameter name="tapestry.web-app-folder" value="src/test/app2" /> + <packages> + <package name="org.apache.tapestry5.jpa.integration.app2" /> + </packages> + </test> -<!-- <test name="Explicit Provider Class Name In Persistence Unit Integration Tests" enabled="true"> --> -<!-- <parameter name="tapestry.web-app-folder" value="src/test/app5" /> --> -<!-- <packages> --> -<!-- <package name="org.apache.tapestry5.jpa.integration.app5" /> --> -<!-- </packages> --> -<!-- </test> --> + <test name="JNDI DataSource Integration Tests" enabled="true"> + <parameter name="tapestry.web-app-folder" value="src/test/app3" /> + <parameter name="tapestry.servlet-container" value="tomcat6" /> + <packages> + <package name="org.apache.tapestry5.jpa.integration.app3" /> + </packages> + </test> -<!-- <test name="Tapestry JPA Unit Tests" enabled="false"> --> -<!-- <packages> --> -<!-- <package name="org.apache.tapestry5.internal.jpa" /> --> -<!-- </packages> --> -<!-- </test> --> - <test name="Tapestry JPA Integration Tests with Annotations in Service Implementation" enabled="true"> <parameter name="tapestry.web-app-folder" value="src/test/app6" /> <packages> <package name="org.apache.tapestry5.jpa.integration.app6" /> </packages> </test> - + + <test name="Tapestry JPA Unit Tests" enabled="true"> + <packages> + <package name="org.apache.tapestry5.internal.jpa" /> + </packages> + </test> + + <!-- Put this last since it modifies + PersistenceProviderResolverHolder.setPersistenceProviderResolver + which affects other test suites --> + <test name="Explicit Provider Class Name In Persistence Unit Integration Tests" enabled="true"> + <parameter name="tapestry.web-app-folder" value="src/test/app5" /> + <packages> + <package name="org.apache.tapestry5.jpa.integration.app5" /> + </packages> + </test> </suite> http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/test/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImplTest.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/test/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImplTest.java b/tapestry-jpa/src/test/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImplTest.java index 6d3eb40..92ffd33 100644 --- a/tapestry-jpa/src/test/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImplTest.java +++ b/tapestry-jpa/src/test/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImplTest.java @@ -32,6 +32,7 @@ import org.apache.tapestry5.jpa.EntityManagerManager; import org.apache.tapestry5.jpa.EntityTransactionManager; import org.apache.tapestry5.jpa.JpaTransactionAdvisor; import org.apache.tapestry5.jpa.annotations.CommitAfter; +import org.slf4j.LoggerFactory; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -66,10 +67,9 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase public void undecorated() { final VoidService delegate = newMock(VoidService.class); - final EntityManagerManager manager = newMock(EntityManagerManager.class); final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); - + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder( VoidService.class, delegate, "foo.Bar"); @@ -87,14 +87,20 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase @Test public void persistence_unit_name_missing() { - final VoidService delegate = newMock(VoidService.class); - final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); Map<String, EntityManager> managers = CollectionFactory.newMap(); managers.put("A", newMock(EntityManager.class)); managers.put("B", newMock(EntityManager.class)); + final VoidService delegate = newMock(VoidService.class); + final EntityManagerManager manager = newMock(EntityManagerManager.class); + expect(manager.getEntityManagers()).andReturn(managers); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder( VoidService.class, delegate, "foo.Bar"); @@ -121,15 +127,24 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase @Test public void persistence_unit_name_missing_single_unit_configured() { - final VoidService delegate = newMock(VoidService.class); - final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); - final EntityTransaction transaction = newMock(EntityTransaction.class); EntityManager em = newMock(EntityManager.class); Map<String, EntityManager> managers = CollectionFactory.newMap(); managers.put("A", em); + final VoidService delegate = newMock(VoidService.class); + final EntityManagerManager manager = newMock(EntityManagerManager.class); + expect(manager.getEntityManagers()).andReturn(managers); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); + + final EntityTransaction transaction = newMock(EntityTransaction.class); + + final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder( VoidService.class, delegate, "foo.Bar"); @@ -150,14 +165,23 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase @Test public void persistence_unit_missing() { - final VoidService delegate = newMock(VoidService.class); - final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); Map<String, EntityManager> managers = CollectionFactory.newMap(); managers.put("A", newMock(EntityManager.class)); managers.put("B", newMock(EntityManager.class)); + final VoidService delegate = newMock(VoidService.class); + final EntityManagerManager manager = newMock(EntityManagerManager.class); + expect(manager.getEntityManagers()).andReturn(managers); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); + + final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder( VoidService.class, delegate, "foo.Bar"); @@ -184,14 +208,20 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase @Test public void persistence_unit_missing_single_unit_configured() { - final VoidService delegate = newMock(VoidService.class); - final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); - final EntityTransaction transaction = newMock(EntityTransaction.class); EntityManager em = newMock(EntityManager.class); Map<String, EntityManager> managers = CollectionFactory.newMap(); managers.put("A", em); + final VoidService delegate = newMock(VoidService.class); + final EntityManagerManager manager = newMock(EntityManagerManager.class); + expect(manager.getEntityManagers()).andReturn(managers); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); + final EntityTransaction transaction = newMock(EntityTransaction.class); final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder( VoidService.class, delegate, "foo.Bar"); @@ -215,8 +245,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase { final VoidService delegate = newMock(VoidService.class); final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); + expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap()); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final EntityManager entityManager = newMock(EntityManager.class); final EntityTransaction transaction = newMock(EntityTransaction.class); @@ -243,8 +279,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase { final VoidService delegate = newMock(VoidService.class); final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); + expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap()); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final EntityManager entityManager = newMock(EntityManager.class); final EntityTransaction transaction = newMock(EntityTransaction.class); @@ -271,8 +313,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase { final VoidService delegate = newMock(VoidService.class); final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); + expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap()); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final EntityManager entityManager = newMock(EntityManager.class); final EntityTransaction transaction = newMock(EntityTransaction.class); @@ -297,8 +345,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase { final Performer delegate = newMock(Performer.class); final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); + expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap()); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final EntityManager entityManager = newMock(EntityManager.class); final EntityTransaction transaction = newMock(EntityTransaction.class); final RuntimeException re = new RuntimeException("Unexpected."); @@ -333,8 +387,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase { final Performer delegate = newMock(Performer.class); final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); + expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap()); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final EntityManager entityManager = newMock(EntityManager.class); final EntityTransaction transaction = newMock(EntityTransaction.class); final SQLException se = new SQLException("Checked."); @@ -374,8 +434,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase { final ReturnTypeService delegate = newTestService(); final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); + expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap()); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final EntityManager entityManager = newMock(EntityManager.class); final EntityTransaction transaction = newMock(EntityTransaction.class); @@ -400,8 +466,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase { final ReturnTypeService delegate = newTestService(); final EntityManagerManager manager = newMock(EntityManagerManager.class); - final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class); - final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager); + expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap()); + + replay(); + final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl( + LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager); + verify(); + final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager); + final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider); final EntityManager entityManager = newMock(EntityManager.class); final EntityTransaction transaction = newMock(EntityTransaction.class); @@ -462,10 +534,9 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase transaction.rollback(); } - private JpaTransactionAdvisor newJpaTransactionAdvisor(final EntityManagerManager manager, - EntityTransactionManager transactionManager) + private JpaTransactionAdvisor newJpaTransactionAdvisor(final JpaAdvisorProvider provider) { - return new JpaTransactionAdvisorImpl(manager, transactionManager); + return new JpaTransactionAdvisorImpl(provider); } private ReturnTypeService newTestService() @@ -533,20 +604,4 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase @PersistenceContext(unitName = UNIT_NAME) void perform() throws SQLException; } - - public interface Service - { - void perform(); - } - - public class ServiceImpl implements Service { - @Override - @CommitAfter - @PersistenceContext(unitName = UNIT_NAME) - public void perform() - { - - } - } - } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-jpa/src/test/java/org/example/app5/services/AppModule.java ---------------------------------------------------------------------- diff --git a/tapestry-jpa/src/test/java/org/example/app5/services/AppModule.java b/tapestry-jpa/src/test/java/org/example/app5/services/AppModule.java index 05d2488..e3f380a 100644 --- a/tapestry-jpa/src/test/java/org/example/app5/services/AppModule.java +++ b/tapestry-jpa/src/test/java/org/example/app5/services/AppModule.java @@ -34,6 +34,7 @@ public class AppModule static { + //This will also affect test suites run after this one.Its better to run this suite last PersistenceProviderResolverHolder.setPersistenceProviderResolver( new PersistenceProviderResolver() { http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-runner/build.gradle ---------------------------------------------------------------------- diff --git a/tapestry-runner/build.gradle b/tapestry-runner/build.gradle index f905c70..3f7a6ff 100644 --- a/tapestry-runner/build.gradle +++ b/tapestry-runner/build.gradle @@ -10,6 +10,7 @@ dependencies { compile "org.apache.tomcat:tomcat-catalina:${versions.tomcat}" compile "org.apache.tomcat:tomcat-coyote:${versions.tomcat}" + compile "org.apache.tomcat:tomcat-jasper:${versions.tomcat}" compile "org.apache.tomcat:tomcat-dbcp:${versions.tomcat}" compile "commons-cli:commons-cli:1.2" http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3c28f94a/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java ---------------------------------------------------------------------- diff --git a/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java b/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java index f382330..a37b580 100644 --- a/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java +++ b/tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java @@ -15,7 +15,6 @@ package org.apache.tapestry5.test; import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; import java.io.File; @@ -50,9 +49,12 @@ public class TomcatRunner implements ServletContainerRunner if (!tmpDir.endsWith(fileSeparator)) tmpDir = tmpDir + fileSeparator; tomcatServer.setBaseDir(tmpDir + "tomcat"); - + tomcatServer.setPort(port); tomcatServer.addWebapp("/", expandedPath); + //Enable jndi lookups + tomcatServer.enableNaming(); + tomcatServer.getConnector().setAllowTrace(true); // SSL support @@ -68,6 +70,7 @@ public class TomcatRunner implements ServletContainerRunner } tomcatServer.start(); + startDaemonAwaitThread(); } /** @@ -82,6 +85,7 @@ public class TomcatRunner implements ServletContainerRunner { // Stop immediately and not gracefully. tomcatServer.stop(); + tomcatServer.destroy(); } catch (Exception ex) { @@ -117,4 +121,19 @@ public class TomcatRunner implements ServletContainerRunner return new File(TapestryRunnerConstants.MODULE_BASE_DIR, moduleLocalPath).getPath(); } + // Unlike Jetty, all Tomcat threads are daemon threads. We create a + // blocking non-daemon to stop immediate shutdown + private void startDaemonAwaitThread() { + Thread awaitThread = new Thread() { + + @Override + public void run() { + TomcatRunner.this.tomcatServer.getServer().await(); + } + + }; + awaitThread.setContextClassLoader(getClass().getClassLoader()); + awaitThread.setDaemon(false); + awaitThread.start(); + } }