org.spicefactory.pimento.context
Class AbstractPersistenceContextPhaseListener

java.lang.Object
  extended by org.spicefactory.pimento.context.AbstractPersistenceContextPhaseListener
All Implemented Interfaces:
PhaseListener
Direct Known Subclasses:
SpringPersistenceContextPhaseListener

public abstract class AbstractPersistenceContextPhaseListener
extends Object
implements PhaseListener

Base implementation of Cinnamon's PhaseListener extension point that wraps the service invocations in a transaction. It will be used during processing of entity snapshots sent from the client which might need to be merged onto the full entities before the actual service operation will be invoked. This transaction will remain active for the processing of all messages for a single request. It will remain active for processing any return value which is a persistent entity to avoid lazy initialization exceptions.

It is recommended to use some kind of lazy DataSource to avoid fetching Connections from the pool unless actually necessary. Since this PhaseListener will wrap all service invocations it would otherwise also affect invocations that are either not transactional or that do not hit the database because all entities could be fetched from the second level cache.

This base implementation must be extended and the five abstract methods that deal directly with transaction management and EntityManager creation must be implemented. They are left abstract in this base class because in most deployment scenarios it would be the best approach to hook into the transaction support of the application framework or server in use.

Pimento comes with a default implementation that uses Spring for transaction management. But this base class does not depend on Spring and should be easy to extend for other application frameworks.

Author:
Jens Halm

Constructor Summary
AbstractPersistenceContextPhaseListener(EntityManagerFactory emf)
          Creates a new instance.
 
Method Summary
 void afterDecodingException(Exception ex)
          Invoked if decoding of the incoming AMF request failed.
 void afterEncoding()
          Invoked after encoding of the response has been completed.
 void afterProcessing(Envelope request, Envelope response)
          Invoked after processing of messages has been completed but before encoding of the response has started.
 void beforeDecoding()
          Invoked before decoding of the incoming AMF request starts.
 void beforeProcessing(Envelope request)
          Invoked after decoding of the request has been completed but before processing the decoded messages.
protected abstract  boolean bindEntityManager()
          Bind an EntityManager to the current thread.
protected abstract  void commitTransaction(Object transactionContext)
          Commits the transaction represented by the specified parameter.
protected  boolean containsError(Envelope response)
          Checks whether the specified Cinnamon response envelope contains any service invocations that led to an error result.
protected  RequestContext createRequestContext()
          Creates and returns a new RequestContext instance.
protected abstract  Object createTransaction()
          Creates a transaction and returns a transaction status object.
protected  EntityManagerFactory getEntityManagerFactory()
          Returns the EntityManagerFactory that this phase listener uses.
protected  void releaseRequestContext()
          Unbinds the RequestContext from the current thread.
protected abstract  void rollbackTransaction(Object transactionContext)
          Performs a rollback for the transaction represented by the specified parameter.
protected abstract  void unbindEntityManager()
          Unbind the EntityManager from the current thread.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

AbstractPersistenceContextPhaseListener

public AbstractPersistenceContextPhaseListener(EntityManagerFactory emf)
Creates a new instance.

Parameters:
emf - the EntityManagerFactory to use
Method Detail

getEntityManagerFactory

protected EntityManagerFactory getEntityManagerFactory()
Returns the EntityManagerFactory that this phase listener uses.

Returns:
the EntityManagerFactory that this phase listener uses

beforeDecoding

public void beforeDecoding()
Description copied from interface: PhaseListener
Invoked before decoding of the incoming AMF request starts.

Specified by:
beforeDecoding in interface PhaseListener

afterDecodingException

public void afterDecodingException(Exception ex)
Description copied from interface: PhaseListener
Invoked if decoding of the incoming AMF request failed. In this case processing of this request will be stopped. No further methods will be invoked in this listener for this particular request, thus all cleanup tasks should be performed in this method.

Specified by:
afterDecodingException in interface PhaseListener
Parameters:
ex - the Exception that was caught while decoding the request

beforeProcessing

public void beforeProcessing(Envelope request)
Description copied from interface: PhaseListener
Invoked after decoding of the request has been completed but before processing the decoded messages.

Specified by:
beforeProcessing in interface PhaseListener
Parameters:
request - the Envelope containing all messages that will be processed

afterProcessing

public void afterProcessing(Envelope request,
                            Envelope response)
Description copied from interface: PhaseListener
Invoked after processing of messages has been completed but before encoding of the response has started.

Specified by:
afterProcessing in interface PhaseListener
Parameters:
request - the Envelope containing all request messages that have been processed
response - the Envelope containing all response messages that will be sent to the client

afterEncoding

public void afterEncoding()
Description copied from interface: PhaseListener
Invoked after encoding of the response has been completed.

Specified by:
afterEncoding in interface PhaseListener

containsError

protected boolean containsError(Envelope response)
Checks whether the specified Cinnamon response envelope contains any service invocations that led to an error result.

Parameters:
response - the Cinnamon envelope to check
Returns:
true if the specified Cinnamon response envelope contains any service invocations that led to an error result

createTransaction

protected abstract Object createTransaction()
Creates a transaction and returns a transaction status object. The type of the returned object depends on the transaction management system in use.

Returns:
a transaction status object

commitTransaction

protected abstract void commitTransaction(Object transactionContext)
Commits the transaction represented by the specified parameter. The type of the parameter depends on the transaction management system in use. It is always the same instance that was returned from createTransaction.

Parameters:
transactionContext - the status object for the transaction to commit

rollbackTransaction

protected abstract void rollbackTransaction(Object transactionContext)
Performs a rollback for the transaction represented by the specified parameter. The type of the parameter depends on the transaction management system in use. It is always the same instance that was returned from createTransaction.

Parameters:
transactionContext - the status object for the transaction to rollback

bindEntityManager

protected abstract boolean bindEntityManager()
Bind an EntityManager to the current thread.

Returns:
true if a new EntityManager was created

unbindEntityManager

protected abstract void unbindEntityManager()
Unbind the EntityManager from the current thread.


createRequestContext

protected RequestContext createRequestContext()
Creates and returns a new RequestContext instance. This method also binds the new instance to the current thread.

Returns:
a new RequestContext instance

releaseRequestContext

protected void releaseRequestContext()
Unbinds the RequestContext from the current thread.