Browse Source

Introduced OptionalValidatorFactoryBean for scenarios where the JSR-303 API is present but no Bean Validation Provider is available (used by the MVC namespace)

Issue: SPR-11272
pull/432/head
Juergen Hoeller 12 years ago
parent
commit
6a5a3c97ed
  1. 18
      spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java
  2. 47
      spring-context/src/main/java/org/springframework/validation/beanvalidation/OptionalValidatorFactoryBean.java
  3. 27
      spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java
  4. 2
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java

18
spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java

@ -45,6 +45,7 @@ import org.springframework.context.MessageSource; @@ -45,6 +45,7 @@ import org.springframework.context.MessageSource;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
@ -84,6 +85,7 @@ import org.springframework.util.ReflectionUtils; @@ -84,6 +85,7 @@ import org.springframework.util.ReflectionUtils;
public class LocalValidatorFactoryBean extends SpringValidatorAdapter
implements ValidatorFactory, ApplicationContextAware, InitializingBean, DisposableBean {
// Bean Validation 1.1 close() method available?
private static final Method closeMethod = ClassUtils.getMethodIfAvailable(ValidatorFactory.class, "close");
@ -214,10 +216,9 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter @@ -214,10 +216,9 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
@Override
@SuppressWarnings("unchecked")
public void afterPropertiesSet() {
@SuppressWarnings("rawtypes")
Configuration configuration = (this.providerClass != null ?
@SuppressWarnings({"rawtypes", "unchecked"})
Configuration<?> configuration = (this.providerClass != null ?
Validation.byProvider(this.providerClass).configure() :
Validation.byDefaultProvider().configure());
@ -240,7 +241,9 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter @@ -240,7 +241,9 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
configuration.constraintValidatorFactory(targetConstraintValidatorFactory);
}
configureParameterNameProviderIfPossible(configuration);
if (this.parameterNameDiscoverer != null) {
configureParameterNameProviderIfPossible(configuration);
}
if (this.mappingLocations != null) {
for (Resource location : this.mappingLocations) {
@ -329,31 +332,36 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter @@ -329,31 +332,36 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
@Override
public Validator getValidator() {
Assert.notNull(this.validatorFactory, "No target ValidatorFactory set");
return this.validatorFactory.getValidator();
}
@Override
public ValidatorContext usingContext() {
Assert.notNull(this.validatorFactory, "No target ValidatorFactory set");
return this.validatorFactory.usingContext();
}
@Override
public MessageInterpolator getMessageInterpolator() {
Assert.notNull(this.validatorFactory, "No target ValidatorFactory set");
return this.validatorFactory.getMessageInterpolator();
}
@Override
public TraversableResolver getTraversableResolver() {
Assert.notNull(this.validatorFactory, "No target ValidatorFactory set");
return this.validatorFactory.getTraversableResolver();
}
@Override
public ConstraintValidatorFactory getConstraintValidatorFactory() {
Assert.notNull(this.validatorFactory, "No target ValidatorFactory set");
return this.validatorFactory.getConstraintValidatorFactory();
}
public void close() {
if (closeMethod != null) {
if (closeMethod != null && this.validatorFactory != null) {
ReflectionUtils.invokeMethod(closeMethod, this.validatorFactory);
}
}

47
spring-context/src/main/java/org/springframework/validation/beanvalidation/OptionalValidatorFactoryBean.java

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
/*
* Copyright 2002-2013 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.validation.beanvalidation;
import javax.validation.ValidationException;
import org.apache.commons.logging.LogFactory;
/**
* {@link LocalValidatorFactoryBean} subclass that simply turns
* {@link org.springframework.validation.Validator} calls into no-ops
* in case of no Bean Validation provider being available.
*
* <p>This is the actual class used by Spring's MVC configuration namespace,
* in case of the {@code javax.validation} API being present but no explicit
* Validator having been configured.
*
* @author Juergen Hoeller
* @since 4.0.1
*/
public class OptionalValidatorFactoryBean extends LocalValidatorFactoryBean {
@Override
public void afterPropertiesSet() {
try {
super.afterPropertiesSet();
}
catch (ValidationException ex) {
LogFactory.getLog(getClass()).debug("Failed to set up a Bean Validation provider", ex);
}
}
}

27
spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java

@ -83,27 +83,31 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation. @@ -83,27 +83,31 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
@Override
public boolean supports(Class<?> clazz) {
return true;
return (this.targetValidator != null);
}
@Override
public void validate(Object target, Errors errors) {
processConstraintViolations(this.targetValidator.validate(target), errors);
if (this.targetValidator != null) {
processConstraintViolations(this.targetValidator.validate(target), errors);
}
}
@Override
@SuppressWarnings("rawtypes")
public void validate(Object target, Errors errors, Object... validationHints) {
Set<Class> groups = new LinkedHashSet<Class>();
if (validationHints != null) {
for (Object hint : validationHints) {
if (hint instanceof Class) {
groups.add((Class) hint);
if (this.targetValidator != null) {
Set<Class> groups = new LinkedHashSet<Class>();
if (validationHints != null) {
for (Object hint : validationHints) {
if (hint instanceof Class) {
groups.add((Class) hint);
}
}
}
processConstraintViolations(
this.targetValidator.validate(target, groups.toArray(new Class[groups.size()])), errors);
}
processConstraintViolations(
this.targetValidator.validate(target, groups.toArray(new Class[groups.size()])), errors);
}
/**
@ -200,11 +204,13 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation. @@ -200,11 +204,13 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
@Override
public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {
Assert.notNull(this.targetValidator, "No target Validator set");
return this.targetValidator.validate(object, groups);
}
@Override
public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) {
Assert.notNull(this.targetValidator, "No target Validator set");
return this.targetValidator.validateProperty(object, propertyName, groups);
}
@ -212,16 +218,19 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation. @@ -212,16 +218,19 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
public <T> Set<ConstraintViolation<T>> validateValue(
Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
Assert.notNull(this.targetValidator, "No target Validator set");
return this.targetValidator.validateValue(beanType, propertyName, value, groups);
}
@Override
public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
Assert.notNull(this.targetValidator, "No target Validator set");
return this.targetValidator.getConstraintsForClass(clazz);
}
@Override
public <T> T unwrap(Class<T> type) {
Assert.notNull(this.targetValidator, "No target Validator set");
return this.targetValidator.unwrap(type);
}

2
spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java

@ -304,7 +304,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { @@ -304,7 +304,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
}
else if (javaxValidationPresent) {
RootBeanDefinition validatorDef = new RootBeanDefinition(
"org.springframework.validation.beanvalidation.LocalValidatorFactoryBean");
"org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean");
validatorDef.setSource(source);
validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef);

Loading…
Cancel
Save