diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/util/AbstractReadOnlyResourceHolder.java b/spring-webflow-sandbox/src/main/java/org/springframework/util/AbstractReadOnlyResourceHolder.java index 5823badb..71478e89 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/util/AbstractReadOnlyResourceHolder.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/util/AbstractReadOnlyResourceHolder.java @@ -2,11 +2,11 @@ package org.springframework.util; /** * Read-only resource holder. - * + * * @author Maxim Petrashev */ public abstract class AbstractReadOnlyResourceHolder extends AbstractResourceHolder { - public final void set(E aObject) { - throw new UnsupportedOperationException(); - } + public final void set(E aObject) { + throw new UnsupportedOperationException(); + } } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/util/AbstractResourceHolder.java b/spring-webflow-sandbox/src/main/java/org/springframework/util/AbstractResourceHolder.java index f63da202..3d002671 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/util/AbstractResourceHolder.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/util/AbstractResourceHolder.java @@ -6,19 +6,19 @@ import java.lang.reflect.Method; /** * Base abstract implementation of resource holder that implement method replacment logic. - * + * * @author Maxim Petrashev */ -public abstract class AbstractResourceHolder implements ResourceHolder - , MethodReplacer {//todo replace on injector in config +public abstract class AbstractResourceHolder implements ResourceHolder, MethodReplacer {// todo replace on + // injector in config @SuppressWarnings("unchecked") - public Object reimplement(Object aObj, Method aMethod, Object[] aArgs) throws Throwable { - Object retVal = null; - if( aArgs.length == 0 ){ - retVal = get(); - } else { - set( (E) aArgs[0] ); - } - return retVal; - } + public Object reimplement(Object aObj, Method aMethod, Object[] aArgs) throws Throwable { + Object retVal = null; + if (aArgs.length == 0) { + retVal = get(); + } else { + set((E) aArgs[0]); + } + return retVal; + } } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/util/ResourceHolder.java b/spring-webflow-sandbox/src/main/java/org/springframework/util/ResourceHolder.java index 1e9ab9b2..68a2b3d2 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/util/ResourceHolder.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/util/ResourceHolder.java @@ -2,10 +2,11 @@ package org.springframework.util; /** * Base interface for object holder concept. - * + * * @author Maxim Petrashev */ public interface ResourceHolder { - E get(); - void set(E aObject); + E get(); + + void set(E aObject); } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ConversationLifecycleListener.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ConversationLifecycleListener.java index a5b822ba..7689b48c 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ConversationLifecycleListener.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ConversationLifecycleListener.java @@ -5,92 +5,93 @@ import org.springframework.webflow.core.collection.MutableAttributeMap; /** * Listener interface for callback notification about phases in during conversation - * + * * @author Maxim Petrashev */ public interface ConversationLifecycleListener { - /** - * Invoked when a flow is launched. The launching flow is not active. - * - * @param aNewFlow The launching flow - * @param aContext The request context - */ + /** + * Invoked when a flow is launched. The launching flow is not active. + * + * @param aNewFlow The launching flow + * @param aContext The request context + */ - void startingFlow(FlowDefinition aNewFlow, RequestContext aContext); + void startingFlow(FlowDefinition aNewFlow, RequestContext aContext); - void flowStarted(RequestContext aContext, MutableAttributeMap aInput); - /** - * Invoked when the root flow session has ended. - * - * @param aEndedSession The ended session - * @param aContext The request context - */ - void flowEnded(FlowSession aEndedSession, RequestContext aContext); + void flowStarted(RequestContext aContext, MutableAttributeMap aInput); - void endingFlow(RequestContext aContext, MutableAttributeMap aOutput); - /** - * Invoked in parent flow before spawning in subflow but after input mapping has been happened. - * The child flow session is not available to implementations of this method because the flow session for - * the child flow has not yet started.

If you need to add items to the - * subflow scope, put them in aInput. - * - * @param aParentSession The active parent flow session - * @param aChild The child flow - * @param aContext The request context - * @param aInput The input map - */ - void startingSubflow(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext - , MutableAttributeMap aInput); - /** - * Invoked when a subflow is launched. The child flow session is not - * available to implementations of this method because the flow session for - * the child flow has not yet started.

If you need to add items to the - * subflow scope, put them in aInput. - * - * @param aContext The request context - * @param aInput The input map - */ - void subflowStarted(RequestContext aContext , MutableAttributeMap aInput); - /** - * Invoked in subflow flow before spawning back to parent flot but after output mapping has been happened. - * The parent flow session is not available to implementations of this method because the flow session for - * the parent flow has not yet continued.

If you need to add items to the - * parent flow scope, put them in aOutput. - * - * @param aContext The request context - * @param aOutput The input map - */ - void endingSubflow(RequestContext aContext , MutableAttributeMap aOutput); - /** - * Invoked when a parent flow is launched back. The child flow session is not - * available to implementations of this method because the flow session for - * the child flow has not yet started.

If you need to add items to the - * subflow scope, put them in aInput. - * - * @param aParentSession The active parent flow session - * @param aChild The child flow - * @param aContext The request context - * @param aOutput The input map - */ - void subflowEnded(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext - , MutableAttributeMap aOutput); - /** - * The currently executing flow session is active. This occurs after the - * first event for the executing request has been signaled or resume event has been happended. Invoked once per - * request and provides access to the active flow session prior to any - * actions being performed. - * - * @param aContext The request context - */ - void sessionActive(RequestContext aContext); - /** - * The currently executing flow session is active. This occurs after the - * first event for the executing request has been signaled or resume event has been happended. Invoked once per - * request and provides access to the active flow session prior to any - * actions being performed. - * - * @param aContext The request context - */ - void sessionDeactive(RequestContext aContext); + /** + * Invoked when the root flow session has ended. + * + * @param aEndedSession The ended session + * @param aContext The request context + */ + void flowEnded(FlowSession aEndedSession, RequestContext aContext); + + void endingFlow(RequestContext aContext, MutableAttributeMap aOutput); + + /** + * Invoked in parent flow before spawning in subflow but after input mapping has been happened. The child flow + * session is not available to implementations of this method because the flow session for the child flow has not + * yet started.

If you need to add items to the subflow scope, put them in aInput. + * + * @param aParentSession The active parent flow session + * @param aChild The child flow + * @param aContext The request context + * @param aInput The input map + */ + void startingSubflow(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext, + MutableAttributeMap aInput); + + /** + * Invoked when a subflow is launched. The child flow session is not available to implementations of this method + * because the flow session for the child flow has not yet started.

If you need to add items to the subflow + * scope, put them in aInput. + * + * @param aContext The request context + * @param aInput The input map + */ + void subflowStarted(RequestContext aContext, MutableAttributeMap aInput); + + /** + * Invoked in subflow flow before spawning back to parent flot but after output mapping has been happened. The + * parent flow session is not available to implementations of this method because the flow session for the parent + * flow has not yet continued.

If you need to add items to the parent flow scope, put them in aOutput. + * + * @param aContext The request context + * @param aOutput The input map + */ + void endingSubflow(RequestContext aContext, MutableAttributeMap aOutput); + + /** + * Invoked when a parent flow is launched back. The child flow session is not available to implementations of this + * method because the flow session for the child flow has not yet started.

If you need to add items to the + * subflow scope, put them in aInput. + * + * @param aParentSession The active parent flow session + * @param aChild The child flow + * @param aContext The request context + * @param aOutput The input map + */ + void subflowEnded(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext, + MutableAttributeMap aOutput); + + /** + * The currently executing flow session is active. This occurs after the first event for the executing request has + * been signaled or resume event has been happended. Invoked once per request and provides access to the active flow + * session prior to any actions being performed. + * + * @param aContext The request context + */ + void sessionActive(RequestContext aContext); + + /** + * The currently executing flow session is active. This occurs after the first event for the executing request has + * been signaled or resume event has been happended. Invoked once per request and provides access to the active flow + * session prior to any actions being performed. + * + * @param aContext The request context + */ + void sessionDeactive(RequestContext aContext); } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ConversationLifecycleListenerAdapter.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ConversationLifecycleListenerAdapter.java index 0dbc5137..d2cfe0b0 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ConversationLifecycleListenerAdapter.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ConversationLifecycleListenerAdapter.java @@ -4,41 +4,44 @@ import org.springframework.webflow.definition.FlowDefinition; import org.springframework.webflow.core.collection.MutableAttributeMap; /** - * + * * @author Maxim Petrashev */ public abstract class ConversationLifecycleListenerAdapter implements ConversationLifecycleListener { - public void startingFlow(FlowDefinition aNewFlow, RequestContext aContext) { - } + public void startingFlow(FlowDefinition aNewFlow, RequestContext aContext) { + } - public void flowStarted(RequestContext aContext, MutableAttributeMap aInput) { - } + public void flowStarted(RequestContext aContext, MutableAttributeMap aInput) { + } - public void flowEnded(FlowSession aEndedSession, RequestContext aContext) { - } + public void flowEnded(FlowSession aEndedSession, RequestContext aContext) { + } - public void endingFlow(RequestContext aContext, MutableAttributeMap aOutput) { - } + public void endingFlow(RequestContext aContext, MutableAttributeMap aOutput) { + } - public void startingSubflow(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext, MutableAttributeMap aInput) { - } + public void startingSubflow(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext, + MutableAttributeMap aInput) { + } - public void subflowStarted(RequestContext aContext, MutableAttributeMap aInput) { - } + public void subflowStarted(RequestContext aContext, MutableAttributeMap aInput) { + } - public void subflowStarted(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext, MutableAttributeMap aInput) { - } + public void subflowStarted(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext, + MutableAttributeMap aInput) { + } - public void endingSubflow(RequestContext aContext, MutableAttributeMap aOutput) { - } + public void endingSubflow(RequestContext aContext, MutableAttributeMap aOutput) { + } - public void subflowEnded(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext, MutableAttributeMap aOutput) { - } + public void subflowEnded(FlowSession aParentSession, FlowDefinition aChild, RequestContext aContext, + MutableAttributeMap aOutput) { + } - public void sessionActive(RequestContext aContext) { - } + public void sessionActive(RequestContext aContext) { + } - public void sessionDeactive(RequestContext aContext) { - } + public void sessionDeactive(RequestContext aContext) { + } } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ExtendedFlowExecutionListenerInterceptor.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ExtendedFlowExecutionListenerInterceptor.java index 28c2b2ff..401e0213 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ExtendedFlowExecutionListenerInterceptor.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/execution/ExtendedFlowExecutionListenerInterceptor.java @@ -9,173 +9,167 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * A listener/interceptor whose purpose is to adapt a HandlerInterceptor and - * FlowExecutionListener to provide expanded coverage at the beginning and - * ending of a request coming into a flow controller. The idea is to signal when - * a flow starts/activates, then signal when it has deactivated or ended. In - * addition, it should be signaled when a subflow starts/activates and - * ends/deactivates. + * A listener/interceptor whose purpose is to adapt a HandlerInterceptor and FlowExecutionListener to provide expanded + * coverage at the beginning and ending of a request coming into a flow controller. The idea is to signal when a flow + * starts/activates, then signal when it has deactivated or ended. In addition, it should be signaled when a subflow + * starts/activates and ends/deactivates. *

