diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/Transition.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/Transition.java index 9a13c4e5..4c8eec00 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/Transition.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/Transition.java @@ -75,6 +75,16 @@ public class Transition extends AnnotatedObject implements TransitionDefinition */ private TargetStateResolver targetStateResolver; + /** + * Create a new transition that always matches and always executes, but its execution does nothing by default. + * @see #setMatchingCriteria(TransitionCriteria) + * @see #setExecutionCriteria(TransitionCriteria) + * @see #setTargetStateResolver(TargetStateResolver) + */ + public Transition() { + this(WildcardTransitionCriteria.INSTANCE, null); + } + /** * Create a new transition that always matches and always executes, transitioning to the target state calculated by * the provided targetStateResolver. diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java index a56ce6cb..87d01d5d 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java @@ -71,6 +71,9 @@ class TextToTargetStateResolver extends AbstractConverter { protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { String targetStateId = (String) source; + if (targetStateId == null) { + return null; + } ExpressionParser parser = flowBuilderContext.getExpressionParser(); if (targetStateId.startsWith(BEAN_PREFIX)) { return flowBuilderContext.getBeanFactory().getBean(targetStateId.substring(BEAN_PREFIX.length())); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/TransitionTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/TransitionTests.java index c2b5e25f..dcab1e4a 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/TransitionTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/TransitionTests.java @@ -98,6 +98,25 @@ public class TransitionTests extends TestCase { assertSame(source, context.getCurrentState()); } + public void testExecuteTransitionNullTargetStateResolver() { + Flow flow = new Flow("flow"); + final TransitionableState source = new TransitionableState(flow, "state 1") { + public void exit(RequestControlContext context) { + exitCalled = true; + } + + protected void doEnter(RequestControlContext context) throws FlowExecutionException { + } + }; + MockRequestControlContext context = new MockRequestControlContext(flow); + context.setCurrentState(source); + Transition t = new Transition(); + boolean stateExited = t.execute(source, context); + assertFalse(stateExited); + assertFalse(exitCalled); + assertSame(source, context.getCurrentState()); + } + public void testTransitionExecutionRefused() { Flow flow = new Flow("flow"); final TransitionableState source = new TransitionableState(flow, "state 1") {