From 78b4254d39d9da7c2865be24e91c9b99b8c95088 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Tue, 9 Jun 2009 18:59:44 +0000 Subject: [PATCH] polish --- .../springframework/ui/binding/Binder.java | 75 +++++++++++-------- .../springframework/ui/binding/Binding.java | 24 ++---- .../springframework/ui/binding/UserValue.java | 2 +- .../ui/binding/BinderTests.java | 22 +++--- 4 files changed, 61 insertions(+), 62 deletions(-) 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 54a18c99bd..01f74e55fd 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 @@ -74,7 +74,6 @@ public class Binder { private boolean strict = false; private static Formatter defaultFormatter = new Formatter() { - public String format(Object object, Locale locale) { if (object == null) { return ""; @@ -182,14 +181,8 @@ public class Binder { public List bind(List userValues) { List results = new ArrayList(userValues.size()); for (UserValue value : userValues) { - Binding binding = getBinding(value.getProperty()); - if (value.isString()) { - results.add(binding.setValue((String) value.getValue())); - } else if (value.isStringArray()) { - results.add(binding.setValues((String[]) value.getValue())); - } else { - throw new IllegalArgumentException("Illegal argument " + value); - } + BindingImpl binding = (BindingImpl) getBinding(value.getProperty()); + results.add(binding.setValue(value.getValue())); } return results; } @@ -205,6 +198,8 @@ public class Binder { formatter = config.getFormatter(); } + // implementing Binding + public String getValue() { Object value; try { @@ -215,24 +210,16 @@ public class Binder { return format(value); } - public BindingResult setValue(String formatted) { - Formatter formatter; - try { - formatter = getFormatter(); - } catch (EvaluationException e) { - // could occur the property was not found or is not readable - // TODO probably should not handle all EL failures, only type conversion & property not found? - return new ExpressionEvaluationErrorResult(property.getExpressionString(), formatted, e); - } - Object parsed; - try { - parsed = formatter.parse(formatted, LocaleContextHolder.getLocale()); - } catch (ParseException e) { - return new InvalidFormatResult(property.getExpressionString(), formatted, e); + public BindingResult setValue(Object value) { + if (value instanceof String) { + return setStringValue((String) value); + } else if (value instanceof String[]) { + return setStringValues((String[]) value); + } else { + return setObjectValue(value); } - return setValue(parsed, formatted); } - + public String format(Object selectableValue) { Formatter formatter; try { @@ -256,7 +243,7 @@ public class Binder { return typeDesc.isCollection() || typeDesc.isArray(); } - public String[] getValues() { + public String[] getCollectionValues() { Object multiValue; try { multiValue = property.getValue(createEvaluationContext()); @@ -281,7 +268,27 @@ public class Binder { return formattedValues; } - public BindingResult setValues(String[] formatted) { + // internal helpers + + private BindingResult setStringValue(String formatted) { + Formatter formatter; + try { + formatter = getFormatter(); + } catch (EvaluationException e) { + // could occur the property was not found or is not readable + // TODO probably should not handle all EL failures, only type conversion & property not found? + return new ExpressionEvaluationErrorResult(property.getExpressionString(), formatted, e); + } + Object parsed; + try { + parsed = formatter.parse(formatted, LocaleContextHolder.getLocale()); + } catch (ParseException e) { + return new InvalidFormatResult(property.getExpressionString(), formatted, e); + } + return setValue(parsed, formatted); + } + + private BindingResult setStringValues(String[] formatted) { Formatter formatter; try { formatter = getFormatter(); @@ -306,8 +313,10 @@ public class Binder { } return setValue(parsed, formatted); } - - // internal helpers + + private BindingResult setObjectValue(Object value) { + return setValue(value, value); + } private Formatter getFormatter() throws EvaluationException { if (formatter != null) { @@ -346,12 +355,12 @@ public class Binder { } } - private BindingResult setValue(Object parsed, Object formatted) { + private BindingResult setValue(Object parsedValue, Object userValue) { try { - property.setValue(createEvaluationContext(), parsed); - return new SuccessResult(property.getExpressionString(), formatted); + property.setValue(createEvaluationContext(), parsedValue); + return new SuccessResult(property.getExpressionString(), userValue); } catch (EvaluationException e) { - return new ExpressionEvaluationErrorResult(property.getExpressionString(), formatted, e); + return new ExpressionEvaluationErrorResult(property.getExpressionString(), userValue, e); } } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/Binding.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/Binding.java index 063d1e94af..dfc7855bdc 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/Binding.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/Binding.java @@ -17,24 +17,22 @@ package org.springframework.ui.binding; /** * A binding between a user interface element and a model property. - * TODO - consider having setValue accept Object to allow for binding special objects like arrays & multi-part files * @author Keith Donald */ public interface Binding { - // single-value properties - /** * The formatted value to display in the user interface. */ String getValue(); /** - * Sets the model property value a from user-entered value. - * @param formatted the value entered by the user + * Set the property associated with this binding to the value provided. + * The value may be a formatted String, a formatted String[] if a collection binding, or an Object of a type that can be coersed to the underlying property type. + * @param value the new value to bind */ - BindingResult setValue(String formatted); - + BindingResult setValue(Object value); + /** * Formats a candidate model property value for display in the user interface. * @param selectableValue a possible value @@ -42,11 +40,9 @@ public interface Binding { */ String format(Object selectableValue); - // multi-value properties - /** * Is this binding associated with a collection or array property? - * If so, a client should call {@link #getValues()} to display property values in the user interface. + * If so, a client should call {@link #getCollectionValues()} to display property values in the user interface. * A client should call {@link #setValues(String[])} to set model property values from user-entered/selected values. */ boolean isCollection(); @@ -54,12 +50,6 @@ public interface Binding { /** * When a collection binding, the formatted values to display in the user interface. */ - String[] getValues(); - - /** - * When a collection binding, sets the model property values a from user-entered/selected values. - * @param formattedValues the values entered by the user - */ - BindingResult setValues(String[] formatted); + String[] getCollectionValues(); } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/UserValue.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/UserValue.java index a185857075..bbe0309f91 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/UserValue.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/UserValue.java @@ -73,7 +73,7 @@ public class UserValue { * @param value the actual user-entered value * @return the singleton user value list */ - public static List singleton(String property, Object value) { + public static List single(String property, Object value) { List values = new ArrayList(1); values.add(new UserValue(property, value)); return values; 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 cc2c5911e9..bc50851a19 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 @@ -85,7 +85,7 @@ public class BinderTests { public void bindSingleValuePropertyFormatter() throws ParseException { Binder binder = new Binder(new TestBean()); binder.add(new BindingConfiguration("date", new DateFormatter())); - binder.bind(UserValue.singleton("date", "2009-06-01")); + binder.bind(UserValue.single("date", "2009-06-01")); assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), binder.getModel().getDate()); } @@ -93,14 +93,14 @@ public class BinderTests { public void bindSingleValuePropertyFormatterParseException() { Binder binder = new Binder(new TestBean()); binder.add(new BindingConfiguration("date", new DateFormatter())); - binder.bind(UserValue.singleton("date", "bogus")); + binder.bind(UserValue.single("date", "bogus")); } @Test public void bindSingleValueWithFormatterRegistedByType() throws ParseException { Binder binder = new Binder(new TestBean()); binder.add(new DateFormatter(), Date.class); - binder.bind(UserValue.singleton("date", "2009-06-01")); + binder.bind(UserValue.single("date", "2009-06-01")); assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), binder.getModel().getDate()); } @@ -108,7 +108,7 @@ public class BinderTests { public void bindSingleValueWithFormatterRegisteredByAnnotation() throws ParseException { Binder binder = new Binder(new TestBean()); binder.add(new CurrencyFormatter(), CurrencyFormat.class); - binder.bind(UserValue.singleton("currency", "$23.56")); + binder.bind(UserValue.single("currency", "$23.56")); assertEquals(new BigDecimal("23.56"), binder.getModel().getCurrency()); } @@ -116,14 +116,14 @@ public class BinderTests { public void bindSingleValueWithnAnnotationFormatterFactoryRegistered() throws ParseException { Binder binder = new Binder(new TestBean()); binder.add(new CurrencyAnnotationFormatterFactory()); - binder.bind(UserValue.singleton("currency", "$23.56")); + binder.bind(UserValue.single("currency", "$23.56")); assertEquals(new BigDecimal("23.56"), binder.getModel().getCurrency()); } @Test public void bindSingleValuePropertyNotFound() throws ParseException { Binder binder = new Binder(new TestBean()); - List results = binder.bind(UserValue.singleton("bogus", "2009-06-01")); + List results = binder.bind(UserValue.single("bogus", "2009-06-01")); assertEquals(1, results.size()); assertTrue(results.get(0).isError()); assertEquals("propertyNotFound", results.get(0).getErrorCode()); @@ -181,12 +181,12 @@ public class BinderTests { Binder binder = new Binder(new TestBean()); Binding b = binder.getBinding("foos"); assertTrue(b.isCollection()); - assertEquals(0, b.getValues().length); - b.setValues(new String[] { "BAR", "BAZ", "BOOP" }); + assertEquals(0, b.getCollectionValues().length); + b.setValue(new String[] { "BAR", "BAZ", "BOOP" }); assertEquals(FooEnum.BAR, binder.getModel().getFoos().get(0)); assertEquals(FooEnum.BAZ, binder.getModel().getFoos().get(1)); assertEquals(FooEnum.BOOP, binder.getModel().getFoos().get(2)); - String[] values = b.getValues(); + String[] values = b.getCollectionValues(); assertEquals(3, values.length); assertEquals("BAR", values[0]); assertEquals("BAZ", values[1]); @@ -198,8 +198,8 @@ public class BinderTests { Binder binder = new Binder(new TestBean()); Binding b = binder.getBinding("foos"); assertTrue(b.isCollection()); - assertEquals(0, b.getValues().length); - BindingResult result = b.setValues(new String[] { "BAR", "BOGUS", "BOOP" }); + assertEquals(0, b.getCollectionValues().length); + BindingResult result = b.setValue(new String[] { "BAR", "BOGUS", "BOOP" }); assertTrue(result.isError()); assertTrue(result.getErrorCause() instanceof EvaluationException); assertEquals("typeConversionFailure", result.getErrorCode());