From 5828010baead086f197d5b5789832b094edc8d35 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Thu, 25 Jun 2009 20:26:22 +0000 Subject: [PATCH] Added binder factory; simplified public binder api --- .../springframework/ui/binding/Binder.java | 41 +------------ .../ui/binding/BinderFactory.java | 31 ++++++++++ .../ui/binding/BindingResult.java | 2 +- .../AnnotatedModelBinderConfigurer.java | 40 +++++++++++++ .../{ => support}/BindingConfiguration.java | 4 +- .../{ => support}/FormatterRegistry.java | 2 +- .../ui/binding/support/GenericBinder.java | 36 +++++++---- .../support/GenericFormatterRegistry.java | 1 - .../ui/binding/support/WebBinder.java | 2 +- .../ui/binding/support/WebBinderFactory.java | 16 +++++ .../WebBindAndValidateLifecycle.java | 60 ++----------------- .../binding/support/GenericBinderTests.java | 13 ++-- .../ui/binding/support/WebBinderTests.java | 8 +-- .../WebBindAndValidateLifecycleTests.java | 51 +--------------- 14 files changed, 138 insertions(+), 169 deletions(-) create mode 100644 org.springframework.context/src/main/java/org/springframework/ui/binding/BinderFactory.java create mode 100644 org.springframework.context/src/main/java/org/springframework/ui/binding/support/AnnotatedModelBinderConfigurer.java rename org.springframework.context/src/main/java/org/springframework/ui/binding/{ => support}/BindingConfiguration.java (93%) rename org.springframework.context/src/main/java/org/springframework/ui/binding/{ => support}/FormatterRegistry.java (97%) create mode 100644 org.springframework.context/src/main/java/org/springframework/ui/binding/support/WebBinderFactory.java 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 643b4360c8..208213124f 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 @@ -17,15 +17,11 @@ package org.springframework.ui.binding; import java.util.Map; -import org.springframework.ui.format.AnnotationFormatterFactory; -import org.springframework.ui.format.Formatter; - /** * Binds user-entered values to properties of a model object. * @author Keith Donald * @since 3.0 - * @see #configureBinding(BindingConfiguration) - * @see #bind(UserValues) + * @see #bind(Map) */ public interface Binder { @@ -35,41 +31,6 @@ public interface Binder { */ Object getModel(); - /** - * Configures if this binder is strict; a strict binder requires all bindings to be registered explicitly using {@link #configureBinding(BindingConfiguration)}. - * An optimistic binder will implicitly create bindings as required to support {@link #bind(UserValues)} operations. - * Default is optimistic. - * @param strict strict binder status - */ - void setStrict(boolean strict); - - /** - * Adds a new binding. - * @param configuration the binding configuration - * @return the new binding created from the configuration provided - */ - Binding configureBinding(BindingConfiguration configuration); - - /** - * Adds a Formatter that will format property values of type propertyType. - * @param propertyType the property type - * @param formatter the formatter - */ - void registerFormatter(Class propertyType, Formatter formatter); - - /** - * Adds a AnnotationFormatterFactory that will format values of properties annotated with a specific annotation. - * @param factory the annotation formatter factory - */ - void registerFormatterFactory(AnnotationFormatterFactory factory); - - /** - * Configures the registry of Formatters to query when no explicit Formatter has been registered for a Binding. - * Allows Formatters to be applied by property type and by property annotation. - * @param registry the formatter registry - */ - void setFormatterRegistry(FormatterRegistry registry); - /** * Returns the binding for the property. * @param property the property path diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/BinderFactory.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/BinderFactory.java new file mode 100644 index 0000000000..0ecd4ef439 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/BinderFactory.java @@ -0,0 +1,31 @@ +/* + * 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.ui.binding; + +/** + * A factory for model Binders. + * @author Keith Donald + * @since 3.0 + */ +public interface BinderFactory { + + /** + * Get the Binder for the model + * @param model the model + * @return the binder + */ + Binder getBinder(Object model); +} diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingResult.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingResult.java index 0947d1e3c6..028261c8d9 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingResult.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingResult.java @@ -21,7 +21,7 @@ import org.springframework.ui.alert.Alert; * The result of a bind operation. * @author Keith Donald * @since 3.0 - * @see Binder#bind(UserValues) + * @see Binder#bind(Map) * @see Binding#setValue(Object) */ public interface BindingResult { diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/AnnotatedModelBinderConfigurer.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/AnnotatedModelBinderConfigurer.java new file mode 100644 index 0000000000..c3dd2bddbf --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/AnnotatedModelBinderConfigurer.java @@ -0,0 +1,40 @@ +package org.springframework.ui.binding.support; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; + +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.ui.binding.Bound; +import org.springframework.ui.binding.Model; + +class AnnotatedModelBinderConfigurer { + + public void configure(GenericBinder binder) { + Class modelClass = binder.getModel().getClass(); + Model m = AnnotationUtils.findAnnotation(modelClass, Model.class); + if (m != null) { + binder.setStrict(m.strictBinding()); + } + if (binder.isStrict()) { + BeanInfo beanInfo; + try { + beanInfo = Introspector.getBeanInfo(modelClass); + } catch (IntrospectionException e) { + throw new IllegalStateException("Unable to introspect model " + binder.getModel(), e); + } + // TODO do we have to still flush introspector cache here? + for (PropertyDescriptor prop : beanInfo.getPropertyDescriptors()) { + Method getter = prop.getReadMethod(); + Bound b = AnnotationUtils.getAnnotation(getter, Bound.class); + if (b != null) { + // TODO should we wire formatter here if using a format annotation - an optimization? + binder.configureBinding(new BindingConfiguration(prop.getName(), null)); + } + } + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingConfiguration.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingConfiguration.java similarity index 93% rename from org.springframework.context/src/main/java/org/springframework/ui/binding/BindingConfiguration.java rename to org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingConfiguration.java index 4ea01d16fe..28cd4aeb63 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingConfiguration.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingConfiguration.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ui.binding; +package org.springframework.ui.binding.support; -import org.springframework.ui.binding.support.GenericBinder; +import org.springframework.ui.binding.Binding; import org.springframework.ui.format.Formatter; /** diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/FormatterRegistry.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/FormatterRegistry.java similarity index 97% rename from org.springframework.context/src/main/java/org/springframework/ui/binding/FormatterRegistry.java rename to org.springframework.context/src/main/java/org/springframework/ui/binding/support/FormatterRegistry.java index ecb697956c..15f232752b 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/FormatterRegistry.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/FormatterRegistry.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.ui.binding; +package org.springframework.ui.binding.support; import org.springframework.core.convert.TypeDescriptor; import org.springframework.ui.format.AnnotationFormatterFactory; diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBinder.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBinder.java index 2ad25684ac..0ce16c7013 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBinder.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBinder.java @@ -53,11 +53,8 @@ import org.springframework.ui.alert.Alert; import org.springframework.ui.alert.Severity; import org.springframework.ui.binding.Binder; import org.springframework.ui.binding.Binding; -import org.springframework.ui.binding.BindingConfiguration; import org.springframework.ui.binding.BindingResult; import org.springframework.ui.binding.BindingResults; -import org.springframework.ui.binding.FormatterRegistry; -import org.springframework.ui.format.AnnotationFormatterFactory; import org.springframework.ui.format.Formatter; import org.springframework.ui.message.MessageBuilder; import org.springframework.ui.message.ResolvableArgument; @@ -109,14 +106,30 @@ public class GenericBinder implements Binder { return model; } + /** + * Is this binder strict? + * A strict binder requires all bindings to be registered explicitly using {@link #configureBinding(BindingConfiguration)}. + */ public boolean isStrict() { return strict; } - + + /** + * Configures if this binder is strict. + * A strict binder requires all bindings to be registered explicitly using {@link #configureBinding(BindingConfiguration)}. + * An optimistic binder will implicitly create bindings as required to support {@link #bind(UserValues)} operations. + * Default is optimistic. + * @param strict strict binder status + */ public void setStrict(boolean strict) { this.strict = strict; } + /** + * Configures the registry of Formatters to query when no explicit Formatter has been registered for a Binding. + * Allows Formatters to be applied by property type and by property annotation. + * @param registry the formatter registry + */ public void setFormatterRegistry(FormatterRegistry formatterRegistry) { Assert.notNull(formatterRegistry, "The FormatterRegistry is required"); this.formatterRegistry = formatterRegistry; @@ -127,6 +140,7 @@ public class GenericBinder implements Binder { * @param messageSource the message source */ public void setMessageSource(MessageSource messageSource) { + Assert.notNull(messageSource, "The MessageSource is required"); this.messageSource = messageSource; } @@ -138,9 +152,15 @@ public class GenericBinder implements Binder { * @see EvaluationContext#getTypeConverter() */ public void setTypeConverter(TypeConverter typeConverter) { + Assert.notNull(messageSource, "The TypeConverter is required"); this.typeConverter = typeConverter; } + /** + * Configures a new binding on this binder. + * @param configuration the binding configuration + * @return the new binding created from the configuration provided + */ public Binding configureBinding(BindingConfiguration configuration) { Binding binding; try { @@ -152,14 +172,6 @@ public class GenericBinder implements Binder { return binding; } - public void registerFormatter(Class propertyType, Formatter formatter) { - formatterRegistry.add(propertyType, formatter); - } - - public void registerFormatterFactory(AnnotationFormatterFactory factory) { - formatterRegistry.add(factory); - } - public Binding getBinding(String property) { Binding binding = bindings.get(property); if (binding == null && !strict) { diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericFormatterRegistry.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericFormatterRegistry.java index ab177ada3f..ded1705463 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericFormatterRegistry.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericFormatterRegistry.java @@ -24,7 +24,6 @@ import java.util.Map; import org.springframework.core.GenericTypeResolver; import org.springframework.core.convert.TypeDescriptor; -import org.springframework.ui.binding.FormatterRegistry; import org.springframework.ui.format.AnnotationFormatterFactory; import org.springframework.ui.format.Formatter; diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/WebBinder.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/WebBinder.java index adbd8094e4..2d915e9550 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/WebBinder.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/WebBinder.java @@ -26,7 +26,7 @@ import java.util.Map; * @see #setDefaultPrefix(String) * @see #setPresentPrefix(String) */ -public class WebBinder extends GenericBinder { +class WebBinder extends GenericBinder { private String defaultPrefix = "!"; diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/WebBinderFactory.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/WebBinderFactory.java new file mode 100644 index 0000000000..8419be3513 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/WebBinderFactory.java @@ -0,0 +1,16 @@ +package org.springframework.ui.binding.support; + +import org.springframework.ui.binding.Binder; +import org.springframework.ui.binding.BinderFactory; + +public class WebBinderFactory implements BinderFactory { + + public Binder getBinder(Object model) { + WebBinder binder = new WebBinder(model); + new AnnotatedModelBinderConfigurer().configure(binder); + return binder; + } + + // internal helpers + +} diff --git a/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/WebBindAndValidateLifecycle.java b/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/WebBindAndValidateLifecycle.java index 375c537de2..2afb8dcf9e 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/WebBindAndValidateLifecycle.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/WebBindAndValidateLifecycle.java @@ -15,24 +15,13 @@ */ package org.springframework.ui.lifecycle; -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Method; import java.util.Map; -import org.springframework.core.annotation.AnnotationUtils; import org.springframework.ui.alert.AlertContext; -import org.springframework.ui.binding.BindingConfiguration; +import org.springframework.ui.binding.Binder; import org.springframework.ui.binding.BindingResult; import org.springframework.ui.binding.BindingResults; -import org.springframework.ui.binding.Bound; -import org.springframework.ui.binding.FormatterRegistry; -import org.springframework.ui.binding.Model; -import org.springframework.ui.binding.support.WebBinder; import org.springframework.ui.validation.Validator; -import org.springframework.util.StringUtils; /** * Implementation of the bind and validate lifecycle for web (HTTP) environments. @@ -41,7 +30,7 @@ import org.springframework.util.StringUtils; */ public class WebBindAndValidateLifecycle { - private final WebBinder binder; + private final Binder binder; private final AlertContext alertContext; @@ -49,19 +38,13 @@ public class WebBindAndValidateLifecycle { private Validator validator; - public WebBindAndValidateLifecycle(Object model, AlertContext alertContext) { - this.binder = new WebBinder(model); - // TODO this doesn't belong in here - configure(binder, model); + public WebBindAndValidateLifecycle(Binder binder, AlertContext alertContext) { + this.binder = binder; this.alertContext = alertContext; } - public void setFormatterRegistry(FormatterRegistry registry) { - binder.setFormatterRegistry(registry); - } - - public void execute(Map userMap) { - BindingResults bindingResults = binder.bind(userMap); + public void execute(Map sourceValues) { + BindingResults bindingResults = binder.bind(sourceValues); if (validator != null && validationDecider.shouldValidateAfter(bindingResults)) { // TODO get validation results validator.validate(binder.getModel(), bindingResults.successes().properties()); @@ -83,35 +66,4 @@ public class WebBindAndValidateLifecycle { }; } - // internal helpers - - private void configure(WebBinder binder, Object model) { - Model m = AnnotationUtils.findAnnotation(model.getClass(), Model.class); - if (m != null) { - if (StringUtils.hasText(m.value())) { - // TODO model name setting - //binder.setModelName(m.value()); - } - binder.setStrict(m.strictBinding()); - } - if (binder.isStrict()) { - BeanInfo beanInfo; - try { - beanInfo = Introspector.getBeanInfo(model.getClass()); - } catch (IntrospectionException e) { - throw new IllegalStateException("Unable to introspect model " + model, e); - } - // TODO do we have to still flush introspector cache here? - for (PropertyDescriptor prop : beanInfo.getPropertyDescriptors()) { - Method getter = prop.getReadMethod(); - Bound b = AnnotationUtils.getAnnotation(getter, Bound.class); - if (b != null) { - // TODO should we wire formatter here if using a format annotation - an optimization? - binder.configureBinding(new BindingConfiguration(prop.getName(), null)); - } - } - // TODO @Bound fields - } - } - } diff --git a/org.springframework.context/src/test/java/org/springframework/ui/binding/support/GenericBinderTests.java b/org.springframework.context/src/test/java/org/springframework/ui/binding/support/GenericBinderTests.java index d8112e5046..8d199bf8b2 100644 --- a/org.springframework.context/src/test/java/org/springframework/ui/binding/support/GenericBinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/ui/binding/support/GenericBinderTests.java @@ -21,7 +21,6 @@ import org.junit.Before; import org.junit.Test; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.ui.binding.Binding; -import org.springframework.ui.binding.BindingConfiguration; import org.springframework.ui.binding.BindingResult; import org.springframework.ui.binding.BindingResults; import org.springframework.ui.format.AnnotationFormatterFactory; @@ -104,21 +103,27 @@ public class GenericBinderTests { @Test public void bindSingleValueWithFormatterRegistedByType() throws ParseException { - binder.registerFormatter(Date.class, new DateFormatter()); + GenericFormatterRegistry registry = new GenericFormatterRegistry(); + registry.add(Date.class, new DateFormatter()); + binder.setFormatterRegistry(registry); binder.bind(Collections.singletonMap("date", "2009-06-01")); assertEquals(new DateFormatter().parse("2009-06-01", Locale.US), bean.getDate()); } @Test public void bindSingleValueWithFormatterRegisteredByAnnotation() throws ParseException { - binder.registerFormatter(CurrencyFormat.class, new CurrencyFormatter()); + GenericFormatterRegistry registry = new GenericFormatterRegistry(); + registry.add(CurrencyFormat.class, new CurrencyFormatter()); + binder.setFormatterRegistry(registry); binder.bind(Collections.singletonMap("currency", "$23.56")); assertEquals(new BigDecimal("23.56"), bean.getCurrency()); } @Test public void bindSingleValueWithnAnnotationFormatterFactoryRegistered() throws ParseException { - binder.registerFormatterFactory(new CurrencyAnnotationFormatterFactory()); + GenericFormatterRegistry registry = new GenericFormatterRegistry(); + registry.add(new CurrencyAnnotationFormatterFactory()); + binder.setFormatterRegistry(registry); binder.bind(Collections.singletonMap("currency", "$23.56")); assertEquals(new BigDecimal("23.56"), bean.getCurrency()); } diff --git a/org.springframework.context/src/test/java/org/springframework/ui/binding/support/WebBinderTests.java b/org.springframework.context/src/test/java/org/springframework/ui/binding/support/WebBinderTests.java index 277b2cd7c0..4524807ff0 100644 --- a/org.springframework.context/src/test/java/org/springframework/ui/binding/support/WebBinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/ui/binding/support/WebBinderTests.java @@ -14,8 +14,6 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.ui.binding.Binder; -import org.springframework.ui.binding.BindingConfiguration; import org.springframework.ui.binding.BindingResults; import org.springframework.ui.format.date.DateFormatter; import org.springframework.ui.format.number.CurrencyFormat; @@ -25,7 +23,7 @@ public class WebBinderTests { TestBean bean = new TestBean(); - Binder binder = new WebBinder(bean); + WebBinder binder = new WebBinder(bean); @Before public void setUp() { @@ -39,7 +37,9 @@ public class WebBinderTests { @Test public void bindUserValuesCreatedFromUserMap() throws ParseException { - binder.registerFormatter(CurrencyFormat.class, new CurrencyFormatter()); + GenericFormatterRegistry registry = new GenericFormatterRegistry(); + registry.add(CurrencyFormat.class, new CurrencyFormatter()); + binder.setFormatterRegistry(registry); binder.configureBinding(new BindingConfiguration("date", new DateFormatter())); Map userMap = new LinkedHashMap(); userMap.put("string", "test"); diff --git a/org.springframework.context/src/test/java/org/springframework/ui/lifecycle/WebBindAndValidateLifecycleTests.java b/org.springframework.context/src/test/java/org/springframework/ui/lifecycle/WebBindAndValidateLifecycleTests.java index b14a335300..8ea5d2bae6 100644 --- a/org.springframework.context/src/test/java/org/springframework/ui/lifecycle/WebBindAndValidateLifecycleTests.java +++ b/org.springframework.context/src/test/java/org/springframework/ui/lifecycle/WebBindAndValidateLifecycleTests.java @@ -14,9 +14,8 @@ import org.springframework.ui.alert.Severity; import org.springframework.ui.alert.support.DefaultAlertContext; import org.springframework.ui.binding.Bound; import org.springframework.ui.binding.Model; -import org.springframework.ui.binding.support.GenericFormatterRegistry; +import org.springframework.ui.binding.support.WebBinderFactory; import org.springframework.ui.format.number.CurrencyFormat; -import org.springframework.ui.format.number.IntegerFormatter; public class WebBindAndValidateLifecycleTests { @@ -30,7 +29,7 @@ public class WebBindAndValidateLifecycleTests { public void setUp() { model = new TestBean(); alertContext = new DefaultAlertContext(); - lifecycle = new WebBindAndValidateLifecycle(model, alertContext); + lifecycle = new WebBindAndValidateLifecycle(new WebBinderFactory().getBinder(model), alertContext); } @Test @@ -55,52 +54,6 @@ public class WebBindAndValidateLifecycleTests { assertEquals("Failed to bind to property 'integer'; user value 'bogus' could not be converted to property type [java.lang.Integer]", alertContext.getAlerts("integer").get(0).getMessage()); } - @Test - public void testExecuteLifecycleInvalidFormatBindingErrors() { - Map userMap = new HashMap(); - GenericFormatterRegistry registry = new GenericFormatterRegistry(); - registry.add(Integer.class, new IntegerFormatter()); - lifecycle.setFormatterRegistry(registry); - userMap.put("string", "test"); - userMap.put("integer", "bogus"); - userMap.put("foo", "BAR"); - lifecycle.execute(userMap); - assertEquals(1, alertContext.getAlerts().size()); - assertEquals(Severity.ERROR, alertContext.getAlerts("integer").get(0).getSeverity()); - assertEquals("Failed to bind to property 'integer'; the user value 'bogus' has an invalid format and could no be parsed", alertContext.getAlerts("integer").get(0).getMessage()); - } - - @Test - public void testExecuteLifecycleAnnotatedModel() { - TestAnnotatedBean model = new TestAnnotatedBean(); - lifecycle = new WebBindAndValidateLifecycle(model, alertContext); - Map userMap = new HashMap(); - GenericFormatterRegistry registry = new GenericFormatterRegistry(); - registry.add(Integer.class, new IntegerFormatter()); - lifecycle.setFormatterRegistry(registry); - userMap.put("editable", "foo"); - lifecycle.execute(userMap); - assertEquals(0, alertContext.getAlerts().size()); - assertEquals("foo", model.getEditable()); - } - - @Test - public void testExecuteLifecycleAnnotatedModelNonEditableBindingAttempt() { - TestAnnotatedBean model = new TestAnnotatedBean(); - lifecycle = new WebBindAndValidateLifecycle(model, alertContext); - Map userMap = new HashMap(); - GenericFormatterRegistry registry = new GenericFormatterRegistry(); - registry.add(Integer.class, new IntegerFormatter()); - lifecycle.setFormatterRegistry(registry); - userMap.put("editable", "foo"); - userMap.put("nonEditable", "whatev"); - lifecycle.execute(userMap); - assertEquals(1, alertContext.getAlerts().size()); - assertEquals("foo", model.getEditable()); - assertEquals(null, model.getNotEditable()); - assertEquals("noSuchBinding", alertContext.getAlerts("nonEditable").get(0).getCode()); - } - public static enum FooEnum { BAR, BAZ, BOOP; } -- GitLab