From 7e3c1bf09acd4a1fd72303e402a9fb4eef9a9c1d Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Fri, 26 Jun 2009 15:33:35 +0000 Subject: [PATCH] prepping for jsr 303 integration --- .../AnnotatedModelBinderConfigurer.java | 2 +- .../binding/support/BindingConfiguration.java | 2 +- .../ui/binding/support/GenericBinder.java | 2 + .../lifecycle/BindAndValidateLifecycle.java | 43 +++++++++++-------- .../ui/lifecycle/ValidationDecider.java | 43 +++++++++++++++++++ .../BindAndValidateLifecycleTests.java | 2 +- 6 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 org.springframework.context/src/main/java/org/springframework/ui/lifecycle/ValidationDecider.java 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 index c3dd2bddbfd..89303de0047 100644 --- 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 @@ -10,7 +10,7 @@ import org.springframework.core.annotation.AnnotationUtils; import org.springframework.ui.binding.Bound; import org.springframework.ui.binding.Model; -class AnnotatedModelBinderConfigurer { +final class AnnotatedModelBinderConfigurer { public void configure(GenericBinder binder) { Class modelClass = binder.getModel().getClass(); diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingConfiguration.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingConfiguration.java index 28cd4aeb631..57e06ab7f26 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingConfiguration.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingConfiguration.java @@ -24,7 +24,7 @@ import org.springframework.ui.format.Formatter; * @since 3.0 * @see GenericBinder#configureBinding(BindingConfiguration) */ -public class BindingConfiguration { +public final class BindingConfiguration { private String property; 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 fe15699ff65..730caa2dc34 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 @@ -169,6 +169,7 @@ public class GenericBinder implements Binder { public Binding configureBinding(BindingConfiguration configuration) { Binding binding; try { + // TODO should probably only allow binding to be created if property exists on model binding = new BindingImpl(configuration); } catch (org.springframework.expression.ParseException e) { throw new IllegalArgumentException(e); @@ -653,6 +654,7 @@ public class GenericBinder implements Binder { if (spelCode == SpelMessage.EXCEPTION_DURING_PROPERTY_WRITE) { return "conversionFailed"; } else if (spelCode == SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE) { + // TODO should probably force property exists before even creating binding return "propertyNotFound"; } else { return "couldNotSetValue"; diff --git a/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/BindAndValidateLifecycle.java b/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/BindAndValidateLifecycle.java index dc766ce0050..7a92ec054aa 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/BindAndValidateLifecycle.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/BindAndValidateLifecycle.java @@ -24,24 +24,39 @@ import org.springframework.ui.binding.BindingResults; import org.springframework.ui.validation.Validator; /** - * Implementation of the bind and validate lifecycle for web (HTTP) environments. + * Implementation of the model bind and validate lifecycle lifecycle. * @author Keith Donald * @since 3.0 */ -public class BindAndValidateLifecycle { +public final class BindAndValidateLifecycle { - private final Binder binder; - - private final AlertContext alertContext; - - private ValidationDecider validationDecider = ValidationDecider.ALWAYS_VALIDATE; + private Binder binder; private Validator validator; - public BindAndValidateLifecycle(Binder binder, AlertContext alertContext) { + private ValidationDecider validationDecider = ValidationDecider.ALWAYS_VALIDATE; + + private final AlertContext alertContext; + + /** + * Create a new bind and validate lifecycle. + * @param binder the binder to use for model binding + * @param validator the validator to use for model validation + * @param alertContext a context for adding binding and validation-related alerts + */ + public BindAndValidateLifecycle(Binder binder, Validator validator, AlertContext alertContext) { this.binder = binder; + this.validator = validator; this.alertContext = alertContext; } + + /** + * Configures the strategy that determines if validation should execute after binding. + * @param validationDecider the validation decider + */ + public void setValidationDecider(ValidationDecider validationDecider) { + this.validationDecider = validationDecider; + } public void execute(Map sourceValues) { BindingResults bindingResults = binder.bind(sourceValues); @@ -50,20 +65,10 @@ public class BindAndValidateLifecycle { validator.validate(binder.getModel(), bindingResults.successes().properties()); } for (BindingResult result : bindingResults.failures()) { + // TODO - you may want to ignore some alerts like propertyNotFound alertContext.add(result.getProperty(), result.getAlert()); } // TODO translate validation results into messages } - interface ValidationDecider { - - boolean shouldValidateAfter(BindingResults results); - - static final ValidationDecider ALWAYS_VALIDATE = new ValidationDecider() { - public boolean shouldValidateAfter(BindingResults results) { - return true; - } - }; - } - } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/ValidationDecider.java b/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/ValidationDecider.java new file mode 100644 index 00000000000..7e90ea61e98 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/lifecycle/ValidationDecider.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002-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.lifecycle; + +import org.springframework.ui.binding.BindingResults; + +/** + * Decides if validation should run for an execution of the bind and validate lifecycle. + * @author Keith Donald + * @since 3.0 + * @see BindAndValidateLifecycle#execute(java.util.Map) + */ +interface ValidationDecider { + + /** + * Should validation execute after model binding? + * @param results the results of model binding + * @return yes or no + */ + boolean shouldValidateAfter(BindingResults results); + + /** + * Singleton reference to a ValidationDecider that always returns true. + */ + static final ValidationDecider ALWAYS_VALIDATE = new ValidationDecider() { + public boolean shouldValidateAfter(BindingResults results) { + return true; + } + }; +} \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/ui/lifecycle/BindAndValidateLifecycleTests.java b/org.springframework.context/src/test/java/org/springframework/ui/lifecycle/BindAndValidateLifecycleTests.java index 1a770dcbd9e..a982e1b7e36 100644 --- a/org.springframework.context/src/test/java/org/springframework/ui/lifecycle/BindAndValidateLifecycleTests.java +++ b/org.springframework.context/src/test/java/org/springframework/ui/lifecycle/BindAndValidateLifecycleTests.java @@ -31,7 +31,7 @@ public class BindAndValidateLifecycleTests { model = new TestBean(); alertContext = new DefaultAlertContext(); Binder binder = new WebBinderFactory().getBinder(model); - lifecycle = new BindAndValidateLifecycle(binder, alertContext); + lifecycle = new BindAndValidateLifecycle(binder, null, alertContext); } @Test