20
20
import java .util .Iterator ;
21
21
import java .util .List ;
22
22
import java .util .Map ;
23
- import java .util .Objects ;
24
23
import java .util .Optional ;
25
24
import java .util .Set ;
26
25
36
35
import javax .validation .valueextraction .ValueExtractor ;
37
36
38
37
import org .hibernate .validator .constraintvalidation .HibernateConstraintValidatorInitializationContext ;
39
- import org .hibernate .validator .internal .engine .ValidationContext .ValidationContextBuilder ;
40
- import org .hibernate .validator .internal .engine .ValidationContext .ValidatorScopedContext ;
41
38
import org .hibernate .validator .internal .engine .ValidatorFactoryImpl .ValidatorFactoryScopedContext ;
42
39
import org .hibernate .validator .internal .engine .constraintvalidation .ConstraintValidatorManager ;
43
40
import org .hibernate .validator .internal .engine .groups .Group ;
48
45
import org .hibernate .validator .internal .engine .path .NodeImpl ;
49
46
import org .hibernate .validator .internal .engine .path .PathImpl ;
50
47
import 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 ;
51
52
import org .hibernate .validator .internal .engine .valueextraction .ValueExtractorDescriptor ;
52
53
import org .hibernate .validator .internal .engine .valueextraction .ValueExtractorHelper ;
53
54
import org .hibernate .validator .internal .engine .valueextraction .ValueExtractorManager ;
62
63
import org .hibernate .validator .internal .metadata .core .MetaConstraint ;
63
64
import org .hibernate .validator .internal .metadata .facets .Cascadable ;
64
65
import 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 ;
69
66
import org .hibernate .validator .internal .util .Contracts ;
70
67
import org .hibernate .validator .internal .util .ExecutableHelper ;
71
68
import org .hibernate .validator .internal .util .ReflectionHelper ;
@@ -175,13 +172,13 @@ public final <T> Set<ConstraintViolation<T>> validateProperty(T object, String p
175
172
sanityCheckPropertyPath ( propertyName );
176
173
sanityCheckGroups ( groups );
177
174
178
- ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateProperty ( object );
175
+ PathImpl propertyPath = PathImpl .createPathFromString ( propertyName );
176
+ ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateProperty ( object , propertyPath );
179
177
180
178
if ( !validationContext .getRootBeanMetaData ().hasConstraints () ) {
181
179
return Collections .emptySet ();
182
180
}
183
181
184
- PathImpl propertyPath = PathImpl .createPathFromString ( propertyName );
185
182
ValueContext <?, Object > valueContext = getValueContextForPropertyValidation ( validationContext , propertyPath );
186
183
187
184
if ( valueContext .getCurrentBean () == null ) {
@@ -199,7 +196,8 @@ public final <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, St
199
196
sanityCheckPropertyPath ( propertyName );
200
197
sanityCheckGroups ( groups );
201
198
202
- ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateValue ( beanType );
199
+ PathImpl propertyPath = PathImpl .createPathFromString ( propertyName );
200
+ ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateValue ( beanType , propertyPath );
203
201
204
202
if ( !validationContext .getRootBeanMetaData ().hasConstraints () ) {
205
203
return Collections .emptySet ();
@@ -210,7 +208,7 @@ public final <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, St
210
208
return validateValueInContext (
211
209
validationContext ,
212
210
value ,
213
- PathImpl . createPathFromString ( propertyName ) ,
211
+ propertyPath ,
214
212
validationOrder
215
213
);
216
214
}
@@ -251,8 +249,7 @@ public <T> Set<ConstraintViolation<T>> validateReturnValue(T object, Method meth
251
249
private <T > Set <ConstraintViolation <T >> validateParameters (T object , Executable executable , Object [] parameterValues , Class <?>... groups ) {
252
250
sanityCheckGroups ( groups );
253
251
254
- ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateParameters (
255
- validatorScopedContext .getParameterNameProvider (),
252
+ ExecutableValidationContext <T > validationContext = getValidationContextBuilder ().forValidateParameters (
256
253
object ,
257
254
executable ,
258
255
parameterValues
@@ -272,7 +269,7 @@ private <T> Set<ConstraintViolation<T>> validateParameters(T object, Executable
272
269
private <T > Set <ConstraintViolation <T >> validateReturnValue (T object , Executable executable , Object returnValue , Class <?>... groups ) {
273
270
sanityCheckGroups ( groups );
274
271
275
- ValidationContext <T > validationContext = getValidationContextBuilder ().forValidateReturnValue (
272
+ ExecutableValidationContext <T > validationContext = getValidationContextBuilder ().forValidateReturnValue (
276
273
object ,
277
274
executable ,
278
275
returnValue
@@ -312,7 +309,7 @@ public ExecutableValidator forExecutables() {
312
309
}
313
310
314
311
private ValidationContextBuilder getValidationContextBuilder () {
315
- return ValidationContext . getValidationContextBuilder (
312
+ return new ValidationContextBuilder (
316
313
beanMetaDataManager ,
317
314
constraintValidatorManager ,
318
315
constraintValidatorFactory ,
@@ -352,10 +349,10 @@ private ValidationOrder determineGroupValidationOrder(Class<?>[] groups) {
352
349
353
350
/**
354
351
* Validates the given object using the available context information.
352
+ *
355
353
* @param validationContext the global validation context
356
354
* @param valueContext the current validation context
357
355
* @param validationOrder Contains the information which and in which order groups have to be executed
358
- *
359
356
* @param <T> The root bean type
360
357
*
361
358
* @return Set of constraint violations or the empty set if there were no violations.
@@ -765,7 +762,7 @@ private ValueContext<?, Object> buildNewLocalExecutionContext(ValueContext<?, ?>
765
762
766
763
private <T > Set <ConstraintViolation <T >> validateValueInContext (ValidationContext <T > validationContext , Object value , PathImpl propertyPath ,
767
764
ValidationOrder validationOrder ) {
768
- ValueContext <?, Object > valueContext = getValueContextForValueValidation ( validationContext , propertyPath );
765
+ ValueContext <?, Object > valueContext = getValueContextForValueValidation ( validationContext . getRootBeanClass () , propertyPath );
769
766
valueContext .setCurrentValidatedValue ( value );
770
767
771
768
BeanMetaData <?> beanMetaData = valueContext .getCurrentBeanMetaData ();
@@ -806,7 +803,7 @@ private <T> Set<ConstraintViolation<T>> validateValueInContext(ValidationContext
806
803
return validationContext .getFailingConstraints ();
807
804
}
808
805
809
- private <T > void validateParametersInContext (ValidationContext <T > validationContext ,
806
+ private <T > void validateParametersInContext (ExecutableValidationContext <T > validationContext ,
810
807
Object [] parameterValues ,
811
808
ValidationOrder validationOrder ) {
812
809
BeanMetaData <T > beanMetaData = validationContext .getRootBeanMetaData ();
@@ -894,7 +891,7 @@ private <T> void validateParametersInContext(ValidationContext<T> validationCont
894
891
}
895
892
}
896
893
897
- private <T > void validateParametersForGroup (ValidationContext <T > validationContext , ExecutableMetaData executableMetaData , Object [] parameterValues ,
894
+ private <T > void validateParametersForGroup (ExecutableValidationContext <T > validationContext , ExecutableMetaData executableMetaData , Object [] parameterValues ,
898
895
Group group ) {
899
896
Contracts .assertNotNull ( executableMetaData , "executableMetaData may not be null" );
900
897
@@ -931,7 +928,7 @@ private <T> void validateParametersForGroup(ValidationContext<T> validationConte
931
928
}
932
929
}
933
930
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 ) {
935
932
if ( !executableMetaData .getCrossParameterConstraints ().isEmpty () ) {
936
933
ValueContext <T , Object > valueContext = getExecutableValueContext (
937
934
validationContext .getRootBean (), executableMetaData , executableMetaData .getValidatableParametersMetaData (), currentValidatedGroup
@@ -1005,7 +1002,7 @@ private <T> ValueContext<T, Object> getExecutableValueContext(T object, Executab
1005
1002
return valueContext ;
1006
1003
}
1007
1004
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 ) {
1009
1006
BeanMetaData <T > beanMetaData = validationContext .getRootBeanMetaData ();
1010
1007
1011
1008
Optional <ExecutableMetaData > executableMetaDataOptional = validationContext .getExecutableMetaData ();
@@ -1141,8 +1138,9 @@ private <T> void validateReturnValueForSingleGroup(ValidationContext<T> validati
1141
1138
*
1142
1139
* @param validationContext The validation context.
1143
1140
* @param propertyPath The property path for which constraints have to be collected.
1141
+ *
1144
1142
* @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.
1146
1144
*/
1147
1145
private <V > ValueContext <?, V > getValueContextForPropertyValidation (ValidationContext <?> validationContext , PathImpl propertyPath ) {
1148
1146
Class <?> clazz = validationContext .getRootBeanClass ();
@@ -1204,7 +1202,6 @@ else if ( propertyPathNode.getKey() != null ) {
1204
1202
throw LOG .getInvalidPropertyPathException ( clazz , propertyPath .asString () );
1205
1203
}
1206
1204
1207
- validationContext .setValidatedProperty ( propertyMetaData .getName () );
1208
1205
propertyPath .removeLeafNode ();
1209
1206
1210
1207
return ValueContext .getLocalExecutionContext ( validatorScopedContext .getParameterNameProvider (), value , beanMetaData , propertyPath );
@@ -1216,14 +1213,14 @@ else if ( propertyPathNode.getKey() != null ) {
1216
1213
* We are only able to use the static types as we don't have the value.
1217
1214
* </p>
1218
1215
*
1219
- * @param validationContext The validation context .
1216
+ * @param rootBeanClass The class of the root bean .
1220
1217
* @param propertyPath The property path for which constraints have to be collected.
1221
1218
* @return Returns an instance of {@code ValueContext} which describes the local validation context associated to
1222
1219
* the given property path.
1223
1220
*/
1224
- private <V > ValueContext <?, V > getValueContextForValueValidation (ValidationContext <?> validationContext ,
1221
+ private <V > ValueContext <?, V > getValueContextForValueValidation (Class <?> rootBeanClass ,
1225
1222
PathImpl propertyPath ) {
1226
- Class <?> clazz = validationContext . getRootBeanClass () ;
1223
+ Class <?> clazz = rootBeanClass ;
1227
1224
BeanMetaData <?> beanMetaData = null ;
1228
1225
PropertyMetaData propertyMetaData = null ;
1229
1226
@@ -1257,7 +1254,6 @@ private <V> ValueContext<?, V> getValueContextForValueValidation(ValidationConte
1257
1254
throw LOG .getInvalidPropertyPathException ( clazz , propertyPath .asString () );
1258
1255
}
1259
1256
1260
- validationContext .setValidatedProperty ( propertyMetaData .getName () );
1261
1257
propertyPath .removeLeafNode ();
1262
1258
1263
1259
return ValueContext .getLocalExecutionContext ( validatorScopedContext .getParameterNameProvider (), clazz , beanMetaData , propertyPath );
@@ -1266,10 +1262,11 @@ private <V> ValueContext<?, V> getValueContextForValueValidation(ValidationConte
1266
1262
private boolean isValidationRequired (ValidationContext <?> validationContext ,
1267
1263
ValueContext <?, ?> valueContext ,
1268
1264
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 ;
1273
1270
}
1274
1271
if ( validationContext .hasMetaConstraintBeenProcessed (
1275
1272
valueContext .getCurrentBean (),
@@ -1366,7 +1363,7 @@ private boolean shouldFailFast(ValidationContext<?> validationContext) {
1366
1363
return validationContext .isFailFastModeEnabled () && !validationContext .getFailingConstraints ().isEmpty ();
1367
1364
}
1368
1365
1369
- private PropertyMetaData getBeanPropertyMetaData (BeanMetaData <?> beanMetaData , Path .Node propertyNode ) {
1366
+ private PropertyMetaData getBeanPropertyMetaData (BeanMetaData <?> beanMetaData , Path .Node propertyNode ) {
1370
1367
if ( !ElementKind .PROPERTY .equals ( propertyNode .getKind () ) ) {
1371
1368
throw LOG .getInvalidPropertyPathException ( beanMetaData .getBeanClass (), propertyNode .getName () );
1372
1369
}
@@ -1377,19 +1374,4 @@ private PropertyMetaData getBeanPropertyMetaData(BeanMetaData<?> beanMetaData, P
1377
1374
private Object getCascadableValue (ValidationContext <?> validationContext , Object object , Cascadable cascadable ) {
1378
1375
return cascadable .getValue ( object );
1379
1376
}
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
- }
1395
1377
}
0 commit comments