diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/Binder.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/Binder.java index fd82e9b4bc3..0fd1e89f0fc 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/Binder.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/Binder.java @@ -32,17 +32,17 @@ public class Binder { private Map bindings; private Map, Formatter> typeFormatters = new HashMap, Formatter>(); - - private Map> annotationFormatters = new HashMap>(); - + + private Map, Formatter> annotationFormatters = new HashMap, Formatter>(); + private ExpressionParser expressionParser; private TypeConverter typeConverter; - + private boolean optimisticBinding = true; private static Formatter defaultFormatter = new Formatter() { - + public Class getFormattedObjectType() { return String.class; } @@ -90,8 +90,9 @@ public class Binder { typeFormatters.put(propertyType, formatter); } - public void add(Formatter formatter, Annotation propertyAnnotation) { - annotationFormatters.put(propertyAnnotation, formatter); + public void addAnnotationBasedFormatter(Formatter formatter, + Class propertyAnnotationClass) { + annotationFormatters.put(propertyAnnotationClass, formatter); } public T getModel() { @@ -222,7 +223,7 @@ public class Binder { } else { Annotation[] annotations = getAnnotations(); for (Annotation a : annotations) { - formatter = annotationFormatters.get(a); + formatter = annotationFormatters.get(a.annotationType()); if (formatter != null) { return formatter; } @@ -234,7 +235,6 @@ public class Binder { private Class getValueType() { try { - // TODO Spring EL currently returns null here when value is null - not correct return property.getValueType(createEvaluationContext()); } catch (EvaluationException e) { throw new IllegalStateException(e); @@ -242,8 +242,12 @@ public class Binder { } private Annotation[] getAnnotations() { - // TODO Spring EL presently gives us no way to get this information - return new Annotation[0]; + try { + return property.getValueTypeDescriptor( + createEvaluationContext()).getAnnotations(); + } catch (EvaluationException e) { + throw new IllegalStateException(e); + } } private void copy(Iterable values, String[] formattedValues) { diff --git a/org.springframework.context/src/test/java/org/springframework/ui/binding/BinderTests.java b/org.springframework.context/src/test/java/org/springframework/ui/binding/BinderTests.java index 6e584185ed1..24fca477f34 100644 --- a/org.springframework.context/src/test/java/org/springframework/ui/binding/BinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/ui/binding/BinderTests.java @@ -4,6 +4,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.math.BigDecimal; import java.text.ParseException; import java.util.Date; @@ -77,29 +79,21 @@ public class BinderTests { } @Test - @Ignore public void bindSingleValueTypeFormatterParsing() throws ParseException { Binder binder = new Binder(new TestBean()); binder.add(new DateFormatter(), Date.class); Map propertyValues = new HashMap(); propertyValues.put("date", "2009-06-01"); - // TODO presently fails because Spring EL does not obtain property valueType using property metadata - // instead it relies on value itself being not null - // talk to andy about this binder.bind(propertyValues); assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), binder.getModel().getDate()); } @Test - @Ignore public void bindSingleValueAnnotationFormatterParsing() throws ParseException { Binder binder = new Binder(new TestBean()); - binder.add(new CurrencyFormatter(), Currency.class); + binder.addAnnotationBasedFormatter(new CurrencyFormatter(), Currency.class); Map propertyValues = new HashMap(); propertyValues.put("currency", "$23.56"); - // TODO presently fails because Spring EL does not obtain property valueType using property metadata - // instead it relies on value itself being not null - // talk to andy about this binder.bind(propertyValues); assertEquals(new BigDecimal("23.56"), binder.getModel().getCurrency()); } @@ -259,6 +253,7 @@ public class BinderTests { } + @Retention(RetentionPolicy.RUNTIME) public @interface Currency { }