polish
This commit is contained in:
parent
04115a4ff4
commit
78b4254d39
|
|
@ -74,7 +74,6 @@ public class Binder<T> {
|
|||
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<T> {
|
|||
public List<BindingResult> bind(List<UserValue> userValues) {
|
||||
List<BindingResult> results = new ArrayList<BindingResult>(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<T> {
|
|||
formatter = config.getFormatter();
|
||||
}
|
||||
|
||||
// implementing Binding
|
||||
|
||||
public String getValue() {
|
||||
Object value;
|
||||
try {
|
||||
|
|
@ -215,22 +210,14 @@ public class Binder<T> {
|
|||
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);
|
||||
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);
|
||||
}
|
||||
Object parsed;
|
||||
try {
|
||||
parsed = formatter.parse(formatted, LocaleContextHolder.getLocale());
|
||||
} catch (ParseException e) {
|
||||
return new InvalidFormatResult(property.getExpressionString(), formatted, e);
|
||||
}
|
||||
return setValue(parsed, formatted);
|
||||
}
|
||||
|
||||
public String format(Object selectableValue) {
|
||||
|
|
@ -256,7 +243,7 @@ public class Binder<T> {
|
|||
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<T> {
|
|||
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();
|
||||
|
|
@ -307,7 +314,9 @@ public class Binder<T> {
|
|||
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<T> {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,23 +17,21 @@ 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.
|
||||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ public class UserValue {
|
|||
* @param value the actual user-entered value
|
||||
* @return the singleton user value list
|
||||
*/
|
||||
public static List<UserValue> singleton(String property, Object value) {
|
||||
public static List<UserValue> single(String property, Object value) {
|
||||
List<UserValue> values = new ArrayList<UserValue>(1);
|
||||
values.add(new UserValue(property, value));
|
||||
return values;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public class BinderTests {
|
|||
public void bindSingleValuePropertyFormatter() throws ParseException {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(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<TestBean> binder = new Binder<TestBean>(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<TestBean> binder = new Binder<TestBean>(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<TestBean> binder = new Binder<TestBean>(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<TestBean> binder = new Binder<TestBean>(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<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
List<BindingResult> results = binder.bind(UserValue.singleton("bogus", "2009-06-01"));
|
||||
List<BindingResult> 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<TestBean> binder = new Binder<TestBean>(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<TestBean> binder = new Binder<TestBean>(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());
|
||||
|
|
|
|||
Loading…
Reference in New Issue