From f214dd00e111509efcc383641d21526827e540e5 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Wed, 5 Mar 2008 20:05:04 +0000 Subject: [PATCH] set type, value fix --- .../webflow/action/ActionResultExposer.java | 6 +-- .../webflow/action/SetAction.java | 43 ++++++++++++++++--- .../engine/builder/xml/XmlFlowBuilder.java | 11 +++-- .../engine/builder/xml/spring-webflow-2.0.xsd | 9 ++++ .../webflow/action/SetActionTests.java | 13 +++++- 5 files changed, 69 insertions(+), 13 deletions(-) diff --git a/spring-webflow/src/main/java/org/springframework/webflow/action/ActionResultExposer.java b/spring-webflow/src/main/java/org/springframework/webflow/action/ActionResultExposer.java index 0fd1d231..15afbdab 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/action/ActionResultExposer.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/action/ActionResultExposer.java @@ -85,14 +85,14 @@ public class ActionResultExposer implements Serializable { * @param context the request context */ public void exposeResult(Object result, RequestContext context) { - resultExpression.setValue(context, applyTypeConversion(result)); + resultExpression.setValue(context, applyTypeConversionIfNecessary(result)); } /** - * Apply type conversion on the supplied value + * Apply type conversion on the supplied value if necessary. * @param value the raw value to be converted */ - private Object applyTypeConversion(Object value) { + private Object applyTypeConversionIfNecessary(Object value) { if (value == null || expectedResultType == null) { return value; } else { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/action/SetAction.java b/spring-webflow/src/main/java/org/springframework/webflow/action/SetAction.java index 865768cf..b8758e7b 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/action/SetAction.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/action/SetAction.java @@ -15,6 +15,7 @@ */ package org.springframework.webflow.action; +import org.springframework.binding.convert.ConversionService; import org.springframework.binding.expression.Expression; import org.springframework.util.Assert; import org.springframework.webflow.execution.Event; @@ -39,20 +40,52 @@ public class SetAction extends AbstractAction { private Expression valueExpression; /** - * Creates a new set attribute action. - * @param nameExpression the name of the property to set - * @param valueExpression the expression to obtain the new property value + * The expected value type. */ - public SetAction(Expression nameExpression, Expression valueExpression) { + private Class expectedType; + + /** + * The service to perform the type conversion if the actual value type does not match the expected. + */ + private ConversionService conversionService; + + /** + * Creates a new set attribute action. + * @param nameExpression the name of the property to set (required) + * @param valueExpression the expression to obtain the new property value (required) + * @param expectedType the expected value type + * @param conversionService the service to perform the type conversion if the actual value type does not match the + * expected + */ + public SetAction(Expression nameExpression, Expression valueExpression, Class expectedType, + ConversionService conversionService) { Assert.notNull(nameExpression, "The name expression is required"); Assert.notNull(valueExpression, "The value expression is required"); + if (expectedType != null) { + Assert.notNull(conversionService, "The conversion service is required if the expectedType is provided"); + } this.nameExpression = nameExpression; this.valueExpression = valueExpression; + this.expectedType = expectedType; + this.conversionService = conversionService; } protected Event doExecute(RequestContext context) throws Exception { Object value = valueExpression.getValue(context); - nameExpression.setValue(context, value); + nameExpression.setValue(context, applyTypeConversionIfNecessary(value)); return success(); } + + /** + * Apply type conversion on the supplied value if necessary. + * @param value the raw value to be converted + */ + private Object applyTypeConversionIfNecessary(Object value) { + if (value == null || expectedType == null) { + return value; + } else { + return conversionService.getConversionExecutor(value.getClass(), expectedType).execute(value); + } + } + } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/XmlFlowBuilder.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/XmlFlowBuilder.java index b1e0bd1d..9615f76c 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/XmlFlowBuilder.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/XmlFlowBuilder.java @@ -723,12 +723,15 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde } private Action parseSetAction(Element element) { - String nameExpressionString = element.getAttribute("name"); - Expression nameExpression = getExpressionParser().parseExpression(nameExpressionString, + Expression nameExpression = getExpressionParser().parseExpression(element.getAttribute("name"), new ParserContextImpl().eval(RequestContext.class)); - Expression valueExpression = getExpressionParser().parseExpression("value", + Expression valueExpression = getExpressionParser().parseExpression(element.getAttribute("value"), new ParserContextImpl().eval(RequestContext.class)); - return new SetAction(nameExpression, valueExpression); + Class expectedType = null; + if (element.hasAttribute("type")) { + expectedType = (Class) fromStringTo(Class.class).execute(element.getAttribute("type")); + } + return new SetAction(nameExpression, valueExpression, expectedType, getConversionService()); } private MutableAttributeMap parseMetaAttributes(Element element) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/spring-webflow-2.0.xsd b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/spring-webflow-2.0.xsd index 262de194..fdc29af3 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/spring-webflow-2.0.xsd +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/spring-webflow-2.0.xsd @@ -688,6 +688,15 @@ The value to be set. + + + + + + + diff --git a/spring-webflow/src/test/java/org/springframework/webflow/action/SetActionTests.java b/spring-webflow/src/test/java/org/springframework/webflow/action/SetActionTests.java index c95bc6d6..54ae2906 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/action/SetActionTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/action/SetActionTests.java @@ -2,6 +2,7 @@ package org.springframework.webflow.action; import junit.framework.TestCase; +import org.springframework.binding.convert.support.DefaultConversionService; import org.springframework.binding.expression.support.StaticExpression; import org.springframework.webflow.execution.Event; import org.springframework.webflow.test.MockRequestContext; @@ -9,10 +10,20 @@ import org.springframework.webflow.test.MockRequestContext; public class SetActionTests extends TestCase { public void testSetAction() throws Exception { StaticExpression name = new StaticExpression(""); - SetAction action = new SetAction(name, new StaticExpression("bar")); + SetAction action = new SetAction(name, new StaticExpression("bar"), null, null); MockRequestContext context = new MockRequestContext(); Event result = action.execute(context); assertEquals("success", result.getId()); assertEquals("bar", name.getValue(null)); } + + public void testSetActionWithTypeConversion() throws Exception { + StaticExpression name = new StaticExpression(""); + SetAction action = new SetAction(name, new StaticExpression("3"), Integer.class, new DefaultConversionService()); + MockRequestContext context = new MockRequestContext(); + Event result = action.execute(context); + assertEquals("success", result.getId()); + assertEquals(new Integer(3), name.getValue(null)); + } + }