diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/FormatterBackedConversionExecutor.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/FormatterBackedConversionExecutor.java new file mode 100644 index 00000000..e109213f --- /dev/null +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/FormatterBackedConversionExecutor.java @@ -0,0 +1,35 @@ +package org.springframework.binding.convert.support; + +import org.springframework.binding.convert.ConversionContext; +import org.springframework.binding.convert.ConversionException; +import org.springframework.binding.convert.ConversionExecutor; +import org.springframework.binding.format.Formatter; + +public class FormatterBackedConversionExecutor implements ConversionExecutor { + + private Formatter formatter; + + private Class targetClass; + + public FormatterBackedConversionExecutor(Formatter formatter, Class targetClass) { + this.formatter = formatter; + this.targetClass = targetClass; + } + + public Object execute(Object source) throws ConversionException { + return execute(source, null); + } + + public Object execute(Object source, ConversionContext context) throws ConversionException { + return formatter.parseValue((String) source); + } + + public Class getSourceClass() { + return String.class; + } + + public Class getTargetClass() { + return targetClass; + } + +} diff --git a/spring-webflow/src/main/java/org/springframework/webflow/definition/TransitionableStateDefinition.java b/spring-webflow/src/main/java/org/springframework/webflow/definition/TransitionableStateDefinition.java index c5075fc6..082effba 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/definition/TransitionableStateDefinition.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/definition/TransitionableStateDefinition.java @@ -28,4 +28,11 @@ public interface TransitionableStateDefinition extends StateDefinition { * @return the available state transitions */ public TransitionDefinition[] getTransitions(); + + /** + * Returns the transition that matches the event with the provided id. + * @param eventId the event id + * @return the transition that matches, or null if no match is found. + */ + public TransitionDefinition getTransition(String eventId); } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/TransitionableState.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/TransitionableState.java index 6e5553c1..0b8b9fd9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/TransitionableState.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/TransitionableState.java @@ -61,6 +61,12 @@ public abstract class TransitionableState extends State implements Transitionabl return getTransitionSet().toArray(); } + public TransitionDefinition getTransition(String eventId) { + return null; + } + + // impl + /** * Returns the set of transitions. The returned set is mutable. */ diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/MvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/MvcView.java index 6c6a711c..75379456 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/MvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/MvcView.java @@ -24,9 +24,11 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.binding.collection.MapAdaptable; +import org.springframework.binding.convert.support.FormatterBackedConversionExecutor; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.ExpressionParser; import org.springframework.binding.expression.support.ParserContextImpl; +import org.springframework.binding.format.Formatter; import org.springframework.binding.format.FormatterRegistry; import org.springframework.binding.format.factories.DateFormatterFactory; import org.springframework.binding.format.factories.NumberFormatterFactory; @@ -39,6 +41,8 @@ import org.springframework.binding.mapping.impl.DefaultMapping; import org.springframework.binding.mapping.results.TargetAccessError; import org.springframework.validation.BindingResult; import org.springframework.webflow.core.collection.ParameterMap; +import org.springframework.webflow.definition.TransitionDefinition; +import org.springframework.webflow.definition.TransitionableStateDefinition; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.execution.View; @@ -159,15 +163,13 @@ class MvcView implements View { } private boolean shouldBind(Object model) { - // this downcast is not ideal - // TransitionableState currentState = (TransitionableState) context.getCurrentState(); - // TODO this won't work because last event isn't set yet... - // Transition transition = currentState.getRequiredTransition(context); - // if (transition.getAttributes().contains("bind")) { - // return transition.getAttributes().getBoolean("bind").booleanValue(); - // } else { - // return false; - // } + TransitionableStateDefinition currentState = (TransitionableStateDefinition) context.getCurrentState(); + TransitionDefinition transition = currentState.getTransition(eventId); + if (transition != null) { + if (transition.getAttributes().contains("bind")) { + return transition.getAttributes().getBoolean("bind").booleanValue(); + } + } return false; } @@ -183,7 +185,11 @@ class MvcView implements View { Expression source = expressionParser .parseExpression(name, new ParserContextImpl().eval(MapAdaptable.class)); Expression target = expressionParser.parseExpression(name, new ParserContextImpl().eval(model.getClass())); - mapper.addMapping(new DefaultMapping(source, target)); + DefaultMapping mapping = new DefaultMapping(source, target); + Class targetClass = target.getValueType(model); + Formatter formatter = formatterRegistry.getFormatter(target.getExpressionString(), targetClass); + mapping.setTypeConverter(new FormatterBackedConversionExecutor(formatter, targetClass)); + mapper.addMapping(mapping); } }