From a66aa8c3205e6552e18435898373480b544b2311 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sun, 26 Jul 2009 20:23:51 +0000 Subject: [PATCH] added bind template / field binder --- .../springframework/model/binder/Binder.java | 6 +- .../model/binder/support/AbstractBinder.java | 87 ++++++------------- .../model/binder/support/BindTemplate.java | 80 +++++++++++++++++ .../model/binder/support/FieldBinder.java | 34 ++++++++ .../ui/support/PresentationModelBinder.java | 78 ++++++++++------- .../model/ui/support/WebBinder.java | 13 +-- .../support/PresentationModelBinderTests.java | 36 ++++---- .../model/ui/support/WebBinderTests.java | 4 +- 8 files changed, 214 insertions(+), 124 deletions(-) create mode 100644 org.springframework.context/src/main/java/org/springframework/model/binder/support/BindTemplate.java create mode 100644 org.springframework.context/src/main/java/org/springframework/model/binder/support/FieldBinder.java diff --git a/org.springframework.context/src/main/java/org/springframework/model/binder/Binder.java b/org.springframework.context/src/main/java/org/springframework/model/binder/Binder.java index 09ebd1dd76..fbb0bf1a93 100644 --- a/org.springframework.context/src/main/java/org/springframework/model/binder/Binder.java +++ b/org.springframework.context/src/main/java/org/springframework/model/binder/Binder.java @@ -22,15 +22,17 @@ import java.util.Map; * @author Keith Donald * @since 3.0 * @see #bind(Map) + * @param The type of model this binder binds to */ -public interface Binder { +public interface Binder { /** * Bind submitted field values. * @param fieldValues the field values to bind + * @param model the model to bind to * @return the results of the binding operation * @throws MissingFieldException when the fieldValues Map is missing required fields */ - BindingResults bind(Map fieldValues); + BindingResults bind(Map fieldValues, M model); } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/model/binder/support/AbstractBinder.java b/org.springframework.context/src/main/java/org/springframework/model/binder/support/AbstractBinder.java index 7f89dbf3ae..511972dc96 100644 --- a/org.springframework.context/src/main/java/org/springframework/model/binder/support/AbstractBinder.java +++ b/org.springframework.context/src/main/java/org/springframework/model/binder/support/AbstractBinder.java @@ -15,8 +15,6 @@ */ package org.springframework.model.binder.support; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import org.springframework.context.MessageSource; @@ -27,28 +25,34 @@ import org.springframework.model.binder.MissingFieldException; import org.springframework.util.Assert; /** - * A base {@link Binder binder} implementation designed for subclassing. + * Base Binder implementation that defines common structural elements. + * Subclasses should parameterized & implement {@link #bind(Map, Object)}. * @author Keith Donald * @since 3.0 * @see #setRequiredFields(String[]) * @see #setMessageSource(MessageSource) - * @see #bind(Map) + * @see #bind(Map, Object) + * @see #createBindTemplate() */ -public abstract class AbstractBinder implements Binder { +public abstract class AbstractBinder implements Binder { - private String[] requiredFields; + private BindTemplate bindTemplate; private MessageSource messageSource; + public AbstractBinder() { + bindTemplate = createBindTemplate(); + } + /** * Configure the fields for which values must be present in each bind attempt. * @param fieldNames the required field names * @see MissingFieldException */ public void setRequiredFields(String[] fieldNames) { - this.requiredFields = fieldNames; + bindTemplate.setRequiredFields(fieldNames); } - + /** * Configure the MessageSource that resolves localized {@link BindingResult} alert messages. * @param messageSource the message source @@ -58,69 +62,30 @@ public abstract class AbstractBinder implements Binder { this.messageSource = messageSource; } - // implementing Binder + public abstract BindingResults bind(Map fieldValues, M model); - public BindingResults bind(Map fieldValues) { - fieldValues = filter(fieldValues); - checkRequired(fieldValues); - ArrayListBindingResults results = new ArrayListBindingResults(fieldValues.size()); - for (Map.Entry fieldValue : fieldValues.entrySet()) { - results.add(bindField(fieldValue.getKey(), fieldValue.getValue())); - } - return results; - } - - // subclassing hooks + // subclass hooks /** - * Hook subclasses may use to filter the source values to bind. - * This hook allows the binder to pre-process the field values before binding occurs. - * For example, a Binder might insert empty or default values for fields that are not present. - * As another example, a Binder might collapse multiple source values into a single source value. - * Default implementation simply returns the fieldValues Map unchanged. - * @param fieldValues the original fieldValues Map provided by the caller - * @return the filtered fieldValues Map that will be used to bind + * Create the template defining the bulk-binding algorithm. + * Subclasses may override to customize the algorithm. */ - protected Map filter(Map fieldValues) { - return fieldValues; + protected BindTemplate createBindTemplate() { + return new BindTemplate(); } /** - * The configured MessageSource that resolves binding result alert messages. + * The template defining the bulk-binding algorithm. */ - protected MessageSource getMessageSource() { - return messageSource; + protected BindTemplate getBindTemplate() { + return bindTemplate; } - + /** - * Hook method subclasses override to perform a single field binding. - * @param name the field name - * @param value the field value - * @return the binding result + * The configured MessageSource that resolves binding result alert messages. */ - protected abstract BindingResult bindField(String name, Object value); - - // internal helpers - - private void checkRequired(Map fieldValues) { - if (requiredFields == null) { - return; - } - List missingRequired = new ArrayList(); - for (String required : requiredFields) { - boolean found = false; - for (String property : fieldValues.keySet()) { - if (property.equals(required)) { - found = true; - } - } - if (!found) { - missingRequired.add(required); - } - } - if (!missingRequired.isEmpty()) { - throw new MissingFieldException(missingRequired, fieldValues); - } + protected MessageSource getMessageSource() { + return messageSource; } - + } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/model/binder/support/BindTemplate.java b/org.springframework.context/src/main/java/org/springframework/model/binder/support/BindTemplate.java new file mode 100644 index 0000000000..44ac2210a1 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/model/binder/support/BindTemplate.java @@ -0,0 +1,80 @@ +/* + * Copyright 2004-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.model.binder.support; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.model.binder.BindingResults; +import org.springframework.model.binder.MissingFieldException; + +/** + * A template that encapsulates the general bulk-binding algorithm. + * @author Keith Donald + * @since 3.0 + * @see #setRequiredFields(String[]) + * @see #bind(Map) + */ +public class BindTemplate { + + private String[] requiredFields; + + /** + * Configure the fields for which values must be present in each bind attempt. + * @param fieldNames the required field names + * @see MissingFieldException + */ + public void setRequiredFields(String[] fieldNames) { + this.requiredFields = fieldNames; + } + + // implementing Binder + + public BindingResults bind(Map fieldValues, FieldBinder fieldBinder) { + checkRequired(fieldValues); + ArrayListBindingResults results = new ArrayListBindingResults(fieldValues.size()); + for (Map.Entry fieldValue : fieldValues.entrySet()) { + results.add(fieldBinder.bind(fieldValue.getKey(), fieldValue.getValue())); + } + return results; + } + + + // internal helpers + + private void checkRequired(Map fieldValues) { + if (requiredFields == null) { + return; + } + List missingRequired = new ArrayList(); + for (String required : requiredFields) { + boolean found = false; + for (String property : fieldValues.keySet()) { + if (property.equals(required)) { + found = true; + } + } + if (!found) { + missingRequired.add(required); + } + } + if (!missingRequired.isEmpty()) { + throw new MissingFieldException(missingRequired, fieldValues); + } + } + +} \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/model/binder/support/FieldBinder.java b/org.springframework.context/src/main/java/org/springframework/model/binder/support/FieldBinder.java new file mode 100644 index 0000000000..4d079d4316 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/model/binder/support/FieldBinder.java @@ -0,0 +1,34 @@ +/* + * Copyright 2004-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.model.binder.support; + +import org.springframework.model.binder.BindingResult; + +/** + * BindTemplate callback interface for binding a single field value. + * @author Keith Donald + * @see BindTemplate#bind(java.util.Map, BindCallback) + */ +public interface FieldBinder { + + /** + * Bind a single field. + * @param fieldName the field name + * @param value the field value + * @return the binding result + */ + BindingResult bind(String fieldName, Object value); +} diff --git a/org.springframework.context/src/main/java/org/springframework/model/ui/support/PresentationModelBinder.java b/org.springframework.context/src/main/java/org/springframework/model/ui/support/PresentationModelBinder.java index c58db42d55..e644e3c3a0 100644 --- a/org.springframework.context/src/main/java/org/springframework/model/ui/support/PresentationModelBinder.java +++ b/org.springframework.context/src/main/java/org/springframework/model/ui/support/PresentationModelBinder.java @@ -18,62 +18,78 @@ package org.springframework.model.ui.support; import java.util.Map; import org.springframework.context.MessageSource; -import org.springframework.model.binder.Binder; import org.springframework.model.binder.BindingResult; +import org.springframework.model.binder.BindingResults; import org.springframework.model.binder.support.AbstractBinder; import org.springframework.model.binder.support.AlertBindingResult; +import org.springframework.model.binder.support.FieldBinder; import org.springframework.model.binder.support.FieldNotEditableResult; import org.springframework.model.binder.support.FieldNotFoundResult; import org.springframework.model.ui.BindingStatus; import org.springframework.model.ui.FieldModel; import org.springframework.model.ui.FieldNotFoundException; import org.springframework.model.ui.PresentationModel; -import org.springframework.util.Assert; /** - * A generic {@link Binder binder} suitable for use in most environments. + * Binds field values to PresentationModel objects. * @author Keith Donald * @since 3.0 * @see #setMessageSource(MessageSource) * @see #setRequiredFields(String[]) - * @see #bind(Map) + * @see #bind(Map, PresentationModel) */ -public class PresentationModelBinder extends AbstractBinder { +public class PresentationModelBinder extends AbstractBinder { - private PresentationModel presentationModel; - - public PresentationModelBinder(PresentationModel presentationModel) { - Assert.notNull(presentationModel, "The PresentationModel is required"); - this.presentationModel = presentationModel; + public BindingResults bind(Map fieldValues, PresentationModel model) { + fieldValues = filter(fieldValues, model); + return getBindTemplate().bind(fieldValues, new FieldModelBinder(model, getMessageSource())); } - + // subclassing hooks - + /** - * Get the model for the field. - * @param fieldName - * @return the field model - * @throws NoSuchFieldException if no such field exists + * Filter the fields to bind. + * Allows for pre-processing the fieldValues Map before any binding occurs. + * For example, you might insert empty or default values for fields that are not present. + * As another example, you might collapse multiple fields into a single field. + * Default implementation simply returns the fieldValues Map unchanged. + * @param fieldValues the original fieldValues Map provided by the caller + * @return the filtered fieldValues Map that will be used to bind */ - protected FieldModel getFieldModel(String fieldName) { - return presentationModel.getFieldModel(fieldName); + protected Map filter(Map fieldValues, PresentationModel model) { + return fieldValues; } + + // internal helpers + + private static class FieldModelBinder implements FieldBinder { + + private PresentationModel presentationModel; - protected BindingResult bindField(String name, Object value) { - FieldModel field; - try { - field = getFieldModel(name); - } catch (FieldNotFoundException e) { - return new FieldNotFoundResult(name, value, getMessageSource()); + private MessageSource messageSource; + + public FieldModelBinder(PresentationModel presentationModel, MessageSource messageSource) { + this.presentationModel = presentationModel; + this.messageSource = messageSource; } - if (!field.isEditable()) { - return new FieldNotEditableResult(name, value, getMessageSource()); - } else { - field.applySubmittedValue(value); - if (field.getBindingStatus() == BindingStatus.DIRTY) { - field.commit(); + + public BindingResult bind(String fieldName, Object value) { + FieldModel field; + try { + field = presentationModel.getFieldModel(fieldName); + } catch (FieldNotFoundException e) { + return new FieldNotFoundResult(fieldName, value, messageSource); + } + if (!field.isEditable()) { + return new FieldNotEditableResult(fieldName, value, messageSource); + } else { + field.applySubmittedValue(value); + if (field.getBindingStatus() == BindingStatus.DIRTY) { + field.commit(); + } + return new AlertBindingResult(fieldName, value, field.getStatusAlert()); } - return new AlertBindingResult(name, value, field.getStatusAlert()); } } + } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/model/ui/support/WebBinder.java b/org.springframework.context/src/main/java/org/springframework/model/ui/support/WebBinder.java index 0883537b24..6c0fbafd15 100644 --- a/org.springframework.context/src/main/java/org/springframework/model/ui/support/WebBinder.java +++ b/org.springframework.context/src/main/java/org/springframework/model/ui/support/WebBinder.java @@ -28,6 +28,7 @@ import org.springframework.model.ui.PresentationModel; * @since 3.0 * @see #setDefaultPrefix(String) * @see #setPresentPrefix(String) + * @see #filter(Map, PresentationModel) */ public class WebBinder extends PresentationModelBinder { @@ -35,14 +36,6 @@ public class WebBinder extends PresentationModelBinder { private String presentPrefix = "_"; - /** - * Creates a new web binder for the model object. - * @param model the model object containing properties this binder will bind to - */ - public WebBinder(PresentationModel bindingFactory) { - super(bindingFactory); - } - /** * Configure the prefix used to detect the default value for a field when no value is submitted. * Default is '!'. @@ -61,7 +54,7 @@ public class WebBinder extends PresentationModelBinder { } @Override - protected Map filter(Map fieldValues) { + protected Map filter(Map fieldValues, PresentationModel model) { LinkedHashMap filteredValues = new LinkedHashMap(); for (Map.Entry entry : fieldValues.entrySet()) { String field = entry.getKey(); @@ -74,7 +67,7 @@ public class WebBinder extends PresentationModelBinder { } else if (field.startsWith(presentPrefix)) { field = field.substring(presentPrefix.length()); if (!fieldValues.containsKey(field) && !fieldValues.containsKey(defaultPrefix + field)) { - value = getEmptyValue(getFieldModel(field)); + value = getEmptyValue(model.getFieldModel(field)); filteredValues.put(field, value); } } else { diff --git a/org.springframework.context/src/test/java/org/springframework/model/ui/support/PresentationModelBinderTests.java b/org.springframework.context/src/test/java/org/springframework/model/ui/support/PresentationModelBinderTests.java index c3c2f12dd4..dff89c33a0 100644 --- a/org.springframework.context/src/test/java/org/springframework/model/ui/support/PresentationModelBinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/model/ui/support/PresentationModelBinderTests.java @@ -47,7 +47,7 @@ public class PresentationModelBinderTests { public void setUp() { bean = new TestBean(); presentationModel = new DefaultPresentationModel(bean); - binder = new PresentationModelBinder(presentationModel); + binder = new PresentationModelBinder(); LocaleContextHolder.setLocale(Locale.US); } @@ -62,7 +62,7 @@ public class PresentationModelBinderTests { values.put("string", "test"); values.put("integer", "3"); values.put("foo", "BAR"); - BindingResults results = binder.bind(values); + BindingResults results = binder.bind(values, presentationModel); assertEquals(3, results.size()); assertEquals("string", results.get(0).getFieldName()); @@ -89,7 +89,7 @@ public class PresentationModelBinderTests { // bad value values.put("integer", "bogus"); values.put("foo", "BAR"); - BindingResults results = binder.bind(values); + BindingResults results = binder.bind(values, presentationModel); assertEquals(3, results.size()); assertTrue(results.get(1).isFailure()); assertEquals("typeMismatch", results.get(1).getAlert().getCode()); @@ -98,14 +98,14 @@ public class PresentationModelBinderTests { @Test public void bindSingleValuePropertyFormatter() throws ParseException { presentationModel.field("date").formatWith(new DateFormatter()); - binder.bind(Collections.singletonMap("date", "2009-06-01")); + binder.bind(Collections.singletonMap("date", "2009-06-01"), presentationModel); assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), bean.getDate()); } @Test public void bindSingleValuePropertyFormatterParseException() { presentationModel.field("date").formatWith(new DateFormatter()); - BindingResults results = binder.bind(Collections.singletonMap("date", "bogus")); + BindingResults results = binder.bind(Collections.singletonMap("date", "bogus"), presentationModel); assertEquals(1, results.size()); assertTrue(results.get(0).isFailure()); assertEquals("typeMismatch", results.get(0).getAlert().getCode()); @@ -117,7 +117,7 @@ public class PresentationModelBinderTests { formatterRegistry.add(Date.class, new DateFormatter()); presentationModel.setFormatterRegistry(formatterRegistry); - binder.bind(Collections.singletonMap("date", "2009-06-01")); + binder.bind(Collections.singletonMap("date", "2009-06-01"), presentationModel); assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), bean.getDate()); } @@ -127,13 +127,13 @@ public class PresentationModelBinderTests { formatterRegistry.add(new CurrencyAnnotationFormatterFactory()); presentationModel.setFormatterRegistry(formatterRegistry); - binder.bind(Collections.singletonMap("currency", "$23.56")); + binder.bind(Collections.singletonMap("currency", "$23.56"), presentationModel); assertEquals(new BigDecimal("23.56"), bean.getCurrency()); } @Test public void bindSingleValuePropertyNotFound() throws ParseException { - BindingResults results = binder.bind(Collections.singletonMap("bogus", "2009-06-01")); + BindingResults results = binder.bind(Collections.singletonMap("bogus", "2009-06-01"), presentationModel); assertEquals("bogus", results.get(0).getFieldName()); assertTrue(results.get(0).isFailure()); assertEquals("fieldNotFound", results.get(0).getAlert().getCode()); @@ -143,7 +143,7 @@ public class PresentationModelBinderTests { public void bindMissingRequiredSourceValue() { binder.setRequiredFields(new String[] { "integer" }); // missing "integer" - violated bind contract - binder.bind(Collections.singletonMap("string", "test")); + binder.bind(Collections.singletonMap("string", "test"), presentationModel); } @Test @@ -236,7 +236,7 @@ public class PresentationModelBinderTests { Map values = new LinkedHashMap(); values.put("addresses", new String[] { "4655 Macy Lane:Melbourne:FL:35452", "1234 Rostock Circle:Palm Bay:FL:32901", "1977 Bel Aire Estates:Coker:AL:12345" }); - binder.bind(values); + binder.bind(values, presentationModel); assertEquals(3, bean.addresses.size()); assertEquals("4655 Macy Lane", bean.addresses.get(0).street); assertEquals("Melbourne", bean.addresses.get(0).city); @@ -250,7 +250,7 @@ public class PresentationModelBinderTests { values.put("addresses[0]", "4655 Macy Lane:Melbourne:FL:35452"); values.put("addresses[1]", "1234 Rostock Circle:Palm Bay:FL:32901"); values.put("addresses[5]", "1977 Bel Aire Estates:Coker:AL:12345"); - binder.bind(values); + binder.bind(values, presentationModel); Assert.assertEquals(6, bean.addresses.size()); assertEquals("4655 Macy Lane", bean.addresses.get(0).street); assertEquals("Melbourne", bean.addresses.get(0).city); @@ -267,7 +267,7 @@ public class PresentationModelBinderTests { values .put("addresses", "4655 Macy Lane:Melbourne:FL:35452,1234 Rostock Circle:Palm Bay:FL:32901,1977 Bel Aire Estates:Coker:AL:12345"); - binder.bind(values); + binder.bind(values, presentationModel); Assert.assertEquals(3, bean.addresses.size()); assertEquals("4655 Macy Lane", bean.addresses.get(0).street); assertEquals("Melbourne", bean.addresses.get(0).city); @@ -289,7 +289,7 @@ public class PresentationModelBinderTests { values .put("addresses", "4655 Macy Lane:Melbourne:FL:35452,1234 Rostock Circle:Palm Bay:FL:32901,1977 Bel Aire Estates:Coker:AL:12345"); - binder.bind(values); + binder.bind(values, presentationModel); Assert.assertEquals(3, bean.addresses.size()); assertEquals("4655 Macy Lane", bean.addresses.get(0).street); assertEquals("Melbourne", bean.addresses.get(0).city); @@ -371,7 +371,7 @@ public class PresentationModelBinderTests { values.put("addresses[5].state", "FL"); values.put("addresses[5].zip", "32901"); - BindingResults results = binder.bind(values); + BindingResults results = binder.bind(values, presentationModel); Assert.assertEquals(6, bean.addresses.size()); Assert.assertEquals("Palm Bay", bean.addresses.get(1).city); Assert.assertNotNull(bean.addresses.get(2)); @@ -382,7 +382,7 @@ public class PresentationModelBinderTests { public void bindToMap() { Map values = new LinkedHashMap(); values.put("favoriteFoodsByGroup", new String[] { "DAIRY=Milk", "FRUIT=Peaches", "MEAT=Ham" }); - binder.bind(values); + binder.bind(values, presentationModel); Assert.assertEquals(3, bean.favoriteFoodsByGroup.size()); assertEquals("Milk", bean.favoriteFoodsByGroup.get(FoodGroup.DAIRY)); assertEquals("Peaches", bean.favoriteFoodsByGroup.get(FoodGroup.FRUIT)); @@ -395,7 +395,7 @@ public class PresentationModelBinderTests { values.put("favoriteFoodsByGroup[DAIRY]", "Milk"); values.put("favoriteFoodsByGroup[FRUIT]", "Peaches"); values.put("favoriteFoodsByGroup[MEAT]", "Ham"); - binder.bind(values); + binder.bind(values, presentationModel); Assert.assertEquals(3, bean.favoriteFoodsByGroup.size()); assertEquals("Milk", bean.favoriteFoodsByGroup.get(FoodGroup.DAIRY)); assertEquals("Peaches", bean.favoriteFoodsByGroup.get(FoodGroup.FRUIT)); @@ -406,7 +406,7 @@ public class PresentationModelBinderTests { public void bindToMapSingleString() { Map values = new LinkedHashMap(); values.put("favoriteFoodsByGroup", "DAIRY=Milk FRUIT=Peaches MEAT=Ham"); - binder.bind(values); + binder.bind(values, presentationModel); Assert.assertEquals(3, bean.favoriteFoodsByGroup.size()); assertEquals("Milk", bean.favoriteFoodsByGroup.get(FoodGroup.DAIRY)); assertEquals("Peaches", bean.favoriteFoodsByGroup.get(FoodGroup.FRUIT)); @@ -429,7 +429,7 @@ public class PresentationModelBinderTests { public void bindToNullObjectPath() { Map values = new LinkedHashMap(); values.put("primaryAddress.city", "Melbourne"); - binder.bind(values); + binder.bind(values, presentationModel); Assert.assertEquals("Melbourne", bean.primaryAddress.city); } diff --git a/org.springframework.context/src/test/java/org/springframework/model/ui/support/WebBinderTests.java b/org.springframework.context/src/test/java/org/springframework/model/ui/support/WebBinderTests.java index 62ee2b7b93..a6617a189c 100644 --- a/org.springframework.context/src/test/java/org/springframework/model/ui/support/WebBinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/model/ui/support/WebBinderTests.java @@ -34,7 +34,7 @@ public class WebBinderTests { public void setUp() { LocaleContextHolder.setLocale(Locale.US); presentationModel = new DefaultPresentationModel(bean); - binder = new WebBinder(presentationModel); + binder = new WebBinder(); } @After @@ -56,7 +56,7 @@ public class WebBinderTests { userMap.put("!currency", "$5.00"); userMap.put("_currency", "doesn't matter"); userMap.put("_addresses", "doesn't matter"); - BindingResults results = binder.bind(userMap); + BindingResults results = binder.bind(userMap, presentationModel); assertEquals(6, results.size()); assertEquals("test", results.get(0).getSubmittedValue()); assertEquals(null, results.get(1).getSubmittedValue());