Skip to content

Commit 7af799e

Browse files
marko-bekhtagsmet
authored andcommitted
HV-1526 Add different implementations of ValidationContext
- add implementations for bean, property/value, executable parameter and executable return value contexts - extract builder for validation contexts to its own class
1 parent c004195 commit 7af799e

17 files changed

+1320
-920
lines changed

engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java

Lines changed: 0 additions & 868 deletions
This file was deleted.

engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ public String toString() {
664664
}
665665
}
666666

667-
static class ValidatorFactoryScopedContext {
667+
public static class ValidatorFactoryScopedContext {
668668
/**
669669
* The default message interpolator for this factory.
670670
*/

engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java

Lines changed: 29 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.Iterator;
2121
import java.util.List;
2222
import java.util.Map;
23-
import java.util.Objects;
2423
import java.util.Optional;
2524
import java.util.Set;
2625

@@ -36,8 +35,6 @@
3635
import javax.validation.valueextraction.ValueExtractor;
3736

3837
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;
39-
import org.hibernate.validator.internal.engine.ValidationContext.ValidationContextBuilder;
40-
import org.hibernate.validator.internal.engine.ValidationContext.ValidatorScopedContext;
4138
import org.hibernate.validator.internal.engine.ValidatorFactoryImpl.ValidatorFactoryScopedContext;
4239
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
4340
import org.hibernate.validator.internal.engine.groups.Group;
@@ -48,6 +45,10 @@
4845
import org.hibernate.validator.internal.engine.path.NodeImpl;
4946
import org.hibernate.validator.internal.engine.path.PathImpl;
5047
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;
5152
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor;
5253
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorHelper;
5354
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
@@ -62,10 +63,6 @@
6263
import org.hibernate.validator.internal.metadata.core.MetaConstraint;
6364
import org.hibernate.validator.internal.metadata.facets.Cascadable;
6465
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;
6966
import org.hibernate.validator.internal.util.Contracts;
7067
import org.hibernate.validator.internal.util.ExecutableHelper;
7168
import 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
}

engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ComposingConstraintTree.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
import javax.validation.ConstraintValidator;
2323

2424
import org.hibernate.validator.constraints.CompositionType;
25-
import org.hibernate.validator.internal.engine.ValidationContext;
2625
import org.hibernate.validator.internal.engine.ValueContext;
26+
import org.hibernate.validator.internal.engine.validationcontext.ValidationContext;
2727
import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl;
2828
import org.hibernate.validator.internal.util.CollectionHelper;
2929
import org.hibernate.validator.internal.util.logging.Log;

engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintTree.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
import javax.validation.ConstraintValidator;
2121
import javax.validation.ValidationException;
2222

23-
import org.hibernate.validator.internal.engine.ValidationContext;
2423
import org.hibernate.validator.internal.engine.ValueContext;
24+
import org.hibernate.validator.internal.engine.validationcontext.ValidationContext;
2525
import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl;
2626
import org.hibernate.validator.internal.util.logging.Log;
2727
import org.hibernate.validator.internal.util.logging.LoggerFactory;

engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/SimpleConstraintTree.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
import javax.validation.ConstraintValidator;
1515

16-
import org.hibernate.validator.internal.engine.ValidationContext;
1716
import org.hibernate.validator.internal.engine.ValueContext;
17+
import org.hibernate.validator.internal.engine.validationcontext.ValidationContext;
1818
import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl;
1919
import org.hibernate.validator.internal.util.logging.Log;
2020
import org.hibernate.validator.internal.util.logging.LoggerFactory;

0 commit comments

Comments
 (0)