diff --git a/spring-binding/.classpath b/spring-binding/.classpath index 01d7235a..dded26c0 100644 --- a/spring-binding/.classpath +++ b/spring-binding/.classpath @@ -10,11 +10,11 @@ - - - - - + + + + + diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/ValueCoercionException.java b/spring-binding/src/main/java/org/springframework/binding/expression/ValueCoercionException.java index b1ef3a39..14aba128 100644 --- a/spring-binding/src/main/java/org/springframework/binding/expression/ValueCoercionException.java +++ b/spring-binding/src/main/java/org/springframework/binding/expression/ValueCoercionException.java @@ -15,16 +15,15 @@ */ package org.springframework.binding.expression; -import org.springframework.core.style.StylerUtils; - /** - * An evaluation exception indicating a expression failed to evaluate because the source value could not be coerced to + * An evaluation exception indicating an expression failed to evaluate because the source value could not be coerced to * the target class * @author Scott Andrews */ public class ValueCoercionException extends EvaluationException { - private Object value; + private transient Object value; + private Class targetClass; /** @@ -49,14 +48,14 @@ public class ValueCoercionException extends EvaluationException { * @param cause root cause of the failure */ public ValueCoercionException(Class contextClass, String property, Object value, Class targetClass, Throwable cause) { - super(contextClass, property, "value " + StylerUtils.style(value) + " could not be coerced to [" - + targetClass.getName() + "]", cause); + super(contextClass, property, "Value [" + value + "] could not be coerced to type [" + targetClass.getName() + + "]", cause); this.value = value; this.targetClass = targetClass; } /** - * @return the value that could not be coerced + * @return the value that could not be coerced; this value is a transient field */ public Object getValue() { return value; diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/el/BindingValueExpression.java b/spring-binding/src/main/java/org/springframework/binding/expression/el/BindingValueExpression.java index daa6dd04..f604c305 100644 --- a/spring-binding/src/main/java/org/springframework/binding/expression/el/BindingValueExpression.java +++ b/spring-binding/src/main/java/org/springframework/binding/expression/el/BindingValueExpression.java @@ -7,7 +7,9 @@ import javax.el.PropertyNotFoundException; import javax.el.PropertyNotWritableException; import javax.el.ValueExpression; +import org.springframework.binding.convert.ConversionException; import org.springframework.binding.convert.ConversionService; +import org.springframework.binding.expression.ValueCoercionException; import org.springframework.util.Assert; /** @@ -47,9 +49,10 @@ class BindingValueExpression extends ValueExpression { return targetExpression.getType(context); } - public Object getValue(ELContext context) throws NullPointerException, PropertyNotFoundException, ELException { + public Object getValue(ELContext context) throws NullPointerException, PropertyNotFoundException, ELException, + ValueCoercionException { Object value = targetExpression.getValue(context); - return convertValueIfNecessary(value, expectedType); + return convertValueIfNecessary(value, expectedType, context); } public boolean isReadOnly(ELContext context) throws NullPointerException, PropertyNotFoundException, ELException { @@ -57,8 +60,8 @@ class BindingValueExpression extends ValueExpression { } public void setValue(ELContext context, Object value) throws NullPointerException, PropertyNotFoundException, - PropertyNotWritableException, ELException { - value = convertValueIfNecessary(value, targetExpression.getType(context)); + PropertyNotWritableException, ELException, ValueCoercionException { + value = convertValueIfNecessary(value, targetExpression.getType(context), context); targetExpression.setValue(context, value); } @@ -87,11 +90,16 @@ class BindingValueExpression extends ValueExpression { return targetExpression.hashCode(); } - private Object convertValueIfNecessary(Object value, Class expectedType) { + private Object convertValueIfNecessary(Object value, Class expectedType, Object context) + throws ValueCoercionException { if (expectedType == null) { return value; } else { - return conversionService.executeConversion(value, expectedType); + try { + return conversionService.executeConversion(value, expectedType); + } catch (ConversionException e) { + throw new ValueCoercionException(context.getClass(), getExpressionString(), value, expectedType, e); + } } } diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/el/ELExpression.java b/spring-binding/src/main/java/org/springframework/binding/expression/el/ELExpression.java index 8c20b213..1c39fc4e 100644 --- a/spring-binding/src/main/java/org/springframework/binding/expression/el/ELExpression.java +++ b/spring-binding/src/main/java/org/springframework/binding/expression/el/ELExpression.java @@ -19,11 +19,9 @@ import javax.el.ELContext; import javax.el.ELException; import javax.el.ValueExpression; -import org.springframework.binding.convert.ConversionExecutionException; import org.springframework.binding.expression.EvaluationException; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.PropertyNotFoundException; -import org.springframework.binding.expression.ValueCoercionException; import org.springframework.util.Assert; /** @@ -85,8 +83,6 @@ public class ELExpression implements Expression { } } catch (javax.el.PropertyNotFoundException e) { throw new PropertyNotFoundException(context.getClass(), getExpressionString(), e); - } catch (ConversionExecutionException e) { - throw new ValueCoercionException(context.getClass(), getExpressionString(), value, e.getTargetClass(), e); } catch (ELException e) { throw new EvaluationException(context.getClass(), getExpressionString(), "An ELException occurred setting the value of expression '" + getExpressionString() diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/ognl/OgnlExpression.java b/spring-binding/src/main/java/org/springframework/binding/expression/ognl/OgnlExpression.java index 3849a880..48a7ebf9 100644 --- a/spring-binding/src/main/java/org/springframework/binding/expression/ognl/OgnlExpression.java +++ b/spring-binding/src/main/java/org/springframework/binding/expression/ognl/OgnlExpression.java @@ -29,7 +29,7 @@ import ognl.TypeConverter; import org.springframework.beans.BeanWrapperImpl; import org.springframework.beans.BeansException; import org.springframework.beans.InvalidPropertyException; -import org.springframework.binding.convert.ConversionExecutionException; +import org.springframework.binding.convert.ConversionException; import org.springframework.binding.convert.ConversionService; import org.springframework.binding.expression.EvaluationException; import org.springframework.binding.expression.Expression; @@ -86,9 +86,13 @@ class OgnlExpression implements Expression { } catch (NoSuchPropertyException e) { throw new PropertyNotFoundException(context.getClass(), getExpressionString(), e); } catch (OgnlException e) { - throw new EvaluationException(context.getClass(), getExpressionString(), - "An OgnlException occurred getting the value for expression '" + getExpressionString() - + "' on context [" + context.getClass() + "]", e); + if (e.getReason() instanceof ValueCoercionException) { + throw (ValueCoercionException) e.getReason(); + } else { + throw new EvaluationException(context.getClass(), getExpressionString(), + "An OgnlException occurred getting the value for expression '" + getExpressionString() + + "' on context [" + context.getClass() + "]", e.getReason()); + } } } @@ -100,10 +104,8 @@ class OgnlExpression implements Expression { } catch (NoSuchPropertyException e) { throw new PropertyNotFoundException(context.getClass(), getExpressionString(), e); } catch (OgnlException e) { - if (e.getReason() instanceof ConversionExecutionException) { - ConversionExecutionException conversionEx = (ConversionExecutionException) e.getReason(); - throw new ValueCoercionException(context.getClass(), expressionString, value, conversionEx - .getTargetClass(), conversionEx); + if (e.getReason() instanceof ValueCoercionException) { + throw (ValueCoercionException) e.getReason(); } else { throw new EvaluationException(context.getClass(), getExpressionString(), "An OgnlException occurred setting the value of expression '" + getExpressionString() @@ -115,8 +117,12 @@ class OgnlExpression implements Expression { private TypeConverter createTypeConverter() { return new TypeConverter() { public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, - Class toType) { - return conversionService.executeConversion(value, toType); + Class toType) throws ValueCoercionException { + try { + return conversionService.executeConversion(value, toType); + } catch (ConversionException e) { + throw new ValueCoercionException(context.getClass(), expressionString, value, toType, e); + } } }; } diff --git a/spring-binding/src/test/java/org/springframework/binding/expression/el/ELExpressionParserTests.java b/spring-binding/src/test/java/org/springframework/binding/expression/el/ELExpressionParserTests.java index 41f6061c..e71bbbd8 100644 --- a/spring-binding/src/test/java/org/springframework/binding/expression/el/ELExpressionParserTests.java +++ b/spring-binding/src/test/java/org/springframework/binding/expression/el/ELExpressionParserTests.java @@ -152,6 +152,25 @@ public class ELExpressionParserTests extends TestCase { assertEquals(int.class, exp.getValueType(context)); } + public void testGetValueWithCoersion() { + String expressionString = "maximum"; + Expression exp = parser.parseExpression(expressionString, new FluentParserContext().expectResult(String.class)); + TestBean context = new TestBean(); + assertEquals("2", exp.getValue(context)); + } + + public void testGetValueCoersionError() { + String expressionString = "maximum"; + Expression exp = parser.parseExpression(expressionString, new FluentParserContext() + .expectResult(TestBean.class)); + TestBean context = new TestBean(); + try { + exp.getValue(context); + fail("Should have failed with coersion"); + } catch (ValueCoercionException e) { + } + } + public void testSetValue() { String expressionString = "maximum"; Expression exp = parser.parseExpression(expressionString, null); @@ -160,7 +179,15 @@ public class ELExpressionParserTests extends TestCase { assertEquals(5, context.getMaximum()); } - public void testSetValueConversionError() { + public void testSetValueWithTypeCoersion() { + String expressionString = "maximum"; + Expression exp = parser.parseExpression(expressionString, null); + TestBean context = new TestBean(); + exp.setValue(context, "5"); + assertEquals(5, context.getMaximum()); + } + + public void testSetValueCoersionError() { String expressionString = "maximum"; Expression exp = parser.parseExpression(expressionString, null); TestBean context = new TestBean(); diff --git a/spring-binding/src/test/java/org/springframework/binding/expression/ognl/OgnlExpressionParserTests.java b/spring-binding/src/test/java/org/springframework/binding/expression/ognl/OgnlExpressionParserTests.java index 53a6d50f..bd7b605f 100644 --- a/spring-binding/src/test/java/org/springframework/binding/expression/ognl/OgnlExpressionParserTests.java +++ b/spring-binding/src/test/java/org/springframework/binding/expression/ognl/OgnlExpressionParserTests.java @@ -174,6 +174,33 @@ public class OgnlExpressionParserTests extends TestCase { assertEquals(null, e.getValueType(bean)); } + public void testGetValueWithCoersion() { + String expressionString = "number"; + Expression exp = parser.parseExpression(expressionString, new FluentParserContext().expectResult(String.class)); + TestBean context = new TestBean(); + assertEquals("0", exp.getValue(context)); + } + + public void testGetValueCoersionError() { + String expressionString = "number"; + Expression exp = parser.parseExpression(expressionString, new FluentParserContext() + .expectResult(TestBean.class)); + TestBean context = new TestBean(); + try { + exp.getValue(context); + fail("Should have failed with coersion"); + } catch (ValueCoercionException e) { + } + } + + public void testSetValue() { + String expressionString = "number"; + Expression exp = parser.parseExpression(expressionString, null); + TestBean context = new TestBean(); + exp.setValue(context, new Integer(5)); + assertEquals(5, context.getNumber()); + } + public void testSetValueWithCoersion() { Expression e = parser.parseExpression("date", null); e.setValue(bean, "2008-9-15");