LocalValidatorFactoryBean properly supports unwrap at ValidatorFactory level
Also documents limitation for Bean Validation 2.0's getClockProvider() method. Issue: SPR-15561 Issue: SPR-13482
This commit is contained in:
		
							parent
							
								
									67881a5726
								
							
						
					
					
						commit
						cb3d1befcd
					
				|  | @ -30,6 +30,7 @@ import javax.validation.MessageInterpolator; | |||
| import javax.validation.ParameterNameProvider; | ||||
| import javax.validation.TraversableResolver; | ||||
| import javax.validation.Validation; | ||||
| import javax.validation.ValidationException; | ||||
| import javax.validation.ValidationProviderResolver; | ||||
| import javax.validation.Validator; | ||||
| import javax.validation.ValidatorContext; | ||||
|  | @ -64,8 +65,12 @@ import org.springframework.util.ReflectionUtils; | |||
|  * you will almost always use the default Validator anyway. This can also be injected directly | ||||
|  * into any target dependency of type {@link org.springframework.validation.Validator}! | ||||
|  * | ||||
|  * <p><b>As of Spring 5.0, this class requires Bean Validation 1.1, with special support | ||||
|  * <p><b>As of Spring 5.0, this class requires Bean Validation 1.1+, with special support | ||||
|  * for Hibernate Validator 5.x</b> (see {@link #setValidationMessageSource}). | ||||
|  * This class is also runtime-compatible with Bean Validation 2.0 and Hibernate Validator 6.0, | ||||
|  * with one special note: If you'd like to call BV 2.0's {@code getClockProvider()} method, | ||||
|  * obtain the native {@code ValidatorFactory} through {@code #unwrap(ValidatorFactory.class)} | ||||
|  * and call the {@code getClockProvider()} method on the returned native reference there. | ||||
|  * | ||||
|  * <p>This class is also being used by Spring's MVC configuration namespace, in case of the | ||||
|  * {@code javax.validation} API being present but no explicit Validator having been configured. | ||||
|  | @ -293,7 +298,6 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter | |||
| 	} | ||||
| 
 | ||||
| 	private void configureParameterNameProviderIfPossible(Configuration<?> configuration) { | ||||
| 		// TODO: inner class | ||||
| 		final ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer; | ||||
| 		final ParameterNameProvider defaultProvider = configuration.getDefaultParameterNameProvider(); | ||||
| 		configuration.parameterNameProvider(new ParameterNameProvider() { | ||||
|  | @ -359,6 +363,32 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter | |||
| 		return this.validatorFactory.getParameterNameProvider(); | ||||
| 	} | ||||
| 
 | ||||
| 	// Bean Validation 2.0: currently not implemented here since it would imply | ||||
| 	// a hard dependency on the new javax.validation.ClockProvider interface. | ||||
| 	// To be resolved once Spring Framework requires Bean Validation 2.0+. | ||||
| 	// Obtain the native ValidatorFactory through unwrap(ValidatorFactory.class) | ||||
| 	// instead which will fully support a getClockProvider() call as well. | ||||
| 	/* | ||||
| 	@Override | ||||
| 	public javax.validation.ClockProvider getClockProvider() { | ||||
| 		Assert.notNull(this.validatorFactory, "No target ValidatorFactory set"); | ||||
| 		return this.validatorFactory.getClockProvider(); | ||||
| 	} | ||||
| 	*/ | ||||
| 
 | ||||
| 	@Override | ||||
| 	public <T> T unwrap(Class<T> type) { | ||||
| 		if (type == null || !ValidatorFactory.class.isAssignableFrom(type)) { | ||||
| 			try { | ||||
| 				return super.unwrap(type); | ||||
| 			} | ||||
| 			catch (ValidationException ex) { | ||||
| 				// ignore - we'll try ValidatorFactory unwrapping next | ||||
| 			} | ||||
| 		} | ||||
| 		return this.validatorFactory.unwrap(type); | ||||
| 	} | ||||
| 
 | ||||
| 	public void close() { | ||||
| 		if (this.validatorFactory != null) { | ||||
| 			this.validatorFactory.close(); | ||||
|  |  | |||
|  | @ -40,13 +40,16 @@ import org.springframework.validation.ObjectError; | |||
| import org.springframework.validation.SmartValidator; | ||||
| 
 | ||||
| /** | ||||
|  * Adapter that takes a JSR-303 {@code javax.validator.Validator} | ||||
|  * and exposes it as a Spring {@link org.springframework.validation.Validator} | ||||
|  * Adapter that takes a JSR-303 {@code javax.validator.Validator} and | ||||
|  * exposes it as a Spring {@link org.springframework.validation.Validator} | ||||
|  * while also exposing the original JSR-303 Validator interface itself. | ||||
|  * | ||||
|  * <p>Can be used as a programmatic wrapper. Also serves as base class for | ||||
|  * {@link CustomValidatorBean} and {@link LocalValidatorFactoryBean}. | ||||
|  * | ||||
|  * <p>As of Spring Framework 5.0, this adapter is fully compatible with | ||||
|  * Bean Validation 1.1 as well as 2.0. | ||||
|  * | ||||
|  * @author Juergen Hoeller | ||||
|  * @since 3.0 | ||||
|  */ | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ import javax.validation.ConstraintValidator; | |||
| import javax.validation.ConstraintValidatorContext; | ||||
| import javax.validation.Payload; | ||||
| import javax.validation.Validation; | ||||
| import javax.validation.Validator; | ||||
| import javax.validation.constraints.Pattern; | ||||
| import javax.validation.constraints.Size; | ||||
| 
 | ||||
|  | @ -51,8 +52,9 @@ import static org.junit.Assert.*; | |||
|  */ | ||||
| public class SpringValidatorAdapterTests { | ||||
| 
 | ||||
| 	private final SpringValidatorAdapter validatorAdapter = new SpringValidatorAdapter( | ||||
| 			Validation.buildDefaultValidatorFactory().getValidator()); | ||||
| 	private final Validator nativeValidator = Validation.buildDefaultValidatorFactory().getValidator(); | ||||
| 
 | ||||
| 	private final SpringValidatorAdapter validatorAdapter = new SpringValidatorAdapter(nativeValidator); | ||||
| 
 | ||||
| 	private final StaticMessageSource messageSource = new StaticMessageSource(); | ||||
| 
 | ||||
|  | @ -66,6 +68,12 @@ public class SpringValidatorAdapterTests { | |||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void testUnwrap() { | ||||
| 		Validator nativeValidator = validatorAdapter.unwrap(Validator.class); | ||||
| 		assertSame(this.nativeValidator, nativeValidator); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test  // SPR-13406 | ||||
| 	public void testNoStringArgumentValue() { | ||||
| 		TestBean testBean = new TestBean(); | ||||
|  |  | |||
|  | @ -33,9 +33,12 @@ import javax.validation.ConstraintValidatorContext; | |||
| import javax.validation.ConstraintViolation; | ||||
| import javax.validation.Payload; | ||||
| import javax.validation.Valid; | ||||
| import javax.validation.Validator; | ||||
| import javax.validation.ValidatorFactory; | ||||
| import javax.validation.constraints.NotNull; | ||||
| 
 | ||||
| import org.hibernate.validator.HibernateValidator; | ||||
| import org.hibernate.validator.HibernateValidatorFactory; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
|  | @ -75,6 +78,12 @@ public class ValidatorFactoryTests { | |||
| 				fail("Invalid constraint violation with path '" + path + "'"); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		Validator nativeValidator = validator.unwrap(Validator.class); | ||||
| 		assertTrue(nativeValidator.getClass().getName().startsWith("org.hibernate")); | ||||
| 		assertTrue(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory); | ||||
| 		assertTrue(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory); | ||||
| 
 | ||||
| 		validator.destroy(); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -96,6 +105,12 @@ public class ValidatorFactoryTests { | |||
| 				fail("Invalid constraint violation with path '" + path + "'"); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		Validator nativeValidator = validator.unwrap(Validator.class); | ||||
| 		assertTrue(nativeValidator.getClass().getName().startsWith("org.hibernate")); | ||||
| 		assertTrue(validator.unwrap(ValidatorFactory.class) instanceof HibernateValidatorFactory); | ||||
| 		assertTrue(validator.unwrap(HibernateValidatorFactory.class) instanceof HibernateValidatorFactory); | ||||
| 
 | ||||
| 		validator.destroy(); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -465,7 +480,7 @@ public class ValidatorFactoryTests { | |||
| 
 | ||||
| 		String message() default "Should not be X"; | ||||
| 
 | ||||
| 		Class<?>[] groups() default { }; | ||||
| 		Class<?>[] groups() default {}; | ||||
| 
 | ||||
| 		Class<? extends Payload>[] payload() default {}; | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue