javax.validation.TraversableResolver
as passed to the constructor of this instance.
Never use it directly, always use getCachingTraversableResolver()
to retrieved the single threaded caching wrapper.
publicValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, MessageInterpolator messageInterpolator, TraversableResolver traversableResolver, BeanMetaDataManager beanMetaDataManager, boolean failFast) {
ValidationContext<T, ConstraintViolation<T>> validationContext = ValidationContext.getContextForValidate(
ValueContext<?, T> valueContext = ValueContext.getLocalExecutionContext( object, PathImpl.createRootPath() );
public final <T> Set<ConstraintViolation<T>>validateProperty(T object, String propertyName, Class<?>... groups) {
ValidationContext<T, ConstraintViolation<T>> context = ValidationContext.getContextForValidateProperty(
return validatePropertyInContext( context, PathImpl.createPathFromString( propertyName ), validationOrder );
public final <T> Set<ConstraintViolation<T>>validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
ValidationContext<T, ConstraintViolation<T>> context = ValidationContext.getContextForValidateValue(
return validateValueInContext( context, value, PathImpl.createPathFromString( propertyName ), validationOrder );
public final <T> Set<MethodConstraintViolation<T>>validateParameter(T object, Method method, Object parameterValue, int parameterIndex, Class<?>... groups) {
public final <T> Set<MethodConstraintViolation<T>>validateAllParameters(T object, Method method, Object[] parameterValues, Class<?>... groups) {
public <T> Set<MethodConstraintViolation<T>>validateReturnValue(T object, Method method, Object returnValue, Class<?>... groups) {
valueContext
the current validation contextcontext
the global validation contextvalidationOrder
Contains the information which and in which order groups have to be executed<T
> The root bean type<V
> The type of the current object on the validation stackprivate <T, U, V, E extends ConstraintViolation<T>> Set<E>validateInContext(ValueContext<U, V> valueContext, ValidationContext<T, E> context, ValidationOrder validationOrder) {
BeanMetaData<U> beanMetaData = beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() );
validationOrder.assertDefaultGroupSequenceIsExpandable( beanMetaData.getDefaultGroupSequence( valueContext.getCurrentBean() ) );
// process first single groups. For these we can optimise object traversal by first running all validations on the current bean
// now we process sequences. For sequences I have to traverse the object graph since I have to stop processing when an error occurs.
private <T, U, V, E extends ConstraintViolation<T>> voidvalidateConstraintsForCurrentGroup(ValidationContext<T, E> validationContext, ValueContext<U, V> valueContext) {
// we are not validating the default group there is nothing special to consider. If we are validating the default
// group sequence we have to consider that a class in the hierarchy could redefine the default group sequence.
private <T, U, V, E extends ConstraintViolation<T>> voidvalidateConstraintsForDefaultGroup(ValidationContext<T, E> validationContext, ValueContext<U, V> valueContext) {
final BeanMetaData<U> beanMetaData = beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() );
// evaluating the constraints of a bean per class in hierarchy, this is necessary to detect potential default group re-definitions
BeanMetaData<U> hostingBeanMetaData = (BeanMetaData<U>) beanMetaDataManager.getBeanMetaData( clazz );
boolean defaultGroupSequenceIsRedefined = hostingBeanMetaData.defaultGroupSequenceIsRedefined();
List<Class<?>> defaultGroupSequence = hostingBeanMetaData.getDefaultGroupSequence( valueContext.getCurrentBean() );
// if the current class redefined the default group sequence, this sequence has to be applied to all the class hierarchy.
// HV-466, an interface implemented more than one time in the hierarchy has to be validated only one
// time. An interface can define more than one constraint, we have to check the class we are validating.
private <T, U, V> voidvalidateConstraintsForNonDefaultGroup(ValidationContext<T, ?> validationContext, ValueContext<U, V> valueContext) {
BeanMetaData<U> beanMetaData = beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() );
private <T, U, V> booleanvalidateConstraint(ValidationContext<T, ?> validationContext, ValueContext<U, V> valueContext, MetaConstraint<?> metaConstraint) {
valueContext.appendNode( ReflectionHelper.getPropertyName( metaConstraint.getLocation().getMember() ) );
private <T, U, V> voidvalidateCascadedConstraints(ValidationContext<T, ?> validationContext, ValueContext<U, V> valueContext) {
Set<Member> cascadedMembers = beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() )
validationContext
The global context for the current validateParameter(s) or
validateReturnValue() call.valueContext
The local context for validating the given parameter/return
value.private <T, U, V> voidvalidateCascadedMethodConstraints(MethodValidationContext<T> validationContext, ValueContext<U, V> valueContext) {
type
the type of the cascaded field or property.value
the actual value.valueContext
context object containing state about the currently validated instanceprivate Iterator<?>createIteratorForCascadedValue(Type type, Object value, ValueContext<?, ?> valueContext) {
type
the type of the cascaded field or property.private <T> voidvalidateCascadedConstraint(ValidationContext<T, ?> context, Iterator<?> iter, boolean isIndexable, ValueContext<?, ?> valueContext) {
newValueContext = ValueContext.getLocalExecutionContext( value, valueContext.getPropertyPath() );
private <T, U, V> Set<ConstraintViolation<T>>validatePropertyInContext(ValidationContext<T, ConstraintViolation<T>> context, PathImpl propertyPath, ValidationOrder validationOrder) {
BeanMetaData<U> beanMetaData = beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() );
validationOrder.assertDefaultGroupSequenceIsExpandable( beanMetaData.getDefaultGroupSequence( valueContext.getCurrentBean() ) );
private <T, U, V> Set<ConstraintViolation<T>>validateValueInContext(ValidationContext<T, ConstraintViolation<T>> context, V value, PathImpl propertyPath, ValidationOrder validationOrder) {
BeanMetaData<U> beanMetaData = beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() );
validationOrder.assertDefaultGroupSequenceIsExpandable( beanMetaData.getDefaultGroupSequence( null ) );
ValueContext
group.
valueContext
The current validation context.validationContext
The global validation context.metaConstraints
All constraints associated to the property.ValueContext
current group.private <T, U, V> intvalidatePropertyForCurrentGroup(ValueContext<U, V> valueContext, ValidationContext<T, ConstraintViolation<T>> validationContext, List<MetaConstraint<?>> metaConstraints) {
// we are validating the default group, we have to consider that a class in the hierarchy could redefine the default group sequence
ValueContext
group.
The current ValueContext
group is not the default group.
valueContext
The current validation context.validationContext
The global validation context.metaConstraints
All constraints associated to the property.ValueContext
current group.private <T, U, V> intvalidatePropertyForNonDefaultGroup(ValueContext<U, V> valueContext, ValidationContext<T, ConstraintViolation<T>> validationContext, List<MetaConstraint<?>> metaConstraints) {
This method checks that the default group sequence is not redefined in the class hierarchy for a superclass hosting constraints for the property to validate.
valueContext
The current validation context.validationContext
The global validation context.constraintList
All constraints associated to the property to check.private <T, U, V> intvalidatePropertyForDefaultGroup(ValueContext<U, V> valueContext, ValidationContext<T, ConstraintViolation<T>> validationContext, List<MetaConstraint<?>> constraintList) {
final int numberOfConstraintViolationsBefore = validationContext.getFailingConstraints().size();
final BeanMetaData<U> beanMetaData = beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() );
// evaluating the constraints of a bean per class in hierarchy. this is necessary to detect potential default group re-definitions
BeanMetaData<U> hostingBeanMetaData = (BeanMetaData<U>) beanMetaDataManager.getBeanMetaData( clazz );
boolean defaultGroupSequenceIsRedefined = hostingBeanMetaData.defaultGroupSequenceIsRedefined();
List<Class<?>> defaultGroupSequence = hostingBeanMetaData.getDefaultGroupSequence( valueContext.getCurrentBean() );
// HV-466, an interface implemented more than one time in the hierarchy has to be validated only one
// time. An interface can define more than one constraint, we have to check the class we are validating.
private <T> voidvalidateParametersInContext(MethodValidationContext<T> validationContext, T object, Object[] parameterValues, ValidationOrder validationOrder) {
BeanMetaData<T> beanMetaData = beanMetaDataManager.getBeanMetaData( validationContext.getRootBeanClass() );
validationOrder.assertDefaultGroupSequenceIsExpandable( beanMetaData.getDefaultGroupSequence( object ) );
private <T> intvalidateParametersForGroup(MethodValidationContext<T> validationContext, T object, Object[] parameterValues, Group group) {
BeanMetaData<T> beanMetaData = beanMetaDataManager.getBeanMetaData( validationContext.getRootBeanClass() );
//ignore this parameter if this validation is for a single parameter and this is not the right one
//ignore this parameter if this validation is for a single parameter and this is not the right one
if ( validationContext.getParameterIndex() != null && !validationContext.getParameterIndex().equals( i ) ) {
validationContext
The validation context for storing constraint violations.valueContext
The value context specifying the group and value to validate.parameterMetaData
Meta data on the constraints to evaluate.private <T, U, V> intvalidateParameterForGroup(MethodValidationContext<T> validationContext, ValueContext<U, V> valueContext, ParameterMetaData parameterMetaData) {
private <V, T> voidvalidateReturnValueInContext(MethodValidationContext<T> context, T bean, V value, ValidationOrder validationOrder) {
BeanMetaData<T> beanMetaData = beanMetaDataManager.getBeanMetaData( context.getRootBeanClass() );
validationOrder.assertDefaultGroupSequenceIsExpandable( beanMetaData.getDefaultGroupSequence( bean ) );
private <T, V> intvalidateReturnValueForGroup(MethodValidationContext<T> validationContext, T bean, V value, Group group) {
BeanMetaData<T> beanMetaData = beanMetaDataManager.getBeanMetaData( validationContext.getRootBeanClass() );
MetaConstraint
s which match the given path relative to the specified root class.
This method is called recursively.
clazz
The class type to check for constraints.value
While resolving the property path this instance points to the current object. Might be null
.propertyIter
An instance of PropertyIterator
in order to iterate the items of the original property path.propertyPath
The property path for which constraints have to be collected.metaConstraintsList
An instance of Map
where MetaConstraint
s which match the given path are saved for each class in the hosting class hierarchy.ValueContext
which describes the local validation context associated to the given property path.private <T, U, V> ValueContext<U, V>collectMetaConstraintsForPath(Class<T> clazz, Object value, Iterator<Path.Node> propertyIter, PathImpl propertyPath, List<MetaConstraint<?>> metaConstraintsList) {