2020import java .util .Iterator ;
2121import java .util .List ;
2222import java .util .Map ;
23- import java .util .Objects ;
2423import java .util .Optional ;
2524import java .util .Set ;
2625
3635import javax .validation .valueextraction .ValueExtractor ;
3736
3837import org .hibernate .validator .constraintvalidation .HibernateConstraintValidatorInitializationContext ;
39- import org .hibernate .validator .internal .engine .ValidationContext .ValidationContextBuilder ;
40- import org .hibernate .validator .internal .engine .ValidationContext .ValidatorScopedContext ;
4138import org .hibernate .validator .internal .engine .ValidatorFactoryImpl .ValidatorFactoryScopedContext ;
4239import org .hibernate .validator .internal .engine .constraintvalidation .ConstraintValidatorManager ;
4340import org .hibernate .validator .internal .engine .groups .Group ;
4845import org .hibernate .validator .internal .engine .path .NodeImpl ;
4946import org .hibernate .validator .internal .engine .path .PathImpl ;
5047import org .hibernate .validator .internal .engine .resolver .TraversableResolvers ;
48+ import org .hibernate .validator .internal .engine .validationcontext .ExecutableValidationContext ;
49+ import org .hibernate .validator .internal .engine .validationcontext .ValidationContext ;
50+ import org .hibernate .validator .internal .engine .validationcontext .ValidationContextBuilder ;
51+ import org .hibernate .validator .internal .engine .validationcontext .ValidatorScopedContext ;
5152import org .hibernate .validator .internal .engine .valueextraction .ValueExtractorDescriptor ;
5253import org .hibernate .validator .internal .engine .valueextraction .ValueExtractorHelper ;
5354import org .hibernate .validator .internal .engine .valueextraction .ValueExtractorManager ;
6263import org .hibernate .validator .internal .metadata .core .MetaConstraint ;
6364import org .hibernate .validator .internal .metadata .facets .Cascadable ;
6465import org .hibernate .validator .internal .metadata .facets .Validatable ;
65- import org .hibernate .validator .internal .metadata .location .ConstraintLocation ;
66- import org .hibernate .validator .internal .metadata .location .FieldConstraintLocation ;
67- import org .hibernate .validator .internal .metadata .location .GetterConstraintLocation ;
68- import org .hibernate .validator .internal .metadata .location .TypeArgumentConstraintLocation ;
6966import org .hibernate .validator .internal .util .Contracts ;
7067import org .hibernate .validator .internal .util .ExecutableHelper ;
7168import org .hibernate .validator .internal .util .ReflectionHelper ;
@@ -175,13 +172,13 @@ public final <T> Set<ConstraintViolation<T>> validateProperty(T object, String p
175172 sanityCheckPropertyPath ( propertyName );
176173 sanityCheckGroups ( groups );
177174
178- ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateProperty ( object );
175+ PathImpl propertyPath = PathImpl .createPathFromString ( propertyName );
176+ ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateProperty ( object , propertyPath );
179177
180178 if ( !validationContext .getRootBeanMetaData ().hasConstraints () ) {
181179 return Collections .emptySet ();
182180 }
183181
184- PathImpl propertyPath = PathImpl .createPathFromString ( propertyName );
185182 ValueContext <?, Object > valueContext = getValueContextForPropertyValidation ( validationContext , propertyPath );
186183
187184 if ( valueContext .getCurrentBean () == null ) {
@@ -199,7 +196,8 @@ public final <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, St
199196 sanityCheckPropertyPath ( propertyName );
200197 sanityCheckGroups ( groups );
201198
202- ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateValue ( beanType );
199+ PathImpl propertyPath = PathImpl .createPathFromString ( propertyName );
200+ ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateValue ( beanType , propertyPath );
203201
204202 if ( !validationContext .getRootBeanMetaData ().hasConstraints () ) {
205203 return Collections .emptySet ();
@@ -210,7 +208,7 @@ public final <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, St
210208 return validateValueInContext (
211209 validationContext ,
212210 value ,
213- PathImpl . createPathFromString ( propertyName ) ,
211+ propertyPath ,
214212 validationOrder
215213 );
216214 }
@@ -251,8 +249,7 @@ public <T> Set<ConstraintViolation<T>> validateReturnValue(T object, Method meth
251249 private <T > Set <ConstraintViolation <T >> validateParameters (T object , Executable executable , Object [] parameterValues , Class <?>... groups ) {
252250 sanityCheckGroups ( groups );
253251
254- ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateParameters (
255- validatorScopedContext .getParameterNameProvider (),
252+ ExecutableValidationContext <T > validationContext = getValidationContextBuilder ().forValidateParameters (
256253 object ,
257254 executable ,
258255 parameterValues
@@ -272,7 +269,7 @@ private <T> Set<ConstraintViolation<T>> validateParameters(T object, Executable
272269 private <T > Set <ConstraintViolation <T >> validateReturnValue (T object , Executable executable , Object returnValue , Class <?>... groups ) {
273270 sanityCheckGroups ( groups );
274271
275- ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateReturnValue (
272+ ExecutableValidationContext <T > validationContext = getValidationContextBuilder ().forValidateReturnValue (
276273 object ,
277274 executable ,
278275 returnValue
@@ -312,7 +309,7 @@ public ExecutableValidator forExecutables() {
312309 }
313310
314311 private ValidationContextBuilder getValidationContextBuilder () {
315- return ValidationContext . getValidationContextBuilder (
312+ return new ValidationContextBuilder (
316313 beanMetaDataManager ,
317314 constraintValidatorManager ,
318315 constraintValidatorFactory ,
@@ -352,10 +349,10 @@ private ValidationOrder determineGroupValidationOrder(Class<?>[] groups) {
352349
353350 /**
354351 * Validates the given object using the available context information.
352+ *
355353 * @param validationContext the global validation context
356354 * @param valueContext the current validation context
357355 * @param validationOrder Contains the information which and in which order groups have to be executed
358- *
359356 * @param <T> The root bean type
360357 *
361358 * @return Set of constraint violations or the empty set if there were no violations.
@@ -765,7 +762,7 @@ private ValueContext<?, Object> buildNewLocalExecutionContext(ValueContext<?, ?>
765762
766763 private <T > Set <ConstraintViolation <T >> validateValueInContext (ValidationContext <T > validationContext , Object value , PathImpl propertyPath ,
767764 ValidationOrder validationOrder ) {
768- ValueContext <?, Object > valueContext = getValueContextForValueValidation ( validationContext , propertyPath );
765+ ValueContext <?, Object > valueContext = getValueContextForValueValidation ( validationContext . getRootBeanClass () , propertyPath );
769766 valueContext .setCurrentValidatedValue ( value );
770767
771768 BeanMetaData <?> beanMetaData = valueContext .getCurrentBeanMetaData ();
@@ -806,7 +803,7 @@ private <T> Set<ConstraintViolation<T>> validateValueInContext(ValidationContext
806803 return validationContext .getFailingConstraints ();
807804 }
808805
809- private <T > void validateParametersInContext (ValidationContext <T > validationContext ,
806+ private <T > void validateParametersInContext (ExecutableValidationContext <T > validationContext ,
810807 Object [] parameterValues ,
811808 ValidationOrder validationOrder ) {
812809 BeanMetaData <T > beanMetaData = validationContext .getRootBeanMetaData ();
@@ -894,7 +891,7 @@ private <T> void validateParametersInContext(ValidationContext<T> validationCont
894891 }
895892 }
896893
897- private <T > void validateParametersForGroup (ValidationContext <T > validationContext , ExecutableMetaData executableMetaData , Object [] parameterValues ,
894+ private <T > void validateParametersForGroup (ExecutableValidationContext <T > validationContext , ExecutableMetaData executableMetaData , Object [] parameterValues ,
898895 Group group ) {
899896 Contracts .assertNotNull ( executableMetaData , "executableMetaData may not be null" );
900897
@@ -931,7 +928,7 @@ private <T> void validateParametersForGroup(ValidationContext<T> validationConte
931928 }
932929 }
933930
934- private <T > void validateParametersForSingleGroup (ValidationContext <T > validationContext , Object [] parameterValues , ExecutableMetaData executableMetaData , Class <?> currentValidatedGroup ) {
931+ private <T > void validateParametersForSingleGroup (ExecutableValidationContext <T > validationContext , Object [] parameterValues , ExecutableMetaData executableMetaData , Class <?> currentValidatedGroup ) {
935932 if ( !executableMetaData .getCrossParameterConstraints ().isEmpty () ) {
936933 ValueContext <T , Object > valueContext = getExecutableValueContext (
937934 validationContext .getRootBean (), executableMetaData , executableMetaData .getValidatableParametersMetaData (), currentValidatedGroup
@@ -1005,7 +1002,7 @@ private <T> ValueContext<T, Object> getExecutableValueContext(T object, Executab
10051002 return valueContext ;
10061003 }
10071004
1008- private <V , T > void validateReturnValueInContext (ValidationContext <T > validationContext , T bean , V value , ValidationOrder validationOrder ) {
1005+ private <V , T > void validateReturnValueInContext (ExecutableValidationContext <T > validationContext , T bean , V value , ValidationOrder validationOrder ) {
10091006 BeanMetaData <T > beanMetaData = validationContext .getRootBeanMetaData ();
10101007
10111008 Optional <ExecutableMetaData > executableMetaDataOptional = validationContext .getExecutableMetaData ();
@@ -1141,8 +1138,9 @@ private <T> void validateReturnValueForSingleGroup(ValidationContext<T> validati
11411138 *
11421139 * @param validationContext The validation context.
11431140 * @param propertyPath The property path for which constraints have to be collected.
1141+ *
11441142 * @return Returns an instance of {@code ValueContext} which describes the local validation context associated to
1145- * the given property path.
1143+ * the given property path.
11461144 */
11471145 private <V > ValueContext <?, V > getValueContextForPropertyValidation (ValidationContext <?> validationContext , PathImpl propertyPath ) {
11481146 Class <?> clazz = validationContext .getRootBeanClass ();
@@ -1204,7 +1202,6 @@ else if ( propertyPathNode.getKey() != null ) {
12041202 throw LOG .getInvalidPropertyPathException ( clazz , propertyPath .asString () );
12051203 }
12061204
1207- validationContext .setValidatedProperty ( propertyMetaData .getName () );
12081205 propertyPath .removeLeafNode ();
12091206
12101207 return ValueContext .getLocalExecutionContext ( validatorScopedContext .getParameterNameProvider (), value , beanMetaData , propertyPath );
@@ -1216,14 +1213,14 @@ else if ( propertyPathNode.getKey() != null ) {
12161213 * We are only able to use the static types as we don't have the value.
12171214 * </p>
12181215 *
1219- * @param validationContext The validation context .
1216+ * @param rootBeanClass The class of the root bean .
12201217 * @param propertyPath The property path for which constraints have to be collected.
12211218 * @return Returns an instance of {@code ValueContext} which describes the local validation context associated to
12221219 * the given property path.
12231220 */
1224- private <V > ValueContext <?, V > getValueContextForValueValidation (ValidationContext <?> validationContext ,
1221+ private <V > ValueContext <?, V > getValueContextForValueValidation (Class <?> rootBeanClass ,
12251222 PathImpl propertyPath ) {
1226- Class <?> clazz = validationContext . getRootBeanClass () ;
1223+ Class <?> clazz = rootBeanClass ;
12271224 BeanMetaData <?> beanMetaData = null ;
12281225 PropertyMetaData propertyMetaData = null ;
12291226
@@ -1257,7 +1254,6 @@ private <V> ValueContext<?, V> getValueContextForValueValidation(ValidationConte
12571254 throw LOG .getInvalidPropertyPathException ( clazz , propertyPath .asString () );
12581255 }
12591256
1260- validationContext .setValidatedProperty ( propertyMetaData .getName () );
12611257 propertyPath .removeLeafNode ();
12621258
12631259 return ValueContext .getLocalExecutionContext ( validatorScopedContext .getParameterNameProvider (), clazz , beanMetaData , propertyPath );
@@ -1266,10 +1262,11 @@ private <V> ValueContext<?, V> getValueContextForValueValidation(ValidationConte
12661262 private boolean isValidationRequired (ValidationContext <?> validationContext ,
12671263 ValueContext <?, ?> valueContext ,
12681264 MetaConstraint <?> metaConstraint ) {
1269- // validateProperty()/validateValue() call, but this constraint is for another property
1270- if ( validationContext .getValidatedProperty () != null &&
1271- !Objects .equals ( validationContext .getValidatedProperty (), getPropertyName ( metaConstraint .getLocation () ) ) ) {
1272- return false ;
1265+ // check if this validation context is qualified to validate the current meta constraint.
1266+ // For instance, in the case of validateProperty()/validateValue(), the current meta constraint
1267+ // could be for another property and, in this case, we don't validate it.
1268+ if ( !validationContext .appliesTo ( metaConstraint ) ) {
1269+ return false ;
12731270 }
12741271 if ( validationContext .hasMetaConstraintBeenProcessed (
12751272 valueContext .getCurrentBean (),
@@ -1366,7 +1363,7 @@ private boolean shouldFailFast(ValidationContext<?> validationContext) {
13661363 return validationContext .isFailFastModeEnabled () && !validationContext .getFailingConstraints ().isEmpty ();
13671364 }
13681365
1369- private PropertyMetaData getBeanPropertyMetaData (BeanMetaData <?> beanMetaData , Path .Node propertyNode ) {
1366+ private PropertyMetaData getBeanPropertyMetaData (BeanMetaData <?> beanMetaData , Path .Node propertyNode ) {
13701367 if ( !ElementKind .PROPERTY .equals ( propertyNode .getKind () ) ) {
13711368 throw LOG .getInvalidPropertyPathException ( beanMetaData .getBeanClass (), propertyNode .getName () );
13721369 }
@@ -1377,19 +1374,4 @@ private PropertyMetaData getBeanPropertyMetaData(BeanMetaData<?> beanMetaData, P
13771374 private Object getCascadableValue (ValidationContext <?> validationContext , Object object , Cascadable cascadable ) {
13781375 return cascadable .getValue ( object );
13791376 }
1380-
1381- private String getPropertyName (ConstraintLocation location ) {
1382- if ( location instanceof TypeArgumentConstraintLocation ) {
1383- location = ( (TypeArgumentConstraintLocation ) location ).getOuterDelegate ();
1384- }
1385-
1386- if ( location instanceof FieldConstraintLocation ) {
1387- return ( (FieldConstraintLocation ) location ).getPropertyName ();
1388- }
1389- else if ( location instanceof GetterConstraintLocation ) {
1390- return ( (GetterConstraintLocation ) location ).getPropertyName ();
1391- }
1392-
1393- return null ;
1394- }
13951377}
0 commit comments