11/*
2- * Copyright 2002-2020 the original author or authors.
2+ * Copyright 2002-2022 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
3131import javax .validation .Constraint ;
3232import javax .validation .ConstraintValidator ;
3333import javax .validation .ConstraintValidatorContext ;
34+ import javax .validation .ConstraintValidatorFactory ;
3435import javax .validation .ConstraintViolation ;
3536import javax .validation .Payload ;
3637import javax .validation .Valid ;
4344import org .junit .jupiter .api .Test ;
4445
4546import org .springframework .beans .factory .annotation .Autowired ;
47+ import org .springframework .beans .factory .support .DefaultListableBeanFactory ;
4648import org .springframework .context .ConfigurableApplicationContext ;
4749import org .springframework .context .annotation .AnnotationConfigApplicationContext ;
4850import org .springframework .core .convert .support .DefaultConversionService ;
5254import org .springframework .validation .FieldError ;
5355import org .springframework .validation .ObjectError ;
5456import org .springframework .validation .beanvalidation .LocalValidatorFactoryBean ;
57+ import org .springframework .validation .beanvalidation .SpringConstraintValidatorFactory ;
5558
5659import static org .assertj .core .api .Assertions .assertThat ;
5760
5861/**
5962 * @author Juergen Hoeller
6063 */
61- @ SuppressWarnings ("resource" )
62- public class ValidatorFactoryTests {
64+ class ValidatorFactoryTests {
6365
6466 @ Test
65- @ SuppressWarnings ( "cast" )
66- public void testSimpleValidation () {
67+ void simpleValidation () {
68+ @ SuppressWarnings ( "resource" )
6769 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
6870 validator .afterPropertiesSet ();
6971
@@ -78,15 +80,15 @@ public void testSimpleValidation() {
7880
7981 Validator nativeValidator = validator .unwrap (Validator .class );
8082 assertThat (nativeValidator .getClass ().getName ().startsWith ("org.hibernate" )).isTrue ();
81- assertThat (validator .unwrap (ValidatorFactory .class ) instanceof HibernateValidatorFactory ). isTrue ( );
82- assertThat (validator .unwrap (HibernateValidatorFactory .class ) instanceof HibernateValidatorFactory ). isTrue ( );
83+ assertThat (validator .unwrap (ValidatorFactory .class )). isInstanceOf ( HibernateValidatorFactory . class );
84+ assertThat (validator .unwrap (HibernateValidatorFactory .class )). isInstanceOf ( HibernateValidatorFactory . class );
8385
8486 validator .destroy ();
8587 }
8688
8789 @ Test
88- @ SuppressWarnings ( "cast" )
89- public void testSimpleValidationWithCustomProvider () {
90+ void simpleValidationWithCustomProvider () {
91+ @ SuppressWarnings ( "resource" )
9092 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
9193 validator .setProviderClass (HibernateValidator .class );
9294 validator .afterPropertiesSet ();
@@ -102,14 +104,15 @@ public void testSimpleValidationWithCustomProvider() {
102104
103105 Validator nativeValidator = validator .unwrap (Validator .class );
104106 assertThat (nativeValidator .getClass ().getName ().startsWith ("org.hibernate" )).isTrue ();
105- assertThat (validator .unwrap (ValidatorFactory .class ) instanceof HibernateValidatorFactory ). isTrue ( );
106- assertThat (validator .unwrap (HibernateValidatorFactory .class ) instanceof HibernateValidatorFactory ). isTrue ( );
107+ assertThat (validator .unwrap (ValidatorFactory .class )). isInstanceOf ( HibernateValidatorFactory . class );
108+ assertThat (validator .unwrap (HibernateValidatorFactory .class )). isInstanceOf ( HibernateValidatorFactory . class );
107109
108110 validator .destroy ();
109111 }
110112
111113 @ Test
112- public void testSimpleValidationWithClassLevel () {
114+ void simpleValidationWithClassLevel () {
115+ @ SuppressWarnings ("resource" )
113116 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
114117 validator .afterPropertiesSet ();
115118
@@ -122,10 +125,13 @@ public void testSimpleValidationWithClassLevel() {
122125 ConstraintViolation <?> cv = iterator .next ();
123126 assertThat (cv .getPropertyPath ().toString ()).isEqualTo ("" );
124127 assertThat (cv .getConstraintDescriptor ().getAnnotation () instanceof NameAddressValid ).isTrue ();
128+
129+ validator .destroy ();
125130 }
126131
127132 @ Test
128- public void testSpringValidationFieldType () {
133+ void springValidationFieldType () {
134+ @ SuppressWarnings ("resource" )
129135 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
130136 validator .afterPropertiesSet ();
131137
@@ -135,11 +141,16 @@ public void testSpringValidationFieldType() {
135141 BeanPropertyBindingResult errors = new BeanPropertyBindingResult (person , "person" );
136142 validator .validate (person , errors );
137143 assertThat (errors .getErrorCount ()).isEqualTo (1 );
138- assertThat (errors .getFieldError ("address" ).getRejectedValue ()).isInstanceOf (ValidAddress .class );
144+ assertThat (errors .getFieldError ("address" ).getRejectedValue ())
145+ .as ("Field/Value type mismatch" )
146+ .isInstanceOf (ValidAddress .class );
147+
148+ validator .destroy ();
139149 }
140150
141151 @ Test
142- public void testSpringValidation () {
152+ void springValidation () {
153+ @ SuppressWarnings ("resource" )
143154 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
144155 validator .afterPropertiesSet ();
145156
@@ -164,10 +175,13 @@ public void testSpringValidation() {
164175 assertThat (errorCodes .contains ("NotNull.street" )).isTrue ();
165176 assertThat (errorCodes .contains ("NotNull.java.lang.String" )).isTrue ();
166177 assertThat (errorCodes .contains ("NotNull" )).isTrue ();
178+
179+ validator .destroy ();
167180 }
168181
169182 @ Test
170- public void testSpringValidationWithClassLevel () {
183+ void springValidationWithClassLevel () {
184+ @ SuppressWarnings ("resource" )
171185 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
172186 validator .afterPropertiesSet ();
173187
@@ -182,10 +196,12 @@ public void testSpringValidationWithClassLevel() {
182196 assertThat (errorCodes .size ()).isEqualTo (2 );
183197 assertThat (errorCodes .contains ("NameAddressValid.person" )).isTrue ();
184198 assertThat (errorCodes .contains ("NameAddressValid" )).isTrue ();
199+
200+ validator .destroy ();
185201 }
186202
187203 @ Test
188- public void testSpringValidationWithAutowiredValidator () {
204+ void springValidationWithAutowiredValidator () {
189205 ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext (
190206 LocalValidatorFactoryBean .class );
191207 LocalValidatorFactoryBean validator = ctx .getBean (LocalValidatorFactoryBean .class );
@@ -202,11 +218,14 @@ public void testSpringValidationWithAutowiredValidator() {
202218 assertThat (errorCodes .size ()).isEqualTo (2 );
203219 assertThat (errorCodes .contains ("NameAddressValid.person" )).isTrue ();
204220 assertThat (errorCodes .contains ("NameAddressValid" )).isTrue ();
221+
222+ validator .destroy ();
205223 ctx .close ();
206224 }
207225
208226 @ Test
209- public void testSpringValidationWithErrorInListElement () {
227+ void springValidationWithErrorInListElement () {
228+ @ SuppressWarnings ("resource" )
210229 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
211230 validator .afterPropertiesSet ();
212231
@@ -221,10 +240,13 @@ public void testSpringValidationWithErrorInListElement() {
221240 assertThat (fieldError .getField ()).isEqualTo ("address.street" );
222241 fieldError = result .getFieldError ("addressList[0].street" );
223242 assertThat (fieldError .getField ()).isEqualTo ("addressList[0].street" );
243+
244+ validator .destroy ();
224245 }
225246
226247 @ Test
227- public void testSpringValidationWithErrorInSetElement () {
248+ void springValidationWithErrorInSetElement () {
249+ @ SuppressWarnings ("resource" )
228250 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
229251 validator .afterPropertiesSet ();
230252
@@ -239,10 +261,13 @@ public void testSpringValidationWithErrorInSetElement() {
239261 assertThat (fieldError .getField ()).isEqualTo ("address.street" );
240262 fieldError = result .getFieldError ("addressSet[].street" );
241263 assertThat (fieldError .getField ()).isEqualTo ("addressSet[].street" );
264+
265+ validator .destroy ();
242266 }
243267
244268 @ Test
245- public void testInnerBeanValidation () {
269+ void innerBeanValidation () {
270+ @ SuppressWarnings ("resource" )
246271 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
247272 validator .afterPropertiesSet ();
248273
@@ -251,10 +276,13 @@ public void testInnerBeanValidation() {
251276 validator .validate (mainBean , errors );
252277 Object rejected = errors .getFieldValue ("inner.value" );
253278 assertThat (rejected ).isNull ();
279+
280+ validator .destroy ();
254281 }
255282
256283 @ Test
257- public void testValidationWithOptionalField () {
284+ void validationWithOptionalField () {
285+ @ SuppressWarnings ("resource" )
258286 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
259287 validator .afterPropertiesSet ();
260288
@@ -263,10 +291,13 @@ public void testValidationWithOptionalField() {
263291 validator .validate (mainBean , errors );
264292 Object rejected = errors .getFieldValue ("inner.value" );
265293 assertThat (rejected ).isNull ();
294+
295+ validator .destroy ();
266296 }
267297
268298 @ Test
269- public void testListValidation () {
299+ void listValidation () {
300+ @ SuppressWarnings ("resource" )
270301 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
271302 validator .afterPropertiesSet ();
272303
@@ -282,6 +313,34 @@ public void testListValidation() {
282313 assertThat (fieldError ).isNotNull ();
283314 assertThat (fieldError .getRejectedValue ()).isEqualTo ("X" );
284315 assertThat (errors .getFieldValue ("list[1]" )).isEqualTo ("X" );
316+
317+ validator .destroy ();
318+ }
319+
320+ @ Test
321+ void withConstraintValidatorFactory () {
322+ ConstraintValidatorFactory cvf = new SpringConstraintValidatorFactory (new DefaultListableBeanFactory ());
323+
324+ @ SuppressWarnings ("resource" )
325+ LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
326+ validator .setConstraintValidatorFactory (cvf );
327+ validator .afterPropertiesSet ();
328+
329+ assertThat (validator .getConstraintValidatorFactory ()).isSameAs (cvf );
330+ validator .destroy ();
331+ }
332+
333+ @ Test
334+ void withCustomInitializer () {
335+ ConstraintValidatorFactory cvf = new SpringConstraintValidatorFactory (new DefaultListableBeanFactory ());
336+
337+ @ SuppressWarnings ("resource" )
338+ LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
339+ validator .setConfigurationInitializer (configuration -> configuration .constraintValidatorFactory (cvf ));
340+ validator .afterPropertiesSet ();
341+
342+ assertThat (validator .getConstraintValidatorFactory ()).isSameAs (cvf );
343+ validator .destroy ();
285344 }
286345
287346
@@ -380,8 +439,8 @@ public boolean isValid(ValidPerson value, ConstraintValidatorContext context) {
380439 }
381440 boolean valid = (value .name == null || !value .address .street .contains (value .name ));
382441 if (!valid && "Phil" .equals (value .name )) {
383- context .buildConstraintViolationWithTemplate (
384- context . getDefaultConstraintMessageTemplate ()) .addPropertyNode ("address" ).addConstraintViolation ().disableDefaultConstraintViolation ();
442+ context .buildConstraintViolationWithTemplate (context . getDefaultConstraintMessageTemplate ())
443+ .addPropertyNode ("address" ).addConstraintViolation ().disableDefaultConstraintViolation ();
385444 }
386445 return valid ;
387446 }
@@ -417,6 +476,7 @@ public static class InnerBean {
417476 public String getValue () {
418477 return value ;
419478 }
479+
420480 public void setValue (String value ) {
421481 this .value = value ;
422482 }
@@ -425,8 +485,8 @@ public void setValue(String value) {
425485
426486 @ Retention (RetentionPolicy .RUNTIME )
427487 @ Target (ElementType .FIELD )
428- @ Constraint (validatedBy = InnerValidator .class )
429- public static @interface InnerValid {
488+ @ Constraint (validatedBy = InnerValidator .class )
489+ public @interface InnerValid {
430490
431491 String message () default "NOT VALID" ;
432492
@@ -446,7 +506,8 @@ public void initialize(InnerValid constraintAnnotation) {
446506 public boolean isValid (InnerBean bean , ConstraintValidatorContext context ) {
447507 context .disableDefaultConstraintViolation ();
448508 if (bean .getValue () == null ) {
449- context .buildConstraintViolationWithTemplate ("NULL" ).addPropertyNode ("value" ).addConstraintViolation ();
509+ context .buildConstraintViolationWithTemplate ("NULL" )
510+ .addPropertyNode ("value" ).addConstraintViolation ();
450511 return false ;
451512 }
452513 return true ;
@@ -494,7 +555,8 @@ public boolean isValid(List<String> list, ConstraintValidatorContext context) {
494555 boolean valid = true ;
495556 for (int i = 0 ; i < list .size (); i ++) {
496557 if ("X" .equals (list .get (i ))) {
497- context .buildConstraintViolationWithTemplate (context .getDefaultConstraintMessageTemplate ()).addBeanNode ().inIterable ().atIndex (i ).addConstraintViolation ();
558+ context .buildConstraintViolationWithTemplate (context .getDefaultConstraintMessageTemplate ())
559+ .addBeanNode ().inIterable ().atIndex (i ).addConstraintViolation ();
498560 valid = false ;
499561 }
500562 }
0 commit comments