- * Adapted from Alex Wolfe's post at + * Adapted from Alex Wolfe's post at * http://forum.springframework.org/showthread.php?t=17633 - * - * + * + * * @author Andrew Ebaugh * @author Maxim Petrashev */ public class ExtendedFlowExecutionListenerInterceptor extends FlowExecutionListenerAdapter { - protected final Log _logger = LogFactory.getLog(getClass()); + protected final Log _logger = LogFactory.getLog(getClass()); - private static String FIRST_EVENT_SIGNALED = ExtendedFlowExecutionListenerInterceptor.class.getName() + ".FIRST_EVENT_SIGNALED"; - private static String CURRENT_SESSION_ENDED = ExtendedFlowExecutionListenerInterceptor.class.getName() + ".CURRENT_SESSION_ENDED"; + private static String FIRST_EVENT_SIGNALED = ExtendedFlowExecutionListenerInterceptor.class.getName() + + ".FIRST_EVENT_SIGNALED"; + private static String CURRENT_SESSION_ENDED = ExtendedFlowExecutionListenerInterceptor.class.getName() + + ".CURRENT_SESSION_ENDED"; + public ExtendedFlowExecutionListenerInterceptor(ConversationLifecycleListener aConversationLifecycleListener) { + _conversationLifecycleListener = aConversationLifecycleListener; + } - public ExtendedFlowExecutionListenerInterceptor(ConversationLifecycleListener aConversationLifecycleListener) { - _conversationLifecycleListener = aConversationLifecycleListener; - } + private ConversationLifecycleListener _conversationLifecycleListener; - private ConversationLifecycleListener _conversationLifecycleListener; + /** + * Called when any client request is submitted to manipulate this flow execution. Sets a flag in the request scope + * that is activated when the first state is entered during this request. This flag is required in order to trigger + * execution of the {@link ConversationLifecycleListener#sessionActive(RequestContext)} method. + * + * @param aContext The request aContext + */ + public final void requestSubmitted(RequestContext aContext) { + aContext.getRequestScope().put(FIRST_EVENT_SIGNALED, Boolean.FALSE); + aContext.getRequestScope().put(CURRENT_SESSION_ENDED, Boolean.FALSE); + } - /** - * Called when any client request is submitted to manipulate this flow - * execution. Sets a flag in the request scope that is activated when the - * first state is entered during this request. This flag is required in - * order to trigger execution of the {@link ConversationLifecycleListener#sessionActive(RequestContext)} - * method. - * - * @param aContext The request aContext - */ - public final void requestSubmitted(RequestContext aContext) { - aContext.getRequestScope().put(FIRST_EVENT_SIGNALED, Boolean.FALSE); - aContext.getRequestScope().put(CURRENT_SESSION_ENDED, Boolean.FALSE); - } + public final void eventSignaled(RequestContext aContext, Event aEvent) { + signalAction(aContext); + } - public final void eventSignaled(RequestContext aContext, Event aEvent) { - signalAction(aContext); - } + public final void stateEntered(RequestContext aContext, StateDefinition aPreviousState, StateDefinition aState) { + signalAction(aContext); + } - public final void stateEntered(RequestContext aContext, StateDefinition aPreviousState, StateDefinition aState) { - signalAction(aContext); - } + /** + * Called when an event is signaled, or a state is entered, but before any potential transition or actions occurs. + * If the action signaled is the first for the request, then the + * {@link ConversationLifecycleListener#sessionActive(RequestContext)} method is invoked. It is necessary that this + * be called prior to any state transitions to provide listeners coverage of any state exit/transition/entry + * actions. + * + * @param aContext The request aContext + */ + private void signalAction(RequestContext aContext) { + if (!firstEventSignaled(aContext)) { + aContext.getRequestScope().put(FIRST_EVENT_SIGNALED, Boolean.TRUE); + _conversationLifecycleListener.sessionActive(aContext); + } + } - /** - * Called when an event is signaled, or a state is entered, but before any - * potential transition or actions occurs. If the action signaled is the - * first for the request, then the {@link ConversationLifecycleListener#sessionActive(RequestContext)} - * method is invoked. It is necessary that this be called prior to any state - * transitions to provide listeners coverage of any state - * exit/transition/entry actions. - * - * @param aContext The request aContext - */ - private void signalAction(RequestContext aContext) { - if (!firstEventSignaled(aContext)) { - aContext.getRequestScope().put(FIRST_EVENT_SIGNALED, Boolean.TRUE); - _conversationLifecycleListener.sessionActive(aContext); - } - } + /** + * A aFlow session is starting. This method invokes + * {@link ConversationLifecycleListener#startingFlow(FlowDefinition, RequestContext)} if the launching aFlow session + * is the root aFlow. Otherwise, the + * {@link ConversationLifecycleListener#startingSubflow(FlowSession, FlowDefinition, RequestContext,MutableAttributeMap)} + * method is invoked. + * + * @param aContext The request aContext + * @param aFlowDefinition + * @param aInput + * @throws EnterStateVetoException The start state transition was not allowed + */ + public final void sessionStarting(RequestContext aContext, FlowDefinition aFlowDefinition, + MutableAttributeMap aInput) { + aContext.getRequestScope().put(FIRST_EVENT_SIGNALED, Boolean.TRUE); + aContext.getRequestScope().put(CURRENT_SESSION_ENDED, Boolean.FALSE); + FlowExecutionContext executionContext = aContext.getFlowExecutionContext(); + FlowSession activeSession = executionContext.isActive() ? executionContext.getActiveSession() : null; + // when starting in default subflow start state? + if (activeSession != null && SubflowState.class.isInstance(activeSession.getState())) { + aFlowDefinition = ((SubflowState) activeSession.getState()).getSubflow(); + } - /** - * A aFlow session is starting. This method invokes - * {@link ConversationLifecycleListener#startingFlow(FlowDefinition, RequestContext)} if the launching aFlow - * session is the root aFlow. Otherwise, the - * {@link ConversationLifecycleListener#startingSubflow(FlowSession, FlowDefinition, RequestContext,MutableAttributeMap)} method is - * invoked. - * - * @param aContext The request aContext - * @param aFlowDefinition - * @param aInput - * @throws EnterStateVetoException - * The start state transition was not allowed - */ - public final void sessionStarting(RequestContext aContext, FlowDefinition aFlowDefinition, MutableAttributeMap aInput) { - aContext.getRequestScope().put(FIRST_EVENT_SIGNALED, Boolean.TRUE); - aContext.getRequestScope().put(CURRENT_SESSION_ENDED, Boolean.FALSE); - FlowExecutionContext executionContext = aContext.getFlowExecutionContext(); - FlowSession activeSession = executionContext.isActive() ? executionContext .getActiveSession() : null; - // when starting in default subflow start state? - if (activeSession != null - && SubflowState.class.isInstance(activeSession.getState())) { - aFlowDefinition = ((SubflowState) activeSession.getState()).getSubflow(); - } + if (activeSession == null) { + _conversationLifecycleListener.startingFlow(aFlowDefinition, aContext); + } else { + _conversationLifecycleListener.startingSubflow(activeSession, aFlowDefinition, aContext, null); + } + } - if (activeSession == null) { - _conversationLifecycleListener.startingFlow(aFlowDefinition, aContext); - } else { - _conversationLifecycleListener.startingSubflow(activeSession, aFlowDefinition, aContext, null); - } - } + public void sessionStarted(RequestContext aContext, FlowSession aSession) { + if (aSession.isRoot()) { + _conversationLifecycleListener.flowStarted(aContext, null); + } else { + _conversationLifecycleListener.subflowStarted(aContext, null); + } + } - public void sessionStarted(RequestContext aContext, FlowSession aSession) { - if( aSession.isRoot() ) { - _conversationLifecycleListener.flowStarted(aContext, null ); - } else { - _conversationLifecycleListener.subflowStarted(aContext,null); - } - } + public void sessionEnding(RequestContext aContext, FlowSession aSession, MutableAttributeMap aOutput) { + if (aSession.isRoot()) { + _conversationLifecycleListener.endingFlow(aContext, null); + } else { + _conversationLifecycleListener.endingSubflow(aContext, null); + } + } - public void sessionEnding(RequestContext aContext, FlowSession aSession, MutableAttributeMap aOutput) { - if( aSession.isRoot() ) { - _conversationLifecycleListener.endingFlow(aContext, null ); - } else { - _conversationLifecycleListener.endingSubflow(aContext,null); - } - } + public void requestProcessed(RequestContext aContext) { + FlowExecutionContext executionContext = aContext.getFlowExecutionContext(); + if (executionContext.isActive()) { + _conversationLifecycleListener.sessionDeactive(aContext); + } + } - public void requestProcessed(RequestContext aContext) { - FlowExecutionContext executionContext = aContext.getFlowExecutionContext(); - if( executionContext.isActive() ) { - _conversationLifecycleListener.sessionDeactive(aContext ); - } - } + /** + * Called when a flow execution session ends. If the ended session was the root session of the flow execution, the + * {@link ConversationLifecycleListener#flowEnded(FlowSession, RequestContext)} method is invoked.

