message resolution fix

This commit is contained in:
Keith Donald
2008-05-14 03:07:29 +00:00
parent 8f9ad87fc8
commit 7010a806a0
14 changed files with 122 additions and 192 deletions

View File

@@ -25,9 +25,10 @@ import java.util.LinkedList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.binding.message.DefaultMessageContext;
import org.springframework.binding.message.MessageContext;
import org.springframework.binding.message.MessageContextFactory;
import org.springframework.binding.message.StateManageableMessageContext;
import org.springframework.context.MessageSource;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.webflow.context.ExternalContext;
@@ -104,11 +105,6 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
*/
private transient FlowExecutionKeyFactory keyFactory;
/**
* The factory for message contexts for tracking flow execution messages.
*/
private transient MessageContextFactory messageContextFactory;
/**
* The key assigned to this flow execution. May be null if a key has not been assigned.
*/
@@ -216,26 +212,27 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
logger.debug("Starting execution in " + externalContext);
}
started = true;
RequestControlContext context = createControlContext(externalContext, createMessageContext());
RequestContextHolder.setRequestContext(context);
listeners.fireRequestSubmitted(context);
MessageContext messageContext = createMessageContext(null);
RequestControlContext requestContext = createRequestContext(externalContext, messageContext);
RequestContextHolder.setRequestContext(requestContext);
listeners.fireRequestSubmitted(requestContext);
try {
start(flow, input, context);
start(flow, input, requestContext);
} catch (FlowExecutionException e) {
handleException(e, context);
handleException(e, requestContext);
} catch (Exception e) {
handleException(wrap(e), context);
handleException(wrap(e), requestContext);
} finally {
if (!hasEnded()) {
saveMessages(context);
saveMessages(requestContext);
try {
listeners.firePaused(context);
listeners.firePaused(requestContext);
} catch (Throwable e) {
logger.error("Flow execution listener threw exception", e);
}
}
try {
listeners.fireRequestProcessed(context);
listeners.fireRequestProcessed(requestContext);
} catch (Throwable e) {
logger.error("Flow execution listener threw exception", e);
}
@@ -243,18 +240,6 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
}
}
public void setCurrentState(String stateId) {
State state = flow.getStateInstance(stateId);
FlowSessionImpl session;
if (started) {
session = getActiveSessionInternal();
} else {
session = activateSession(flow);
started = true;
}
session.setCurrentState(state);
}
public void resume(ExternalContext externalContext) throws FlowExecutionException, IllegalStateException {
if (!isActive()) {
if (started) {
@@ -266,27 +251,29 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
if (logger.isDebugEnabled()) {
logger.debug("Resuming execution in " + externalContext);
}
RequestControlContext context = createControlContext(externalContext, createMessageContext());
RequestContextHolder.setRequestContext(context);
listeners.fireRequestSubmitted(context);
Flow activeFlow = getActiveSessionInternal().getFlow();
MessageContext messageContext = createMessageContext(activeFlow.getApplicationContext());
RequestControlContext requestContext = createRequestContext(externalContext, messageContext);
RequestContextHolder.setRequestContext(requestContext);
listeners.fireRequestSubmitted(requestContext);
try {
listeners.fireResuming(context);
getActiveSessionInternal().getFlow().resume(context);
listeners.fireResuming(requestContext);
activeFlow.resume(requestContext);
} catch (FlowExecutionException e) {
handleException(e, context);
handleException(e, requestContext);
} catch (Exception e) {
handleException(wrap(e), context);
handleException(wrap(e), requestContext);
} finally {
if (!hasEnded()) {
saveMessages(context);
saveMessages(requestContext);
try {
listeners.firePaused(context);
listeners.firePaused(requestContext);
} catch (Throwable e) {
logger.error("Flow execution listener threw exception", e);
}
}
try {
listeners.fireRequestProcessed(context);
listeners.fireRequestProcessed(requestContext);
} catch (Throwable e) {
logger.error("Flow execution listener threw exception", e);
}
@@ -294,8 +281,27 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
}
}
private MessageContext createMessageContext() {
StateManageableMessageContext messageContext = messageContextFactory.createMessageContext();
/**
* Jump to a state of the currently active flow. If this execution has not been started, a new session will be
* activated and its current state will be set. This is a implementation-internal method that bypasses the
* {@link #start(MutableAttributeMap, ExternalContext)} operation and allows for jumping to an arbitrary flow state.
* Useful for testing.
* @param stateId the identifier of the state to jump to
*/
public void setCurrentState(String stateId) {
FlowSessionImpl session;
if (started) {
session = getActiveSessionInternal();
} else {
session = activateSession(flow);
started = true;
}
State state = session.getFlow().getStateInstance(stateId);
session.setCurrentState(state);
}
private MessageContext createMessageContext(MessageSource messageSource) {
StateManageableMessageContext messageContext = new DefaultMessageContext(messageSource);
Serializable messagesMemento = (Serializable) getFlashScope().extract("messagesMemento");
if (messagesMemento != null) {
messageContext.restoreMessages(messagesMemento);
@@ -304,8 +310,8 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
}
private void saveMessages(RequestContext context) {
Serializable messagesMemento = ((StateManageableMessageContext) context.getMessageContext())
.createMessagesMemento();
StateManageableMessageContext messageContext = (StateManageableMessageContext) context.getMessageContext();
Serializable messagesMemento = messageContext.createMessagesMemento();
getFlashScope().put("messagesMemento", messagesMemento);
}
@@ -315,7 +321,8 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
* Create a flow execution control context.
* @param externalContext the external context triggering this request
*/
protected RequestControlContext createControlContext(ExternalContext externalContext, MessageContext messageContext) {
protected RequestControlContext createRequestContext(ExternalContext externalContext,
MessageContext messageContext) {
return new RequestControlContextImpl(this, externalContext, messageContext);
}
@@ -337,6 +344,8 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
if (input == null) {
input = new LocalAttributeMap();
}
StateManageableMessageContext messageContext = (StateManageableMessageContext) context.getMessageContext();
messageContext.setMessageSource(flow.getApplicationContext());
listeners.fireSessionStarting(context, session, input);
flow.start(context, input);
listeners.fireSessionStarted(context, session);
@@ -429,14 +438,6 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable {
this.keyFactory = keyFactory;
}
MessageContextFactory getMessageContextFactory() {
return messageContextFactory;
}
void setMessageContextFactory(MessageContextFactory messageContextFactory) {
this.messageContextFactory = messageContextFactory;
}
// Used by {@link FlowExecutionImplFactory}
/**

View File

@@ -19,7 +19,6 @@ import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.binding.message.DefaultMessageContextFactory;
import org.springframework.util.Assert;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.CollectionUtils;
@@ -81,7 +80,8 @@ public class FlowExecutionImplFactory implements FlowExecutionFactory {
logger.debug("Creating new execution of '" + flowDefinition.getId() + "'");
}
FlowExecutionImpl execution = new FlowExecutionImpl((Flow) flowDefinition);
configureServices(execution);
execution.setAttributes(executionAttributes);
execution.setListeners(executionListenerLoader.getListeners(execution.getDefinition()));
execution.setKeyFactory(executionKeyFactory);
return execution;
}
@@ -112,20 +112,10 @@ public class FlowExecutionImplFactory implements FlowExecutionFactory {
conversationScope = new LocalAttributeMap();
}
execution.setConversationScope(conversationScope);
configureServices(execution);
return execution;
}
/**
* Called by subclasses to apply the configured set of standard services to the flow execution.
* @param execution the flow execution
*/
protected void configureServices(FlowExecutionImpl execution) {
execution.setAttributes(executionAttributes);
execution.setListeners(executionListenerLoader.getListeners(execution.getDefinition()));
execution.setKeyFactory(executionKeyFactory);
execution.setMessageContextFactory(new DefaultMessageContextFactory(execution.getDefinition()
.getApplicationContext()));
return execution;
}
/**

View File

@@ -247,7 +247,15 @@ public class MockExternalContext implements ExternalContext {
}
/**
* Sets the current user principal as a string.
* Sets the current user principal.
* @param currentUser the current user
*/
public void setCurrentUser(Principal currentUser) {
this.currentUser = currentUser;
}
/**
* Convenience method that sets the current user principal as a string.
* @param currentUser the current user name
*/
public void setCurrentUser(String currentUser) {

View File

@@ -15,9 +15,8 @@
*/
package org.springframework.webflow.test;
import org.springframework.binding.message.DefaultMessageContextFactory;
import org.springframework.binding.message.DefaultMessageContext;
import org.springframework.binding.message.MessageContext;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.LocalAttributeMap;
@@ -94,7 +93,7 @@ public class MockRequestContext implements RequestContext {
public MockRequestContext(ParameterMap requestParameterMap) {
this.flowExecutionContext = new MockFlowExecutionContext();
this.externalContext = new MockExternalContext(requestParameterMap);
this.messageContext = new DefaultMessageContextFactory(new StaticMessageSource()).createMessageContext();
this.messageContext = new DefaultMessageContext();
}
/**
@@ -105,7 +104,7 @@ public class MockRequestContext implements RequestContext {
public MockRequestContext(FlowExecutionContext flowExecutionContext) {
this.flowExecutionContext = flowExecutionContext;
this.externalContext = new MockExternalContext();
this.messageContext = new DefaultMessageContextFactory(new StaticMessageSource()).createMessageContext();
this.messageContext = new DefaultMessageContext();
}
// implementing RequestContext

View File

@@ -17,8 +17,6 @@ package org.springframework.webflow.engine.impl;
import junit.framework.TestCase;
import org.springframework.binding.message.DefaultMessageContextFactory;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.engine.EndState;
import org.springframework.webflow.engine.Flow;
@@ -55,7 +53,6 @@ public class FlowExecutionImplTests extends TestCase {
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setListeners(listeners);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
MockExternalContext context = new MockExternalContext();
assertFalse(execution.hasStarted());
execution.start(null, context);
@@ -89,7 +86,6 @@ public class FlowExecutionImplTests extends TestCase {
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setListeners(listeners);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
MockExternalContext context = new MockExternalContext();
execution.start(null, context);
assertTrue(execution.isActive());
@@ -112,7 +108,6 @@ public class FlowExecutionImplTests extends TestCase {
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setListeners(listeners);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
MockExternalContext context = new MockExternalContext();
execution.start(null, context);
assertTrue(execution.isActive());
@@ -130,7 +125,6 @@ public class FlowExecutionImplTests extends TestCase {
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setListeners(listeners);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
MockExternalContext context = new MockExternalContext();
assertFalse(execution.hasStarted());
try {
@@ -150,7 +144,6 @@ public class FlowExecutionImplTests extends TestCase {
}
};
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
MockExternalContext context = new MockExternalContext();
assertFalse(execution.hasStarted());
try {
@@ -171,7 +164,6 @@ public class FlowExecutionImplTests extends TestCase {
}
};
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
MockExternalContext context = new MockExternalContext();
assertFalse(execution.hasStarted());
try {
@@ -186,7 +178,6 @@ public class FlowExecutionImplTests extends TestCase {
Flow flow = new Flow("flow");
new EndState(flow, "end");
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
MockExternalContext context = new MockExternalContext();
execution.start(null, context);
try {
@@ -203,7 +194,6 @@ public class FlowExecutionImplTests extends TestCase {
MockFlowExecutionListener mockListener = new MockFlowExecutionListener();
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
execution.setListeners(listeners);
execution.setKeyFactory(new MockFlowExecutionKeyFactory());
MockExternalContext context = new MockExternalContext();
@@ -224,7 +214,6 @@ public class FlowExecutionImplTests extends TestCase {
MockFlowExecutionListener mockListener = new MockFlowExecutionListener();
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
execution.setListeners(listeners);
MockExternalContext context = new MockExternalContext();
execution.start(null, context);
@@ -242,7 +231,6 @@ public class FlowExecutionImplTests extends TestCase {
Flow flow = new Flow("flow");
new EndState(flow, "end");
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
MockExternalContext context = new MockExternalContext();
execution.start(null, context);
try {
@@ -263,7 +251,6 @@ public class FlowExecutionImplTests extends TestCase {
MockFlowExecutionListener mockListener = new MockFlowExecutionListener();
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
execution.setListeners(listeners);
execution.setKeyFactory(new MockFlowExecutionKeyFactory());
MockExternalContext context = new MockExternalContext();
@@ -289,7 +276,6 @@ public class FlowExecutionImplTests extends TestCase {
MockFlowExecutionListener mockListener = new MockFlowExecutionListener();
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
execution.setListeners(listeners);
execution.setKeyFactory(new MockFlowExecutionKeyFactory());
MockExternalContext context = new MockExternalContext();
@@ -318,7 +304,6 @@ public class FlowExecutionImplTests extends TestCase {
FlowExecutionListener[] listeners = new FlowExecutionListener[] { mockListener };
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setListeners(listeners);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
execution.setKeyFactory(new MockFlowExecutionKeyFactory());
MockExternalContext context = new MockExternalContext();
execution.start(null, context);
@@ -336,7 +321,6 @@ public class FlowExecutionImplTests extends TestCase {
}
};
FlowExecutionImpl execution = new FlowExecutionImpl(flow);
execution.setMessageContextFactory(new DefaultMessageContextFactory(new StaticMessageSource()));
execution.setKeyFactory(new MockFlowExecutionKeyFactory());
MockExternalContext context = new MockExternalContext();