Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or .
*/
package org.hibernate.validator.internal.engine;
import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES;
import java.lang.annotation.ElementType;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.ConstraintViolation;
import javax.validation.ElementKind;
import javax.validation.Path;
import javax.validation.TraversableResolver;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;
import javax.validation.groups.Default;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.valueextraction.ValueExtractor;
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;
import org.hibernate.validator.internal.engine.ValidationContext.ValidationContextBuilder;
import org.hibernate.validator.internal.engine.ValidationContext.ValidatorScopedContext;
import org.hibernate.validator.internal.engine.ValidatorFactoryImpl.ValidatorFactoryScopedContext;
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
import org.hibernate.validator.internal.engine.groups.Group;
import org.hibernate.validator.internal.engine.groups.GroupWithInheritance;
import org.hibernate.validator.internal.engine.groups.Sequence;
import org.hibernate.validator.internal.engine.groups.ValidationOrder;
import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator;
import org.hibernate.validator.internal.engine.path.NodeImpl;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.hibernate.validator.internal.engine.resolver.TraversableResolvers;
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorDescriptor;
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorHelper;
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
import org.hibernate.validator.internal.metadata.BeanMetaDataManager;
import org.hibernate.validator.internal.metadata.aggregated.BeanMetaData;
import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaData;
import org.hibernate.validator.internal.metadata.aggregated.ContainerCascadingMetaData;
import org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData;
import org.hibernate.validator.internal.metadata.aggregated.ParameterMetaData;
import org.hibernate.validator.internal.metadata.aggregated.PropertyMetaData;
import org.hibernate.validator.internal.metadata.aggregated.ReturnValueMetaData;
import org.hibernate.validator.internal.metadata.core.MetaConstraint;
import org.hibernate.validator.internal.metadata.facets.Cascadable;
import org.hibernate.validator.internal.metadata.facets.Validatable;
import org.hibernate.validator.internal.metadata.location.ConstraintLocation;
import org.hibernate.validator.internal.metadata.location.FieldConstraintLocation;
import org.hibernate.validator.internal.metadata.location.GetterConstraintLocation;
import org.hibernate.validator.internal.metadata.location.TypeArgumentConstraintLocation;
import org.hibernate.validator.internal.util.Contracts;
import org.hibernate.validator.internal.util.ExecutableHelper;
import org.hibernate.validator.internal.util.ReflectionHelper;
import org.hibernate.validator.internal.util.TypeHelper;
import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
/**
* The main Bean Validation class. This is the core processing class of Hibernate Validator.
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
* @author Gunnar Morling
* @author Kevin Pollet <[email protected]> (C) 2011 SERLI
* @author Guillaume Smet
*/
public class ValidatorImpl implements Validator, ExecutableValidator {
private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
/**
* The default group array used in case any of the validate methods is called without a group.
*/
private static final Collection> DEFAULT_GROUPS = Collections.>singletonList( Default.class );
/**
* Used to resolve the group execution order for a validate call.
*/
private final transient ValidationOrderGenerator validationOrderGenerator;
/**
* Reference to shared {@code ConstraintValidatorFactory}.
*/
private final ConstraintValidatorFactory constraintValidatorFactory;
/**
* {@link TraversableResolver} as passed to the constructor of this instance.
* Never use it directly, always use {@link #getCachingTraversableResolver()} to retrieved the single threaded caching wrapper.
*/
private final TraversableResolver traversableResolver;
/**
* Used to get access to the bean meta data. Used to avoid to parsing the constraint configuration for each call
* of a given entity.
*/
private final BeanMetaDataManager beanMetaDataManager;
/**
* Manages the life cycle of constraint validator instances
*/
private final ConstraintValidatorManager constraintValidatorManager;
private final ValueExtractorManager valueExtractorManager;
/**
* Context containing all {@link Validator} level helpers and configuration properties.
*/
private final ValidatorScopedContext validatorScopedContext;
/**
* The constraint initialization context is stored at this level to prevent creating a new instance each time we
* initialize a new constraint validator as, for now, it only contains Validator scoped objects.
*/
private final HibernateConstraintValidatorInitializationContext constraintValidatorInitializationContext;
public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory,
BeanMetaDataManager beanMetaDataManager,
ValueExtractorManager valueExtractorManager,
ConstraintValidatorManager constraintValidatorManager,
ValidationOrderGenerator validationOrderGenerator,
ValidatorFactoryScopedContext validatorFactoryScopedContext) {
this.constraintValidatorFactory = constraintValidatorFactory;
this.beanMetaDataManager = beanMetaDataManager;
this.valueExtractorManager = valueExtractorManager;
this.constraintValidatorManager = constraintValidatorManager;
this.validationOrderGenerator = validationOrderGenerator;
this.validatorScopedContext = new ValidatorScopedContext( validatorFactoryScopedContext );
this.traversableResolver = validatorFactoryScopedContext.getTraversableResolver();
this.constraintValidatorInitializationContext = validatorFactoryScopedContext.getConstraintValidatorInitializationContext();
}
@Override
public final Set> validate(T object, Class... groups) {
Contracts.assertNotNull( object, MESSAGES.validatedObjectMustNotBeNull() );
sanityCheckGroups( groups );
ValidationContext validationContext = getValidationContextBuilder().forValidate( object );
if ( !validationContext.getRootBeanMetaData().hasConstraints() ) {
return Collections.emptySet();
}
ValidationOrder validationOrder = determineGroupValidationOrder( groups );
ValueContext valueContext = ValueContext.getLocalExecutionContext(
validatorScopedContext.getParameterNameProvider(),
object,
validationContext.getRootBeanMetaData(),
PathImpl.createRootPath()
);
return validateInContext( validationContext, valueContext, validationOrder );
}
@Override
public final Set> validateProperty(T object, String propertyName, Class... groups) {
Contracts.assertNotNull( object, MESSAGES.validatedObjectMustNotBeNull() );
sanityCheckPropertyPath( propertyName );
sanityCheckGroups( groups );
ValidationContext validationContext = getValidationContextBuilder().forValidateProperty( object );
if ( !validationContext.getRootBeanMetaData().hasConstraints() ) {
return Collections.emptySet();
}
PathImpl propertyPath = PathImpl.createPathFromString( propertyName );
ValueContext valueContext = getValueContextForPropertyValidation( validationContext, propertyPath );
if ( valueContext.getCurrentBean() == null ) {
throw LOG.getUnableToReachPropertyToValidateException( validationContext.getRootBean(), propertyPath );
}
ValidationOrder validationOrder = determineGroupValidationOrder( groups );
return validateInContext( validationContext, valueContext, validationOrder );
}
@Override
public final Set> validateValue(Class beanType, String propertyName, Object value, Class... groups) {
Contracts.assertNotNull( beanType, MESSAGES.beanTypeCannotBeNull() );
sanityCheckPropertyPath( propertyName );
sanityCheckGroups( groups );
ValidationContext validationContext = getValidationContextBuilder().forValidateValue( beanType );
if ( !validationContext.getRootBeanMetaData().hasConstraints() ) {
return Collections.emptySet();
}
ValidationOrder validationOrder = determineGroupValidationOrder( groups );
return validateValueInContext(
validationContext,
value,
PathImpl.createPathFromString( propertyName ),
validationOrder
);
}
@Override
public Set> validateParameters(T object, Method method, Object[] parameterValues, Class... groups) {
Contracts.assertNotNull( object, MESSAGES.validatedObjectMustNotBeNull() );
Contracts.assertNotNull( method, MESSAGES.validatedMethodMustNotBeNull() );
Contracts.assertNotNull( parameterValues, MESSAGES.validatedParameterArrayMustNotBeNull() );
return validateParameters( object, (Executable) method, parameterValues, groups );
}
@Override
public Set> validateConstructorParameters(Constructor constructor, Object[] parameterValues, Class... groups) {
Contracts.assertNotNull( constructor, MESSAGES.validatedConstructorMustNotBeNull() );
Contracts.assertNotNull( parameterValues, MESSAGES.validatedParameterArrayMustNotBeNull() );
return validateParameters( null, constructor, parameterValues, groups );
}
@Override
public Set> validateConstructorReturnValue(Constructor constructor, T createdObject, Class... groups) {
Contracts.assertNotNull( constructor, MESSAGES.validatedConstructorMustNotBeNull() );
Contracts.assertNotNull( createdObject, MESSAGES.validatedConstructorCreatedInstanceMustNotBeNull() );
return validateReturnValue( null, constructor, createdObject, groups );
}
@Override
public Set> validateReturnValue(T object, Method method, Object returnValue, Class... groups) {
Contracts.assertNotNull( object, MESSAGES.validatedObjectMustNotBeNull() );
Contracts.assertNotNull( method, MESSAGES.validatedMethodMustNotBeNull() );
return validateReturnValue( object, (Executable) method, returnValue, groups );
}
private Set> validateParameters(T object, Executable executable, Object[] parameterValues, Class... groups) {
sanityCheckGroups( groups );
ValidationContext validationContext = getValidationContextBuilder().forValidateParameters(
validatorScopedContext.getParameterNameProvider(),
object,
executable,
parameterValues
);
if ( !validationContext.getRootBeanMetaData().hasConstraints() ) {
return Collections.emptySet();
}
ValidationOrder validationOrder = determineGroupValidationOrder( groups );
validateParametersInContext( validationContext, parameterValues, validationOrder );
return validationContext.getFailingConstraints();
}
private Set> validateReturnValue(T object, Executable executable, Object returnValue, Class... groups) {
sanityCheckGroups( groups );
ValidationContext validationContext = getValidationContextBuilder().forValidateReturnValue(
object,
executable,
returnValue
);
if ( !validationContext.getRootBeanMetaData().hasConstraints() ) {
return Collections.emptySet();
}
ValidationOrder validationOrder = determineGroupValidationOrder( groups );
validateReturnValueInContext( validationContext, object, returnValue, validationOrder );
return validationContext.getFailingConstraints();
}
@Override
public final BeanDescriptor getConstraintsForClass(Class clazz) {
return beanMetaDataManager.getBeanMetaData( clazz ).getBeanDescriptor();
}
@Override
public final T unwrap(Class type) {
//allow unwrapping into public super types; intentionally not exposing the
//fact that ExecutableValidator is implemented by this class as well as this
//might change
if ( type.isAssignableFrom( Validator.class ) ) {
return type.cast( this );
}
throw LOG.getTypeNotSupportedForUnwrappingException( type );
}
@Override
public ExecutableValidator forExecutables() {
return this;
}
private ValidationContextBuilder getValidationContextBuilder() {
return ValidationContext.getValidationContextBuilder(
beanMetaDataManager,
constraintValidatorManager,
constraintValidatorFactory,
validatorScopedContext,
TraversableResolvers.wrapWithCachingForSingleValidation( traversableResolver, validatorScopedContext.isTraversableResolverResultCacheEnabled() ),
constraintValidatorInitializationContext
);
}
private void sanityCheckPropertyPath(String propertyName) {
if ( propertyName == null || propertyName.length() == 0 ) {
throw LOG.getInvalidPropertyPathException();
}
}
private void sanityCheckGroups(Class[] groups) {
Contracts.assertNotNull( groups, MESSAGES.groupMustNotBeNull() );
for ( Class clazz : groups ) {
if ( clazz == null ) {
throw new IllegalArgumentException( MESSAGES.groupMustNotBeNull() );
}
}
}
private ValidationOrder determineGroupValidationOrder(Class[] groups) {
Collection> resultGroups;
// if no groups is specified use the default
if ( groups.length == 0 ) {
resultGroups = DEFAULT_GROUPS;
}
else {
resultGroups = Arrays.asList( groups );
}
return validationOrderGenerator.getValidationOrder( resultGroups );
}
/**
* Validates the given object using the available context information.
* @param validationContext the global validation context
* @param valueContext the current validation context
* @param validationOrder Contains the information which and in which order groups have to be executed
*
* @param The root bean type
*
* @return Set of constraint violations or the empty set if there were no violations.
*/
private Set> validateInContext(ValidationContext validationContext, ValueContext valueContext,
ValidationOrder validationOrder) {
if ( valueContext.getCurrentBean() == null ) {
return Collections.emptySet();
}
BeanMetaData beanMetaData = valueContext.getCurrentBeanMetaData();
if ( beanMetaData.defaultGroupSequenceIsRedefined() ) {
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
// before traversing the object.
Iterator groupIterator = validationOrder.getGroupIterator();
while ( groupIterator.hasNext() ) {
Group group = groupIterator.next();
valueContext.setCurrentGroup( group.getDefiningClass() );
validateConstraintsForCurrentGroup( validationContext, valueContext );
if ( shouldFailFast( validationContext ) ) {
return validationContext.getFailingConstraints();
}
}
groupIterator = validationOrder.getGroupIterator();
while ( groupIterator.hasNext() ) {
Group group = groupIterator.next();
valueContext.setCurrentGroup( group.getDefiningClass() );
validateCascadedConstraints( validationContext, valueContext );
if ( shouldFailFast( validationContext ) ) {
return validationContext.getFailingConstraints();
}
}
// now we process sequences. For sequences I have to traverse the object graph since I have to stop processing when an error occurs.
Iterator sequenceIterator = validationOrder.getSequenceIterator();
while ( sequenceIterator.hasNext() ) {
Sequence sequence = sequenceIterator.next();
for ( GroupWithInheritance groupOfGroups : sequence ) {
int numberOfViolations = validationContext.getFailingConstraints().size();
for ( Group group : groupOfGroups ) {
valueContext.setCurrentGroup( group.getDefiningClass() );
validateConstraintsForCurrentGroup( validationContext, valueContext );
if ( shouldFailFast( validationContext ) ) {
return validationContext.getFailingConstraints();
}
validateCascadedConstraints( validationContext, valueContext );
if ( shouldFailFast( validationContext ) ) {
return validationContext.getFailingConstraints();
}
}
if ( validationContext.getFailingConstraints().size() > numberOfViolations ) {
break;
}
}
}
return validationContext.getFailingConstraints();
}
private void validateConstraintsForCurrentGroup(ValidationContext validationContext, ValueContext 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.
if ( !valueContext.validatingDefault() ) {
validateConstraintsForNonDefaultGroup( validationContext, valueContext );
}
else {
validateConstraintsForDefaultGroup( validationContext, valueContext );
}
}
private void validateConstraintsForDefaultGroup(ValidationContext validationContext, ValueContext valueContext) {
final BeanMetaData beanMetaData = valueContext.getCurrentBeanMetaData();
final Map, Class> validatedInterfaces = new HashMap<>();
// evaluating the constraints of a bean per class in hierarchy, this is necessary to detect potential default group re-definitions
for ( Class clazz : beanMetaData.getClassHierarchy() ) {
BeanMetaData hostingBeanMetaData = beanMetaDataManager.getBeanMetaData( clazz );
boolean defaultGroupSequenceIsRedefined = hostingBeanMetaData.defaultGroupSequenceIsRedefined();
// if the current class redefined the default group sequence, this sequence has to be applied to all the class hierarchy.
if ( defaultGroupSequenceIsRedefined ) {
Iterator defaultGroupSequence = hostingBeanMetaData.getDefaultValidationSequence( valueContext.getCurrentBean() );
Set> metaConstraints = hostingBeanMetaData.getMetaConstraints();
while ( defaultGroupSequence.hasNext() ) {
for ( GroupWithInheritance groupOfGroups : defaultGroupSequence.next() ) {
boolean validationSuccessful = true;
for ( Group defaultSequenceMember : groupOfGroups ) {
validationSuccessful = validateConstraintsForSingleDefaultGroupElement( validationContext, valueContext, validatedInterfaces, clazz,
metaConstraints, defaultSequenceMember );
}
if ( !validationSuccessful ) {
break;
}
}
}
}
// fast path in case the default group sequence hasn't been redefined
else {
Set> metaConstraints = hostingBeanMetaData.getDirectMetaConstraints();
validateConstraintsForSingleDefaultGroupElement( validationContext, valueContext, validatedInterfaces, clazz, metaConstraints,
Group.DEFAULT_GROUP );
}
validationContext.markCurrentBeanAsProcessed( valueContext );
// all constraints in the hierarchy has been validated, stop validation.
if ( defaultGroupSequenceIsRedefined ) {
break;
}
}
}
private boolean validateConstraintsForSingleDefaultGroupElement(ValidationContext validationContext, ValueContext valueContext, final Map, Class> validatedInterfaces,
Class clazz, Set> metaConstraints, Group defaultSequenceMember) {
boolean validationSuccessful = true;
valueContext.setCurrentGroup( defaultSequenceMember.getDefiningClass() );
for ( MetaConstraint metaConstraint : metaConstraints ) {
// 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.
final Class declaringClass = metaConstraint.getLocation().getDeclaringClass();
if ( declaringClass.isInterface() ) {
Class validatedForClass = validatedInterfaces.get( declaringClass );
if ( validatedForClass != null && !validatedForClass.equals( clazz ) ) {
continue;
}
validatedInterfaces.put( declaringClass, clazz );
}
boolean tmp = validateMetaConstraint( validationContext, valueContext, valueContext.getCurrentBean(), metaConstraint );
if ( shouldFailFast( validationContext ) ) {
return false;
}
validationSuccessful = validationSuccessful && tmp;
}
return validationSuccessful;
}
private void validateConstraintsForNonDefaultGroup(ValidationContext validationContext, ValueContext valueContext) {
validateMetaConstraints( validationContext, valueContext, valueContext.getCurrentBean(), valueContext.getCurrentBeanMetaData().getMetaConstraints() );
validationContext.markCurrentBeanAsProcessed( valueContext );
}
private void validateMetaConstraints(ValidationContext validationContext, ValueContext valueContext, Object parent,
Iterable> constraints) {
for ( MetaConstraint metaConstraint : constraints ) {
validateMetaConstraint( validationContext, valueContext, parent, metaConstraint );
if ( shouldFailFast( validationContext ) ) {
break;
}
}
}
private boolean validateMetaConstraint(ValidationContext validationContext, ValueContext valueContext, Object parent, MetaConstraint metaConstraint) {
ValueContext.ValueState