If the ended + * session was not the root session, then the + * {@link ConversationLifecycleListener#subflowEnded(FlowSession, FlowDefinition, RequestContext, MutableAttributeMap)} } + * method is invoked. Prior to this, and in either case, the + * {@link ConversationLifecycleListener#sessionDeactive(RequestContext)} method is invoked. + * + * @param aContext The source of the event + * @param aEndedSession The ended FlowSession + */ + public final void sessionEnded(RequestContext aContext, FlowSession aEndedSession, AttributeMap aSessionOutput) { + FlowExecutionContext exeCtx = aContext.getFlowExecutionContext(); + FlowSession newSession = exeCtx.isActive() ? exeCtx.getActiveSession() : null; + if (aEndedSession != null) { + try { + if (aEndedSession.isRoot()) { + _conversationLifecycleListener.flowEnded(aEndedSession, aContext); + } else { + _conversationLifecycleListener.subflowEnded(newSession, aEndedSession.getDefinition(), aContext, + null); + } + } catch (RuntimeException e) { // todo to think which base exception need wrap + String message = "Can't end session"; + if (_logger.isWarnEnabled()) { + _logger.warn(message, e); + } + throw new FlowExecutionException(exeCtx.getDefinition().getId(), newSession != null ? newSession + .getState().getId() : aEndedSession.getState().getId(), message, e); + } + } + aContext.getRequestScope().put(CURRENT_SESSION_ENDED, Boolean.TRUE); + } - /** - * Called when a flow execution session ends. If the ended session was the - * root session of the flow execution, the - * {@link ConversationLifecycleListener#flowEnded(FlowSession, RequestContext)} method is - * invoked.

If the ended session was not the root session, then the - * {@link ConversationLifecycleListener#subflowEnded(FlowSession, FlowDefinition, RequestContext, MutableAttributeMap)} } - * method is invoked. Prior to this, and in either case, the - * {@link ConversationLifecycleListener#sessionDeactive(RequestContext)} method is invoked. - * - * @param aContext The source of the event - * @param aEndedSession The ended FlowSession - */ - public final void sessionEnded(RequestContext aContext, FlowSession aEndedSession, AttributeMap aSessionOutput) { - FlowExecutionContext exeCtx = aContext.getFlowExecutionContext(); - FlowSession newSession = exeCtx.isActive() ? exeCtx.getActiveSession() : null; - if (aEndedSession != null) { - try{ - if (aEndedSession.isRoot()) { - _conversationLifecycleListener.flowEnded(aEndedSession, aContext); - } else { - _conversationLifecycleListener.subflowEnded(newSession, aEndedSession.getDefinition(), aContext, null); - } - } catch( RuntimeException e ){ //todo to think which base exception need wrap - String message = "Can't end session"; - if( _logger.isWarnEnabled() ) { - _logger.warn(message,e); - } - throw new FlowExecutionException( exeCtx.getDefinition().getId() - , newSession != null ? newSession.getState().getId() : aEndedSession.getState().getId() - , message, e); - } - } - aContext.getRequestScope().put(CURRENT_SESSION_ENDED, Boolean.TRUE); - } + /** + * Determine whether the current request has handled an event. + * + * @param aContext The request context + * @return true if an event has already been signaled during the current request, otherwise + * false + */ + private boolean firstEventSignaled(RequestContext aContext) { + return aContext.getRequestScope().get(FIRST_EVENT_SIGNALED).equals(Boolean.TRUE); + } - /** - * Determine whether the current request has handled an event. - * - * @param aContext The request context - * @return true if an event has already been signaled during - * the current request, otherwise false - */ - private boolean firstEventSignaled(RequestContext aContext) { - return aContext.getRequestScope().get(FIRST_EVENT_SIGNALED).equals(Boolean.TRUE); - } - public void resumed(RequestContext context) { - signalAction(context); - } + public void resumed(RequestContext context) { + signalAction(context); + } } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/DefaultEntityManagerLifecycleController.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/DefaultEntityManagerLifecycleController.java index 0d46b356..6d462cc7 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/DefaultEntityManagerLifecycleController.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/DefaultEntityManagerLifecycleController.java @@ -11,61 +11,65 @@ import javax.persistence.EntityManagerFactory; /** * Default abstract JPA implementation for {@link EntityManagerLifecycleController}. - * + * * @author Maxim Petrashev */ public abstract class DefaultEntityManagerLifecycleController implements EntityManagerLifecycleController { - private EntityManagerFactory _entityManagerFactory; + private EntityManagerFactory _entityManagerFactory; - public DefaultEntityManagerLifecycleController(EntityManagerFactory aEntityManagerFactory) { - _entityManagerFactory = aEntityManagerFactory; - } + public DefaultEntityManagerLifecycleController(EntityManagerFactory aEntityManagerFactory) { + _entityManagerFactory = aEntityManagerFactory; + } - public void close(EntityManager aEntityManager) { - Assert.isTrue(aEntityManager.isOpen(), "Entity manager was already closed"); - aEntityManager.close(); - } + public void close(EntityManager aEntityManager) { + Assert.isTrue(aEntityManager.isOpen(), "Entity manager was already closed"); + aEntityManager.close(); + } - public void deactivate(EntityManager aEntityManager) { - unbind(aEntityManager); - if (_log.isDebugEnabled()) { - _log.debug("Entity manager unbinded: " + aEntityManager.isOpen()); - } - } + public void deactivate(EntityManager aEntityManager) { + unbind(aEntityManager); + if (_log.isDebugEnabled()) { + _log.debug("Entity manager unbinded: " + aEntityManager.isOpen()); + } + } - public EntityManager create() { - return _entityManagerFactory.createEntityManager(); - } + public EntityManager create() { + return _entityManagerFactory.createEntityManager(); + } - public void flush(EntityManager aEntityManager) { - try { - aEntityManager.flush(); - } catch (RuntimeException e) {//todo review this code - aEntityManager.getTransaction().rollback(); - throw e; - } - } + public void flush(EntityManager aEntityManager) { + try { + aEntityManager.flush(); + } catch (RuntimeException e) {// todo review this code + aEntityManager.getTransaction().rollback(); + throw e; + } + } - public void activate(EntityManager aEntityManager) { - bind(aEntityManager); - if (_log.isDebugEnabled()) { - _log.debug("Session activate: " + aEntityManager.isOpen()); - } - } - protected void bind(EntityManager aEntityManager) { - TransactionSynchronizationManager.bindResource(_entityManagerFactory, new EntityManagerHolder(aEntityManager)); - } + public void activate(EntityManager aEntityManager) { + bind(aEntityManager); + if (_log.isDebugEnabled()) { + _log.debug("Session activate: " + aEntityManager.isOpen()); + } + } - protected void unbind( EntityManager aEntityManager ) { - synchronized(_entityManagerFactory){//todo is this need? - Assert.isTrue( TransactionSynchronizationManager.hasResource(_entityManagerFactory) ); //todo remove this code. Resource must be already present. - TransactionSynchronizationManager.unbindResource(_entityManagerFactory); - } - } + protected void bind(EntityManager aEntityManager) { + TransactionSynchronizationManager.bindResource(_entityManagerFactory, new EntityManagerHolder(aEntityManager)); + } - protected EntityManagerFactory getEntityManagerFactory() { - return _entityManagerFactory; - } + protected void unbind(EntityManager aEntityManager) { + synchronized (_entityManagerFactory) {// todo is this need? + Assert.isTrue(TransactionSynchronizationManager.hasResource(_entityManagerFactory)); // todo remove this + // code. Resource + // must be already + // present. + TransactionSynchronizationManager.unbindResource(_entityManagerFactory); + } + } - protected final Log _log = LogFactory.getLog(getClass()); + protected EntityManagerFactory getEntityManagerFactory() { + return _entityManagerFactory; + } + + protected final Log _log = LogFactory.getLog(getClass()); } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/EntityManagerLifecycleController.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/EntityManagerLifecycleController.java index 2ec54785..74eb6b4e 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/EntityManagerLifecycleController.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/EntityManagerLifecycleController.java @@ -9,35 +9,37 @@ import javax.persistence.EntityManager; * org.hibernate.annotations.FlushModeType.MANUAL *

  • Binding/Unbinding persistence context resources for current thread
  • * - * + * * @author Maxim Petrashev */ public interface EntityManagerLifecycleController { - /** - * Create new entity manager and return wrapper for it with aId id. - */ - EntityManager create(); + /** + * Create new entity manager and return wrapper for it with aId id. + */ + EntityManager create(); - /** - * Reconnect entity manager and bind to current thread. - * @param aEntityManager - */ - void activate(EntityManager aEntityManager); - /** - * Disconnect current session and unbind from current thread. - * @param aEntityManager - */ - void deactivate(EntityManager aEntityManager); + /** + * Reconnect entity manager and bind to current thread. + * @param aEntityManager + */ + void activate(EntityManager aEntityManager); - /** - * Commit application transaction. - * @param aEntityManager - */ - void flush(EntityManager aEntityManager); - /** - * Close opened entity manager. - * @param aEntityManager - */ - void close(EntityManager aEntityManager); + /** + * Disconnect current session and unbind from current thread. + * @param aEntityManager + */ + void deactivate(EntityManager aEntityManager); + + /** + * Commit application transaction. + * @param aEntityManager + */ + void flush(EntityManager aEntityManager); + + /** + * Close opened entity manager. + * @param aEntityManager + */ + void close(EntityManager aEntityManager); } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/OpenEntityManagerPerConversationFlowListener.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/OpenEntityManagerPerConversationFlowListener.java index dd6dd603..8bff4dd3 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/OpenEntityManagerPerConversationFlowListener.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/OpenEntityManagerPerConversationFlowListener.java @@ -12,130 +12,125 @@ import org.springframework.webflow.execution.ConversationLifecycleListenerAdapte import org.springframework.webflow.execution.FlowExecutionContext; import org.springframework.webflow.execution.FlowSession; import org.springframework.webflow.execution.RequestContext; + /** - * Intended for those wating a long session model within webflows. A entity - * manager is created when the flow begins, and is disconnected and reconnected - * as necessary throughout the lifecycle of the flow. In particular, it should - * be thought of as both a - * {@link org.springframework.webflow.execution.FlowExecutionListener} and - * {@link WebRequestInterceptor} - * that binds a - * entity manager to the current thread for the activate span of a FlowSession. - * This implementation shares the entity manager between a parent flow and any - * subflows. + * Intended for those wating a long session model within webflows. A entity manager is created when the flow begins, and + * is disconnected and reconnected as necessary throughout the lifecycle of the flow. In particular, it should be + * thought of as both a {@link org.springframework.webflow.execution.FlowExecutionListener} and + * {@link WebRequestInterceptor} that binds a entity manager to the current thread for the activate span of a + * FlowSession. This implementation shares the entity manager between a parent flow and any subflows. *

    - * To facilitate the long session idea, objects within the flow will be - * reassociated with the jpa persistence context when the flow is - * re-activated. Deserialized jpa flow scope - * objects lose their association to the persistence context, and thus result in - * problems when you attempt to perform persistence operations (run into - * non-unique object exceptions, null sessions in persistent collections, and a - * host of other weird behaviors). There is a basic facility to apply a - * flushMode to new entity managers that are created, but not as - * sophisticated as that provided by a HibernateAccessor. Config example: - * + * To facilitate the long session idea, objects within the flow will be reassociated with the jpa persistence context + * when the flow is re-activated. Deserialized jpa flow scope objects lose their association to the persistence context, + * and thus result in problems when you attempt to perform persistence operations (run into non-unique object + * exceptions, null sessions in persistent collections, and a host of other weird behaviors). There is a basic facility + * to apply a flushMode to new entity managers that are created, but not as sophisticated as that provided by a + * HibernateAccessor. Config example: + * *
      *      	<bean id="openEntityManagerFlowListener"
      *       			class="org.springframework.webflow.jpa.OpenEntityManagerPerConversationFlowListener">
      *       		<constructor ref="_lifecycleController"/>
      *      	</bean>
      * 
    - * + * *

    - * Adapted from Alex Wolfe's post at + * Adapted from Alex Wolfe's post at * http://forum.springframework.org/showthread.php?t=17633 - * + * * @author Maxim Petrashev */ public class OpenEntityManagerPerConversationFlowListener extends ConversationLifecycleListenerAdapter { - protected final Log _logger = LogFactory.getLog( getClass() ); + protected final Log _logger = LogFactory.getLog(getClass()); - private final EntityManagerLifecycleController _lifecycleController; + private final EntityManagerLifecycleController _lifecycleController; - /** - * Attribute name for annotated state which mark end-state and application commit end-state. - */ - public static final String APPLICATION_TRANSACTION_COMMIT_ATTR_NAME = "applicationTransactionCommit"; - /** - * Attribute name under wich in conversation scope will be stored entity manager for conversation. - */ - private static final String ENTITY_MANAGER_ATTR_NAME = OpenEntityManagerPerConversationFlowListener.class.getName() + ".ENTITY_MANAGER"; + /** + * Attribute name for annotated state which mark end-state and application commit end-state. + */ + public static final String APPLICATION_TRANSACTION_COMMIT_ATTR_NAME = "applicationTransactionCommit"; + /** + * Attribute name under wich in conversation scope will be stored entity manager for conversation. + */ + private static final String ENTITY_MANAGER_ATTR_NAME = OpenEntityManagerPerConversationFlowListener.class.getName() + + ".ENTITY_MANAGER"; - protected OpenEntityManagerPerConversationFlowListener(EntityManagerLifecycleController aLifecycleController ) { - _lifecycleController = aLifecycleController; - } + protected OpenEntityManagerPerConversationFlowListener(EntityManagerLifecycleController aLifecycleController) { + _lifecycleController = aLifecycleController; + } - protected EntityManager getEntityManager(RequestContext aContext){ - return (EntityManager) aContext.getConversationScope().get( ENTITY_MANAGER_ATTR_NAME ); - } + protected EntityManager getEntityManager(RequestContext aContext) { + return (EntityManager) aContext.getConversationScope().get(ENTITY_MANAGER_ATTR_NAME); + } - /** - * Create entity manager for new conversation. - * @param aNewFlow - * @param aContext - */ - public void startingFlow(FlowDefinition aNewFlow, RequestContext aContext) { - _logger.debug("Creating entity manager for flow: " + aNewFlow.getId()); - EntityManager entityManager = _lifecycleController.create(); - _lifecycleController.activate( entityManager ); - aContext.getConversationScope().put(ENTITY_MANAGER_ATTR_NAME, entityManager); - } + /** + * Create entity manager for new conversation. + * @param aNewFlow + * @param aContext + */ + public void startingFlow(FlowDefinition aNewFlow, RequestContext aContext) { + _logger.debug("Creating entity manager for flow: " + aNewFlow.getId()); + EntityManager entityManager = _lifecycleController.create(); + _lifecycleController.activate(entityManager); + aContext.getConversationScope().put(ENTITY_MANAGER_ATTR_NAME, entityManager); + } - /** - * Try commit application transaction on application transaction commit end state. - * Clean also all resources that were allocated for conversation entity manager. - * @param aEndedSession - * @param aContext - */ - public void flowEnded(FlowSession aEndedSession, RequestContext aContext) { - EntityManager entityManager = getEntityManager(aContext); - try{ - if (isApplicationTransactionCommitState(aEndedSession.getState())) { - _lifecycleController.flush(entityManager); - } - }finally{ - try{ - _lifecycleController.deactivate(entityManager); - }finally{ - _lifecycleController.close( entityManager ); - } - } - } + /** + * Try commit application transaction on application transaction commit end state. Clean also all resources that + * were allocated for conversation entity manager. + * @param aEndedSession + * @param aContext + */ + public void flowEnded(FlowSession aEndedSession, RequestContext aContext) { + EntityManager entityManager = getEntityManager(aContext); + try { + if (isApplicationTransactionCommitState(aEndedSession.getState())) { + _lifecycleController.flush(entityManager); + } + } finally { + try { + _lifecycleController.deactivate(entityManager); + } finally { + _lifecycleController.close(entityManager); + } + } + } - /** - * {@inheritDoc} - */ - public void sessionActive(RequestContext aContext) { - EntityManager entityManager = getEntityManager(aContext); - _lifecycleController.activate( entityManager ); - } + /** + * {@inheritDoc} + */ + public void sessionActive(RequestContext aContext) { + EntityManager entityManager = getEntityManager(aContext); + _lifecycleController.activate(entityManager); + } - /** - * Deactivate current entity manager on end of request handling process. - */ - public void sessionDeactive(RequestContext aContext) { - FlowExecutionContext flowExecutionContext = aContext.getFlowExecutionContext(); - if( flowExecutionContext.isActive() ) {//todo need CommandManager or request specific lifecycleController - EntityManager entityManager = getEntityManager(aContext); - _lifecycleController.deactivate( entityManager ); - } else { - //entity manager already was closed in flowEnded method - } - } + /** + * Deactivate current entity manager on end of request handling process. + */ + public void sessionDeactive(RequestContext aContext) { + FlowExecutionContext flowExecutionContext = aContext.getFlowExecutionContext(); + if (flowExecutionContext.isActive()) {// todo need CommandManager or request specific lifecycleController + EntityManager entityManager = getEntityManager(aContext); + _lifecycleController.deactivate(entityManager); + } else { + // entity manager already was closed in flowEnded method + } + } - /** - * Return is aState application commit state or not. Returns true if aState is EndState and aState is annotated - * by {@link #APPLICATION_TRANSACTION_COMMIT_ATTR_NAME} attribute. - */ - protected boolean isApplicationTransactionCommitState(StateDefinition aState) { - boolean retVal = false; - if (aState instanceof EndState) { - retVal = aState.getAttributes().get(APPLICATION_TRANSACTION_COMMIT_ATTR_NAME, "false").equals("true"); - } - return retVal; - } + /** + * Return is aState application commit state or not. Returns true if aState is EndState and aState is annotated by + * {@link #APPLICATION_TRANSACTION_COMMIT_ATTR_NAME} attribute. + */ + protected boolean isApplicationTransactionCommitState(StateDefinition aState) { + boolean retVal = false; + if (aState instanceof EndState) { + retVal = aState.getAttributes().get(APPLICATION_TRANSACTION_COMMIT_ATTR_NAME, "false").equals("true"); + } + return retVal; + } - public static final String CURRENT_ENTITY_MANAGER_KEY_ATTR_NAME = OpenEntityManagerPerConversationFlowListener.class.getName() + ".CURRENT_ENTITY_MANAGER_KEY"; - //todo review exceptionThrown + public static final String CURRENT_ENTITY_MANAGER_KEY_ATTR_NAME = OpenEntityManagerPerConversationFlowListener.class + .getName() + + ".CURRENT_ENTITY_MANAGER_KEY"; + // todo review exceptionThrown } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/TransactionSynchronizationManagerEnityManagerHolder.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/TransactionSynchronizationManagerEnityManagerHolder.java index e9a2d7c8..0b4254fa 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/TransactionSynchronizationManagerEnityManagerHolder.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/TransactionSynchronizationManagerEnityManagerHolder.java @@ -8,18 +8,18 @@ import javax.persistence.EntityManager; /** * Resource holder that is wrapper for TransactionSynchronizationManager. - * + * * @author Maxim Petrashev */ public class TransactionSynchronizationManagerEnityManagerHolder extends AbstractReadOnlyResourceHolder { - public EntityManager get() { - EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource( _key ); - return emHolder.getEntityManager(); - } + public EntityManager get() { + EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(_key); + return emHolder.getEntityManager(); + } - public TransactionSynchronizationManagerEnityManagerHolder(Object aKey) { - _key = aKey; - } + public TransactionSynchronizationManagerEnityManagerHolder(Object aKey) { + _key = aKey; + } - private Object _key; + private Object _key; } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/hibernate/EntityManagerLifecycleController.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/hibernate/EntityManagerLifecycleController.java index 65c44c2c..07c8e7b9 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/hibernate/EntityManagerLifecycleController.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/hibernate/EntityManagerLifecycleController.java @@ -13,56 +13,61 @@ import javax.persistence.EntityTransaction; /** * Hibernate specific implementation of EntityManagerLifecycleController interface. Set for each new entity manager * hibernate specific flush mode and starts new JPA transaction on activation, and commit it on deactivation - * + * * @author Maxim Petrashev */ public class EntityManagerLifecycleController extends DefaultEntityManagerLifecycleController { - public EntityManagerLifecycleController(EntityManagerFactory aEntityManagerFactory) { - super(aEntityManagerFactory); - } - public EntityManager create() { - EntityManager retVal = super.create(); - Session session = HibernateUtils.getSession(retVal); - session.setFlushMode(FlushMode.MANUAL); //todo review this code - return retVal; - } - protected void unbind( EntityManager aEntityManager ) { - try{ - SessionFactory sessionFactory = HibernateUtils.getSessionFactory( getEntityManagerFactory() ); - ManagedSessionContext.unbind(sessionFactory); - }finally{ - super.unbind( aEntityManager ); - } - } + public EntityManagerLifecycleController(EntityManagerFactory aEntityManagerFactory) { + super(aEntityManagerFactory); + } - protected void bind(EntityManager aEntityManager) { - super.bind(aEntityManager); - //todo remove this code in hibernate specific class - ManagedSessionContext.bind( HibernateUtils.getSession( aEntityManager ) ); - } + public EntityManager create() { + EntityManager retVal = super.create(); + Session session = HibernateUtils.getSession(retVal); + session.setFlushMode(FlushMode.MANUAL); // todo review this code + return retVal; + } - public void activate(EntityManager aEntityManager) { - beginTransaction(aEntityManager); - super.activate(aEntityManager); - } + protected void unbind(EntityManager aEntityManager) { + try { + SessionFactory sessionFactory = HibernateUtils.getSessionFactory(getEntityManagerFactory()); + ManagedSessionContext.unbind(sessionFactory); + } finally { + super.unbind(aEntityManager); + } + } - public void deactivate(EntityManager aEntityManager) { - try{ - disconnectSession(aEntityManager); - } finally { - super.deactivate(aEntityManager); - } - } + protected void bind(EntityManager aEntityManager) { + super.bind(aEntityManager); + // todo remove this code in hibernate specific class + ManagedSessionContext.bind(HibernateUtils.getSession(aEntityManager)); + } - protected void beginTransaction(EntityManager aEntityManager) {//todo is it method need? May be transaction aspect has to cover it? - //begin database transaction for taking available connection - aEntityManager.getTransaction().begin(); - } - protected void disconnectSession(EntityManager aEntityManager) {//todo is it method need? May be transaction aspect has to cover it? - EntityTransaction transaction = aEntityManager.getTransaction(); - transaction.commit(); - //todo is it need ? aSession.disconnect(); - } + public void activate(EntityManager aEntityManager) { + beginTransaction(aEntityManager); + super.activate(aEntityManager); + } + + public void deactivate(EntityManager aEntityManager) { + try { + disconnectSession(aEntityManager); + } finally { + super.deactivate(aEntityManager); + } + } + + protected void beginTransaction(EntityManager aEntityManager) {// todo is it method need? May be transaction aspect + // has to cover it? + // begin database transaction for taking available connection + aEntityManager.getTransaction().begin(); + } + + protected void disconnectSession(EntityManager aEntityManager) {// todo is it method need? May be transaction aspect + // has to cover it? + EntityTransaction transaction = aEntityManager.getTransaction(); + transaction.commit(); + // todo is it need ? aSession.disconnect(); + } } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/hibernate/HibernateUtils.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/hibernate/HibernateUtils.java index 4aaad430..2ee3672a 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/hibernate/HibernateUtils.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/jpa/hibernate/HibernateUtils.java @@ -15,30 +15,33 @@ import java.util.LinkedList; /** * Utils class for common hibernate JPA routines. - * + * * @author Maxim Petrashev */ public abstract class HibernateUtils { - public static SessionFactory getSessionFactory(EntityManagerFactory aEntityManagerFactory) { - HibernateEntityManagerFactory hibernateEntityManagerFactory - = (HibernateEntityManagerFactory) aEntityManagerFactory; - return hibernateEntityManagerFactory.getSessionFactory(); - } - public static Session getSession(EntityManager aEntityManager) { - return (Session) ((HibernateEntityManager)aEntityManager).getSession(); - } - @Deprecated public static List getEntityClasses( EntityManager aEntityManager ) { - SessionFactory sessionFactory = getSession(aEntityManager).getSessionFactory(); - @SuppressWarnings("unchecked") - Map metadataMap = sessionFactory.getAllClassMetadata(); - List retVal = new LinkedList(); - for (ClassMetadata classMetadata : metadataMap.values()) { - Class type = classMetadata.getMappedClass(EntityMode.POJO); - retVal.add( type ); - } - return retVal; - } - public static Object getIdentifier(SessionFactory aSessionFactory, Object aEntity) { - return aSessionFactory.getCurrentSession().getIdentifier( aEntity ); - } + public static SessionFactory getSessionFactory(EntityManagerFactory aEntityManagerFactory) { + HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) aEntityManagerFactory; + return hibernateEntityManagerFactory.getSessionFactory(); + } + + public static Session getSession(EntityManager aEntityManager) { + return (Session) ((HibernateEntityManager) aEntityManager).getSession(); + } + + @Deprecated + public static List getEntityClasses(EntityManager aEntityManager) { + SessionFactory sessionFactory = getSession(aEntityManager).getSessionFactory(); + @SuppressWarnings("unchecked") + Map metadataMap = sessionFactory.getAllClassMetadata(); + List retVal = new LinkedList(); + for (ClassMetadata classMetadata : metadataMap.values()) { + Class type = classMetadata.getMappedClass(EntityMode.POJO); + retVal.add(type); + } + return retVal; + } + + public static Object getIdentifier(SessionFactory aSessionFactory, Object aEntity) { + return aSessionFactory.getCurrentSession().getIdentifier(aEntity); + } } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/Sale.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/Sale.java index 01fce276..46204cc3 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/Sale.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/Sale.java @@ -31,23 +31,23 @@ import javax.persistence.Transient; @Entity @Table(name = "T_SALES") -@Proxy(lazy=true) +@Proxy(lazy = true) public class Sale implements Serializable { - @Id - @TableGenerator( name="ids" ) - @GeneratedValue(strategy= GenerationType.TABLE) - public int getId() { - return id; - } + @Id + @TableGenerator(name = "ids") + @GeneratedValue(strategy = GenerationType.TABLE) + public int getId() { + return id; + } - public void setId(int aId) { - id = aId; - } + public void setId(int aId) { + id = aId; + } - private int id; + private int id; - private double price; + private double price; private int itemCount; @@ -113,22 +113,21 @@ public class Sale implements Serializable { * Returns the base amount of the sale, without discount or delivery costs. */ @Transient - public double getAmount() { + public double getAmount() { return price * itemCount; } /** * Returns the discount rate to apply. */ - @Transient - public double getDiscountRate() { + @Transient + public double getDiscountRate() { double discount = 0.02; if ("A".equals(category)) { if (itemCount >= 100) { discount = 0.1; } - } - else if ("B".equals(category)) { + } else if ("B".equals(category)) { if (itemCount >= 200) { discount = 0.2; } @@ -139,21 +138,20 @@ public class Sale implements Serializable { /** * Returns the savings because of the discount. */ - @Transient - public double getSavings() { + @Transient + public double getSavings() { return getDiscountRate() * getAmount(); } /** * Returns the delivery cost. */ - @Transient - public double getDeliveryCost() { + @Transient + public double getDeliveryCost() { double delCost = 0.0; if ("S".equals(shippingType)) { delCost = 10.0; - } - else if ("E".equals(shippingType)) { + } else if ("E".equals(shippingType)) { delCost = 20.0; } return delCost; @@ -163,7 +161,7 @@ public class Sale implements Serializable { * Returns the total cost of the sale, including discount and delivery cost. */ @Transient - public double getTotalCost() { + public double getTotalCost() { return getAmount() + getDeliveryCost() - getSavings(); } diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/SaleValidator.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/SaleValidator.java index 51cfcef5..a7731a55 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/SaleValidator.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/SaleValidator.java @@ -18,7 +18,7 @@ package org.springframework.webflow.samples.sellitem; import org.springframework.validation.Errors; import org.springframework.validation.Validator; -//todo remove dependency on Validator interface +// todo remove dependency on Validator interface public class SaleValidator implements Validator { public boolean supports(Class clazz) { @@ -26,10 +26,10 @@ public class SaleValidator implements Validator { } public void validate(Object obj, Errors errors) { - Sale sale = (Sale)obj; + Sale sale = (Sale) obj; validatePriceAndItemCount(sale, errors); } - + public void validatePriceAndItemCount(Sale sale, Errors errors) { if (sale.getItemCount() <= 0) { errors.rejectValue("itemCount", "tooLittle", "Item count must be greater than 0"); diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/SellItemFlowExecutionListener.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/SellItemFlowExecutionListener.java index 91467324..94545c27 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/SellItemFlowExecutionListener.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/SellItemFlowExecutionListener.java @@ -29,7 +29,12 @@ public class SellItemFlowExecutionListener extends FlowExecutionListenerAdapter public void stateEntering(RequestContext context, StateDefinition nextState) throws EnterStateVetoException { String role = nextState.getAttributes().getString("role"); if (StringUtils.hasText(role)) { - HttpServletRequest request = ((ServletExternalContext)context.getExternalContext()).getRequest();//todo remove dependency on servlet api + HttpServletRequest request = ((ServletExternalContext) context.getExternalContext()).getRequest();// todo + // remove + // dependency + // on + // servlet + // api if (!request.isUserInRole(role)) { throw new EnterStateVetoException(context.getActiveFlow().getId(), context.getCurrentState().getId(), nextState.getId(), "State requires role '" + role diff --git a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/jpa/JpaSaleProcessor.java b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/jpa/JpaSaleProcessor.java index 1e54c3a4..82a8233b 100644 --- a/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/jpa/JpaSaleProcessor.java +++ b/spring-webflow-sandbox/src/main/java/org/springframework/webflow/samples/sellitem/jpa/JpaSaleProcessor.java @@ -6,9 +6,10 @@ import org.springframework.webflow.samples.sellitem.Sale; import javax.persistence.EntityManager; public abstract class JpaSaleProcessor implements SaleProcessor { - public void process(Sale sale) { - EntityManager entityManager = getEntityManager(); - entityManager.persist(sale); - } - protected abstract EntityManager getEntityManager(); + public void process(Sale sale) { + EntityManager entityManager = getEntityManager(); + entityManager.persist(sale); + } + + protected abstract EntityManager getEntityManager(); }