more pruning
This commit is contained in:
parent
a74422ed65
commit
840ac88b29
|
|
@ -48,6 +48,9 @@ public interface BinderExecutor<M> {
|
|||
BindingResults bind();
|
||||
|
||||
// TODO return validation results
|
||||
/**
|
||||
* Execute the validate operation.
|
||||
*/
|
||||
void validate();
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
package org.springframework.ui.lifecycle;
|
||||
|
||||
public interface BindAndValidateLifecycle {
|
||||
|
||||
public void execute();
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package org.springframework.ui.lifecycle;
|
||||
|
||||
public interface BindAndValidateLifecycleFactory {
|
||||
BindAndValidateLifecycle getLifecycle(Object model);
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* 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 java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.ui.alert.AlertContext;
|
||||
import org.springframework.ui.binding.binder.Binder;
|
||||
import org.springframework.ui.binding.binder.BindingResult;
|
||||
import org.springframework.ui.binding.binder.BindingResults;
|
||||
import org.springframework.ui.validation.ValidationFailure;
|
||||
import org.springframework.ui.validation.Validator;
|
||||
|
||||
/**
|
||||
* Implementation of the model bind and validate lifecycle.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public final class BindAndValidateLifecycleImpl {
|
||||
|
||||
private Binder binder;
|
||||
|
||||
private Validator validator;
|
||||
|
||||
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 BindAndValidateLifecycleImpl(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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the bind and validate lifecycle.
|
||||
* Any bind or validation errors are recorded as alerts against the {@link AlertContext}.
|
||||
* @param sourceValues the source values to bind and validate
|
||||
*/
|
||||
public void execute(Map<String, ? extends Object> sourceValues) {
|
||||
BindingResults bindingResults = binder.bind(sourceValues);
|
||||
List<ValidationFailure> validationFailures = validate(bindingResults);
|
||||
for (BindingResult result : bindingResults.failures()) {
|
||||
alertContext.add(result.getProperty(), result.getAlert());
|
||||
}
|
||||
for (ValidationFailure failure : validationFailures) {
|
||||
alertContext.add(failure.getProperty(), failure.getAlert());
|
||||
}
|
||||
}
|
||||
|
||||
private List<ValidationFailure> validate(BindingResults bindingResults) {
|
||||
if (validator != null && validationDecider.shouldValidateAfter(bindingResults)) {
|
||||
return validator.validate(binder.getModel(), bindingResults.successes().properties());
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* 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.binder.BindingResults;
|
||||
|
||||
/**
|
||||
* Decides if validation should run for an execution of the bind and validate lifecycle.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see BindAndValidateLifecycleImpl#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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ui.validation.constraint;
|
||||
package org.springframework.ui.validation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ui.validation.constraint;
|
||||
package org.springframework.ui.validation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ui.validation.constraint;
|
||||
package org.springframework.ui.validation;
|
||||
|
||||
public interface ValidationConstraint<T> {
|
||||
boolean validate(T value);
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package org.springframework.ui.validation;
|
||||
|
||||
import org.springframework.ui.alert.Alert;
|
||||
|
||||
/**
|
||||
* A single validation failure generated by a Validator.
|
||||
* @author Keith Donald
|
||||
* @see Validator#validate(Object, java.util.List)
|
||||
*/
|
||||
public interface ValidationFailure {
|
||||
|
||||
/**
|
||||
* The name of the model property associated with this validation result.
|
||||
*/
|
||||
String getProperty();
|
||||
|
||||
/**
|
||||
* Gets the alert for this validation failure, appropriate for rendering the failure to the user.
|
||||
*/
|
||||
Alert getAlert();
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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.validation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Validates a model object.
|
||||
* @author Keith Donald
|
||||
* @param <M> the type of model object this validator supports
|
||||
*/
|
||||
public interface Validator {
|
||||
|
||||
/**
|
||||
* Validate the properties of the model object.
|
||||
* @param model the model object
|
||||
* @param properties the properties to validate
|
||||
* @return a list of validation failures, empty if there were no failures
|
||||
*/
|
||||
List<ValidationFailure> validate(Object model, List<String> properties);
|
||||
}
|
||||
|
|
@ -1,308 +0,0 @@
|
|||
package org.springframework.ui.lifecycle;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
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.WebBinder;
|
||||
import org.springframework.ui.binding.support.GenericBindingFactory;
|
||||
import org.springframework.ui.format.number.CurrencyFormat;
|
||||
import org.springframework.ui.validation.ValidationFailure;
|
||||
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;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
|
||||
public class BindAndValidateLifecycleTests {
|
||||
|
||||
private BindAndValidateLifecycleImpl lifecycle;
|
||||
|
||||
private TestBean model;
|
||||
|
||||
private DefaultAlertContext alertContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
model = new TestBean();
|
||||
alertContext = new DefaultAlertContext();
|
||||
WebBinder binder = new WebBinder(new GenericBindingFactory(model));
|
||||
Validator validator = new TestBeanValidator();
|
||||
lifecycle = new BindAndValidateLifecycleImpl(binder, validator, alertContext);
|
||||
}
|
||||
|
||||
static class TestBeanValidator implements Validator {
|
||||
public List<ValidationFailure> validate(Object model, List<String> properties) {
|
||||
TestBean bean = (TestBean) model;
|
||||
RequiredConstraint required = new RequiredConstraint();
|
||||
boolean valid = required.validate(bean);
|
||||
if (!valid) {
|
||||
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Message({"en=#{label} is required", "es=#{label} es necesario"})
|
||||
static class RequiredConstraint implements ValidationConstraint<Object> {
|
||||
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<String> {
|
||||
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<SignupForm> {
|
||||
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<Number> {
|
||||
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 TestValidationFailure implements ValidationFailure {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testExecuteLifecycleNoErrors() {
|
||||
Map<String, Object> userMap = new HashMap<String, Object>();
|
||||
userMap.put("string", "test");
|
||||
userMap.put("integer", "3");
|
||||
userMap.put("foo", "BAR");
|
||||
lifecycle.execute(userMap);
|
||||
assertEquals(0, alertContext.getAlerts().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testExecuteLifecycleBindingErrors() {
|
||||
Map<String, Object> userMap = new HashMap<String, Object>();
|
||||
userMap.put("string", "test");
|
||||
userMap.put("integer", "bogus");
|
||||
userMap.put("foo", "BAR");
|
||||
lifecycle.execute(userMap);
|
||||
assertEquals(1, alertContext.getAlerts().size());
|
||||
assertEquals(Severity.FATAL, alertContext.getAlerts("integer").get(0).getSeverity());
|
||||
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());
|
||||
}
|
||||
|
||||
public static enum FooEnum {
|
||||
BAR, BAZ, BOOP;
|
||||
}
|
||||
|
||||
public static class TestBean {
|
||||
private String string;
|
||||
private int integer;
|
||||
private Date date;
|
||||
private FooEnum foo;
|
||||
private BigDecimal currency;
|
||||
private List<FooEnum> foos;
|
||||
private List<Address> addresses;
|
||||
|
||||
public String getString() {
|
||||
return string;
|
||||
}
|
||||
|
||||
public void setString(String string) {
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public int getInteger() {
|
||||
return integer;
|
||||
}
|
||||
|
||||
public void setInteger(int integer) {
|
||||
this.integer = integer;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public FooEnum getFoo() {
|
||||
return foo;
|
||||
}
|
||||
|
||||
public void setFoo(FooEnum foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
@CurrencyFormat
|
||||
public BigDecimal getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public void setCurrency(BigDecimal currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public List<FooEnum> getFoos() {
|
||||
return foos;
|
||||
}
|
||||
|
||||
public void setFoos(List<FooEnum> foos) {
|
||||
this.foos = foos;
|
||||
}
|
||||
|
||||
public List<Address> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public void setAddresses(List<Address> addresses) {
|
||||
this.addresses = addresses;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Address {
|
||||
private String street;
|
||||
private String city;
|
||||
private String state;
|
||||
private String zip;
|
||||
private String country;
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getZip() {
|
||||
return zip;
|
||||
}
|
||||
|
||||
public void setZip(String zip) {
|
||||
this.zip = zip;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TestAnnotatedBean {
|
||||
|
||||
private String editable;
|
||||
|
||||
private String notEditable;
|
||||
|
||||
public String getEditable() {
|
||||
return editable;
|
||||
}
|
||||
|
||||
public void setEditable(String editable) {
|
||||
this.editable = editable;
|
||||
}
|
||||
|
||||
public String getNotEditable() {
|
||||
return notEditable;
|
||||
}
|
||||
|
||||
public void setNotEditable(String notEditable) {
|
||||
this.notEditable = notEditable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SignupForm {
|
||||
private String username;
|
||||
private String password;
|
||||
private String confirmPassword;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue