You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@onami.apache.org by sc...@apache.org on 2014/04/07 16:12:21 UTC
svn commit: r1585487 [2/5] - in /onami/sandbox/persist: ./
src/main/java/org/apache/onami/persist/ src/sandbox/
src/test/java/org/apache/onami/persist/
src/test/java/org/apache/onami/persist/test/
src/test/java/org/apache/onami/persist/test/transaction...
Modified: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceModule.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceModule.java?rev=1585487&r1=1585486&r2=1585487&view=diff
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceModule.java (original)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceModule.java Mon Apr 7 14:12:18 2014
@@ -20,245 +20,146 @@ package org.apache.onami.persist;
*/
import com.google.inject.AbstractModule;
+import com.google.inject.Key;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
import com.google.inject.matcher.Matcher;
-import com.google.inject.matcher.Matchers;
-import org.aopalliance.intercept.MethodInterceptor;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
-import javax.transaction.UserTransaction;
import java.lang.reflect.AnnotatedElement;
import java.util.ArrayList;
import java.util.List;
-import java.util.Properties;
-import static org.apache.onami.persist.Preconditions.checkNotNull;
+import static com.google.inject.matcher.Matchers.annotatedWith;
import static com.google.inject.matcher.Matchers.any;
+import static org.apache.onami.persist.Preconditions.checkNotNull;
/**
- * Main module of the jpa-persistence guice extension.
+ * Main module of the onami persist guice extension.
* <p/>
- * Add either a {@link ApplicationManagedPersistenceUnitModule} or a
- * {@link ContainerManagedPersistenceUnitModule} per persistence unit using the methods
+ * Add persistence unit using the methods
* <ul>
- * <li>{@link #add(ApplicationManagedPersistenceUnitModule)}</li>
* <li>{@link #addApplicationManagedPersistenceUnit(String)}</li>
- * <li>{@link #addApplicationManagedPersistenceUnit(String, Properties)}</li>
- * <li>{@link #add(ContainerManagedPersistenceUnitModule)}</li>
- * <li>{@link #addContainerManagedPersistenceUnit(String)}</li>
- * <li>{@link #addContainerManagedPersistenceUnit(String, Properties)}</li>
+ * <li>{@link #addContainerManagedPersistenceUnitWithJndiName(String)}</li>
+ * <li>{@link #addContainerManagedPersistenceUnit(EntityManagerFactory)}</li>
+ * <li>{@link #addContainerManagedPersistenceUnitProvidedBy(Provider<EntityManagerFactory>)}</li>
* </ul>
- * <p/>
- * If container managed persistence units have been added and JTA transactions are supported.
- * Use {@link #setUserTransactionJndiName(String)} to define the JNDI name of the
- * {@link UserTransaction} provided by the container.
*/
-public final class PersistenceModule
+public abstract class PersistenceModule
extends AbstractModule
{
- // ---- Members
+ private List<PersistenceUnitModule> puModules;
+
+ private final PersistenceUnitContainer container = new PersistenceUnitContainer();
+ private final Matcher<AnnotatedElement> transactionalMatcher = annotatedWith( Transactional.class );
+ private final Matcher<Object> anyMatcher = any();
- /**
- * List of all module builders.
- */
- private final List<PersistenceUnitBuilder> moduleBuilders = new ArrayList<PersistenceUnitBuilder>();
-
- /**
- * List of all persistence unit modules.
- * If this list is empty it means that configure has not yet been called
- */
- private final List<AbstractPersistenceUnitModule> modules = new ArrayList<AbstractPersistenceUnitModule>();
-
- /**
- * Container for holding all registered persistence units.
- */
- private final PersistenceUnitContainer puContainer = new PersistenceUnitContainer();
-
- /**
- * The JNDI name to lookup the {@link UserTransaction}.
- */
- private String utJndiName;
-
- /**
- * The {@link UserTransactionFacade}.
- */
- private UserTransactionFacade utFacade = null;
-
- // ---- Methods
-
- /**
- * Adds an application managed persistence unit.
- *
- * @param puName the name of the persistence unit as specified in the persistence.xml. Must not be {@code null}.
- * @return a builder to further configure the persistence unit.
- */
- public PersistenceUnitBuilder addApplicationManagedPersistenceUnit( String puName )
- {
- checkNotNull( puName );
- return add( new ApplicationManagedPersistenceUnitModule( puName ) );
- }
-
- /**
- * Adds an application managed persistence unit.
- *
- * @param puName the name of the persistence unit as specified in the persistence.xml. Must not be {@code null}.
- * @param properties the properties to pass to the {@link EntityManagerFactory}. Must not be {@code null}.
- * @return a builder to further configure the persistence unit.
- */
- public PersistenceUnitBuilder addApplicationManagedPersistenceUnit( String puName, Properties properties )
- {
- checkNotNull( puName );
- checkNotNull( properties );
- return add( new ApplicationManagedPersistenceUnitModule( puName, properties ) );
- }
-
- /**
- * Adds an application managed persistence unit.
- *
- * @param module the module of the persistence unit. Must not be {@code null}.
- * @return a builder to further configure the persistence unit.
- */
- public PersistenceUnitBuilder add( ApplicationManagedPersistenceUnitModule module )
- {
- ensureConfigurHasNotYetBeenExecuted();
- checkNotNull( module );
- final PersistenceUnitBuilder builder = new PersistenceUnitBuilder( module );
- moduleBuilders.add( builder );
- return builder;
- }
-
- /**
- * Adds an container managed persistence unit.
- *
- * @param emfJndiName the JNDI name of the {@link EntityManagerFactory}. Must not be {@code null}.
- * @return a builder to further configure the persistence unit.
- */
- public PersistenceUnitBuilder addContainerManagedPersistenceUnit( String emfJndiName )
- {
- checkNotNull( emfJndiName );
- return add( new ContainerManagedPersistenceUnitModule( emfJndiName ) );
- }
-
- /**
- * Adds an container managed persistence unit.
- *
- * @param emfJndiName the JNDI name of the {@link EntityManagerFactory}. Must not be {@code null}.
- * @param properties the properties to pass to the {@link EntityManager}. Must not be {@code null}.
- * @return a builder to further configure the persistence unit.
- */
- public PersistenceUnitBuilder addContainerManagedPersistenceUnit( String emfJndiName, Properties properties )
- {
- checkNotNull( emfJndiName );
- checkNotNull( properties );
- return add( new ContainerManagedPersistenceUnitModule( emfJndiName, properties ) );
- }
-
- /**
- * Adds an container managed persistence unit.
- *
- * @param module the module of the persistence unit. Must not be {@code null}.
- * @return a builder to further configure the persistence unit.
- */
- public PersistenceUnitBuilder add( ContainerManagedPersistenceUnitModule module )
- {
- ensureConfigurHasNotYetBeenExecuted();
- checkNotNull( module );
- final PersistenceUnitBuilder builder = new PersistenceUnitBuilder( module );
- moduleBuilders.add( builder );
- return builder;
- }
-
- /**
- * Setter for defining the JNDI name of the container managed {@link UserTransaction}.
- *
- * @param utJndiName the JNDI name of the container managed {@link UserTransaction}.
- */
- public void setUserTransactionJndiName( String utJndiName )
- {
- ensureConfigurHasNotYetBeenExecuted();
- this.utJndiName = utJndiName;
- }
-
- /**
- * {@inheritDoc}
- */
@Override
- protected void configure()
+ protected final void configure()
{
- if ( configureHasNotBeenExecutedYet() )
+ if ( puModules != null )
{
- if ( 0 == moduleBuilders.size() )
- {
- addError( "no persistence units defined. At least one persistence unit is required." );
- return;
- }
- initUserTransactionFacade();
- for ( PersistenceUnitBuilder builder : moduleBuilders )
- {
- final AbstractPersistenceUnitModule module = builder.build();
- puContainer.add( module.getPersistenceService(), module.getUnitOfWork() );
- modules.add( module );
- }
+ throw new RuntimeException( "cannot reenter the configure method" );
}
-
- for ( AbstractPersistenceUnitModule module : modules )
+ try {
+ puModules = new ArrayList<PersistenceUnitModule>();
+ doConfigure();
+ }
+ finally
{
- install( module );
+ puModules = null;
+ }
+ }
- final Matcher<AnnotatedElement> matcher = Matchers.annotatedWith( Transactional.class );
- final MethodInterceptor transactionInterceptor = module.getTransactionInterceptor( utFacade );
+ private void doConfigure()
+ {
+ configurePersistence();
- bindInterceptor( matcher, any(), transactionInterceptor );
- bindInterceptor( any(), matcher, transactionInterceptor );
+ for(PersistenceUnitModule pu : puModules)
+ {
+ final TxnInterceptor txnInterceptor = new TxnInterceptor();
+ pu.setPersistenceUnitContainer( container );
+ pu.setTransactionInterceptor( txnInterceptor );
+ install( pu );
+ bindInterceptor( anyMatcher, transactionalMatcher, txnInterceptor );
+ bindInterceptor( transactionalMatcher, anyMatcher, txnInterceptor );
}
+ }
- bind( PersistenceService.class ).annotatedWith( AllPersistenceUnits.class ).toInstance( puContainer );
- bind( UnitOfWork.class ).annotatedWith( AllPersistenceUnits.class ).toInstance( puContainer );
- bind( PersistenceFilter.class ).toInstance( new PersistenceFilter( puContainer ) );
+ protected abstract void configurePersistence();
+
+ protected UnannotatedPersistenceUnitBuilder addApplicationManagedPersistenceUnit( String puName )
+ {
+ checkNotNull( puModules,
+ "calling addApplicationManagedPersistenceUnit outside of configurePersistence is not supported" );
+ final PersistenceUnitModuleConfigurator configurator = createAndAddPuModule();
+ configurator.setPuName(puName);
+ return configurator;
}
- /**
- * @return {@code true} if {@link #configure()} has not yet been invoked.
- */
- private boolean configureHasNotBeenExecutedYet()
+ protected UnannotatedPersistenceUnitBuilder addContainerManagedPersistenceUnit( EntityManagerFactory emf )
{
- return modules.size() == 0;
+ checkNotNull( puModules,
+ "calling addContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
+ final PersistenceUnitModuleConfigurator configurator = createAndAddPuModule();
+ configurator.setEmf( emf );
+ return configurator;
}
- /**
- * Make sure that the {@link #configure()} method has not been executed yet.
- */
- private void ensureConfigurHasNotYetBeenExecuted()
+ protected UnannotatedPersistenceUnitBuilder addContainerManagedPersistenceUnitWithJndiName( String jndiName )
{
- if ( configureHasNotBeenExecutedYet() )
- {
- return;
- }
- throw new IllegalStateException( "cannot change a module after creating the injector." );
+ checkNotNull( puModules,
+ "calling addContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
+ final PersistenceUnitModuleConfigurator configurator = createAndAddPuModule();
+ configurator.setEmfJndiName( jndiName );
+ return configurator;
}
- /**
- * Initializes the field {@link #utFacade} with the {@link UserTransaction} obtained by a
- * JNDI lookup.
- */
- private void initUserTransactionFacade()
+ protected UnannotatedPersistenceUnitBuilder addContainerManagedPersistenceUnitProvidedBy(
+ Provider<EntityManagerFactory> emfProvider )
{
- if ( null != utJndiName )
- {
- try
- {
- final InitialContext ctx = new InitialContext();
- final UserTransaction txn = (UserTransaction) ctx.lookup( utJndiName );
- utFacade = new UserTransactionFacade( txn );
- }
- catch ( NamingException e )
- {
- addError( "lookup for UserTransaction with JNDI name '%s' failed", utJndiName );
- }
- }
+ checkNotNull( puModules,
+ "calling addContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
+ final PersistenceUnitModuleConfigurator configurator = createAndAddPuModule();
+ configurator.setEmfProvider( emfProvider );
+ return configurator;
+ }
+
+ protected UnannotatedPersistenceUnitBuilder addContainerManagedPersistenceUnitProvidedBy(
+ Class<? extends Provider<EntityManagerFactory>> emfProviderClass )
+ {
+ checkNotNull( puModules,
+ "calling addContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
+ final PersistenceUnitModuleConfigurator configurator = createAndAddPuModule();
+ configurator.setEmfProviderClass( emfProviderClass );
+ return configurator;
+ }
+
+ protected UnannotatedPersistenceUnitBuilder addContainerManagedPersistenceUnitProvidedBy(
+ TypeLiteral<? extends Provider<EntityManagerFactory>> emfProviderType )
+ {
+ checkNotNull( puModules,
+ "calling addContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
+ final PersistenceUnitModuleConfigurator configurator = createAndAddPuModule();
+ configurator.setEmfProviderType( emfProviderType );
+ return configurator;
}
+ protected UnannotatedPersistenceUnitBuilder addContainerManagedPersistenceUnitProvidedBy(
+ Key<? extends Provider<EntityManagerFactory>> emfProviderKey )
+ {
+ checkNotNull( puModules,
+ "calling addContainerManagedPersistenceUnit outside of configurePersistence is not supported" );
+ final PersistenceUnitModuleConfigurator configurator = createAndAddPuModule();
+ configurator.setEmfProviderKey( emfProviderKey );
+ return configurator;
+ }
+
+ private PersistenceUnitModuleConfigurator createAndAddPuModule()
+ {
+ final PersistenceUnitModuleConfigurator configurator = new PersistenceUnitModuleConfigurator();
+ puModules.add( configurator.getPuModule() );
+ return configurator;
+ }
}
Modified: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceService.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceService.java?rev=1585487&r1=1585486&r2=1585487&view=diff
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceService.java (original)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceService.java Mon Apr 7 14:12:18 2014
@@ -22,15 +22,15 @@ package org.apache.onami.persist;
/**
* This is the main control to the entire persistence engine. Before calling any other method
* of either {@link UnitOfWork}, {@link EntityManagerProvider}, or any method annotated with
- * @{@link Transactional} the persistence service must be started.
+ * {@link Transactional @Transactional} the persistence service must be started.
*/
public interface PersistenceService
{
/**
- * Starts the underlying persistence engine and makes jpa-persist ready for use.
- * This method must be called by your code prior to using any other jpa-persist artifacts.
- * If you are using jpa-persist in a web container {@link PersistenceFilter} will call this
+ * Starts the underlying persistence engine and makes onami-persist ready for use.
+ * This method must be called by your code prior to using any other onami-persist artifacts.
+ * If you are using onami-persist in a web container {@link PersistenceFilter} will call this
* method upon initialization of the web application.
*
* @throws IllegalArgumentException if the service is already running.
Modified: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitContainer.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitContainer.java?rev=1585487&r1=1585486&r2=1585487&view=diff
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitContainer.java (original)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitContainer.java Mon Apr 7 14:12:18 2014
@@ -19,6 +19,9 @@ package org.apache.onami.persist;
* under the License.
*/
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
import java.util.HashSet;
import java.util.Set;
@@ -26,15 +29,13 @@ import static org.apache.onami.persist.P
/**
* Container of persistence units. This is a convenience wrapper for multiple
- * persistence units. calling any method of either {@link PersistenceService} or
- * {@link UnitOfWork} will propagate this call to all added persistence units.
+ * persistence units.
*/
+@Singleton
class PersistenceUnitContainer
- implements PersistenceService, UnitOfWork
+ implements AllPersistenceServices, AllUnitsOfWork
{
- // ---- Members
-
/**
* Collection of all known persistence services.
*/
@@ -45,14 +46,13 @@ class PersistenceUnitContainer
*/
private final Set<UnitOfWork> unitsOfWork = new HashSet<UnitOfWork>();
- // ---- Methods
-
/**
* Adds a persistence service and a unit of work to this container.
*
* @param ps the persistence service to add. Must not be {@code null}.
* @param uow the unit of work to add. Must not be {@code null}.
*/
+ @Inject
void add( PersistenceService ps, UnitOfWork uow )
{
checkNotNull( ps );
@@ -65,81 +65,94 @@ class PersistenceUnitContainer
* {@inheritDoc}
*/
// @Override
- public synchronized void start()
- {
- for ( PersistenceService ps : persistenceServices )
- {
- ps.start();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- // @Override
- public synchronized boolean isRunning()
+ public void startAllStoppedPersistenceServices()
{
+ AggregatedException.Builder exceptionBuilder = new AggregatedException.Builder();
for ( PersistenceService ps : persistenceServices )
{
- if ( !ps.isRunning() )
+ try
{
- return false;
+ if(! ps.isRunning())
+ {
+ ps.start();
+ }
+ }
+ catch ( Exception e )
+ {
+ exceptionBuilder.add( e );
}
}
- return true;
+ exceptionBuilder.throwRuntimeExceptionIfHasCauses(
+ "multiple exception occurred while starting the persistence service" );
}
/**
* {@inheritDoc}
*/
// @Override
- public synchronized void stop()
+ public void stopAllRunningPersistenceServices()
{
+ AggregatedException.Builder exceptionBuilder = new AggregatedException.Builder();
for ( PersistenceService ps : persistenceServices )
{
- ps.stop();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- // @Override
- public void begin()
- {
- for ( UnitOfWork unitOfWork : unitsOfWork )
- {
- unitOfWork.begin();
+ try
+ {
+ ps.stop();
+ }
+ catch ( Exception e )
+ {
+ exceptionBuilder.add( e );
+ }
}
+ exceptionBuilder.throwRuntimeExceptionIfHasCauses(
+ "multiple exception occurred while stopping the persistence service" );
}
/**
* {@inheritDoc}
*/
// @Override
- public boolean isActive()
+ public void beginAllInactiveUnitsOfWork()
{
+ AggregatedException.Builder exceptionBuilder = new AggregatedException.Builder();
for ( UnitOfWork unitOfWork : unitsOfWork )
{
- if ( !unitOfWork.isActive() )
+ try
{
- return false;
+ if(! unitOfWork.isActive())
+ {
+ unitOfWork.begin();
+ }
+ }
+ catch ( Exception e )
+ {
+ exceptionBuilder.add( e );
}
}
- return true;
+ exceptionBuilder.throwRuntimeExceptionIfHasCauses(
+ "multiple exception occurred while starting the unit of work" );
}
/**
* {@inheritDoc}
*/
// @Override
- public void end()
+ public void endAllUnitsOfWork()
{
+ AggregatedException.Builder exceptionBuilder = new AggregatedException.Builder();
for ( UnitOfWork unitOfWork : unitsOfWork )
{
- unitOfWork.end();
+ try
+ {
+ unitOfWork.end();
+ }
+ catch ( Exception e )
+ {
+ exceptionBuilder.add( e );
+ }
}
-
+ exceptionBuilder.throwRuntimeExceptionIfHasCauses(
+ "multiple exception occurred while ending the unit of work" );
}
}
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModule.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModule.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModule.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModule.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,258 @@
+package org.apache.onami.persist;
+
+import com.google.inject.Key;
+import com.google.inject.PrivateModule;
+import com.google.inject.util.Providers;
+
+import javax.persistence.EntityManagerFactory;
+import javax.transaction.UserTransaction;
+import java.util.Properties;
+
+import static org.apache.onami.persist.Preconditions.checkNotNull;
+
+/**
+ * Module for configuring a single persistence unit.
+ *
+ * @see PersistenceModule
+ */
+class PersistenceUnitModule
+ extends PrivateModule
+{
+
+ /**
+ * The configuration for the persistence unit.
+ */
+ private final PersistenceUnitModuleConfigurator config;
+
+ /**
+ * Transaction interceptor which can be passed in from the outside for injecting dependencies
+ */
+ private TxnInterceptor transactionInterceptor;
+
+ /**
+ * Persistence unit container which can be passed in from the outside for adding this persistence unit to it.
+ */
+ private PersistenceUnitContainer container;
+
+ /**
+ * Constructor.
+ *
+ * @param configurator the configuration holding all configs.
+ */
+ PersistenceUnitModule( PersistenceUnitModuleConfigurator configurator )
+ {
+ this.config = checkNotNull( configurator, "config is mandatory!" );
+ }
+
+ /**
+ * Sets the transaction interceptor for injection of dependencies.
+ *
+ * @param transactionInterceptor the interceptor into which to inject dependencies.
+ */
+ void setTransactionInterceptor( TxnInterceptor transactionInterceptor )
+ {
+ this.transactionInterceptor = transactionInterceptor;
+ }
+
+ /**
+ * Sets the persistence unit container for adding this persistence unit to it.
+ *
+ * @param container the container to which to add the persistence unit.
+ */
+ void setPersistenceUnitContainer( PersistenceUnitContainer container )
+ {
+ this.container = container;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void configure()
+ {
+ bind( AnnotationHolder.class ).toInstance( config.getAnnotationHolder() );
+
+ bindPersistenceServiceAndEntityManagerFactoryProviderAndProperties();
+ bindTransactionFacadeFactory();
+
+ bind( EntityManagerProvider.class ).to( EntityManagerProviderImpl.class );
+ bind( UnitOfWork.class ).to( EntityManagerProviderImpl.class );
+
+ exposePersistenceServiceAndEntityManagerProviderAndUnitOfWork();
+
+ // request injection into transaction interceptor - this adds the required dependencies to the interceptor.
+ if ( transactionInterceptor != null )
+ {
+ requestInjection( transactionInterceptor );
+ }
+
+ // request injection into persistence unit container - this adds the current persistence unit to the container.
+ if ( container != null )
+ {
+ requestInjection( container );
+ }
+ }
+
+ /**
+ * exposes the following interfaces (optionally annotated if an annotation is defined in the configuration).
+ * <ul>
+ * <li>{@link PersistenceService}</li>
+ * <li>{@link EntityManagerProvider}</li>
+ * <li>{@link UnitOfWork}</li>
+ * </ul>
+ */
+ private void exposePersistenceServiceAndEntityManagerProviderAndUnitOfWork()
+ {
+ if ( config.isAnnotated() )
+ {
+ bindAndExposedAnnotated( PersistenceService.class );
+ bindAndExposedAnnotated( EntityManagerProvider.class );
+ bindAndExposedAnnotated( UnitOfWork.class );
+ }
+ else
+ {
+ expose( PersistenceService.class );
+ expose( EntityManagerProvider.class );
+ expose( UnitOfWork.class );
+ }
+ }
+
+ /**
+ * helper to expose a binding with annotation added.
+ *
+ * @param type the type to expose.
+ * @param <T> the type to expose.
+ */
+ private <T> void bindAndExposedAnnotated( Class<T> type )
+ {
+ bind( type ).annotatedWith( config.getAnnotation() ).to( Key.get( type ) );
+ expose( type ).annotatedWith( config.getAnnotation() );
+ }
+
+ private void bindPersistenceServiceAndEntityManagerFactoryProviderAndProperties()
+ {
+ if ( config.isApplicationManagedPersistenceUnit() )
+ {
+ bindApplicationManagedPersistenceServiceAndEntityManagerFactoryProviderAndProperties();
+ }
+ else
+ {
+ bindContainerManagedPersistenceServiceAndEntityManagerFactoryProviderAndProperties();
+ }
+ }
+
+ private void bindApplicationManagedPersistenceServiceAndEntityManagerFactoryProviderAndProperties()
+ {
+ bind( PersistenceService.class ).to( ApplicationManagedEntityManagerFactoryProvider.class );
+ bind( EntityManagerFactoryProvider.class ).to( ApplicationManagedEntityManagerFactoryProvider.class );
+ bind( Properties.class ).annotatedWith( ForContainerManaged.class ).toProvider(
+ Providers.<Properties>of( null ) );
+ bind( Properties.class ).annotatedWith( ForApplicationManaged.class ).toProvider(
+ Providers.of( config.getProperties() ) );
+
+ // required in ApplicationManagedEntityManagerFactoryProvider
+ bind( EntityManagerFactoryFactory.class );
+ // required in EntityManagerFactoryFactory
+ bind( String.class ).annotatedWith( ForApplicationManaged.class ).toInstance( config.getPuName() );
+ }
+
+ private void bindContainerManagedPersistenceServiceAndEntityManagerFactoryProviderAndProperties()
+ {
+ bind( PersistenceService.class ).to( ContainerManagedEntityManagerFactoryProvider.class );
+ bind( EntityManagerFactoryProvider.class ).to( ContainerManagedEntityManagerFactoryProvider.class );
+ bind( Properties.class ).annotatedWith( ForContainerManaged.class ).toProvider(
+ Providers.of( config.getProperties() ) );
+ bind( Properties.class ).annotatedWith( ForApplicationManaged.class ).toProvider(
+ Providers.<Properties>of( null ) );
+
+ // required in ContainerManagedEntityManagerFactoryProvider
+ bindEntityManagerFactorySource();
+ }
+
+ private void bindEntityManagerFactorySource()
+ {
+ if ( config.isEmfProvidedByJndiLookup() )
+ {
+ bind( EntityManagerFactorySource.class ).to( EntityManagerFactorySourceByJndiLookup.class );
+
+ // required in EntityManagerFactorySourceByJndiLookup
+ bind( String.class ).annotatedWith( ForContainerManaged.class ).toInstance( config.getEmfJndiName() );
+ }
+ else
+ {
+ bind( EntityManagerFactorySource.class ).to( EntityManagerFactorySourceViaProvider.class );
+
+ // required in EntityManagerFactorySourceViaProvider
+ bindInternalEntityManagerFactoryProvider();
+ }
+ }
+
+ private void bindInternalEntityManagerFactoryProvider()
+ {
+ if ( config.isEmfProvidedByInstance() )
+ {
+ bind( EntityManagerFactory.class ).annotatedWith( ForContainerManaged.class ).toInstance( config.getEmf() );
+ }
+ else if ( config.isEmfProvidedByProvider() )
+ {
+ bind( EntityManagerFactory.class ).annotatedWith( ForContainerManaged.class ).toProvider(
+ config.getEmfProvider() );
+ }
+ else if ( config.isEmfProvidedByProviderKey() )
+ {
+ bind( EntityManagerFactory.class ).annotatedWith( ForContainerManaged.class ).toProvider(
+ config.getEmfProviderKey() );
+ }
+ else
+ {
+ throw new RuntimeException( "EntityManager is improperly configured" );
+ }
+ }
+
+ private void bindTransactionFacadeFactory()
+ {
+ if ( config.isJta() )
+ {
+ bindJtaTransactionFacadeFactory();
+ }
+ else
+ {
+ bind( TransactionFacadeFactory.class ).to( ResourceLocalTransactionFacadeFactory.class );
+ }
+ }
+
+ private void bindJtaTransactionFacadeFactory()
+ {
+ bind( TransactionFacadeFactory.class ).to( JtaTransactionFacadeFactory.class );
+
+ // required in JtaTransactionFacadeFactory
+ binInternalUserTransactionProvider();
+ }
+
+ private void binInternalUserTransactionProvider()
+ {
+ if ( config.isUserTransactionProvidedByInstance() )
+ {
+ bind( UserTransaction.class ).toInstance( config.getUserTransaction() );
+ }
+ else if ( config.isUserTransactionProvidedByJndiLookup() )
+ {
+ bind( UserTransaction.class ).toProvider( UserTransactionProviderByJndiLookup.class );
+
+ // required in UserTransactionProviderByJndiLookup
+ bind( String.class ).annotatedWith( UserTransactionJndiName.class ).toInstance( config.getUtJndiName() );
+ }
+ else if ( config.isUserTransactionProvidedByProvider() )
+ {
+ bind( UserTransaction.class ).toProvider( config.getUtProvider() );
+ }
+ else if ( config.isUserTransactionProvidedByProviderKey() )
+ {
+ bind( UserTransaction.class ).toProvider( config.getUtProviderKey() );
+ }
+ else
+ {
+ throw new RuntimeException( "UserTransaction is improperly configured" );
+ }
+ }
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModule.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModule.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModuleConfigurator.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModuleConfigurator.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModuleConfigurator.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModuleConfigurator.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,249 @@
+package org.apache.onami.persist;
+
+import com.google.inject.Key;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
+
+import javax.persistence.EntityManagerFactory;
+import javax.transaction.UserTransaction;
+import java.lang.annotation.Annotation;
+import java.util.Properties;
+
+class PersistenceUnitModuleConfigurator
+ implements UnannotatedPersistenceUnitBuilder, AnnotatedPersistenceUnitBuilder, UnconfiguredPersistenceUnitBuilder
+{
+ private Class<? extends Annotation> annotation;
+
+ private UserTransaction userTransaction;
+
+ private String utJndiName;
+
+ private Provider<UserTransaction> utProvider;
+
+ private Key<? extends Provider<UserTransaction>> utProviderKey;
+
+ private Properties properties;
+
+ private String puName;
+
+ private EntityManagerFactory emf;
+
+ private String emfJndiName;
+
+ private Provider<EntityManagerFactory> emfProvider;
+
+ private Key<? extends Provider<EntityManagerFactory>> emfProviderKey;
+
+ PersistenceUnitModule getPuModule()
+ {
+ return new PersistenceUnitModule( this );
+ }
+
+ public AnnotatedPersistenceUnitBuilder annotatedWith( Class<? extends Annotation> annotation )
+ {
+ this.annotation = annotation;
+ return this;
+ }
+
+ public UnconfiguredPersistenceUnitBuilder useLocalTransaction()
+ {
+ // does nothing
+ return this;
+ }
+
+ public UnconfiguredPersistenceUnitBuilder useGlobalTransaction( UserTransaction userTransaction )
+ {
+ this.userTransaction = userTransaction;
+ return this;
+ }
+
+ public UnconfiguredPersistenceUnitBuilder useGlobalTransactionWithJndiName( String utJndiName )
+ {
+ this.utJndiName = utJndiName;
+ return this;
+ }
+
+ public UnconfiguredPersistenceUnitBuilder useGlobalTransactionProvidedBy( Provider<UserTransaction> utProvider )
+ {
+ this.utProvider = utProvider;
+ return this;
+ }
+
+ public UnconfiguredPersistenceUnitBuilder useGlobalTransactionProvidedBy(
+ Class<? extends Provider<UserTransaction>> utProviderClass )
+ {
+ utProviderKey = Key.get( utProviderClass );
+ return this;
+ }
+
+ public UnconfiguredPersistenceUnitBuilder useGlobalTransactionProvidedBy(
+ TypeLiteral<? extends Provider<UserTransaction>> utProviderType )
+ {
+ utProviderKey = Key.get( utProviderType );
+ return this;
+ }
+
+ public UnconfiguredPersistenceUnitBuilder useGlobalTransactionProvidedBy(
+ Key<? extends Provider<UserTransaction>> utProviderKey )
+ {
+ this.utProviderKey = utProviderKey;
+ return this;
+ }
+
+ public void addProperties( Properties properties )
+ {
+ this.properties = properties;
+ }
+
+ public void setPuName( String puName )
+ {
+ this.puName = puName;
+ }
+
+ public void setEmf( EntityManagerFactory emf )
+ {
+ this.emf = emf;
+ }
+
+ public void setEmfJndiName( String emfJndiName )
+ {
+ this.emfJndiName = emfJndiName;
+ }
+
+ public void setEmfProvider( Provider<EntityManagerFactory> emfProvider )
+ {
+ this.emfProvider = emfProvider;
+ }
+
+ public void setEmfProviderClass( Class<? extends Provider<EntityManagerFactory>> emfProviderClass )
+ {
+ this.emfProviderKey = Key.get( emfProviderClass );
+ }
+
+ public void setEmfProviderType( TypeLiteral<? extends Provider<EntityManagerFactory>> emfProviderType )
+ {
+ this.emfProviderKey = Key.get( emfProviderType );
+ }
+
+ public void setEmfProviderKey( Key<? extends Provider<EntityManagerFactory>> emfProviderKey )
+ {
+ this.emfProviderKey = emfProviderKey;
+ }
+
+ public boolean isApplicationManagedPersistenceUnit()
+ {
+ return puName != null;
+ }
+
+
+ UserTransaction getUserTransaction()
+ {
+ return userTransaction;
+ }
+
+ String getUtJndiName()
+ {
+ return utJndiName;
+ }
+
+ Provider<UserTransaction> getUtProvider()
+ {
+ return utProvider;
+ }
+
+ Key<? extends Provider<UserTransaction>> getUtProviderKey()
+ {
+ return utProviderKey;
+ }
+
+ Properties getProperties()
+ {
+ return properties;
+ }
+
+ String getPuName()
+ {
+ return puName;
+ }
+
+ EntityManagerFactory getEmf()
+ {
+ return emf;
+ }
+
+ String getEmfJndiName()
+ {
+ return emfJndiName;
+ }
+
+ Provider<EntityManagerFactory> getEmfProvider()
+ {
+ return emfProvider;
+ }
+
+ Key<? extends Provider<EntityManagerFactory>> getEmfProviderKey()
+ {
+ return emfProviderKey;
+ }
+
+ public boolean isEmfProvidedByJndiLookup()
+ {
+ return emfJndiName != null;
+ }
+
+ public boolean isEmfProvidedByInstance()
+ {
+ return emf != null;
+ }
+
+ public boolean isEmfProvidedByProvider()
+ {
+ return emfProvider != null;
+ }
+
+ public boolean isEmfProvidedByProviderKey()
+ {
+ return emfProviderKey != null;
+ }
+
+ public boolean isJta()
+ {
+ return utJndiName != null || userTransaction != null || utProvider != null || utProviderKey != null;
+ }
+
+ public boolean isUserTransactionProvidedByJndiLookup()
+ {
+ return utJndiName != null;
+ }
+
+
+ public boolean isUserTransactionProvidedByInstance()
+ {
+ return userTransaction != null;
+ }
+
+ public boolean isUserTransactionProvidedByProvider()
+ {
+ return utProvider != null;
+ }
+
+ public boolean isUserTransactionProvidedByProviderKey()
+ {
+ return utProviderKey != null;
+ }
+
+ public boolean isAnnotated()
+ {
+ return annotation != null;
+ }
+
+ public AnnotationHolder getAnnotationHolder()
+ {
+ return new AnnotationHolder( annotation );
+ }
+
+ Class<? extends Annotation> getAnnotation()
+ {
+ return annotation;
+ }
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModuleConfigurator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModuleConfigurator.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/PersistenceUnitModuleConfigurator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: onami/sandbox/persist/src/main/java/org/apache/onami/persist/Preconditions.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/Preconditions.java?rev=1585487&r1=1585486&r2=1585487&view=diff
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/Preconditions.java (original)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/Preconditions.java Mon Apr 7 14:12:18 2014
@@ -28,14 +28,16 @@ class Preconditions
/**
* Check that a reference is not null.
*
- * @param <T> the type of the reference
+ * @param <T> the type of the reference
* @param reference the reference to check.
* @return the reference itself.
* @throws NullPointerException if the reference is null.
*/
- static <T> T checkNotNull(T reference) {
- if (reference == null) {
- throw new NullPointerException( );
+ static <T> T checkNotNull( T reference )
+ {
+ if ( reference == null )
+ {
+ throw new NullPointerException();
}
return reference;
}
@@ -43,14 +45,16 @@ class Preconditions
/**
* Check that a reference is not null.
*
- * @param <T> the type of the reference
+ * @param <T> the type of the reference
* @param reference the reference to check.
- * @param message the message of the NullPointerException if one is thrown.
+ * @param message the message of the NullPointerException if one is thrown.
* @return the reference itself.
* @throws NullPointerException if the reference is null.
*/
- static <T> T checkNotNull(T reference, String message) {
- if (reference == null) {
+ static <T> T checkNotNull( T reference, String message )
+ {
+ if ( reference == null )
+ {
throw new NullPointerException( message );
}
return reference;
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/ResourceLocalTransactionFacadeFactory.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/ResourceLocalTransactionFacadeFactory.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/ResourceLocalTransactionFacadeFactory.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/ResourceLocalTransactionFacadeFactory.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,168 @@
+package org.apache.onami.persist;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import javax.persistence.EntityTransaction;
+
+import static org.apache.onami.persist.Preconditions.checkNotNull;
+
+/**
+ * Factory for transaction facades in case of resource local transactions.
+ */
+@Singleton
+class ResourceLocalTransactionFacadeFactory
+ implements TransactionFacadeFactory
+{
+
+ /**
+ * The provider for the entity manager.
+ */
+ private final EntityManagerProvider emProvider;
+
+ /**
+ * Constructor.
+ *
+ * @param emProvider the provider for the entity manager
+ */
+ @Inject
+ ResourceLocalTransactionFacadeFactory( EntityManagerProvider emProvider )
+ {
+ this.emProvider = checkNotNull( emProvider, "emProvider is mandatory!" );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // @Override
+ public TransactionFacade createTransactionFacade()
+ {
+ final EntityTransaction txn = emProvider.get().getTransaction();
+ if ( txn.isActive() )
+ {
+ return new Inner( txn );
+ }
+ else
+ {
+ return new Outer( txn );
+ }
+ }
+
+ /**
+ * TransactionFacade representing an inner (nested) transaction.
+ * Starting and committing a transaction has no effect.
+ * This Facade will set the rollbackOnly flag in case of a roll back.
+ */
+ private static class Inner
+ implements TransactionFacade
+ {
+ private final EntityTransaction txn;
+
+ Inner( EntityTransaction txn )
+ {
+ this.txn = checkNotNull( txn, "txn is mandatory!" );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // @Override
+ public void begin()
+ {
+ // Do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // @Override
+ public void commit()
+ {
+ // Do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // @Override
+ public void rollback()
+ {
+ txn.setRollbackOnly();
+ }
+ }
+
+ /**
+ * TransactionFacade representing an outer transaction.
+ * This Facade starts and ends the transaction.
+ * If an inner transaction has set the rollbackOnly flag the transaction will be rolled back
+ * in any case.
+ */
+ private static class Outer
+ implements TransactionFacade
+ {
+ private final EntityTransaction txn;
+
+ /**
+ * {@inheritDoc}
+ */
+ Outer( EntityTransaction txn )
+ {
+ this.txn = checkNotNull( txn, "txn is mandatory!" );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // @Override
+ public void begin()
+ {
+ txn.begin();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // @Override
+ public void commit()
+ {
+ if ( txn.getRollbackOnly() )
+ {
+ txn.rollback();
+ }
+ else
+ {
+ txn.commit();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ // @Override
+ public void rollback()
+ {
+ txn.rollback();
+ }
+ }
+
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/ResourceLocalTransactionFacadeFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/ResourceLocalTransactionFacadeFactory.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/ResourceLocalTransactionFacadeFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacade.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacade.java?rev=1585487&r1=1585486&r2=1585487&view=diff
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacade.java (original)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacade.java Mon Apr 7 14:12:18 2014
@@ -19,12 +19,9 @@ package org.apache.onami.persist;
* under the License.
*/
-import javax.persistence.EntityTransaction;
-import javax.transaction.UserTransaction;
-
/**
* Interface which hides away the details of inner (nested) and outer transactions as well
- * as the details between {@link EntityTransaction} and {@link UserTransaction}.
+ * as the details between {@link javax.persistence.EntityTransaction} and {@link javax.transaction.UserTransaction}.
*/
interface TransactionFacade
{
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacadeFactory.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacadeFactory.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacadeFactory.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacadeFactory.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,34 @@
+package org.apache.onami.persist;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Factory for {@link TransactionFacade}.
+ */
+interface TransactionFacadeFactory
+{
+
+ /**
+ * Creates a new transaction facade.
+ *
+ * @return the transaction facade
+ */
+ TransactionFacade createTransactionFacade();
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacadeFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacadeFactory.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionFacadeFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: onami/sandbox/persist/src/main/java/org/apache/onami/persist/Transactional.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/Transactional.java?rev=1585487&r1=1585486&r2=1585487&view=diff
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/Transactional.java (original)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/Transactional.java Mon Apr 7 14:12:18 2014
@@ -39,20 +39,20 @@ import java.lang.annotation.Target;
* transaction will be marked as rollbackOnly.
* <p/>
* Guice uses AOP to enhance a method annotated with @{@link Transactional} with a wrapper.
- * This means the @{@link Transactional} only works as expected when:
+ * This means the {@link Transactional @Transactional} only works as expected when:
* <ul>
* <li>
- * The object on which the method is called has been created by guice.
+ * The object on which the method is called has been created by guice.<br/>
* This can be achieved by having it (or a {@link Provider}) injected into your class
* or by calling {@link Injector#getInstance(Class)} or {@link Injector#getInstance(Key)}.
* </li>
* <li>
- * The method which should be run transactional is not private and not final
+ * The method which should be run transactional is not private, not static and not final.
* </li>
* </ul>
*/
-@Target({ ElementType.METHOD, ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
+@Target( { ElementType.METHOD, ElementType.TYPE } )
+@Retention( RetentionPolicy.RUNTIME )
@Inherited
public @interface Transactional
{
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationHelper.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationHelper.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationHelper.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationHelper.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,161 @@
+package org.apache.onami.persist;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.aopalliance.intercept.MethodInvocation;
+
+import java.lang.annotation.Annotation;
+
+import static java.util.Arrays.asList;
+import static org.apache.onami.persist.Preconditions.checkNotNull;
+
+/**
+ * Helper class for working with {@link Transactional @Transactional} annotations.
+ */
+@Singleton
+class TransactionalAnnotationHelper
+{
+
+ /**
+ * Annotation of the persistence unit.
+ */
+ private final Class<? extends Annotation> puAnntoation;
+
+ /**
+ * Reader for {@link Transactional @Transactional} annotations.
+ */
+ private final TransactionalAnnotationReader txnAnnoReader;
+
+ /**
+ * Constructor.
+ *
+ * @param annotationHolder Holder of teh annotation of the persistence unit.
+ * @param txnAnnoReader reader for {@link Transactional @Transactional} annotations.
+ */
+ @Inject
+ TransactionalAnnotationHelper( AnnotationHolder annotationHolder, TransactionalAnnotationReader txnAnnoReader )
+ {
+ this.puAnntoation = annotationHolder.getAnnotation();
+ this.txnAnnoReader = checkNotNull( txnAnnoReader, "txnAnnoReader is mandatory!" );
+ }
+
+ /**
+ * Decides if the current persistence unit participates in a transaction for the given method invocation.
+ * For a detailed description of when a persistence unit participates see the documentation at the
+ * {@link Transactional @Transactional} annotation.
+ *
+ * @param methodInvocation the method invocation which may be wrapped in a transaction.
+ * @return {@code true} if the current persistence unit participates in a transaction for the given method.
+ */
+ public boolean persistenceUnitParticipatesInTransactionFor( MethodInvocation methodInvocation )
+ {
+ return puAnntoation == null || participates( methodInvocation );
+ }
+
+ /**
+ * Decides if the current persistence unit participates in a transaction for the given method invocation.
+ * The persistence unit has is annotated.
+ *
+ * @param methodInvocation the method invocation which may be wrapped in a transaction.
+ * @return {@code true} if the current persistence unit participates in a transaction for the given method.
+ */
+ private boolean participates( MethodInvocation methodInvocation )
+ {
+ final Transactional transactional = txnAnnoReader.readAnnotationFrom( methodInvocation );
+ final Class<? extends Annotation>[] onUnits = transactional.onUnits();
+ return isEmpty( onUnits ) || contains( onUnits, puAnntoation );
+ }
+
+ /**
+ * Returns {@code true} if the given array is empty.
+ *
+ * @param array the array to test for emptiness.
+ * @return {@code true} if the the given array has is {@code null} or has length 0.
+ */
+ private boolean isEmpty( Object[] array )
+ {
+ return array == null || array.length == 0;
+ }
+
+ /**
+ * Returns {@code true} if the given array contains the specified element.
+ *
+ * @param array the array in which to search for the specified element.
+ * @param key the element to look for.
+ * @return {@code true} if the given array contains the specified element.
+ */
+ private boolean contains( Object[] array, Object key )
+ {
+ return asList( array ).contains( key );
+ }
+
+ /**
+ * Decides if a rollback is necessary for the given method invocation and a thrown exception.
+ *
+ * @param methodInvocation the method invocation during which an exception was thrown.
+ * @param exc the exception which was thrown
+ * @return {@code true} if the transaction needs to be rolled back.
+ */
+ public boolean isRollbackNecessaryFor( MethodInvocation methodInvocation, Throwable exc )
+ {
+ final Transactional transactional = txnAnnoReader.readAnnotationFrom( methodInvocation );
+ return isRollbackNecessaryFor( transactional, exc );
+ }
+
+ /**
+ * Decides if a rollback is necessary for the given transactional annotation and a thrown exception.
+ *
+ * @param transactional the transactional annotation of the method during which an exception was thrown.
+ * @param exc the exception which was thrown
+ * @return {@code true} if the transaction needs to be rolled back.
+ */
+ private boolean isRollbackNecessaryFor( Transactional transactional, Throwable exc )
+ {
+ for ( Class<? extends Exception> rollbackOn : transactional.rollbackOn() )
+ {
+ if ( rollbackOn.isInstance( exc ) )
+ {
+ return isNotIgnoredForRollback( transactional, exc );
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Decides if a rollback is not performed for the given transactional annotation and a thrown exception.
+ *
+ * @param transactional the transactional annotation of the method during which an exception was thrown.
+ * @param exc the exception which was thrown
+ * @return {@code true} if the transaction needs to be rolled back.
+ */
+ private boolean isNotIgnoredForRollback( Transactional transactional, Throwable exc )
+ {
+ for ( Class<? extends Exception> ignore : transactional.ignore() )
+ {
+ if ( ignore.isInstance( exc ) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationHelper.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationHelper.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationReader.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationReader.java?rev=1585487&r1=1585486&r2=1585487&view=diff
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationReader.java (original)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/TransactionalAnnotationReader.java Mon Apr 7 14:12:18 2014
@@ -19,47 +19,33 @@ package org.apache.onami.persist;
* under the License.
*/
+import com.google.inject.Singleton;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;
/**
- * Reader which obtains the concrete @{@link Transactional} annotation on a method. The reader may use some sort of
- * caching.
+ * Reader which obtains the concrete {@link Transactional @Transactional} annotation of a method.
*/
+@Singleton
class TransactionalAnnotationReader
{
- private static final Transactional DEFAULT_TRANSACTIONAL = DefaultTransactional.class.getAnnotation( Transactional.class );
-
/**
- * cache for {@link Transactional} annotations per method.
+ * Constant holding the a transactional instance with all default values.
*/
- final TransactionalCache transactionalCache = new TransactionalCache();
-
+ private static final Transactional DEFAULT_TRANSACTIONAL =
+ DefaultTransactional.class.getAnnotation( Transactional.class );
/**
- * Reads the @{@link Transactional} of a given method invocation.
+ * Reads the {@link Transactional @Transactional} of a given method invocation.
*
- * @param methodInvocation the method invocation for which to obtain the @{@link Transactional}.
- * @return the @{@link Transactional} of the given method invocation. Never {@code null}.
+ * @param methodInvocation the method invocation for which to obtain the {@link Transactional @Transactional}.
+ * @return the {@link Transactional @Transactional} of the given method invocation. Never {@code null}.
*/
Transactional readAnnotationFrom( MethodInvocation methodInvocation )
{
- final Method method = methodInvocation.getMethod();
- Transactional result;
-
- result = transactionalCache.get( method );
- if ( null == result )
- {
- result = getTransactional( methodInvocation, method );
- transactionalCache.put( method, result );
- }
- return result;
- }
-
- private Transactional getTransactional( MethodInvocation methodInvocation, Method method )
- {
Transactional result;
+ final Method method = methodInvocation.getMethod();
result = method.getAnnotation( Transactional.class );
if ( null == result )
{
@@ -74,23 +60,10 @@ class TransactionalAnnotationReader
}
/**
- * Helper class for obtaining the default of @{@link Transactional}.
+ * Helper class for obtaining the default of {@link Transactional @Transactional}.
*/
@Transactional
private static class DefaultTransactional
{
}
-
- private static class TransactionalCache
- {
- Transactional get( Method method )
- {
- return null;
- }
-
- void put( Method method, Transactional annotation )
- {
- // nop
- }
- }
}
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TxnInterceptor.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/TxnInterceptor.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/TxnInterceptor.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/TxnInterceptor.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,213 @@
+package org.apache.onami.persist;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.inject.Inject;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * Interceptor for methods and classes annotated with @{@link Transactional} annotation.
+ */
+class TxnInterceptor
+ implements MethodInterceptor
+{
+
+ /**
+ * Unit of work.
+ */
+ @Inject
+ @VisibleForTesting
+ UnitOfWork unitOfWork;
+
+ /**
+ * Factory for {@link TransactionFacade}.
+ */
+ @Inject
+ @VisibleForTesting
+ TransactionFacadeFactory tfProvider;
+
+ /**
+ * Helper for working with the concrete transactional annotations on methods and classes.
+ */
+ @Inject
+ @VisibleForTesting
+ TransactionalAnnotationHelper txnAnnotationHelper;
+
+ /**
+ * {@inheritDoc}
+ */
+ // @Override
+ public final Object invoke( MethodInvocation methodInvocation )
+ throws Throwable
+ {
+ if ( persistenceUnitParticipatesInTransactionFor( methodInvocation ) )
+ {
+ return invokeInTransactionAndUnitOfWork( methodInvocation );
+ }
+ else
+ {
+ return methodInvocation.proceed();
+ }
+
+ }
+
+ private boolean persistenceUnitParticipatesInTransactionFor( MethodInvocation methodInvocation )
+ {
+ return txnAnnotationHelper.persistenceUnitParticipatesInTransactionFor( methodInvocation );
+ }
+
+ /**
+ * Invokes the original method within a unit of work and a transaction.
+ *
+ * @param methodInvocation the method to be executed within the transaction
+ * @return the result of the invocation of the original method.
+ * @throws Throwable if an exception occurs during the call to the original method.
+ */
+ private Object invokeInTransactionAndUnitOfWork( MethodInvocation methodInvocation )
+ throws Throwable
+ {
+ final boolean weStartedTheUnitOfWork = !unitOfWork.isActive();
+ if ( weStartedTheUnitOfWork )
+ {
+ unitOfWork.begin();
+ }
+
+ Throwable originalException = null;
+ try
+ {
+ return invokeInTransaction( methodInvocation );
+ }
+ catch ( Throwable exc )
+ {
+ originalException = exc;
+ throw exc;
+ }
+ finally
+ {
+ if ( weStartedTheUnitOfWork )
+ {
+ endUnitOfWorkAndThrow( originalException );
+ }
+ }
+ }
+
+ /**
+ * Ends the unit of work and throws the original exception if not null.
+ *
+ * @param originalException the original transaction to throw if not null.
+ * @throws Throwable the original exception or an exception which occurred when closing the unit of work.
+ */
+ private void endUnitOfWorkAndThrow( Throwable originalException )
+ throws Throwable
+ {
+ try
+ {
+ unitOfWork.end();
+ }
+ catch ( Throwable exc )
+ {
+ if ( originalException != null )
+ {
+ throw originalException;
+ }
+ else
+ {
+ throw exc;
+ }
+ }
+ }
+
+ /**
+ * Invoke the original method within a transaction.
+ *
+ * @param methodInvocation the original method invocation.
+ * @return the result of the invocation of the original method.
+ * @throws Throwable if an exception occurs during the call to the original method.
+ */
+ private Object invokeInTransaction( MethodInvocation methodInvocation )
+ throws Throwable
+ {
+ final TransactionFacade transactionFacade = tfProvider.createTransactionFacade();
+ transactionFacade.begin();
+ final Object result = invokeAndHandleException( methodInvocation, transactionFacade );
+ transactionFacade.commit();
+
+ return result;
+ }
+
+ /**
+ * Invoke the original method assuming a transaction has already been started.
+ * This method is responsible of calling rollback if necessary.
+ *
+ * @param methodInvocation the original method invocation.
+ * @param transactionFacade the facade to the underlying resource local or jta transaction.
+ * @return the result of the invocation of the original method.
+ * @throws Throwable if an exception occurs during the call to the original method.
+ */
+ private Object invokeAndHandleException( MethodInvocation methodInvocation, TransactionFacade transactionFacade )
+ throws Throwable
+ {
+ try
+ {
+ return methodInvocation.proceed();
+ }
+ catch ( Throwable exc )
+ {
+ handleException( methodInvocation, transactionFacade, exc );
+ throw exc;
+ }
+ }
+
+ /**
+ * Handles the case that an exception was thrown by the original method.
+ *
+ * @param methodInvocation the original method invocation.
+ * @param transactionFacade the facade to the underlying resource local or jta transaction.
+ * @param exc the exception thrown by the original method.
+ */
+ private void handleException( MethodInvocation methodInvocation, TransactionFacade transactionFacade,
+ Throwable exc )
+ throws Throwable
+ {
+ try
+ {
+ if ( isRollbackNecessaryFor( methodInvocation, exc ) )
+ {
+ transactionFacade.rollback();
+ }
+ else
+ {
+ transactionFacade.commit();
+ }
+ }
+ catch ( Exception swallowedException )
+ {
+ // swallow exception from transaction facade in favor of th exception thrown by the original method.
+ throw exc;
+ }
+ }
+
+ private boolean isRollbackNecessaryFor( MethodInvocation methodInvocation, Throwable exc )
+ {
+ return txnAnnotationHelper.isRollbackNecessaryFor( methodInvocation, exc );
+ }
+
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TxnInterceptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TxnInterceptor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/TxnInterceptor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnannotatedPersistenceUnitBuilder.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnannotatedPersistenceUnitBuilder.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnannotatedPersistenceUnitBuilder.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnannotatedPersistenceUnitBuilder.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,28 @@
+package org.apache.onami.persist;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.lang.annotation.Annotation;
+
+public interface UnannotatedPersistenceUnitBuilder
+ extends AnnotatedPersistenceUnitBuilder
+{
+ AnnotatedPersistenceUnitBuilder annotatedWith( Class<? extends Annotation> annotation );
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnannotatedPersistenceUnitBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnannotatedPersistenceUnitBuilder.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnannotatedPersistenceUnitBuilder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnconfiguredPersistenceUnitBuilder.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnconfiguredPersistenceUnitBuilder.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnconfiguredPersistenceUnitBuilder.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnconfiguredPersistenceUnitBuilder.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,27 @@
+package org.apache.onami.persist;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Properties;
+
+public interface UnconfiguredPersistenceUnitBuilder
+{
+ void addProperties( Properties properties );
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnconfiguredPersistenceUnitBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnconfiguredPersistenceUnitBuilder.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UnconfiguredPersistenceUnitBuilder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionFacade.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionFacade.java?rev=1585487&r1=1585486&r2=1585487&view=diff
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionFacade.java (original)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionFacade.java Mon Apr 7 14:12:18 2014
@@ -19,6 +19,8 @@ package org.apache.onami.persist;
* under the License.
*/
+import com.google.inject.Singleton;
+
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
@@ -26,36 +28,44 @@ import javax.transaction.RollbackExcepti
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import static org.apache.onami.persist.Preconditions.checkNotNull;
+
/**
- * Facade to the {@link UserTransaction} which wraps all checked exception into runtime exceptions.
+ * Facade to the {@link javax.transaction.UserTransaction} which wraps all checked exception into runtime exceptions.
+ * Adds some convenience methods.
*/
+@Singleton
class UserTransactionFacade
{
- // ---- Members
+ /**
+ * Transaction states in which only a rollback is possible
+ */
+ private static final Set<Integer> ROLLBACK_ONLY_STATES = new HashSet<Integer>(
+ Arrays.asList( Status.STATUS_MARKED_ROLLBACK, Status.STATUS_ROLLING_BACK, Status.STATUS_ROLLEDBACK ) );
+ /**
+ * The wrapped user transaction.
+ */
private final UserTransaction txn;
- // ---- Constructor
-
/**
* Constructor.
*
- * @param txn the actual user transaction to facade. Must not be {@code null}.
+ * @param txn the actual user transaction to wrap. Must not be {@code null}.
*/
UserTransactionFacade( UserTransaction txn )
{
- checkNotNull( txn );
- this.txn = txn;
+ this.txn = checkNotNull( txn, "txn is mandatory!" );
}
- // ---- Methods
-
/**
- * @see {@link UserTransaction#begin()}.
+ * @see {@link javax.transaction.UserTransaction#begin()}.
*/
void begin()
{
@@ -74,7 +84,7 @@ class UserTransactionFacade
}
/**
- * @see {@link UserTransaction#commit()}.
+ * @see {@link javax.transaction.UserTransaction#commit()}.
*/
void commit()
{
@@ -109,7 +119,7 @@ class UserTransactionFacade
}
/**
- * @see {@link UserTransaction#rollback()}.
+ * @see {@link javax.transaction.UserTransaction#rollback()}.
*/
void rollback()
{
@@ -132,7 +142,7 @@ class UserTransactionFacade
}
/**
- * @see {@link UserTransaction#setRollbackOnly()}.
+ * @see {@link javax.transaction.UserTransaction#setRollbackOnly()}.
*/
void setRollbackOnly()
{
@@ -151,18 +161,37 @@ class UserTransactionFacade
}
/**
- * @see {@link UserTransaction#getStatus()}.
+ * @return {@code true} if this transaction may onl roll back. {@code false} otherwise.
+ */
+ boolean getRollbackOnly()
+ {
+ return ROLLBACK_ONLY_STATES.contains( getStatus() );
+ }
+
+ /**
+ * @return {@code true} if there is already a transaction active. {@code false} otherwise.
+ */
+ boolean isActive()
+ {
+ return getStatus() != Status.STATUS_NO_TRANSACTION;
+ }
+
+ /**
+ * @see {@link javax.transaction.UserTransaction#getStatus()}.
+ * <p/>
+ * Retries several times when the status is {@link Status#STATUS_UNKNOWN}.
+ * Will abort retrying after aproximatly one second.
*/
- int getStatus()
+ private int getStatus()
{
try
{
int status = txn.getStatus();
- for ( int i = 0; Status.STATUS_UNKNOWN == status && i < 5; i++ )
+ for ( int i = 0; status == Status.STATUS_UNKNOWN && i < 8; i++ )
{
try
{
- Thread.sleep( 30L );
+ Thread.sleep( ( 30L * i ) + 30L );
}
catch ( InterruptedException e )
{
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionJndiName.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionJndiName.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionJndiName.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionJndiName.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,38 @@
+package org.apache.onami.persist;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.google.inject.BindingAnnotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * Annotation to mark bindings which are specific for container managed persistence units.
+ */
+@Target( { ElementType.PARAMETER } )
+@Retention( RetentionPolicy.RUNTIME )
+@BindingAnnotation
+@interface UserTransactionJndiName
+{
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionJndiName.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionJndiName.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionJndiName.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionProviderByJndiLookup.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionProviderByJndiLookup.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionProviderByJndiLookup.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionProviderByJndiLookup.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,45 @@
+package org.apache.onami.persist;
+
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+import javax.transaction.UserTransaction;
+
+import static org.apache.onami.persist.Preconditions.checkNotNull;
+
+/**
+ * Provider fro {@link UserTransaction} which retrieves the value from the JNDI context.
+ */
+@Singleton
+public class UserTransactionProviderByJndiLookup
+ implements Provider<UserTransaction>
+{
+
+ private final String jndiName;
+
+ private final JndiLookupHelper jndiLookupHelper;
+
+ /**
+ * Constructor.
+ *
+ * @param jndiName jndi name of the entity manager factory. Must not be {@code null}.
+ */
+ UserTransactionProviderByJndiLookup( @UserTransactionJndiName String jndiName, JndiLookupHelper jndiLookupHelper )
+ {
+ this.jndiName = checkNotNull( jndiName, "jndiName is mandatory!" );
+ this.jndiLookupHelper = checkNotNull( jndiLookupHelper, "jndiLookupHelper is mandatory!" );
+ }
+
+ /**
+ * Gets a {@link UserTransaction} by looking it up in the JNDI context.
+ *
+ * @return the found entity user transaction
+ * @throws RuntimeException when no user transaction was found.
+ */
+ //@Override
+ public UserTransaction get()
+ {
+ return jndiLookupHelper.doJndiLookup( UserTransaction.class, jndiName );
+ }
+
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionProviderByJndiLookup.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionProviderByJndiLookup.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/UserTransactionProviderByJndiLookup.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: onami/sandbox/persist/src/main/java/org/apache/onami/persist/VisibleForTesting.java
URL: http://svn.apache.org/viewvc/onami/sandbox/persist/src/main/java/org/apache/onami/persist/VisibleForTesting.java?rev=1585487&view=auto
==============================================================================
--- onami/sandbox/persist/src/main/java/org/apache/onami/persist/VisibleForTesting.java (added)
+++ onami/sandbox/persist/src/main/java/org/apache/onami/persist/VisibleForTesting.java Mon Apr 7 14:12:18 2014
@@ -0,0 +1,34 @@
+package org.apache.onami.persist;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to mark the intention of increasing the visibility of a method or field so it can be used in a test.
+ */
+@Target( { ElementType.METHOD, ElementType.FIELD } )
+@Retention( RetentionPolicy.SOURCE )
+@interface VisibleForTesting
+{
+}
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/VisibleForTesting.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/VisibleForTesting.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: onami/sandbox/persist/src/main/java/org/apache/onami/persist/VisibleForTesting.java
------------------------------------------------------------------------------
svn:mime-type = text/plain