Browse Source

Support multiple Validators in DataBinder

DataBinder now allows registering additional Validator instances.
This may be useful when adding a Spring Validator to a globally
registered JSR-303 LocalValidatorFactoryBean.

Issue: SPR-9436
pull/215/head
Rossen Stoyanchev 13 years ago
parent
commit
54c873b4c4
  1. 74
      spring-context/src/main/java/org/springframework/validation/DataBinder.java

74
spring-context/src/main/java/org/springframework/validation/DataBinder.java

@ -18,7 +18,11 @@ package org.springframework.validation; @@ -18,7 +18,11 @@ package org.springframework.validation;
import java.beans.PropertyEditor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
@ -141,7 +145,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { @@ -141,7 +145,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
private BindingErrorProcessor bindingErrorProcessor = new DefaultBindingErrorProcessor();
private Validator validator;
private final List<Validator> validators = new ArrayList<Validator>();
private ConversionService conversionService;
@ -493,21 +497,58 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { @@ -493,21 +497,58 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
/**
* Set the Validator to apply after each binding step.
* @see #addValidators(Validator...)
* @see #replaceValidators(Validator...)
*/
public void setValidator(Validator validator) {
if (validator != null && (getTarget() != null && !validator.supports(getTarget().getClass()))) {
throw new IllegalStateException("Invalid target for Validator [" + validator + "]: " + getTarget());
assertValidators(validator);
this.validators.clear();
this.validators.add(validator);
}
private void assertValidators(Validator... validators) {
Assert.notNull(validators, "Validators required");
for (Validator validator : validators) {
if (validator != null && (getTarget() != null && !validator.supports(getTarget().getClass()))) {
throw new IllegalStateException("Invalid target for Validator [" + validator + "]: " + getTarget());
}
}
this.validator = validator;
}
/**
* Return the Validator to apply after each binding step, if any.
* Add Validators to apply after each binding step.
* @see #setValidator(Validator)
* @see #replaceValidators(Validator...)
*/
public void addValidators(Validator... validators) {
assertValidators(validators);
this.validators.addAll(Arrays.asList(validators));
}
/**
* Replace the Validators to apply after each binding step.
* @see #setValidator(Validator)
* @see #addValidators(Validator...)
*/
public void replaceValidators(Validator... validators) {
assertValidators(validators);
this.validators.clear();
this.validators.addAll(Arrays.asList(validators));
}
/**
* Return the primary Validator to apply after each binding step, if any.
*/
public Validator getValidator() {
return this.validator;
return this.validators.size() > 0 ? this.validators.get(0) : null;
}
/**
* Return the Validators to apply after data binding.
*/
public List<Validator> getValidators() {
return Collections.unmodifiableList(this.validators);
}
//---------------------------------------------------------------------
// Implementation of PropertyEditorRegistry/TypeConverter interface
@ -708,28 +749,31 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { @@ -708,28 +749,31 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
/**
* Invoke the specified Validator, if any.
* Invoke the specified Validators, if any.
* @see #setValidator(Validator)
* @see #getBindingResult()
*/
public void validate() {
this.validator.validate(getTarget(), getBindingResult());
for (Validator validator : this.validators) {
validator.validate(getTarget(), getBindingResult());
}
}
/**
* Invoke the specified Validator, if any, with the given validation hints.
* Invoke the specified Validators, if any, with the given validation hints.
* <p>Note: Validation hints may get ignored by the actual target Validator.
* @param validationHints one or more hint objects to be passed to a {@link SmartValidator}
* @see #setValidator(Validator)
* @see SmartValidator#validate(Object, Errors, Object...)
*/
public void validate(Object... validationHints) {
Validator validator = getValidator();
if (!ObjectUtils.isEmpty(validationHints) && validator instanceof SmartValidator) {
((SmartValidator) validator).validate(getTarget(), getBindingResult(), validationHints);
}
else if (validator != null) {
validator.validate(getTarget(), getBindingResult());
for (Validator validator : getValidators()) {
if (!ObjectUtils.isEmpty(validationHints) && validator instanceof SmartValidator) {
((SmartValidator) validator).validate(getTarget(), getBindingResult(), validationHints);
}
else if (validator != null) {
validator.validate(getTarget(), getBindingResult());
}
}
}

Loading…
Cancel
Save