Removed model parameterized type after review with juergen

This commit is contained in:
Keith Donald 2009-06-10 20:44:35 +00:00
parent 72e89510da
commit 6403107c08
5 changed files with 37 additions and 51 deletions

View File

@ -29,13 +29,13 @@ import org.springframework.ui.format.Formatter;
* @see #add(BindingConfiguration) * @see #add(BindingConfiguration)
* @see #bind(UserValues) * @see #bind(UserValues)
*/ */
public interface Binder<M> { public interface Binder {
/** /**
* The model object this binder binds to. * The model object this binder binds to.
* @return the model object * @return the model object
*/ */
M getModel(); Object getModel();
/** /**
* Configures if this binder is <i>strict</i>; a strict binder requires all bindings to be registered explicitly using {@link #add(BindingConfiguration)}. * Configures if this binder is <i>strict</i>; a strict binder requires all bindings to be registered explicitly using {@link #add(BindingConfiguration)}.

View File

@ -55,17 +55,15 @@ import org.springframework.ui.format.Formatter;
/** /**
* Binds user-entered values to properties of a model object. * Binds user-entered values to properties of a model object.
* @author Keith Donald * @author Keith Donald
*
* @param <M> The type of model object this binder binds to - TODO is this worth it?
* @see #add(BindingConfiguration) * @see #add(BindingConfiguration)
* @see #bind(UserValues) * @see #bind(UserValues)
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class GenericBinder<M> implements Binder<M> { public class GenericBinder implements Binder {
private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final String[] EMPTY_STRING_ARRAY = new String[0];
private M model; private Object model;
private Map<String, Binding> bindings; private Map<String, Binding> bindings;
@ -101,7 +99,7 @@ public class GenericBinder<M> implements Binder<M> {
* Creates a new binder for the model object. * Creates a new binder for the model object.
* @param model the model object containing properties this binder will bind to * @param model the model object containing properties this binder will bind to
*/ */
public GenericBinder(M model) { public GenericBinder(Object model) {
this.model = model; this.model = model;
bindings = new HashMap<String, Binding>(); bindings = new HashMap<String, Binding>();
int parserConfig = SpelExpressionParserConfiguration.CreateListsOnAttemptToIndexIntoNull int parserConfig = SpelExpressionParserConfiguration.CreateListsOnAttemptToIndexIntoNull
@ -110,7 +108,7 @@ public class GenericBinder<M> implements Binder<M> {
typeConverter = new DefaultTypeConverter(); typeConverter = new DefaultTypeConverter();
} }
public M getModel() { public Object getModel() {
return model; return model;
} }

View File

@ -23,11 +23,10 @@ import org.springframework.ui.binding.UserValues;
* A binder designed for use in HTTP (web) environments. * A binder designed for use in HTTP (web) environments.
* Suited for binding user-provided HTTP query parameters to model properties. * Suited for binding user-provided HTTP query parameters to model properties.
* @author Keith Donald * @author Keith Donald
* @param <M> The type of model object this binder binds to
* @see #setFieldDefaultPrefix(String) * @see #setFieldDefaultPrefix(String)
* @see #setFieldMarkerPrefix(String) * @see #setFieldMarkerPrefix(String)
*/ */
public class WebBinder<M> extends GenericBinder<M> { public class WebBinder extends GenericBinder {
private String fieldMarkerPrefix = "_"; private String fieldMarkerPrefix = "_";
@ -37,7 +36,7 @@ public class WebBinder<M> extends GenericBinder<M> {
* Creates a new web binder for the model object. * Creates a new web binder for the model object.
* @param model the model object containing properties this binder will bind to * @param model the model object containing properties this binder will bind to
*/ */
public WebBinder(M model) { public WebBinder(Object model) {
super(model); super(model);
} }

View File

@ -33,8 +33,13 @@ import org.springframework.ui.format.number.IntegerFormatter;
public class GenericBinderTests { public class GenericBinderTests {
private TestBean bean;
private Binder binder;
@Before @Before
public void setUp() { public void setUp() {
bean = new TestBean();
binder = new GenericBinder(bean);
LocaleContextHolder.setLocale(Locale.US); LocaleContextHolder.setLocale(Locale.US);
} }
@ -45,7 +50,6 @@ public class GenericBinderTests {
@Test @Test
public void bindSingleValuesWithDefaultTypeConverterConversion() { public void bindSingleValuesWithDefaultTypeConverterConversion() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
UserValues values = new UserValues(); UserValues values = new UserValues();
values.add("string", "test"); values.add("string", "test");
values.add("integer", "3"); values.add("integer", "3");
@ -68,14 +72,13 @@ public class GenericBinderTests {
assertNull(results.get(2).getErrorCause()); assertNull(results.get(2).getErrorCause());
assertEquals("BAR", results.get(2).getUserValue()); assertEquals("BAR", results.get(2).getUserValue());
assertEquals("test", binder.getModel().getString()); assertEquals("test", bean.getString());
assertEquals(3, binder.getModel().getInteger()); assertEquals(3, bean.getInteger());
assertEquals(FooEnum.BAR, binder.getModel().getFoo()); assertEquals(FooEnum.BAR, bean.getFoo());
} }
@Test @Test
public void bindSingleValuesWithDefaultTypeCoversionFailure() { public void bindSingleValuesWithDefaultTypeCoversionFailure() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
UserValues values = new UserValues(); UserValues values = new UserValues();
values.add("string", "test"); values.add("string", "test");
// bad value // bad value
@ -89,46 +92,40 @@ public class GenericBinderTests {
@Test @Test
public void bindSingleValuePropertyFormatter() throws ParseException { public void bindSingleValuePropertyFormatter() throws ParseException {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
binder.add(new BindingConfiguration("date", new DateFormatter())); binder.add(new BindingConfiguration("date", new DateFormatter()));
binder.bind(UserValues.single("date", "2009-06-01")); binder.bind(UserValues.single("date", "2009-06-01"));
assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), binder.getModel().getDate()); assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), bean.getDate());
} }
@Test @Test
public void bindSingleValuePropertyFormatterParseException() { public void bindSingleValuePropertyFormatterParseException() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
binder.add(new BindingConfiguration("date", new DateFormatter())); binder.add(new BindingConfiguration("date", new DateFormatter()));
binder.bind(UserValues.single("date", "bogus")); binder.bind(UserValues.single("date", "bogus"));
} }
@Test @Test
public void bindSingleValueWithFormatterRegistedByType() throws ParseException { public void bindSingleValueWithFormatterRegistedByType() throws ParseException {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
binder.add(new DateFormatter(), Date.class); binder.add(new DateFormatter(), Date.class);
binder.bind(UserValues.single("date", "2009-06-01")); binder.bind(UserValues.single("date", "2009-06-01"));
assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), binder.getModel().getDate()); assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), bean.getDate());
} }
@Test @Test
public void bindSingleValueWithFormatterRegisteredByAnnotation() throws ParseException { public void bindSingleValueWithFormatterRegisteredByAnnotation() throws ParseException {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
binder.add(new CurrencyFormatter(), CurrencyFormat.class); binder.add(new CurrencyFormatter(), CurrencyFormat.class);
binder.bind(UserValues.single("currency", "$23.56")); binder.bind(UserValues.single("currency", "$23.56"));
assertEquals(new BigDecimal("23.56"), binder.getModel().getCurrency()); assertEquals(new BigDecimal("23.56"), bean.getCurrency());
} }
@Test @Test
public void bindSingleValueWithnAnnotationFormatterFactoryRegistered() throws ParseException { public void bindSingleValueWithnAnnotationFormatterFactoryRegistered() throws ParseException {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
binder.add(new CurrencyAnnotationFormatterFactory()); binder.add(new CurrencyAnnotationFormatterFactory());
binder.bind(UserValues.single("currency", "$23.56")); binder.bind(UserValues.single("currency", "$23.56"));
assertEquals(new BigDecimal("23.56"), binder.getModel().getCurrency()); assertEquals(new BigDecimal("23.56"), bean.getCurrency());
} }
@Test @Test
public void bindSingleValuePropertyNotFound() throws ParseException { public void bindSingleValuePropertyNotFound() throws ParseException {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
List<BindingResult> results = binder.bind(UserValues.single("bogus", "2009-06-01")); List<BindingResult> results = binder.bind(UserValues.single("bogus", "2009-06-01"));
assertEquals(1, results.size()); assertEquals(1, results.size());
assertTrue(results.get(0).isError()); assertTrue(results.get(0).isError());
@ -137,7 +134,6 @@ public class GenericBinderTests {
@Test @Test
public void bindUserValuesCreatedFromUserMap() { public void bindUserValuesCreatedFromUserMap() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
Map<String, String> userMap = new LinkedHashMap<String, String>(); Map<String, String> userMap = new LinkedHashMap<String, String>();
userMap.put("string", "test"); userMap.put("string", "test");
userMap.put("integer", "3"); userMap.put("integer", "3");
@ -146,13 +142,12 @@ public class GenericBinderTests {
assertEquals(2, results.size()); assertEquals(2, results.size());
assertEquals("test", results.get(0).getUserValue()); assertEquals("test", results.get(0).getUserValue());
assertEquals("3", results.get(1).getUserValue()); assertEquals("3", results.get(1).getUserValue());
assertEquals("test", binder.getModel().getString()); assertEquals("test", bean.getString());
assertEquals(3, binder.getModel().getInteger()); assertEquals(3, bean.getInteger());
} }
@Test @Test
public void getBindingOptimistic() { public void getBindingOptimistic() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
Binding b = binder.getBinding("integer"); Binding b = binder.getBinding("integer");
assertFalse(b.isCollection()); assertFalse(b.isCollection());
assertEquals("0", b.getValue()); assertEquals("0", b.getValue());
@ -163,7 +158,6 @@ public class GenericBinderTests {
@Test @Test
public void getBindingStrict() { public void getBindingStrict() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
binder.setStrict(true); binder.setStrict(true);
Binding b = binder.getBinding("integer"); Binding b = binder.getBinding("integer");
assertNull(b); assertNull(b);
@ -178,7 +172,6 @@ public class GenericBinderTests {
@Test @Test
public void getBindingCustomFormatter() { public void getBindingCustomFormatter() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
binder.add(new BindingConfiguration("currency", new CurrencyFormatter())); binder.add(new BindingConfiguration("currency", new CurrencyFormatter()));
Binding b = binder.getBinding("currency"); Binding b = binder.getBinding("currency");
assertFalse(b.isCollection()); assertFalse(b.isCollection());
@ -189,7 +182,6 @@ public class GenericBinderTests {
@Test @Test
public void getBindingCustomFormatterRequiringTypeCoersion() { public void getBindingCustomFormatterRequiringTypeCoersion() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
// IntegerFormatter formats Longs, so conversion from Integer -> Long is performed // IntegerFormatter formats Longs, so conversion from Integer -> Long is performed
binder.add(new BindingConfiguration("integer", new IntegerFormatter())); binder.add(new BindingConfiguration("integer", new IntegerFormatter()));
Binding b = binder.getBinding("integer"); Binding b = binder.getBinding("integer");
@ -199,14 +191,13 @@ public class GenericBinderTests {
@Test @Test
public void getBindingMultiValued() { public void getBindingMultiValued() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
Binding b = binder.getBinding("foos"); Binding b = binder.getBinding("foos");
assertTrue(b.isCollection()); assertTrue(b.isCollection());
assertEquals(0, b.getCollectionValues().length); assertEquals(0, b.getCollectionValues().length);
b.setValue(new String[] { "BAR", "BAZ", "BOOP" }); b.setValue(new String[] { "BAR", "BAZ", "BOOP" });
assertEquals(FooEnum.BAR, binder.getModel().getFoos().get(0)); assertEquals(FooEnum.BAR, bean.getFoos().get(0));
assertEquals(FooEnum.BAZ, binder.getModel().getFoos().get(1)); assertEquals(FooEnum.BAZ, bean.getFoos().get(1));
assertEquals(FooEnum.BOOP, binder.getModel().getFoos().get(2)); assertEquals(FooEnum.BOOP, bean.getFoos().get(2));
String[] values = b.getCollectionValues(); String[] values = b.getCollectionValues();
assertEquals(3, values.length); assertEquals(3, values.length);
assertEquals("BAR", values[0]); assertEquals("BAR", values[0]);
@ -216,7 +207,6 @@ public class GenericBinderTests {
@Test @Test
public void getBindingMultiValuedTypeConversionFailure() { public void getBindingMultiValuedTypeConversionFailure() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
Binding b = binder.getBinding("foos"); Binding b = binder.getBinding("foos");
assertTrue(b.isCollection()); assertTrue(b.isCollection());
assertEquals(0, b.getCollectionValues().length); assertEquals(0, b.getCollectionValues().length);
@ -228,8 +218,6 @@ public class GenericBinderTests {
@Test @Test
public void bindHandleNullValueInNestedPath() { public void bindHandleNullValueInNestedPath() {
TestBean testbean = new TestBean();
Binder<TestBean> binder = new GenericBinder<TestBean>(testbean);
UserValues values = new UserValues(); UserValues values = new UserValues();
// EL configured with some options from SpelExpressionParserConfiguration: // EL configured with some options from SpelExpressionParserConfiguration:
@ -257,15 +245,14 @@ public class GenericBinderTests {
values.add("addresses[5].zip", "32901"); values.add("addresses[5].zip", "32901");
List<BindingResult> results = binder.bind(values); List<BindingResult> results = binder.bind(values);
Assert.assertEquals(6,testbean.addresses.size()); Assert.assertEquals(6, bean.addresses.size());
Assert.assertEquals("Palm Bay",testbean.addresses.get(1).city); Assert.assertEquals("Palm Bay", bean.addresses.get(1).city);
Assert.assertNotNull(testbean.addresses.get(2)); Assert.assertNotNull(bean.addresses.get(2));
assertEquals(12, results.size()); assertEquals(12, results.size());
} }
@Test @Test
public void formatPossibleValue() { public void formatPossibleValue() {
Binder<TestBean> binder = new GenericBinder<TestBean>(new TestBean());
binder.add(new BindingConfiguration("currency", new CurrencyFormatter())); binder.add(new BindingConfiguration("currency", new CurrencyFormatter()));
Binding b = binder.getBinding("currency"); Binding b = binder.getBinding("currency");
assertEquals("$5.00", b.format(new BigDecimal("5"))); assertEquals("$5.00", b.format(new BigDecimal("5")));

View File

@ -24,6 +24,9 @@ import org.springframework.ui.format.number.CurrencyFormat;
public class WebBinderTests { public class WebBinderTests {
TestBean bean = new TestBean();
Binder binder = new WebBinder(bean);
@Before @Before
public void setUp() { public void setUp() {
LocaleContextHolder.setLocale(Locale.US); LocaleContextHolder.setLocale(Locale.US);
@ -36,7 +39,6 @@ public class WebBinderTests {
@Test @Test
public void bindUserValuesCreatedFromUserMap() throws ParseException { public void bindUserValuesCreatedFromUserMap() throws ParseException {
Binder<TestBean> binder = new WebBinder<TestBean>(new TestBean());
binder.add(new CurrencyAnnotationFormatterFactory()); binder.add(new CurrencyAnnotationFormatterFactory());
binder.add(new BindingConfiguration("date", new DateFormatter())); binder.add(new BindingConfiguration("date", new DateFormatter()));
Map<String, String> userMap = new LinkedHashMap<String, String>(); Map<String, String> userMap = new LinkedHashMap<String, String>();
@ -57,12 +59,12 @@ public class WebBinderTests {
assertEquals("$5.00", results.get(4).getUserValue()); assertEquals("$5.00", results.get(4).getUserValue());
assertEquals(null, results.get(5).getUserValue()); assertEquals(null, results.get(5).getUserValue());
assertEquals("test", binder.getModel().getString()); assertEquals("test", bean.getString());
assertEquals(0, binder.getModel().getInteger()); assertEquals(0, bean.getInteger());
assertEquals(new DateFormatter().parse("2009-06-10", Locale.US), binder.getModel().getDate()); assertEquals(new DateFormatter().parse("2009-06-10", Locale.US), bean.getDate());
assertEquals(false, binder.getModel().isBool()); assertEquals(false, bean.isBool());
assertEquals(new BigDecimal("5.00"), binder.getModel().getCurrency()); assertEquals(new BigDecimal("5.00"), bean.getCurrency());
assertEquals(null, binder.getModel().getAddresses()); assertEquals(null, bean.getAddresses());
} }
public static enum FooEnum { public static enum FooEnum {