diff --git a/org.springframework.context/src/main/java/org/springframework/ui/validation/ValidationResults.java b/org.springframework.context/src/main/java/org/springframework/ui/validation/ValidationResults.java index 27aab1227e6..b5d41ab1c2a 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/validation/ValidationResults.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/validation/ValidationResults.java @@ -13,14 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.ui.validation; -/** - * TODO Document ValidateResults. - * @author Keith Donald - * @since 3.0 - */ -public interface ValidationResults { +public interface ValidationResults extends Iterable { } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/validation/Validator.java b/org.springframework.context/src/main/java/org/springframework/ui/validation/Validator.java index a4d7544d271..6496764fc70 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/validation/Validator.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/validation/Validator.java @@ -13,25 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.ui.validation; import java.util.List; -/** - * TODO Document Validator. - * @author Keith Donald - * @since 3.0 - */ -public interface Validator { - - /** - * TODO Document validate(). - * - * @param model - * @param properties - * @return - */ - ValidationResults validate(Object model, List properties); - +public interface Validator { + ValidationResults validate(M model, List properties); } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/Impact.java b/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/Impact.java new file mode 100644 index 00000000000..8d4b596c202 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/Impact.java @@ -0,0 +1,33 @@ +/* + * 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.validation.constraint; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.ui.alert.Severity; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Impact { + + Severity value(); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/Message.java b/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/Message.java new file mode 100644 index 00000000000..496c4a7a2da --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/Message.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.validation.constraint; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Message { + + String[] value(); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/ValidationConstraint.java b/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/ValidationConstraint.java new file mode 100644 index 00000000000..3e52c718e7b --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/validation/constraint/ValidationConstraint.java @@ -0,0 +1,20 @@ +/* + * 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.validation.constraint; + +public interface ValidationConstraint { + boolean validate(T value); +} \ 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 a982e1b7e36..7cc5ece5eca 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 @@ -3,13 +3,17 @@ package org.springframework.ui.lifecycle; import static org.junit.Assert.assertEquals; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import org.junit.Before; import org.junit.Test; +import org.springframework.ui.alert.Alert; +import org.springframework.ui.alert.Alerts; import org.springframework.ui.alert.Severity; import org.springframework.ui.alert.support.DefaultAlertContext; import org.springframework.ui.binding.Binder; @@ -17,6 +21,12 @@ import org.springframework.ui.binding.Bound; import org.springframework.ui.binding.Model; import org.springframework.ui.binding.support.WebBinderFactory; import org.springframework.ui.format.number.CurrencyFormat; +import org.springframework.ui.validation.ValidationResult; +import org.springframework.ui.validation.ValidationResults; +import org.springframework.ui.validation.Validator; +import org.springframework.ui.validation.constraint.Impact; +import org.springframework.ui.validation.constraint.Message; +import org.springframework.ui.validation.constraint.ValidationConstraint; public class BindAndValidateLifecycleTests { @@ -31,7 +41,112 @@ public class BindAndValidateLifecycleTests { model = new TestBean(); alertContext = new DefaultAlertContext(); Binder binder = new WebBinderFactory().getBinder(model); - lifecycle = new BindAndValidateLifecycle(binder, null, alertContext); + Validator validator = new TestBeanValidator(); + lifecycle = new BindAndValidateLifecycle(binder, validator, alertContext); + } + + static class TestBeanValidator implements Validator { + public ValidationResults validate(TestBean model, List properties) { + TestValidationResults results = new TestValidationResults(); + RequiredConstraint required = new RequiredConstraint(); + boolean valid = required.validate(model.getString()); + if (!valid) { + + } + return results; + } + } + + @Message({"en=#{label} is required", "es=#{label} es necesario"}) + static class RequiredConstraint implements ValidationConstraint { + public boolean validate(Object value) { + if (value != null) { + return value instanceof String ? ((String) value).length() > 0 : true; + } else { + return false; + } + } + } + + @Message("#{label} is a weak password") + @Impact(Severity.WARNING) + static class StrongPasswordConstraint implements ValidationConstraint { + public boolean validate(String password) { + if (password.length() > 6) { + return true; + } else { + return false; + } + } + } + + @Message("#{label} could not be confirmed; #{value} must match #{model.confirmPassword}") + static class ConfirmedPasswordConstraint implements ValidationConstraint { + public boolean validate(SignupForm form) { + if (form.password.equals(form.confirmPassword)) { + return true; + } else { + return false; + } + } + } + + @Message("#{label} must be between #{this.min} and #{this.max}") + static class RangeConstraint implements ValidationConstraint { + private Long min; + + private Long max; + + public RangeConstraint(Long min, Long max) { + this.min = min; + this.max = max; + } + + public boolean validate(Number value) { + Long longValue = value.longValue(); + if (longValue >= min && longValue <= max) { + return true; + } else { + return false; + } + } + } + + static class TestValidationResults implements ValidationResults { + private List results = new ArrayList(); + + public void add(ValidationResult result) { + results.add(result); + } + + public Iterator iterator() { + return results.iterator(); + } + + } + + static class TestValidationFailure implements ValidationResult { + + private String property; + + private String message; + + public TestValidationFailure(String property, String message) { + this.property = property; + } + + public String getProperty() { + return property; + } + + public Alert getAlert() { + return Alerts.error(message); + } + + public boolean isFailure() { + return true; + } + } @Test @@ -200,7 +315,12 @@ public class BindAndValidateLifecycleTests { public void setNotEditable(String notEditable) { this.notEditable = notEditable; } - - + + } + + public static class SignupForm { + private String username; + private String password; + private String confirmPassword; } }