From 53ea896ad865eb949216b630739fe8af89409235 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Sat, 10 Mar 2018 14:29:50 +0100 Subject: [PATCH 01/24] HV-1623 Build abstraction over reflection in ConstraintLocation and related code --- .../cfg/context/ConfiguredConstraint.java | 41 ++-- .../ConstraintMappingContextImplBase.java | 2 +- ...nstructorConstraintMappingContextImpl.java | 7 +- ...erElementConstraintMappingContextImpl.java | 2 +- ...ParameterConstraintMappingContextImpl.java | 4 +- ...xecutableConstraintMappingContextImpl.java | 31 ++- .../MethodConstraintMappingContextImpl.java | 9 +- ...ParameterConstraintMappingContextImpl.java | 15 +- .../PropertyConstraintMappingContextImpl.java | 37 ++-- ...turnValueConstraintMappingContextImpl.java | 14 +- .../TypeConstraintMappingContextImpl.java | 49 +++-- .../engine/ConstraintViolationImpl.java | 7 - .../PropertyValidationContext.java | 10 +- .../metadata/aggregated/BeanMetaDataImpl.java | 7 +- .../aggregated/ExecutableMetaData.java | 49 +++-- .../metadata/aggregated/FieldCascadable.java | 110 ----------- .../metadata/aggregated/MetaDataBuilder.java | 2 +- .../aggregated/ParameterMetaData.java | 14 +- ...ascadable.java => PropertyCascadable.java} | 38 ++-- .../metadata/aggregated/PropertyMetaData.java | 51 +++-- .../rule/MethodConfigurationRule.java | 8 +- ...ethodMustNotAlterParameterConstraints.java | 4 +- ...GroupConversionForCascadedReturnValue.java | 4 +- ...hodsMustNotDefineParameterConstraints.java | 4 +- ...eMarkedOnceAsCascadedPerHierarchyLine.java | 4 +- ...ethodsMustNotBeReturnValueConstrained.java | 7 +- .../core/AnnotationProcessingOptions.java | 10 +- .../core/AnnotationProcessingOptionsImpl.java | 60 +++--- .../descriptor/ConstraintDescriptorImpl.java | 91 +++------ .../location/BeanConstraintLocation.java | 4 +- .../metadata/location/ConstraintLocation.java | 52 ++--- .../CrossParameterConstraintLocation.java | 30 ++- .../location/ParameterConstraintLocation.java | 33 ++-- .../location/PropertyConstraintLocation.java | 88 +++++++++ .../ReturnValueConstraintLocation.java | 33 ++-- .../TypeArgumentConstraintLocation.java | 6 +- .../provider/AnnotationMetaDataProvider.java | 126 ++++++------ .../metadata/raw/ConstrainedExecutable.java | 50 ++--- .../metadata/raw/ConstrainedField.java | 39 ++-- .../metadata/raw/ConstrainedParameter.java | 31 ++- .../internal/properties/Callable.java | 41 ++++ .../internal/properties/Constrainable.java | 28 +++ .../properties/ConstrainableType.java | 14 ++ .../internal/properties/Property.java | 17 ++ .../properties/javabean/JavaBean.java | 37 ++++ .../javabean/JavaBeanExecutable.java | 187 ++++++++++++++++++ .../javabean/JavaBeanField.java} | 86 ++++---- .../javabean/JavaBeanGetter.java} | 97 ++++----- .../properties/javabean/package-info.java | 8 + .../internal/util/ExecutableHelper.java | 5 + .../validator/internal/util/logging/Log.java | 34 ++-- .../formatter/ConstrainableFormatter.java | 39 ++++ .../ConstrainedConstructorStaxBuilder.java | 12 +- .../mapping/ConstrainedFieldStaxBuilder.java | 11 +- .../mapping/ConstrainedGetterStaxBuilder.java | 10 +- .../mapping/ConstrainedMethodStaxBuilder.java | 12 +- .../ConstrainedParameterStaxBuilder.java | 13 +- .../mapping/ConstraintTypeStaxBuilder.java | 4 +- .../mapping/CrossParameterStaxBuilder.java | 8 +- .../xml/mapping/ReturnValueStaxBuilder.java | 17 +- .../test/cfg/ConstraintMappingTest.java | 4 +- .../engine/failfast/FailFastTest.java | 10 +- .../metadata/core/MetaConstraintTest.java | 5 +- .../location/ConstraintLocationTest.java | 5 +- .../AnnotationMetaDataProviderTest.java | 13 +- .../AnnotationMetaDataProviderTestBase.java | 17 +- .../testutil/ConstraintViolationAssert.java | 17 +- 67 files changed, 1086 insertions(+), 848 deletions(-) delete mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java rename engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/{GetterCascadable.java => PropertyCascadable.java} (60%) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/Constrainable.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/ConstrainableType.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/Property.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBean.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java rename engine/src/main/java/org/hibernate/validator/internal/{metadata/location/FieldConstraintLocation.java => properties/javabean/JavaBeanField.java} (52%) rename engine/src/main/java/org/hibernate/validator/internal/{metadata/location/GetterConstraintLocation.java => properties/javabean/JavaBeanGetter.java} (52%) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/javabean/package-info.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/util/logging/formatter/ConstrainableFormatter.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java index 8f338757fe..3f47510fca 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java @@ -10,10 +10,6 @@ import java.lang.annotation.ElementType; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.security.AccessController; @@ -24,7 +20,9 @@ import org.hibernate.validator.cfg.AnnotationDef; import org.hibernate.validator.cfg.ConstraintDef; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.util.ExecutableHelper; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.util.annotation.AnnotationDescriptor; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.internal.util.logging.Log; @@ -58,42 +56,33 @@ static ConfiguredConstraint forType(ConstraintDef( constraint, ConstraintLocation.forClass( beanType ), ElementType.TYPE ); } - static ConfiguredConstraint forProperty(ConstraintDef constraint, Member member) { - if ( member instanceof Field ) { - return new ConfiguredConstraint<>( - constraint, - ConstraintLocation.forField( (Field) member ), - ElementType.FIELD - ); - } - else { - return new ConfiguredConstraint<>( + static ConfiguredConstraint forProperty(ConstraintDef constraint, Property property) { + return new ConfiguredConstraint<>( constraint, - ConstraintLocation.forGetter( (Method) member ), - ElementType.METHOD - ); - } + ConstraintLocation.forProperty( property ), + property instanceof JavaBeanField ? ElementType.FIELD : ElementType.METHOD + ); } - public static ConfiguredConstraint forParameter(ConstraintDef constraint, Executable executable, int parameterIndex) { + public static ConfiguredConstraint forParameter(ConstraintDef constraint, Callable callable, int parameterIndex) { return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forParameter( executable, parameterIndex ), ExecutableHelper.getElementType( executable ) + constraint, ConstraintLocation.forParameter( callable, parameterIndex ), callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD ); } - public static ConfiguredConstraint forExecutable(ConstraintDef constraint, Executable executable) { + public static ConfiguredConstraint forExecutable(ConstraintDef constraint, Callable callable) { return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forReturnValue( executable ), ExecutableHelper.getElementType( executable ) + constraint, ConstraintLocation.forReturnValue( callable ), callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD ); } - public static ConfiguredConstraint forCrossParameter(ConstraintDef constraint, Executable executable) { + public static ConfiguredConstraint forCrossParameter(ConstraintDef constraint, Callable callable) { return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forCrossParameter( executable ), ExecutableHelper.getElementType( executable ) + constraint, ConstraintLocation.forCrossParameter( callable ), callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD ); } - public static ConfiguredConstraint forTypeArgument(ConstraintDef constraint,ConstraintLocation delegate, TypeVariable typeArgument, Type typeOfAnnotatedElement) { + public static ConfiguredConstraint forTypeArgument(ConstraintDef constraint, ConstraintLocation delegate, TypeVariable typeArgument, Type typeOfAnnotatedElement) { return new ConfiguredConstraint<>( constraint, ConstraintLocation.forTypeArgument( delegate, typeArgument, typeOfAnnotatedElement ), diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java index 3eb7a9c92c..ec6257bd05 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java @@ -73,7 +73,7 @@ private MetaConstraint asMetaConstraint(ConfiguredCons TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { ConstraintDescriptorImpl constraintDescriptor = new ConstraintDescriptorImpl( constraintHelper, - config.getLocation().getMember(), + config.getLocation().getConstrainable(), config.createAnnotationDescriptor(), config.getElementType(), getConstraintType() diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstructorConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstructorConstraintMappingContextImpl.java index 7f9683a57a..2b71b966a4 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstructorConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstructorConstraintMappingContextImpl.java @@ -6,9 +6,8 @@ */ package org.hibernate.validator.internal.cfg.context; -import java.lang.reflect.Constructor; - import org.hibernate.validator.cfg.context.ConstructorConstraintMappingContext; +import org.hibernate.validator.internal.properties.Callable; /** * Constraint mapping creational context representing a constructor. @@ -17,7 +16,7 @@ */ class ConstructorConstraintMappingContextImpl extends ExecutableConstraintMappingContextImpl implements ConstructorConstraintMappingContext { - ConstructorConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Constructor constructor) { + ConstructorConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Callable constructor) { super( typeContext, constructor ); } @@ -25,7 +24,7 @@ ConstructorConstraintMappingContextImpl(TypeConstraintMappingContextImpl public ConstructorConstraintMappingContext ignoreAnnotations(boolean ignoreAnnotations) { typeContext.mapping .getAnnotationProcessingOptions() - .ignoreConstraintAnnotationsOnMember( executable, ignoreAnnotations ); + .ignoreConstraintAnnotationsOnMember( callable, ignoreAnnotations ); return this; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java index cf33e40d86..755b09f7ce 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java @@ -237,7 +237,7 @@ private MetaConstraint asMetaConstraint(ConfiguredCons TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { ConstraintDescriptorImpl constraintDescriptor = new ConstraintDescriptorImpl<>( constraintHelper, - config.getLocation().getMember(), + config.getLocation().getConstrainable(), config.createAnnotationDescriptor(), config.getElementType(), getConstraintType() diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/CrossParameterConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/CrossParameterConstraintMappingContextImpl.java index 8cae876274..d1247c09eb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/CrossParameterConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/CrossParameterConstraintMappingContextImpl.java @@ -32,14 +32,14 @@ final class CrossParameterConstraintMappingContextImpl @Override public CrossParameterConstraintMappingContext constraint(ConstraintDef definition) { - super.addConstraint( ConfiguredConstraint.forCrossParameter( definition, executableContext.getExecutable() ) ); + super.addConstraint( ConfiguredConstraint.forCrossParameter( definition, executableContext.getCallable() ) ); return this; } @Override public CrossParameterConstraintMappingContext ignoreAnnotations(boolean ignoreAnnotations) { mapping.getAnnotationProcessingOptions().ignoreConstraintAnnotationsForCrossParameterConstraint( - executableContext.getExecutable(), ignoreAnnotations + executableContext.getCallable(), ignoreAnnotations ); return this; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ExecutableConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ExecutableConstraintMappingContextImpl.java index 3f2f6d3523..9cb9d826a2 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ExecutableConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ExecutableConstraintMappingContextImpl.java @@ -9,7 +9,6 @@ import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; import java.lang.invoke.MethodHandles; -import java.lang.reflect.Executable; import java.util.Collections; import java.util.List; @@ -24,7 +23,7 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; -import org.hibernate.validator.internal.util.ReflectionHelper; +import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; @@ -41,20 +40,20 @@ abstract class ExecutableConstraintMappingContextImpl { private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() ); protected final TypeConstraintMappingContextImpl typeContext; - protected final Executable executable; + protected final Callable callable; private final ParameterConstraintMappingContextImpl[] parameterContexts; private ReturnValueConstraintMappingContextImpl returnValueContext; private CrossParameterConstraintMappingContextImpl crossParameterContext; - protected ExecutableConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Executable executable) { + protected ExecutableConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Callable callable) { this.typeContext = typeContext; - this.executable = executable; - this.parameterContexts = new ParameterConstraintMappingContextImpl[executable.getParameterTypes().length]; + this.callable = callable; + this.parameterContexts = new ParameterConstraintMappingContextImpl[callable.getParameterTypes().length]; } public ParameterConstraintMappingContext parameter(int index) { - if ( index < 0 || index >= executable.getParameterTypes().length ) { - throw LOG.getInvalidExecutableParameterIndexException( executable, index ); + if ( index < 0 || index >= callable.getParameterTypes().length ) { + throw LOG.getInvalidExecutableParameterIndexException( callable, index ); } ParameterConstraintMappingContextImpl context = parameterContexts[index]; @@ -62,7 +61,7 @@ public ParameterConstraintMappingContext parameter(int index) { if ( context != null ) { throw LOG.getParameterHasAlreadyBeConfiguredViaProgrammaticApiException( typeContext.getBeanClass(), - executable, + callable, index ); } @@ -76,7 +75,7 @@ public CrossParameterConstraintMappingContext crossParameter() { if ( crossParameterContext != null ) { throw LOG.getCrossParameterElementHasAlreadyBeConfiguredViaProgrammaticApiException( typeContext.getBeanClass(), - executable + callable ); } @@ -88,7 +87,7 @@ public ReturnValueConstraintMappingContext returnValue() { if ( returnValueContext != null ) { throw LOG.getReturnValueHasAlreadyBeConfiguredViaProgrammaticApiException( typeContext.getBeanClass(), - executable + callable ); } @@ -96,8 +95,8 @@ public ReturnValueConstraintMappingContext returnValue() { return returnValueContext; } - public Executable getExecutable() { - return executable; + public Callable getCallable() { + return callable; } public TypeConstraintMappingContextImpl getTypeContext() { @@ -108,7 +107,7 @@ public ConstrainedElement build(ConstraintHelper constraintHelper, TypeResolutio ValueExtractorManager valueExtractorManager) { return new ConstrainedExecutable( ConfigurationSource.API, - executable, + callable, getParameters( constraintHelper, typeResolutionHelper, valueExtractorManager ), crossParameterContext != null ? crossParameterContext.getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ) : Collections.>emptySet(), returnValueContext != null ? returnValueContext.getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ) : Collections.>emptySet(), @@ -130,8 +129,8 @@ private List getParameters(ConstraintHelper constraintHelp constrainedParameters.add( new ConstrainedParameter( ConfigurationSource.API, - executable, - ReflectionHelper.typeOf( executable, i ), + callable, + callable.getTypeOfParameter( i ), i ) ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/MethodConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/MethodConstraintMappingContextImpl.java index 6ff256f34a..19e74b27db 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/MethodConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/MethodConstraintMappingContextImpl.java @@ -6,9 +6,8 @@ */ package org.hibernate.validator.internal.cfg.context; -import java.lang.reflect.Method; - import org.hibernate.validator.cfg.context.MethodConstraintMappingContext; +import org.hibernate.validator.internal.properties.Callable; /** * Constraint mapping creational context representing a method. @@ -17,15 +16,15 @@ */ class MethodConstraintMappingContextImpl extends ExecutableConstraintMappingContextImpl implements MethodConstraintMappingContext { - MethodConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Method method) { - super( typeContext, method ); + MethodConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Callable callable) { + super( typeContext, callable ); } @Override public MethodConstraintMappingContext ignoreAnnotations(boolean ignoreAnnotations) { typeContext.mapping .getAnnotationProcessingOptions() - .ignoreConstraintAnnotationsOnMember( executable, ignoreAnnotations ); + .ignoreConstraintAnnotationsOnMember( callable, ignoreAnnotations ); return this; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ParameterConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ParameterConstraintMappingContextImpl.java index 5009fc76cd..1f8bc55dc5 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ParameterConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ParameterConstraintMappingContextImpl.java @@ -21,7 +21,6 @@ import org.hibernate.validator.internal.metadata.location.ConstraintLocation; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; -import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; /** @@ -41,7 +40,7 @@ final class ParameterConstraintMappingContextImpl ParameterConstraintMappingContextImpl(ExecutableConstraintMappingContextImpl executableContext, int parameterIndex) { super( executableContext.getTypeContext().getConstraintMapping(), - executableContext.executable.getGenericParameterTypes()[parameterIndex] + executableContext.callable.getGenericParameterTypes()[parameterIndex] ); this.executableContext = executableContext; @@ -58,7 +57,7 @@ public ParameterConstraintMappingContext constraint(ConstraintDef definiti super.addConstraint( ConfiguredConstraint.forParameter( definition, - executableContext.getExecutable(), + executableContext.getCallable(), parameterIndex ) ); @@ -68,7 +67,7 @@ public ParameterConstraintMappingContext constraint(ConstraintDef definiti @Override public ParameterConstraintMappingContext ignoreAnnotations(boolean ignoreAnnotations) { mapping.getAnnotationProcessingOptions().ignoreConstraintAnnotationsOnParameter( - executableContext.getExecutable(), + executableContext.getCallable(), parameterIndex, ignoreAnnotations ); @@ -105,7 +104,7 @@ public ContainerElementConstraintMappingContext containerElementType() { return super.containerElement( this, executableContext.getTypeContext(), - ConstraintLocation.forParameter( executableContext.getExecutable(), parameterIndex ) + ConstraintLocation.forParameter( executableContext.getCallable(), parameterIndex ) ); } @@ -114,7 +113,7 @@ public ContainerElementConstraintMappingContext containerElementType(int index, return super.containerElement( this, executableContext.getTypeContext(), - ConstraintLocation.forParameter( executableContext.getExecutable(), parameterIndex ), + ConstraintLocation.forParameter( executableContext.getCallable(), parameterIndex ), index, nestedIndexes ); @@ -122,11 +121,11 @@ public ContainerElementConstraintMappingContext containerElementType(int index, public ConstrainedParameter build(ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { - Type parameterType = ReflectionHelper.typeOf( executableContext.getExecutable(), parameterIndex ); + Type parameterType = executableContext.getCallable().getTypeOfParameter( parameterIndex ); return new ConstrainedParameter( ConfigurationSource.API, - executableContext.getExecutable(), + executableContext.getCallable(), parameterType, parameterIndex, getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java index dcb6681ce5..95e51deec5 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java @@ -7,10 +7,6 @@ package org.hibernate.validator.internal.cfg.context; import java.lang.annotation.ElementType; -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; import org.hibernate.validator.cfg.ConstraintDef; import org.hibernate.validator.cfg.context.ConstructorConstraintMappingContext; @@ -25,7 +21,9 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; -import org.hibernate.validator.internal.util.ReflectionHelper; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.util.TypeResolutionHelper; /** @@ -42,19 +40,14 @@ final class PropertyConstraintMappingContextImpl private final TypeConstraintMappingContextImpl typeContext; // either Field or Method - private final Member member; + private final Property property; private final ConstraintLocation location; - PropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Member member) { - super( typeContext.getConstraintMapping(), ReflectionHelper.typeOf( member ) ); + PropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Property property) { + super( typeContext.getConstraintMapping(), property.getType() ); this.typeContext = typeContext; - this.member = member; - if ( member instanceof Field ) { - this.location = ConstraintLocation.forField( (Field) member ); - } - else { - this.location = ConstraintLocation.forGetter( (Method) member ); - } + this.property = property; + this.location = ConstraintLocation.forProperty( property ); } @Override @@ -64,17 +57,17 @@ protected PropertyConstraintMappingContextImpl getThis() { @Override public PropertyConstraintMappingContext constraint(ConstraintDef definition) { - if ( member instanceof Field ) { + if ( property instanceof JavaBeanField ) { super.addConstraint( ConfiguredConstraint.forProperty( - definition, member + definition, property ) ); } else { super.addConstraint( ConfiguredConstraint.forExecutable( - definition, (Method) member + definition, property.as( Callable.class ) ) ); } @@ -88,7 +81,7 @@ public PropertyConstraintMappingContext ignoreAnnotations() { @Override public PropertyConstraintMappingContext ignoreAnnotations(boolean ignoreAnnotations) { - mapping.getAnnotationProcessingOptions().ignoreConstraintAnnotationsOnMember( member, ignoreAnnotations ); + mapping.getAnnotationProcessingOptions().ignoreConstraintAnnotationsOnMember( property, ignoreAnnotations ); return this; } @@ -118,10 +111,10 @@ public ContainerElementConstraintMappingContext containerElementType(int index, } ConstrainedElement build(ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { - if ( member instanceof Field ) { + if ( property instanceof JavaBeanField ) { return new ConstrainedField( ConfigurationSource.API, - (Field) member, + property, getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), getTypeArgumentConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), getCascadingMetaDataBuilder() @@ -130,7 +123,7 @@ ConstrainedElement build(ConstraintHelper constraintHelper, TypeResolutionHelper else { return new ConstrainedExecutable( ConfigurationSource.API, - (Executable) member, + property.as( Callable.class ), getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), getTypeArgumentConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), getCascadingMetaDataBuilder() diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ReturnValueConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ReturnValueConstraintMappingContextImpl.java index df930c5ce6..7b98e80ea1 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ReturnValueConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ReturnValueConstraintMappingContextImpl.java @@ -15,7 +15,6 @@ import org.hibernate.validator.cfg.context.ReturnValueConstraintMappingContext; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.util.ReflectionHelper; /** * Constraint mapping creational context which allows to configure the constraints for one method return value. @@ -31,10 +30,7 @@ final class ReturnValueConstraintMappingContextImpl private final ExecutableConstraintMappingContextImpl executableContext; ReturnValueConstraintMappingContextImpl(ExecutableConstraintMappingContextImpl executableContext) { - super( - executableContext.getTypeContext().getConstraintMapping(), - ReflectionHelper.typeOf( executableContext.getExecutable() ) - ); + super( executableContext.getTypeContext().getConstraintMapping(), executableContext.getCallable().getType() ); this.executableContext = executableContext; } @@ -45,14 +41,14 @@ protected ReturnValueConstraintMappingContext getThis() { @Override public ReturnValueConstraintMappingContext constraint(ConstraintDef definition) { - super.addConstraint( ConfiguredConstraint.forExecutable( definition, executableContext.getExecutable() ) ); + super.addConstraint( ConfiguredConstraint.forExecutable( definition, executableContext.getCallable() ) ); return this; } @Override public ReturnValueConstraintMappingContext ignoreAnnotations(boolean ignoreAnnotations) { mapping.getAnnotationProcessingOptions().ignoreConstraintAnnotationsForReturnValue( - executableContext.getExecutable(), ignoreAnnotations + executableContext.getCallable(), ignoreAnnotations ); return this; } @@ -80,7 +76,7 @@ public ConstructorConstraintMappingContext constructor(Class... parameterType @Override public ContainerElementConstraintMappingContext containerElementType() { return super.containerElement( - this, executableContext.getTypeContext(), ConstraintLocation.forReturnValue( executableContext.getExecutable() ) + this, executableContext.getTypeContext(), ConstraintLocation.forReturnValue( executableContext.getCallable() ) ); } @@ -89,7 +85,7 @@ public ContainerElementConstraintMappingContext containerElementType(int index, return super.containerElement( this, executableContext.getTypeContext(), - ConstraintLocation.forReturnValue( executableContext.getExecutable() ), + ConstraintLocation.forReturnValue( executableContext.getCallable() ), index, nestedIndexes ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index 63275fc6aa..7bc3b920ac 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -12,7 +12,7 @@ import java.lang.annotation.ElementType; import java.lang.invoke.MethodHandles; import java.lang.reflect.Constructor; -import java.lang.reflect.Member; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; @@ -33,6 +33,12 @@ import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.Contracts; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ReflectionHelper; @@ -64,7 +70,7 @@ public final class TypeConstraintMappingContextImpl extends ConstraintMapping private final Set executableContexts = newHashSet(); private final Set propertyContexts = newHashSet(); - private final Set configuredMembers = newHashSet(); + private final Set configuredMembers = newHashSet(); private List> defaultGroupSequence; private Class> defaultGroupSequenceProviderClass; @@ -116,7 +122,7 @@ public PropertyConstraintMappingContext property(String property, ElementType el Contracts.assertNotNull( elementType, "The element type must not be null." ); Contracts.assertNotEmpty( property, MESSAGES.propertyNameMustNotBeEmpty() ); - Member member = getMember( + Property member = getProperty( beanClass, property, elementType ); @@ -148,15 +154,17 @@ public MethodConstraintMappingContext method(String name, Class... parameterT throw LOG.getBeanDoesNotContainMethodException( beanClass, name, parameterTypes ); } - if ( configuredMembers.contains( method ) ) { - throw LOG.getMethodHasAlreadyBeConfiguredViaProgrammaticApiException( + Callable callable = JavaBeanExecutable.of( method ); + + if ( configuredMembers.contains( callable ) ) { + throw LOG.getMethodHasAlreadyBeenConfiguredViaProgrammaticApiException( beanClass, ExecutableHelper.getExecutableAsString( name, parameterTypes ) ); } - MethodConstraintMappingContextImpl context = new MethodConstraintMappingContextImpl( this, method ); - configuredMembers.add( method ); + MethodConstraintMappingContextImpl context = new MethodConstraintMappingContextImpl( this, callable ); + configuredMembers.add( callable ); executableContexts.add( context ); return context; @@ -173,7 +181,9 @@ public ConstructorConstraintMappingContext constructor(Class... parameterType ); } - if ( configuredMembers.contains( constructor ) ) { + Callable callable = JavaBeanExecutable.of( constructor ); + + if ( configuredMembers.contains( callable ) ) { throw LOG.getConstructorHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, ExecutableHelper.getExecutableAsString( beanClass.getSimpleName(), parameterTypes ) @@ -182,9 +192,9 @@ public ConstructorConstraintMappingContext constructor(Class... parameterType ConstructorConstraintMappingContextImpl context = new ConstructorConstraintMappingContextImpl( this, - constructor + callable ); - configuredMembers.add( constructor ); + configuredMembers.add( callable ); executableContexts.add( context ); return context; @@ -246,15 +256,15 @@ protected ConstraintType getConstraintType() { } /** - * Returns the member with the given name and type. + * Returns the property with the given name and type. * - * @param clazz The class from which to retrieve the member. Cannot be {@code null}. + * @param clazz The class from which to retrieve the property. Cannot be {@code null}. * @param property The property name without "is", "get" or "has". Cannot be {@code null} or empty. * @param elementType The element type. Either {@code ElementType.FIELD} or {@code ElementType METHOD}. * - * @return the member which matching the name and type or {@code null} if no such member exists. + * @return the property which matches the name and type or {@code null} if no such property exists. */ - private Member getMember(Class clazz, String property, ElementType elementType) { + private Property getProperty(Class clazz, String property, ElementType elementType) { Contracts.assertNotNull( clazz, MESSAGES.classCannotBeNull() ); if ( property == null || property.length() == 0 ) { @@ -265,20 +275,21 @@ private Member getMember(Class clazz, String property, ElementType elementTyp throw LOG.getElementTypeHasToBeFieldOrMethodException(); } - Member member = null; if ( ElementType.FIELD.equals( elementType ) ) { - member = run( GetDeclaredField.action( clazz, property ) ); + Field field = run( GetDeclaredField.action( clazz, property ) ); + return field == null ? null : new JavaBeanField( field ); } else { + Method method = null; String methodName = property.substring( 0, 1 ).toUpperCase( Locale.ROOT ) + property.substring( 1 ); for ( String prefix : ReflectionHelper.PROPERTY_ACCESSOR_PREFIXES ) { - member = run( GetMethod.action( clazz, prefix + methodName ) ); - if ( member != null ) { + method = run( GetMethod.action( clazz, prefix + methodName ) ); + if ( method != null ) { break; } } + return method == null ? null : new JavaBeanGetter( method ); } - return member; } /** diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java index eecdd5fbbd..59e3ee04c9 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java @@ -39,7 +39,6 @@ public class ConstraintViolationImpl implements HibernateConstraintViolation< private final Map messageParameters; private final Map expressionVariables; private final Class rootBeanClass; - private final ElementType elementType; private final Object[] executableParameters; private final Object executableReturnValue; private final Object dynamicPayload; @@ -161,7 +160,6 @@ private ConstraintViolationImpl(String messageTemplate, this.leafBeanInstance = leafBeanInstance; this.constraintDescriptor = constraintDescriptor; this.rootBeanClass = rootBeanClass; - this.elementType = elementType; this.executableParameters = executableParameters; this.executableReturnValue = executableReturnValue; this.dynamicPayload = dynamicPayload; @@ -296,10 +294,6 @@ public boolean equals(Object o) { if ( constraintDescriptor != null ? !constraintDescriptor.equals( that.constraintDescriptor ) : that.constraintDescriptor != null ) { return false; } - if ( elementType != null ? !elementType.equals( that.elementType ) : that.elementType != null ) { - return false; - } - return true; } @@ -331,7 +325,6 @@ private int createHashCode() { result = 31 * result + System.identityHashCode( value ); result = 31 * result + ( constraintDescriptor != null ? constraintDescriptor.hashCode() : 0 ); result = 31 * result + ( messageTemplate != null ? messageTemplate.hashCode() : 0 ); - result = 31 * result + ( elementType != null ? elementType.hashCode() : 0 ); return result; } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java index 1a2a1d8a1f..04e37dfecb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java @@ -23,8 +23,7 @@ import org.hibernate.validator.internal.metadata.aggregated.BeanMetaData; import org.hibernate.validator.internal.metadata.core.MetaConstraint; 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.PropertyConstraintLocation; import org.hibernate.validator.internal.metadata.location.TypeArgumentConstraintLocation; /** @@ -72,11 +71,8 @@ private String getPropertyName(ConstraintLocation location) { location = ( (TypeArgumentConstraintLocation) location ).getOuterDelegate(); } - if ( location instanceof FieldConstraintLocation ) { - return ( (FieldConstraintLocation) location ).getPropertyName(); - } - else if ( location instanceof GetterConstraintLocation ) { - return ( (GetterConstraintLocation) location ).getPropertyName(); + if ( location instanceof PropertyConstraintLocation ) { + return ( (PropertyConstraintLocation) location ).getPropertyName(); } return null; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java index dedbfd2128..26f691a72d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java @@ -12,8 +12,6 @@ import java.lang.annotation.ElementType; import java.lang.invoke.MethodHandles; import java.lang.reflect.Executable; -import java.lang.reflect.Member; -import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -48,6 +46,7 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; +import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -735,11 +734,11 @@ public BuilderDelegate( case CONSTRUCTOR: case METHOD: ConstrainedExecutable constrainedExecutable = (ConstrainedExecutable) constrainedElement; - Member member = constrainedExecutable.getExecutable(); + Callable member = constrainedExecutable.getCallable(); // HV-890 Not adding meta-data for private super-type methods to the method meta-data of this bean; // It is not needed and it may conflict with sub-type methods of the same signature - if ( !Modifier.isPrivate( member.getModifiers() ) || beanClass == member.getDeclaringClass() ) { + if ( !member.isPrivate() || beanClass == member.getDeclaringClass() ) { methodBuilder = new ExecutableMetaData.Builder( beanClass, constrainedExecutable, diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java index 46d1aa7050..d8c2df456c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java @@ -10,9 +10,6 @@ import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; -import java.lang.reflect.Constructor; -import java.lang.reflect.Executable; -import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Collections; @@ -33,10 +30,10 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; +import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; -import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.stereotypes.Immutable; @@ -260,7 +257,7 @@ public static class Builder extends MetaDataBuilder { */ private final ConstrainedElement.ConstrainedElementKind kind; private final Set constrainedExecutables = newHashSet(); - private Executable executable; + private Callable callable; private final boolean isGetterMethod; private final Set> crossParameterConstraints = newHashSet(); private final Set rules; @@ -293,7 +290,7 @@ public Builder( this.executableHelper = executableHelper; this.parameterNameProvider = parameterNameProvider; this.kind = constrainedExecutable.getKind(); - this.executable = constrainedExecutable.getExecutable(); + this.callable = constrainedExecutable.getCallable(); this.rules = methodValidationConfiguration.getConfiguredRuleSet(); this.isGetterMethod = constrainedExecutable.isGetterMethod(); @@ -306,27 +303,27 @@ public boolean accepts(ConstrainedElement constrainedElement) { return false; } - Executable candidate = ( (ConstrainedExecutable) constrainedElement ).getExecutable(); + Callable candidate = ( (ConstrainedExecutable) constrainedElement ).getCallable(); //are the locations equal (created by different builders) or //does one of the executables override the other one? - return isResolvedToSameMethodInHierarchy( executable, candidate ); + return isResolvedToSameMethodInHierarchy( callable, candidate ); } - private boolean isResolvedToSameMethodInHierarchy(Executable first, Executable other) { - if ( first instanceof Constructor || other instanceof Constructor ) { + private boolean isResolvedToSameMethodInHierarchy(Callable first, Callable other) { + if ( first.isConstructor() || other.isConstructor() ) { return first.equals( other ); } - return executableHelper.isResolvedToSameMethodInHierarchy( getBeanClass(), (Method) first, (Method) other ); + return first.isResolvedToSameMethodInHierarchy( executableHelper, getBeanClass(), other ); } - private boolean overrides(Executable first, Executable other) { - if ( first instanceof Constructor || other instanceof Constructor ) { + private boolean overrides(Callable first, Callable other) { + if ( first.isConstructor() || other.isConstructor() ) { return false; } - return executableHelper.overrides( (Method) first, (Method) other ); + return executableHelper.overrides( first, other ); } @Override @@ -334,7 +331,7 @@ public final void add(ConstrainedElement constrainedElement) { super.add( constrainedElement ); ConstrainedExecutable constrainedExecutable = (ConstrainedExecutable) constrainedElement; - signatures.add( ExecutableHelper.getSignature( constrainedExecutable.getExecutable() ) ); + signatures.add( constrainedExecutable.getCallable().getSignature() ); constrainedExecutables.add( constrainedExecutable ); isConstrained = isConstrained || constrainedExecutable.isConstrained(); @@ -350,11 +347,11 @@ public final void add(ConstrainedElement constrainedElement) { // keep the "lowest" executable in hierarchy to make sure any type parameters declared on super-types (and // used in overridden methods) are resolved for the specific sub-type we are interested in - if ( executable != null && overrides( - constrainedExecutable.getExecutable(), - executable + if ( callable != null && overrides( + constrainedExecutable.getCallable(), + callable ) ) { - executable = constrainedExecutable.getExecutable(); + callable = constrainedExecutable.getCallable(); } } @@ -365,7 +362,7 @@ public final void add(ConstrainedElement constrainedElement) { * @param executable The executable to merge. */ private void addToExecutablesByDeclaringType(ConstrainedExecutable executable) { - Class beanClass = executable.getExecutable().getDeclaringClass(); + Class beanClass = executable.getCallable().getDeclaringClass(); ConstrainedExecutable mergedExecutable = executablesByDeclaringType.get( beanClass ); if ( mergedExecutable != null ) { @@ -383,17 +380,17 @@ public ExecutableMetaData build() { assertCorrectnessOfConfiguration(); return new ExecutableMetaData( - kind == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? executable.getDeclaringClass().getSimpleName() : executable.getName(), - ReflectionHelper.typeOf( executable ), - executable.getParameterTypes(), + kind == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? callable.getDeclaringClass().getSimpleName() : callable.getName(), + callable.getType(), + callable.getParameterTypes(), kind == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? ElementKind.CONSTRUCTOR : ElementKind.METHOD, - kind == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? Collections.singleton( ExecutableHelper.getSignature( executable ) ) : + kind == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? Collections.singleton( callable.getSignature() ) : CollectionHelper.toImmutableSet( signatures ), adaptOriginsAndImplicitGroups( getDirectConstraints() ), adaptOriginsAndImplicitGroups( getContainerElementConstraints() ), findParameterMetaData(), adaptOriginsAndImplicitGroups( crossParameterConstraints ), - cascadingMetaDataBuilder.build( valueExtractorManager, executable ), + cascadingMetaDataBuilder.build( valueExtractorManager, callable ), isConstrained, isGetterMethod ); @@ -416,7 +413,7 @@ private List findParameterMetaData() { for ( ConstrainedParameter oneParameter : oneExecutable.getAllParameterMetaData() ) { parameterBuilders.add( new ParameterMetaData.Builder( - executable.getDeclaringClass(), + callable.getDeclaringClass(), oneParameter, constraintHelper, typeResolutionHelper, diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java deleted file mode 100644 index 6ca82faea5..0000000000 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.metadata.aggregated; - -import java.lang.annotation.ElementType; -import java.lang.reflect.Field; -import java.lang.reflect.Type; -import java.security.AccessController; -import java.security.PrivilegedAction; - -import org.hibernate.validator.HibernateValidatorPermission; -import org.hibernate.validator.internal.engine.path.PathImpl; -import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; -import org.hibernate.validator.internal.metadata.facets.Cascadable; -import org.hibernate.validator.internal.util.ReflectionHelper; -import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredField; - -/** - * A {@link Cascadable} backed by a field of a Java bean. - * - * @author Gunnar Morling - */ -public class FieldCascadable implements Cascadable { - - private final Field field; - private final Type cascadableType; - private final CascadingMetaData cascadingMetaData; - - FieldCascadable(Field field, CascadingMetaData cascadingMetaData) { - this.field = field; - this.cascadableType = ReflectionHelper.typeOf( field ); - this.cascadingMetaData = cascadingMetaData; - } - - @Override - public ElementType getElementType() { - return ElementType.FIELD; - } - - @Override - public Type getCascadableType() { - return cascadableType; - } - - @Override - public Object getValue(Object parent) { - return ReflectionHelper.getValue( field, parent ); - } - - @Override - public void appendTo(PathImpl path) { - path.addPropertyNode( field.getName() ); - } - - @Override - public CascadingMetaData getCascadingMetaData() { - return cascadingMetaData; - } - - public static class Builder implements Cascadable.Builder { - - private final ValueExtractorManager valueExtractorManager; - private final Field field; - private CascadingMetaDataBuilder cascadingMetaDataBuilder; - - public Builder(ValueExtractorManager valueExtractorManager, Field field, CascadingMetaDataBuilder cascadingMetaDataBuilder) { - this.valueExtractorManager = valueExtractorManager; - this.field = field; - this.cascadingMetaDataBuilder = cascadingMetaDataBuilder; - } - - @Override - public void mergeCascadingMetaData(CascadingMetaDataBuilder cascadingMetaData) { - this.cascadingMetaDataBuilder = this.cascadingMetaDataBuilder.merge( cascadingMetaData ); - } - - @Override - public FieldCascadable build() { - return new FieldCascadable( getAccessible( field ), cascadingMetaDataBuilder.build( valueExtractorManager, field ) ); - } - - /** - * Returns an accessible copy of the given member. - */ - private Field getAccessible(Field original) { - SecurityManager sm = System.getSecurityManager(); - if ( sm != null ) { - sm.checkPermission( HibernateValidatorPermission.ACCESS_PRIVATE_MEMBERS ); - } - - Class clazz = original.getDeclaringClass(); - - return run( GetDeclaredField.andMakeAccessible( clazz, original.getName() ) ); - } - - /** - * Runs the given privileged action, using a privileged block if required. - *

- * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary - * privileged actions within HV's protection domain. - */ - private T run(PrivilegedAction action) { - return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run(); - } - } -} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/MetaDataBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/MetaDataBuilder.java index 92e7c077be..66e756da06 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/MetaDataBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/MetaDataBuilder.java @@ -129,7 +129,7 @@ private MetaConstraint adaptOriginAndImplicitGroup(Met ConstraintDescriptorImpl descriptor = new ConstraintDescriptorImpl<>( constraintHelper, - constraint.getLocation().getMember(), + constraint.getLocation().getConstrainable(), constraint.getDescriptor().getAnnotationDescriptor(), constraint.getElementType(), constraintClass.isInterface() ? constraintClass : null, diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java index d175c6e548..c40e659fb1 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java @@ -7,7 +7,6 @@ package org.hibernate.validator.internal.metadata.aggregated; import java.lang.annotation.ElementType; -import java.lang.reflect.Executable; import java.lang.reflect.Type; import java.util.List; import java.util.Set; @@ -24,6 +23,7 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; +import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.TypeResolutionHelper; @@ -112,7 +112,7 @@ public static class Builder extends MetaDataBuilder { private final ExecutableParameterNameProvider parameterNameProvider; private final Type parameterType; private final int parameterIndex; - private Executable executableForNameRetrieval; + private Callable callableForNameRetrieval; private CascadingMetaDataBuilder cascadingMetaDataBuilder; public Builder(Class beanClass, @@ -156,9 +156,9 @@ public void add(ConstrainedElement constrainedElement) { // use this parent class parameter name instead of the more specific one. // Worse case, we are consistent, best case parameters from parents are more meaningful. // See HV-887 and the associated unit test - if ( executableForNameRetrieval == null || - newConstrainedParameter.getExecutable().getDeclaringClass().isAssignableFrom( executableForNameRetrieval.getDeclaringClass() ) ) { - executableForNameRetrieval = newConstrainedParameter.getExecutable(); + if ( callableForNameRetrieval == null || + newConstrainedParameter.getCallable().getDeclaringClass().isAssignableFrom( callableForNameRetrieval.getDeclaringClass() ) ) { + callableForNameRetrieval = newConstrainedParameter.getCallable(); } } @@ -166,11 +166,11 @@ public void add(ConstrainedElement constrainedElement) { public ParameterMetaData build() { return new ParameterMetaData( parameterIndex, - parameterNameProvider.getParameterNames( executableForNameRetrieval ).get( parameterIndex ), + callableForNameRetrieval.getParameterName( parameterNameProvider, parameterIndex ), parameterType, adaptOriginsAndImplicitGroups( getDirectConstraints() ), adaptOriginsAndImplicitGroups( getContainerElementConstraints() ), - cascadingMetaDataBuilder.build( valueExtractorManager, executableForNameRetrieval ) + cascadingMetaDataBuilder.build( valueExtractorManager, callableForNameRetrieval ) ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java similarity index 60% rename from engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java rename to engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java index 72854cfa39..7afa0fd018 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java @@ -7,36 +7,37 @@ package org.hibernate.validator.internal.metadata.aggregated; import java.lang.annotation.ElementType; -import java.lang.reflect.Method; import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.facets.Cascadable; -import org.hibernate.validator.internal.util.ReflectionHelper; +import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; /** - * A {@link Cascadable} backed by a property getter of a Java bean. + * A {@link Cascadable} backed by a field of a Java bean. * * @author Gunnar Morling + * @author Marko Bekhta */ -public class GetterCascadable implements Cascadable { +public class PropertyCascadable implements Cascadable { - private final Method method; - private final String propertyName; + private final Property property; private final Type cascadableType; private final CascadingMetaData cascadingMetaData; + private final ElementType elementType; - GetterCascadable(Method method, CascadingMetaData cascadingMetaData) { - this.method = method; - this.propertyName = ReflectionHelper.getPropertyName( method ); - this.cascadableType = ReflectionHelper.typeOf( method ); + PropertyCascadable(Property property, CascadingMetaData cascadingMetaData) { + this.property = property; + this.cascadableType = property.getType(); this.cascadingMetaData = cascadingMetaData; + this.elementType = property instanceof JavaBeanField ? ElementType.FIELD : ElementType.METHOD; } @Override public ElementType getElementType() { - return ElementType.METHOD; + return elementType; } @Override @@ -46,12 +47,12 @@ public Type getCascadableType() { @Override public Object getValue(Object parent) { - return ReflectionHelper.getValue( method, parent ); + return property.getValueFrom( parent ); } @Override public void appendTo(PathImpl path) { - path.addPropertyNode( propertyName ); + path.addPropertyNode( property.getPropertyName() ); } @Override @@ -62,13 +63,12 @@ public CascadingMetaData getCascadingMetaData() { public static class Builder implements Cascadable.Builder { private final ValueExtractorManager valueExtractorManager; - private final Method method; + private final Property property; private CascadingMetaDataBuilder cascadingMetaDataBuilder; - // Note: the method passed here has to be accessible: the caller is responsible for that - public Builder(ValueExtractorManager valueExtractorManager, Method method, CascadingMetaDataBuilder cascadingMetaDataBuilder) { + public Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { this.valueExtractorManager = valueExtractorManager; - this.method = method; + this.property = property; this.cascadingMetaDataBuilder = cascadingMetaDataBuilder; } @@ -78,8 +78,8 @@ public void mergeCascadingMetaData(CascadingMetaDataBuilder cascadingMetaData) { } @Override - public GetterCascadable build() { - return new GetterCascadable( method, cascadingMetaDataBuilder.build( valueExtractorManager, method ) ); + public PropertyCascadable build() { + return new PropertyCascadable( property, cascadingMetaDataBuilder.build( valueExtractorManager, property ) ); } } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index f616e8e923..7282c947f7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -6,8 +6,6 @@ */ package org.hibernate.validator.internal.metadata.aggregated; -import java.lang.reflect.Field; -import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.security.AccessController; @@ -33,15 +31,17 @@ import org.hibernate.validator.internal.metadata.descriptor.PropertyDescriptorImpl; import org.hibernate.validator.internal.metadata.facets.Cascadable; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.metadata.location.GetterConstraintLocation; +import org.hibernate.validator.internal.metadata.location.PropertyConstraintLocation; import org.hibernate.validator.internal.metadata.location.TypeArgumentConstraintLocation; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.CollectionHelper; -import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredMethod; import org.hibernate.validator.internal.util.stereotypes.Immutable; @@ -157,18 +157,17 @@ public static class Builder extends MetaDataBuilder { ); private final String propertyName; - private final Map cascadableBuilders = new HashMap<>(); + private final Map cascadableBuilders = new HashMap<>(); private final Type propertyType; private boolean cascadingProperty = false; - private Method getterAccessibleMethod; - public Builder(Class beanClass, ConstrainedField constrainedField, ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, + public Builder(Class beanClass, ConstrainedField constrainedProperty, ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { super( beanClass, constraintHelper, typeResolutionHelper, valueExtractorManager ); - this.propertyName = constrainedField.getField().getName(); - this.propertyType = ReflectionHelper.typeOf( constrainedField.getField() ); - add( constrainedField ); + this.propertyName = constrainedProperty.getProperty().getName(); + this.propertyType = constrainedProperty.getProperty().getType(); + add( constrainedProperty ); } public Builder(Class beanClass, ConstrainedType constrainedType, ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, @@ -184,8 +183,8 @@ public Builder(Class beanClass, ConstrainedExecutable constrainedMethod, Cons ValueExtractorManager valueExtractorManager) { super( beanClass, constraintHelper, typeResolutionHelper, valueExtractorManager ); - this.propertyName = ReflectionHelper.getPropertyName( constrainedMethod.getExecutable() ); - this.propertyType = ReflectionHelper.typeOf( constrainedMethod.getExecutable() ); + this.propertyName = constrainedMethod.getCallable().as( Property.class ).getPropertyName(); + this.propertyType = constrainedMethod.getCallable().getType(); add( constrainedMethod ); } @@ -205,12 +204,6 @@ public boolean accepts(ConstrainedElement constrainedElement) { @Override public final void add(ConstrainedElement constrainedElement) { - // if we are in the case of a getter and if we have constraints (either on the annotated object itself or on - // a container element) or cascaded validation, we want to create an accessible version of the getter only once. - if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD && constrainedElement.isConstrained() ) { - getterAccessibleMethod = getAccessible( (Method) ( (ConstrainedExecutable) constrainedElement ).getExecutable() ); - } - super.add( constrainedElement ); cascadingProperty = cascadingProperty || constrainedElement.getCascadingMetaDataBuilder().isCascading(); @@ -218,23 +211,23 @@ public final void add(ConstrainedElement constrainedElement) { if ( constrainedElement.getCascadingMetaDataBuilder().isMarkedForCascadingOnAnnotatedObjectOrContainerElements() || constrainedElement.getCascadingMetaDataBuilder().hasGroupConversionsOnAnnotatedObjectOrContainerElements() ) { if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { - Field field = ( (ConstrainedField) constrainedElement ).getField(); - Cascadable.Builder builder = cascadableBuilders.get( field ); + Property property = ( (ConstrainedField) constrainedElement ).getProperty(); + Cascadable.Builder builder = cascadableBuilders.get( property ); if ( builder == null ) { - builder = new FieldCascadable.Builder( valueExtractorManager, field, constrainedElement.getCascadingMetaDataBuilder() ); - cascadableBuilders.put( field, builder ); + builder = new PropertyCascadable.Builder( valueExtractorManager, property, constrainedElement.getCascadingMetaDataBuilder() ); + cascadableBuilders.put( property, builder ); } else { builder.mergeCascadingMetaData( constrainedElement.getCascadingMetaDataBuilder() ); } } else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { - Method method = (Method) ( (ConstrainedExecutable) constrainedElement ).getExecutable(); + Callable method = ( (ConstrainedExecutable) constrainedElement ).getCallable(); Cascadable.Builder builder = cascadableBuilders.get( method ); if ( builder == null ) { - builder = new GetterCascadable.Builder( valueExtractorManager, getterAccessibleMethod, constrainedElement.getCascadingMetaDataBuilder() ); + builder = new PropertyCascadable.Builder( valueExtractorManager, method.as( Property.class ), constrainedElement.getCascadingMetaDataBuilder() ); cascadableBuilders.put( method, builder ); } else { @@ -250,7 +243,7 @@ protected Set> adaptConstraints(ConstrainedElement constrained return constraints; } - ConstraintLocation getterConstraintLocation = ConstraintLocation.forGetter( getterAccessibleMethod ); + ConstraintLocation getterConstraintLocation = ConstraintLocation.forProperty( ( (ConstrainedExecutable) constrainedElement ).getCallable().as( Property.class ) ); // convert return value locations into getter locations for usage within this meta-data return constraints.stream() @@ -264,7 +257,7 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint // fast track if it's a regular constraint if ( !(constraint.getLocation() instanceof TypeArgumentConstraintLocation) ) { // Change the constraint location to a GetterConstraintLocation if it is not already one - if ( constraint.getLocation() instanceof GetterConstraintLocation ) { + if ( constraint.getLocation() instanceof PropertyConstraintLocation ) { converted = constraint.getLocation(); } else { @@ -291,7 +284,7 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint for ( ConstraintLocation location : locationStack ) { if ( !(location instanceof TypeArgumentConstraintLocation) ) { // Change the constraint location to a GetterConstraintLocation if it is not already one - if ( location instanceof GetterConstraintLocation ) { + if ( location instanceof PropertyConstraintLocation ) { converted = location; } else { @@ -313,10 +306,10 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint private String getPropertyName(ConstrainedElement constrainedElement) { if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { - return ReflectionHelper.getPropertyName( ( (ConstrainedField) constrainedElement ).getField() ); + return ( (ConstrainedField) constrainedElement ).getProperty().getPropertyName(); } else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { - return ReflectionHelper.getPropertyName( ( (ConstrainedExecutable) constrainedElement ).getExecutable() ); + return ( (ConstrainedExecutable) constrainedElement ).getCallable().as( Property.class ).getPropertyName(); } return null; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/MethodConfigurationRule.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/MethodConfigurationRule.java index c7d1831283..7b4eeffd7e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/MethodConfigurationRule.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/MethodConfigurationRule.java @@ -54,8 +54,8 @@ protected boolean isStrictSubType(Class clazz, Class otherClazz) { * {@code otherExecutable}, {@code false} otherwise */ protected boolean isDefinedOnSubType(ConstrainedExecutable executable, ConstrainedExecutable otherExecutable) { - Class clazz = executable.getExecutable().getDeclaringClass(); - Class otherClazz = otherExecutable.getExecutable().getDeclaringClass(); + Class clazz = executable.getCallable().getDeclaringClass(); + Class otherClazz = otherExecutable.getCallable().getDeclaringClass(); return isStrictSubType( clazz, otherClazz ); } @@ -71,8 +71,8 @@ protected boolean isDefinedOnSubType(ConstrainedExecutable executable, Constrain * {@code otherExecutable}, {@code false} otherwise */ protected boolean isDefinedOnParallelType(ConstrainedExecutable executable, ConstrainedExecutable otherExecutable) { - Class clazz = executable.getExecutable().getDeclaringClass(); - Class otherClazz = otherExecutable.getExecutable().getDeclaringClass(); + Class clazz = executable.getCallable().getDeclaringClass(); + Class otherClazz = otherExecutable.getCallable().getDeclaringClass(); return !( clazz.isAssignableFrom( otherClazz ) || otherClazz.isAssignableFrom( clazz ) ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/OverridingMethodMustNotAlterParameterConstraints.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/OverridingMethodMustNotAlterParameterConstraints.java index 2e402c25bb..2b88e5e953 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/OverridingMethodMustNotAlterParameterConstraints.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/OverridingMethodMustNotAlterParameterConstraints.java @@ -22,8 +22,8 @@ public void apply(ConstrainedExecutable method, ConstrainedExecutable otherMetho otherMethod.hasParameterConstraints() && !method.isEquallyParameterConstrained( otherMethod ) ) { throw LOG.getParameterConfigurationAlteredInSubTypeException( - method.getExecutable(), - otherMethod.getExecutable() + method.getCallable(), + otherMethod.getCallable() ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ParallelMethodsMustNotDefineGroupConversionForCascadedReturnValue.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ParallelMethodsMustNotDefineGroupConversionForCascadedReturnValue.java index 4546d1278e..69cc7debfb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ParallelMethodsMustNotDefineGroupConversionForCascadedReturnValue.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ParallelMethodsMustNotDefineGroupConversionForCascadedReturnValue.java @@ -25,8 +25,8 @@ public void apply(ConstrainedExecutable method, ConstrainedExecutable otherMetho if ( isDefinedOnParallelType( method, otherMethod ) && isCascaded && hasGroupConversions ) { throw LOG.getMethodsFromParallelTypesMustNotDefineGroupConversionsForCascadedReturnValueException( - method.getExecutable(), - otherMethod.getExecutable() + method.getCallable(), + otherMethod.getCallable() ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ParallelMethodsMustNotDefineParameterConstraints.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ParallelMethodsMustNotDefineParameterConstraints.java index 2023e3ab2d..12abf849b4 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ParallelMethodsMustNotDefineParameterConstraints.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ParallelMethodsMustNotDefineParameterConstraints.java @@ -21,8 +21,8 @@ public void apply(ConstrainedExecutable method, ConstrainedExecutable otherMetho if ( isDefinedOnParallelType( method, otherMethod ) && ( method.hasParameterConstraints() || otherMethod.hasParameterConstraints() ) ) { throw LOG.getParameterConstraintsDefinedInMethodsFromParallelTypesException( - method.getExecutable(), - otherMethod.getExecutable() + method.getCallable(), + otherMethod.getCallable() ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ReturnValueMayOnlyBeMarkedOnceAsCascadedPerHierarchyLine.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ReturnValueMayOnlyBeMarkedOnceAsCascadedPerHierarchyLine.java index 7bac3875e9..f29b70cc94 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ReturnValueMayOnlyBeMarkedOnceAsCascadedPerHierarchyLine.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/ReturnValueMayOnlyBeMarkedOnceAsCascadedPerHierarchyLine.java @@ -22,8 +22,8 @@ public void apply(ConstrainedExecutable method, ConstrainedExecutable otherMetho otherMethod.getCascadingMetaDataBuilder().isMarkedForCascadingOnAnnotatedObjectOrContainerElements() && ( isDefinedOnSubType( method, otherMethod ) || isDefinedOnSubType( otherMethod, method ) ) ) { throw LOG.getMethodReturnValueMustNotBeMarkedMoreThanOnceForCascadedValidationException( - method.getExecutable(), - otherMethod.getExecutable() + method.getCallable(), + otherMethod.getCallable() ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/VoidMethodsMustNotBeReturnValueConstrained.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/VoidMethodsMustNotBeReturnValueConstrained.java index 3344bd0515..15600a1876 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/VoidMethodsMustNotBeReturnValueConstrained.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/rule/VoidMethodsMustNotBeReturnValueConstrained.java @@ -6,8 +6,6 @@ */ package org.hibernate.validator.internal.metadata.aggregated.rule; -import java.lang.reflect.Method; - import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; /** @@ -20,11 +18,10 @@ public class VoidMethodsMustNotBeReturnValueConstrained extends MethodConfigurat @Override public void apply(ConstrainedExecutable executable, ConstrainedExecutable otherExecutable) { - if ( ( executable.getExecutable() instanceof Method ) && - ( (Method) executable.getExecutable() ).getReturnType() == void.class && + if ( !executable.getCallable().hasReturnValue() && ( !executable.getConstraints().isEmpty() || executable.getCascadingMetaDataBuilder().isMarkedForCascadingOnAnnotatedObjectOrContainerElements() ) ) { - throw LOG.getVoidMethodsMustNotBeConstrainedException( executable.getExecutable() ); + throw LOG.getVoidMethodsMustNotBeConstrainedException( executable.getCallable() ); } } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/AnnotationProcessingOptions.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/AnnotationProcessingOptions.java index 5e80ed6b4b..dfbc674ff8 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/AnnotationProcessingOptions.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/AnnotationProcessingOptions.java @@ -6,7 +6,7 @@ */ package org.hibernate.validator.internal.metadata.core; -import java.lang.reflect.Member; +import org.hibernate.validator.internal.properties.Constrainable; /** * An {@code AnnotationProcessingOptions} instance keeps track of annotations which should be ignored as configuration source. @@ -18,13 +18,13 @@ public interface AnnotationProcessingOptions { boolean areClassLevelConstraintsIgnoredFor(Class clazz); - boolean areMemberConstraintsIgnoredFor(Member member); + boolean areMemberConstraintsIgnoredFor(Constrainable constrainable); - boolean areReturnValueConstraintsIgnoredFor(Member member); + boolean areReturnValueConstraintsIgnoredFor(Constrainable constrainable); - boolean areCrossParameterConstraintsIgnoredFor(Member member); + boolean areCrossParameterConstraintsIgnoredFor(Constrainable constrainable); - boolean areParameterConstraintsIgnoredFor(Member member, int index); + boolean areParameterConstraintsIgnoredFor(Constrainable constrainable, int index); void merge(AnnotationProcessingOptions annotationProcessingOptions); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/AnnotationProcessingOptionsImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/AnnotationProcessingOptionsImpl.java index 11bc7d6ccf..b0746a0bdd 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/AnnotationProcessingOptionsImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/AnnotationProcessingOptionsImpl.java @@ -6,15 +6,15 @@ */ package org.hibernate.validator.internal.metadata.core; +import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; + import java.lang.invoke.MethodHandles; -import java.lang.reflect.Member; import java.util.Map; +import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; -import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; - /** * An {@code AnnotationProcessingOptions} instance keeps track of annotations which should be ignored as configuration source. * The main validation source for Bean Validation is annotation and alternate configuration sources use this class @@ -40,17 +40,17 @@ public class AnnotationProcessingOptionsImpl implements AnnotationProcessingOpti /** * Keeps track of explicitly excluded members (fields and properties). */ - private final Map annotationIgnoredForMembers = newHashMap(); + private final Map annotationIgnoredForMembers = newHashMap(); /** * Keeps track of explicitly excluded return value constraints for methods/constructors. */ - private final Map annotationIgnoresForReturnValues = newHashMap(); + private final Map annotationIgnoresForReturnValues = newHashMap(); /** * Keeps track of explicitly excluded cross parameter constraints for methods/constructors. */ - private final Map annotationIgnoresForCrossParameter = newHashMap(); + private final Map annotationIgnoresForCrossParameter = newHashMap(); /** * Keeps track whether the 'ignore-annotations' flag is set on a method/constructor parameter @@ -58,10 +58,10 @@ public class AnnotationProcessingOptionsImpl implements AnnotationProcessingOpti private final Map annotationIgnoresForMethodParameter = newHashMap(); @Override - public boolean areMemberConstraintsIgnoredFor(Member member) { - Class clazz = member.getDeclaringClass(); - if ( annotationIgnoredForMembers.containsKey( member ) ) { - return annotationIgnoredForMembers.get( member ); + public boolean areMemberConstraintsIgnoredFor(Constrainable constrainable) { + Class clazz = constrainable.getDeclaringClass(); + if ( annotationIgnoredForMembers.containsKey( constrainable ) ) { + return annotationIgnoredForMembers.get( constrainable ); } else { return areAllConstraintAnnotationsIgnoredFor( clazz ); @@ -69,33 +69,33 @@ public boolean areMemberConstraintsIgnoredFor(Member member) { } @Override - public boolean areReturnValueConstraintsIgnoredFor(Member member) { - if ( annotationIgnoresForReturnValues.containsKey( member ) ) { - return annotationIgnoresForReturnValues.get( member ); + public boolean areReturnValueConstraintsIgnoredFor(Constrainable constrainable) { + if ( annotationIgnoresForReturnValues.containsKey( constrainable ) ) { + return annotationIgnoresForReturnValues.get( constrainable ); } else { - return areMemberConstraintsIgnoredFor( member ); + return areMemberConstraintsIgnoredFor( constrainable ); } } @Override - public boolean areCrossParameterConstraintsIgnoredFor(Member member) { - if ( annotationIgnoresForCrossParameter.containsKey( member ) ) { - return annotationIgnoresForCrossParameter.get( member ); + public boolean areCrossParameterConstraintsIgnoredFor(Constrainable constrainable) { + if ( annotationIgnoresForCrossParameter.containsKey( constrainable ) ) { + return annotationIgnoresForCrossParameter.get( constrainable ); } else { - return areMemberConstraintsIgnoredFor( member ); + return areMemberConstraintsIgnoredFor( constrainable ); } } @Override - public boolean areParameterConstraintsIgnoredFor(Member member, int index) { - ExecutableParameterKey key = new ExecutableParameterKey( member, index ); + public boolean areParameterConstraintsIgnoredFor(Constrainable constrainable, int index) { + ExecutableParameterKey key = new ExecutableParameterKey( constrainable, index ); if ( annotationIgnoresForMethodParameter.containsKey( key ) ) { return annotationIgnoresForMethodParameter.get( key ); } else { - return areMemberConstraintsIgnoredFor( member ); + return areMemberConstraintsIgnoredFor( constrainable ); } } @@ -138,19 +138,19 @@ public void ignoreAnnotationConstraintForClass(Class clazz, Boolean b) { } } - public void ignoreConstraintAnnotationsOnMember(Member member, Boolean b) { + public void ignoreConstraintAnnotationsOnMember(Constrainable member, Boolean b) { annotationIgnoredForMembers.put( member, b ); } - public void ignoreConstraintAnnotationsForReturnValue(Member member, Boolean b) { + public void ignoreConstraintAnnotationsForReturnValue(Constrainable member, Boolean b) { annotationIgnoresForReturnValues.put( member, b ); } - public void ignoreConstraintAnnotationsForCrossParameterConstraint(Member member, Boolean b) { + public void ignoreConstraintAnnotationsForCrossParameterConstraint(Constrainable member, Boolean b) { annotationIgnoresForCrossParameter.put( member, b ); } - public void ignoreConstraintAnnotationsOnParameter(Member member, int index, Boolean b) { + public void ignoreConstraintAnnotationsOnParameter(Constrainable member, int index, Boolean b) { ExecutableParameterKey key = new ExecutableParameterKey( member, index ); annotationIgnoresForMethodParameter.put( key, b ); } @@ -164,11 +164,11 @@ private boolean areAllConstraintAnnotationsIgnoredFor(Class clazz) { } public class ExecutableParameterKey { - private final Member member; + private final Constrainable constrainable; private final int index; - public ExecutableParameterKey(Member member, int index) { - this.member = member; + public ExecutableParameterKey(Constrainable constrainable, int index) { + this.constrainable = constrainable; this.index = index; } @@ -186,7 +186,7 @@ public boolean equals(Object o) { if ( index != that.index ) { return false; } - if ( member != null ? !member.equals( that.member ) : that.member != null ) { + if ( constrainable != null ? !constrainable.equals( that.constrainable ) : that.constrainable != null ) { return false; } @@ -195,7 +195,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - int result = member != null ? member.hashCode() : 0; + int result = constrainable != null ? constrainable.hashCode() : 0; result = 31 * result + index; return result; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java index 094c6e54b2..edecfb516c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java @@ -17,10 +17,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.lang.reflect.Member; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; @@ -49,6 +45,9 @@ import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorDescriptor; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.ConstraintOrigin; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.StringHelper; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; @@ -164,7 +163,7 @@ public class ConstraintDescriptorImpl implements Constrain private final int hashCode; public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, - Member member, + Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, ElementType type, Class implicitGroup, @@ -182,7 +181,7 @@ public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, this.groups = buildGroupSet( annotationDescriptor, implicitGroup ); this.payloads = buildPayloadSet( annotationDescriptor ); - this.valueUnwrapping = determineValueUnwrapping( this.payloads, member, annotationDescriptor.getType() ); + this.valueUnwrapping = determineValueUnwrapping( this.payloads, constrainable, annotationDescriptor.getType() ); this.validationAppliesTo = determineValidationAppliesTo( annotationDescriptor ); @@ -206,13 +205,13 @@ public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, this.constraintType = determineConstraintType( annotationDescriptor.getType(), - member, + constrainable, type, !genericValidatorDescriptors.isEmpty(), !crossParameterValidatorDescriptors.isEmpty(), externalConstraintType ); - this.composingConstraints = parseComposingConstraints( constraintHelper, member, constraintType ); + this.composingConstraints = parseComposingConstraints( constraintHelper, constrainable, constraintType ); this.compositionType = parseCompositionType( constraintHelper ); validateComposingConstraintTypes(); @@ -227,18 +226,18 @@ public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, } public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, - Member member, + Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, ElementType type) { - this( constraintHelper, member, annotationDescriptor, type, null, ConstraintOrigin.DEFINED_LOCALLY, null ); + this( constraintHelper, constrainable, annotationDescriptor, type, null, ConstraintOrigin.DEFINED_LOCALLY, null ); } public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, - Member member, + Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, ElementType type, ConstraintType constraintType) { - this( constraintHelper, member, annotationDescriptor, type, null, ConstraintOrigin.DEFINED_LOCALLY, constraintType ); + this( constraintHelper, constrainable, annotationDescriptor, type, null, ConstraintOrigin.DEFINED_LOCALLY, constraintType ); } public ConstraintAnnotationDescriptor getAnnotationDescriptor() { @@ -389,7 +388,7 @@ public String toString() { * specify the target explicitly). * * - * @param member The annotated member + * @param constrainable The annotated member * @param elementType The type of the annotated element * @param hasGenericValidators Whether the constraint has at least one generic validator or * not @@ -400,7 +399,7 @@ public String toString() { * @return The type of this constraint */ private ConstraintType determineConstraintType(Class constraintAnnotationType, - Member member, + Constrainable constrainable, ElementType elementType, boolean hasGenericValidators, boolean hasCrossParameterValidator, @@ -453,9 +452,10 @@ else if ( constraintAnnotationType.isAnnotationPresent( SupportedValidationTarge } //try to derive from existence of parameters/return value - else { - boolean hasParameters = hasParameters( member ); - boolean hasReturnValue = hasReturnValue( member ); + //hence look only if it is a callable + else if ( constrainable instanceof Callable ) { + boolean hasParameters = constrainable.as( Callable.class ).hasParameters(); + boolean hasReturnValue = constrainable.as( Callable.class ).hasReturnValue(); if ( !hasParameters && hasReturnValue ) { constraintType = ConstraintType.GENERIC; @@ -472,16 +472,16 @@ else if ( hasParameters && !hasReturnValue ) { } if ( constraintType == ConstraintType.CROSS_PARAMETER ) { - validateCrossParameterConstraintType( member, hasCrossParameterValidator ); + validateCrossParameterConstraintType( constrainable, hasCrossParameterValidator ); } return constraintType; } - private static ValidateUnwrappedValue determineValueUnwrapping(Set> payloads, Member member, Class annotationType) { + private static ValidateUnwrappedValue determineValueUnwrapping(Set> payloads, Constrainable constrainable, Class annotationType) { if ( payloads.contains( Unwrapping.Unwrap.class ) ) { if ( payloads.contains( Unwrapping.Skip.class ) ) { - throw LOG.getInvalidUnwrappingConfigurationForConstraintException( member, annotationType ); + throw LOG.getInvalidUnwrappingConfigurationForConstraintException( constrainable, annotationType ); } return ValidateUnwrappedValue.UNWRAP; @@ -498,20 +498,20 @@ private static ConstraintTarget determineValidationAppliesTo(ConstraintAnnotatio return annotationDescriptor.getValidationAppliesTo(); } - private void validateCrossParameterConstraintType(Member member, boolean hasCrossParameterValidator) { + private void validateCrossParameterConstraintType(Constrainable constrainable, boolean hasCrossParameterValidator) { if ( !hasCrossParameterValidator ) { throw LOG.getCrossParameterConstraintHasNoValidatorException( annotationDescriptor.getType() ); } - else if ( member == null ) { + else if ( constrainable == null ) { throw LOG.getCrossParameterConstraintOnClassException( annotationDescriptor.getType() ); } - else if ( member instanceof Field ) { - throw LOG.getCrossParameterConstraintOnFieldException( annotationDescriptor.getType(), member ); + else if ( constrainable instanceof Property ) { + throw LOG.getCrossParameterConstraintOnFieldException( annotationDescriptor.getType(), constrainable ); } - else if ( !hasParameters( member ) ) { + else if ( !constrainable.as( Callable.class ).hasParameters() ) { throw LOG.getCrossParameterConstraintOnMethodWithoutParametersException( annotationDescriptor.getType(), - (Executable) member + constrainable ); } } @@ -533,35 +533,6 @@ private void validateComposingConstraintTypes() { } } - private boolean hasParameters(Member member) { - boolean hasParameters = false; - if ( member instanceof Constructor ) { - Constructor constructor = (Constructor) member; - hasParameters = constructor.getParameterTypes().length > 0; - } - else if ( member instanceof Method ) { - Method method = (Method) member; - hasParameters = method.getParameterTypes().length > 0; - } - return hasParameters; - } - - private boolean hasReturnValue(Member member) { - boolean hasReturnValue; - if ( member instanceof Constructor ) { - hasReturnValue = true; - } - else if ( member instanceof Method ) { - Method method = (Method) member; - hasReturnValue = method.getGenericReturnType() != void.class; - } - else { - // field or type - hasReturnValue = false; - } - return hasReturnValue; - } - private boolean isExecutable(ElementType elementType) { return elementType == ElementType.METHOD || elementType == ElementType.CONSTRUCTOR; } @@ -648,7 +619,7 @@ private void ensureAttributeIsOverridable(Method m, OverridesAttribute overrides } } - private Set> parseComposingConstraints(ConstraintHelper constraintHelper, Member member, + private Set> parseComposingConstraints(ConstraintHelper constraintHelper, Constrainable constrainable, ConstraintType constraintType) { Set> composingConstraintsSet = newHashSet(); Map> overrideParameters = parseOverrideParameters(); @@ -669,7 +640,7 @@ private Set> parseComposingConstraints(ConstraintHel ConstraintDescriptorImpl descriptor = createComposingConstraintDescriptor( constraintHelper, - member, + constrainable, overrideParameters, OVERRIDES_PARAMETER_DEFAULT_INDEX, declaredAnnotation, @@ -691,7 +662,7 @@ else if ( constraintHelper.isMultiValueConstraint( declaredAnnotationType ) ) { ConstraintDescriptorImpl descriptor = createComposingConstraintDescriptor( constraintHelper, - member, + constrainable, overrideParameters, index, constraintAnnotation, @@ -727,7 +698,7 @@ private CompositionType parseCompositionType(ConstraintHelper constraintHelper) private ConstraintDescriptorImpl createComposingConstraintDescriptor( ConstraintHelper constraintHelper, - Member member, + Constrainable constrainable, Map> overrideParameters, int index, U constraintAnnotation, @@ -773,7 +744,7 @@ annotationType, run( GetAnnotationAttributes.action( constraintAnnotation ) ) } return new ConstraintDescriptorImpl<>( - constraintHelper, member, annotationDescriptorBuilder.build(), elementType, null, definedOn, constraintType + constraintHelper, constrainable, annotationDescriptorBuilder.build(), elementType, null, definedOn, constraintType ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/BeanConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/BeanConstraintLocation.java index e8a573f27b..d6d8f3a0ab 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/BeanConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/BeanConstraintLocation.java @@ -6,10 +6,10 @@ */ package org.hibernate.validator.internal.metadata.location; -import java.lang.reflect.Member; import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.TypeHelper; @@ -47,7 +47,7 @@ public Class getDeclaringClass() { } @Override - public Member getMember() { + public Constrainable getConstrainable() { return null; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index 1277f85051..a5626998c5 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -6,14 +6,13 @@ */ package org.hibernate.validator.internal.metadata.location; -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; /** @@ -39,49 +38,24 @@ static ConstraintLocation forClass(Class declaringClass) { return new BeanConstraintLocation( declaringClass ); } - static ConstraintLocation forField(Field field) { - return new FieldConstraintLocation( field ); - } - - /** - * Create a new {@link GetterConstraintLocation} for the given getter method. - * - * @param getter The getter method being constrained - * @return A new GetterConstraintLocation - */ - static ConstraintLocation forGetter(Method getter) { - return new GetterConstraintLocation( getter.getDeclaringClass(), getter ); - } - - /** - * Create a new {@link GetterConstraintLocation} for the given declaring class and getter method. - *

- * This provides an alternative to {@link ConstraintLocation#forGetter(Method)} where the given declaring class is usually a sub-class of the - * actual class on which the getter method is declared. This is provided to support XML mapping configurations used to specify constraints on - * subclasses for inherited getter methods. - * - * @param declaringClass The class on which the constraint is defined. - * @param getter The getter method being constrained. - * @return A new GetterConstraintLocation - */ - static ConstraintLocation forGetter(Class declaringClass, Method getter ) { - return new GetterConstraintLocation( declaringClass, getter ); + static ConstraintLocation forProperty(Property property) { + return new PropertyConstraintLocation( property ); } static ConstraintLocation forTypeArgument(ConstraintLocation delegate, TypeVariable typeParameter, Type typeOfAnnotatedElement) { return new TypeArgumentConstraintLocation( delegate, typeParameter, typeOfAnnotatedElement ); } - static ConstraintLocation forReturnValue(Executable executable) { - return new ReturnValueConstraintLocation( executable ); + static ConstraintLocation forReturnValue(Callable callable) { + return new ReturnValueConstraintLocation( callable ); } - static ConstraintLocation forCrossParameter(Executable executable) { - return new CrossParameterConstraintLocation( executable ); + static ConstraintLocation forCrossParameter(Callable callable) { + return new CrossParameterConstraintLocation( callable ); } - static ConstraintLocation forParameter(Executable executable, int index) { - return new ParameterConstraintLocation( executable, index ); + static ConstraintLocation forParameter(Callable callable, int index) { + return new ParameterConstraintLocation( callable, index ); } /** @@ -94,7 +68,7 @@ static ConstraintLocation forParameter(Executable executable, int index) { * * @return the member represented by this location. Will be {@code null} when this location represents a type. */ - Member getMember(); + Constrainable getConstrainable(); /** * Returns the type to be used when resolving constraint validators for constraints at this location. Note that this @@ -112,7 +86,7 @@ static ConstraintLocation forParameter(Executable executable, int index) { /** * Obtains the value of this location from the parent. The type of the passed parent depends on the location type, - * e.g. a bean would be passed for a {@link FieldConstraintLocation} or {@link GetterConstraintLocation} but an + * e.g. a bean would be passed for a {@link PropertyConstraintLocation} but an * object array for a {@link ParameterConstraintLocation}. */ Object getValue(Object parent); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java index 0c127fbb0f..549ab73e1e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java @@ -6,11 +6,11 @@ */ package org.hibernate.validator.internal.metadata.location; -import java.lang.reflect.Executable; -import java.lang.reflect.Member; import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; /** @@ -21,20 +21,20 @@ */ class CrossParameterConstraintLocation implements ConstraintLocation { - private final Executable executable; + private final Callable callable; - CrossParameterConstraintLocation(Executable executable) { - this.executable = executable; + CrossParameterConstraintLocation(Callable executable) { + this.callable = executable; } @Override public Class getDeclaringClass() { - return executable.getDeclaringClass(); + return callable.getDeclaringClass(); } @Override - public Member getMember() { - return executable; + public Constrainable getConstrainable() { + return callable; } @Override @@ -54,15 +54,12 @@ public Object getValue(Object parent) { @Override public String toString() { - return "CrossParameterConstraintLocation [executable=" + executable + "]"; + return "CrossParameterConstraintLocation [callable=" + callable + "]"; } @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ( ( executable == null ) ? 0 : executable.hashCode() ); - return result; + return callable.hashCode(); } @Override @@ -77,12 +74,7 @@ public boolean equals(Object obj) { return false; } CrossParameterConstraintLocation other = (CrossParameterConstraintLocation) obj; - if ( executable == null ) { - if ( other.executable != null ) { - return false; - } - } - else if ( !executable.equals( other.executable ) ) { + if ( !callable.equals( other.callable ) ) { return false; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java index 8c816b2299..c51b9308aa 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java @@ -6,11 +6,11 @@ */ package org.hibernate.validator.internal.metadata.location; -import java.lang.reflect.Executable; -import java.lang.reflect.Member; import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.ReflectionHelper; @@ -22,24 +22,24 @@ */ public class ParameterConstraintLocation implements ConstraintLocation { - private final Executable executable; + private final Callable callable; private final int index; private final Type typeForValidatorResolution; - ParameterConstraintLocation(Executable executable, int index) { - this.executable = executable; + public ParameterConstraintLocation(Callable callable, int index) { + this.callable = callable; this.index = index; - this.typeForValidatorResolution = ReflectionHelper.boxedType( ReflectionHelper.typeOf( executable, index ) ); + this.typeForValidatorResolution = ReflectionHelper.boxedType( callable.getTypeOfParameter( index ) ); } @Override public Class getDeclaringClass() { - return executable.getDeclaringClass(); + return callable.getDeclaringClass(); } @Override - public Member getMember() { - return executable; + public Constrainable getConstrainable() { + return callable; } @Override @@ -53,8 +53,7 @@ public int getIndex() { @Override public void appendTo(ExecutableParameterNameProvider parameterNameProvider, PathImpl path) { - String name = parameterNameProvider.getParameterNames( executable ).get( index ); - path.addParameterNode( name, index ); + path.addParameterNode( callable.getParameterName( parameterNameProvider, index ), index ); } @Override @@ -64,15 +63,14 @@ public Object getValue(Object parent) { @Override public String toString() { - return "ParameterConstraintLocation [executable=" + executable + ", index=" + index - + ", typeForValidatorResolution=" + typeForValidatorResolution + "]"; + return "ParameterConstraintLocation [executable=" + callable + ", index=" + index + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ( ( executable == null ) ? 0 : executable.hashCode() ); + result = prime * result + callable.hashCode(); result = prime * result + index; return result; } @@ -89,12 +87,7 @@ public boolean equals(Object obj) { return false; } ParameterConstraintLocation other = (ParameterConstraintLocation) obj; - if ( executable == null ) { - if ( other.executable != null ) { - return false; - } - } - else if ( !executable.equals( other.executable ) ) { + if ( !callable.equals( other.callable ) ) { return false; } if ( index != other.index ) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java new file mode 100644 index 0000000000..78b9ccc4b0 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java @@ -0,0 +1,88 @@ +/* + * 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.metadata.location; + +import java.lang.reflect.Type; + +import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; + +/** + * Property constraint location. + * + * @author Marko Bekhta + */ +public class PropertyConstraintLocation implements ConstraintLocation { + + /** + * The member the constraint was defined on. + */ + private final Property property; + + PropertyConstraintLocation(Property property) { + this.property = property; + } + + @Override + public Class getDeclaringClass() { + return property.getDeclaringClass(); + } + + @Override + public Constrainable getConstrainable() { + return property; + } + + public String getPropertyName() { + return property.getPropertyName(); + } + + @Override + public Type getTypeForValidatorResolution() { + return property.getTypeForValidatorResolution(); + } + + @Override + public void appendTo(ExecutableParameterNameProvider parameterNameProvider, PathImpl path) { + path.addPropertyNode( property.getPropertyName() ); + } + + @Override + public Object getValue(Object parent) { + return property.getValueFrom( parent ); + } + + @Override + public String toString() { + return "PropertyConstraintLocation [property=" + property + "]"; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + PropertyConstraintLocation that = (PropertyConstraintLocation) o; + + if ( !property.equals( that.property ) ) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + return property.hashCode(); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java index b6ac18e2ca..30c66c5889 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java @@ -6,43 +6,41 @@ */ package org.hibernate.validator.internal.metadata.location; -import java.lang.reflect.Executable; -import java.lang.reflect.Member; import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; -import org.hibernate.validator.internal.util.ReflectionHelper; /** * Executable return value constraint location. * * @author Hardy Ferentschik * @author Gunnar Morling + * @author Marko Bekhta */ class ReturnValueConstraintLocation implements ConstraintLocation { - private final Executable executable; - private final Type typeForValidatorResolution; + private final Callable callable; - ReturnValueConstraintLocation(Executable executable) { - this.executable = executable; - this.typeForValidatorResolution = ReflectionHelper.boxedType( ReflectionHelper.typeOf( executable ) ); + ReturnValueConstraintLocation(Callable callable) { + this.callable = callable; } @Override public Class getDeclaringClass() { - return executable.getDeclaringClass(); + return callable.getDeclaringClass(); } @Override - public Member getMember() { - return executable; + public Constrainable getConstrainable() { + return callable; } @Override public Type getTypeForValidatorResolution() { - return typeForValidatorResolution; + return callable.getTypeForValidatorResolution(); } @Override @@ -57,14 +55,14 @@ public Object getValue(Object parent) { @Override public String toString() { - return "ReturnValueConstraintLocation [executable=" + executable + "]"; + return "ReturnValueConstraintLocation [executable=" + callable + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ( ( executable == null ) ? 0 : executable.hashCode() ); + result = prime * result + callable.hashCode(); return result; } @@ -80,12 +78,7 @@ public boolean equals(Object obj) { return false; } ReturnValueConstraintLocation other = (ReturnValueConstraintLocation) obj; - if ( executable == null ) { - if ( other.executable != null ) { - return false; - } - } - else if ( !executable.equals( other.executable ) ) { + if ( !callable.equals( other.callable ) ) { return false; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/TypeArgumentConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/TypeArgumentConstraintLocation.java index 989d8a2c76..d470c8c8bd 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/TypeArgumentConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/TypeArgumentConstraintLocation.java @@ -6,11 +6,11 @@ */ package org.hibernate.validator.internal.metadata.location; -import java.lang.reflect.Member; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.StringHelper; @@ -52,8 +52,8 @@ public Class getDeclaringClass() { } @Override - public Member getMember() { - return delegate.getMember(); + public Constrainable getConstrainable() { + return delegate.getConstrainable(); } public TypeVariable getTypeParameter() { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index 1b387b8e13..12aeaa9e06 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -63,8 +63,12 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedField; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.util.CollectionHelper; -import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; @@ -214,45 +218,46 @@ private Set getFieldMetaData(Class beanClass) { Set propertyMetaData = newHashSet(); for ( Field field : run( GetDeclaredFields.action( beanClass ) ) ) { + Property property = new JavaBeanField( field ); // HV-172 if ( Modifier.isStatic( field.getModifiers() ) || - annotationProcessingOptions.areMemberConstraintsIgnoredFor( field ) || + annotationProcessingOptions.areMemberConstraintsIgnoredFor( property ) || field.isSynthetic() ) { continue; } - propertyMetaData.add( findPropertyMetaData( field ) ); + propertyMetaData.add( findPropertyMetaData( field, property ) ); } return propertyMetaData; } - private ConstrainedField findPropertyMetaData(Field field) { + private ConstrainedField findPropertyMetaData(Field field, Property property) { Set> constraints = convertToMetaConstraints( - findConstraints( field, ElementType.FIELD ), - field + findConstraints( field, ElementType.FIELD, property ), + property ); CascadingMetaDataBuilder cascadingMetaDataBuilder = findCascadingMetaData( field ); - Set> typeArgumentsConstraints = findTypeAnnotationConstraints( field ); + Set> typeArgumentsConstraints = findTypeAnnotationConstraints( field, property ); return new ConstrainedField( ConfigurationSource.ANNOTATION, - field, + property, constraints, typeArgumentsConstraints, cascadingMetaDataBuilder ); } - private Set> convertToMetaConstraints(List> constraintDescriptors, Field field) { + private Set> convertToMetaConstraints(List> constraintDescriptors, Property property) { if ( constraintDescriptors.isEmpty() ) { return Collections.emptySet(); } Set> constraints = newHashSet(); - ConstraintLocation location = ConstraintLocation.forField( field ); + ConstraintLocation location = ConstraintLocation.forProperty( property ); for ( ConstraintDescriptorImpl constraintDescription : constraintDescriptors ) { constraints.add( MetaConstraints.create( typeResolutionHelper, valueExtractorManager, constraintDescription, location ) ); @@ -297,20 +302,23 @@ private Set getMetaData(Executable[] executableElements) * given element. */ private ConstrainedExecutable findExecutableMetaData(Executable executable) { - List parameterConstraints = getParameterMetaData( executable ); + Callable callable = JavaBeanExecutable.of( executable ); + List parameterConstraints = getParameterMetaData( executable, callable ); - Map>> executableConstraints = findConstraints( executable, ExecutableHelper.getElementType( executable ) ) - .stream() - .collect( Collectors.groupingBy( ConstraintDescriptorImpl::getConstraintType ) ); + Map>> executableConstraints = findConstraints( + executable, + callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD, + callable + ).stream().collect( Collectors.groupingBy( ConstraintDescriptorImpl::getConstraintType ) ); Set> crossParameterConstraints; - if ( annotationProcessingOptions.areCrossParameterConstraintsIgnoredFor( executable ) ) { + if ( annotationProcessingOptions.areCrossParameterConstraintsIgnoredFor( callable ) ) { crossParameterConstraints = Collections.emptySet(); } else { crossParameterConstraints = convertToMetaConstraints( executableConstraints.get( ConstraintType.CROSS_PARAMETER ), - executable + callable ); } @@ -318,7 +326,7 @@ private ConstrainedExecutable findExecutableMetaData(Executable executable) { Set> typeArgumentsConstraints; CascadingMetaDataBuilder cascadingMetaDataBuilder; - if ( annotationProcessingOptions.areReturnValueConstraintsIgnoredFor( executable ) ) { + if ( annotationProcessingOptions.areReturnValueConstraintsIgnoredFor( callable ) ) { returnValueConstraints = Collections.emptySet(); typeArgumentsConstraints = Collections.emptySet(); cascadingMetaDataBuilder = CascadingMetaDataBuilder.nonCascading(); @@ -326,17 +334,17 @@ private ConstrainedExecutable findExecutableMetaData(Executable executable) { else { AnnotatedType annotatedReturnType = executable.getAnnotatedReturnType(); - typeArgumentsConstraints = findTypeAnnotationConstraints( executable, annotatedReturnType ); + typeArgumentsConstraints = findTypeAnnotationConstraints( executable, callable, annotatedReturnType ); returnValueConstraints = convertToMetaConstraints( executableConstraints.get( ConstraintType.GENERIC ), - executable + callable ); cascadingMetaDataBuilder = findCascadingMetaData( executable, annotatedReturnType ); } return new ConstrainedExecutable( ConfigurationSource.ANNOTATION, - executable, + callable, parameterConstraints, crossParameterConstraints, returnValueConstraints, @@ -345,15 +353,15 @@ private ConstrainedExecutable findExecutableMetaData(Executable executable) { ); } - private Set> convertToMetaConstraints(List> constraintsDescriptors, Executable executable) { + private Set> convertToMetaConstraints(List> constraintsDescriptors, Callable callable) { if ( constraintsDescriptors == null ) { return Collections.emptySet(); } Set> constraints = newHashSet(); - ConstraintLocation returnValueLocation = ConstraintLocation.forReturnValue( executable ); - ConstraintLocation crossParameterLocation = ConstraintLocation.forCrossParameter( executable ); + ConstraintLocation returnValueLocation = ConstraintLocation.forReturnValue( callable ); + ConstraintLocation crossParameterLocation = ConstraintLocation.forCrossParameter( callable ); for ( ConstraintDescriptorImpl constraintDescriptor : constraintsDescriptors ) { ConstraintLocation location = constraintDescriptor.getConstraintType() == ConstraintType.GENERIC ? returnValueLocation : crossParameterLocation; @@ -369,9 +377,10 @@ private Set> convertToMetaConstraints(List getParameterMetaData(Executable executable) { + private List getParameterMetaData(Executable executable, Callable callable) { if ( executable.getParameterCount() == 0 ) { return Collections.emptyList(); } @@ -393,12 +402,12 @@ private List getParameterMetaData(Executable executable) { Set> parameterConstraints = newHashSet(); - if ( annotationProcessingOptions.areParameterConstraintsIgnoredFor( executable, i ) ) { + if ( annotationProcessingOptions.areParameterConstraintsIgnoredFor( callable, i ) ) { Type type = ReflectionHelper.typeOf( executable, i ); metaData.add( new ConstrainedParameter( ConfigurationSource.ANNOTATION, - executable, + callable, type, i, parameterConstraints, @@ -410,12 +419,12 @@ private List getParameterMetaData(Executable executable) { continue; } - ConstraintLocation location = ConstraintLocation.forParameter( executable, i ); + ConstraintLocation location = ConstraintLocation.forParameter( callable, i ); for ( Annotation parameterAnnotation : parameterAnnotations ) { // collect constraints if this annotation is a constraint annotation List> constraints = findConstraintAnnotations( - executable, parameterAnnotation, ElementType.PARAMETER + callable, parameterAnnotation, ElementType.PARAMETER ); for ( ConstraintDescriptorImpl constraintDescriptorImpl : constraints ) { parameterConstraints.add( @@ -426,13 +435,13 @@ private List getParameterMetaData(Executable executable) { AnnotatedType parameterAnnotatedType = parameter.getAnnotatedType(); - Set> typeArgumentsConstraints = findTypeAnnotationConstraintsForExecutableParameter( executable, i, parameterAnnotatedType ); + Set> typeArgumentsConstraints = findTypeAnnotationConstraintsForExecutableParameter( executable, callable, i, parameterAnnotatedType ); CascadingMetaDataBuilder cascadingMetaData = findCascadingMetaData( executable, parameters, i, parameterAnnotatedType ); metaData.add( new ConstrainedParameter( ConfigurationSource.ANNOTATION, - executable, + callable, ReflectionHelper.typeOf( executable, i ), i, parameterConstraints, @@ -455,10 +464,10 @@ private List getParameterMetaData(Executable executable) { * * @return A list of constraint descriptors for all constraint specified for the given member. */ - private List> findConstraints(Member member, ElementType type) { + private List> findConstraints(Member member, ElementType type, Constrainable constrainable) { List> metaData = newArrayList(); for ( Annotation annotation : ( (AccessibleObject) member ).getDeclaredAnnotations() ) { - metaData.addAll( findConstraintAnnotations( member, annotation, type ) ); + metaData.addAll( findConstraintAnnotations( constrainable, annotation, type ) ); } return metaData; @@ -483,7 +492,7 @@ private List> findClassLevelConstraints(Class bea /** * Examines the given annotation to see whether it is a single- or multi-valued constraint annotation. * - * @param member The member to check for constraints annotations + * @param constrainable The constrainable to check for constraints annotations * @param annotation The annotation to examine * @param type the element type on which the annotation/constraint is placed on * @param the annotation type @@ -491,7 +500,8 @@ private List> findClassLevelConstraints(Class bea * @return A list of constraint descriptors or the empty list in case {@code annotation} is neither a * single nor multi-valued annotation. */ - protected List> findConstraintAnnotations(Member member, + protected List> findConstraintAnnotations( + Constrainable constrainable, A annotation, ElementType type) { @@ -512,7 +522,7 @@ else if ( constraintHelper.isMultiValueConstraint( annotationType ) ) { } return constraints.stream() - .map( c -> buildConstraintDescriptor( member, c, type ) ) + .map( c -> buildConstraintDescriptor( constrainable, c, type ) ) .collect( Collectors.toList() ); } @@ -549,12 +559,12 @@ private Map, Class> getGroupConversions(ConvertGroup groupConversion return groupConversions; } - private ConstraintDescriptorImpl buildConstraintDescriptor(Member member, + private ConstraintDescriptorImpl buildConstraintDescriptor(Constrainable constrainable, A annotation, ElementType type) { return new ConstraintDescriptorImpl<>( constraintHelper, - member, + constrainable, new ConstraintAnnotationDescriptor<>( annotation ), type ); @@ -573,22 +583,22 @@ private T run(PrivilegedAction action) { /** * Finds type arguments constraints for fields. */ - protected Set> findTypeAnnotationConstraints(Field field) { + protected Set> findTypeAnnotationConstraints(Field field, Property property) { return findTypeArgumentsConstraints( - field, - new TypeArgumentFieldLocation( field ), - field.getAnnotatedType() + property, + new TypeArgumentFieldLocation( field ), + field.getAnnotatedType() ); } /** * Finds type arguments constraints for method return values. */ - protected Set> findTypeAnnotationConstraints(Executable executable, AnnotatedType annotatedReturnType) { + protected Set> findTypeAnnotationConstraints(Executable executable, Callable callable, AnnotatedType annotatedReturnType) { return findTypeArgumentsConstraints( - executable, - new TypeArgumentReturnValueLocation( executable ), - annotatedReturnType + callable, + new TypeArgumentReturnValueLocation( executable ), + annotatedReturnType ); } @@ -707,10 +717,10 @@ else if ( annotatedType instanceof AnnotatedParameterizedType ) { * * @return a set of type arguments constraints, or an empty set if no constrained type arguments are found */ - protected Set> findTypeAnnotationConstraintsForExecutableParameter(Executable executable, int i, AnnotatedType parameterAnnotatedType) { + protected Set> findTypeAnnotationConstraintsForExecutableParameter(Executable executable, Callable callable, int i, AnnotatedType parameterAnnotatedType) { try { return findTypeArgumentsConstraints( - executable, + callable, new TypeArgumentExecutableParameterLocation( executable, i ), parameterAnnotatedType ); @@ -721,7 +731,7 @@ protected Set> findTypeAnnotationConstraintsForExecutableParam } } - private Set> findTypeArgumentsConstraints(Member member, TypeArgumentLocation location, AnnotatedType annotatedType) { + private Set> findTypeArgumentsConstraints(Constrainable constrainable, TypeArgumentLocation location, AnnotatedType annotatedType) { // HV-1428 Container element support is disabled for arrays if ( !(annotatedType instanceof AnnotatedParameterizedType) ) { return Collections.emptySet(); @@ -735,9 +745,9 @@ private Set> findTypeArgumentsConstraints(Member member, TypeA Type validatedType = annotatedArrayType.getAnnotatedGenericComponentType().getType(); TypeVariable arrayElementTypeArgument = new ArrayElement( annotatedArrayType ); - typeArgumentConstraints.addAll( findTypeUseConstraints( member, annotatedArrayType, arrayElementTypeArgument, location, validatedType ) ); + typeArgumentConstraints.addAll( findTypeUseConstraints( constrainable, annotatedArrayType, arrayElementTypeArgument, location, validatedType ) ); - typeArgumentConstraints.addAll( findTypeArgumentsConstraints( member, + typeArgumentConstraints.addAll( findTypeArgumentsConstraints( constrainable, new NestedTypeArgumentLocation( location, arrayElementTypeArgument, validatedType ), annotatedArrayType.getAnnotatedGenericComponentType() ) ); } @@ -755,10 +765,10 @@ else if ( annotatedType instanceof AnnotatedParameterizedType ) { // In the latter case a value unwrapping has to occur Type validatedType = annotatedTypeParameter.getType(); - typeArgumentConstraints.addAll( findTypeUseConstraints( member, annotatedTypeParameter, typeVariable, location, validatedType ) ); + typeArgumentConstraints.addAll( findTypeUseConstraints( constrainable, annotatedTypeParameter, typeVariable, location, validatedType ) ); if ( validatedType instanceof ParameterizedType ) { - typeArgumentConstraints.addAll( findTypeArgumentsConstraints( member, + typeArgumentConstraints.addAll( findTypeArgumentsConstraints( constrainable, new NestedTypeArgumentLocation( location, typeVariable, validatedType ), annotatedTypeParameter ) ); } @@ -773,9 +783,9 @@ else if ( annotatedType instanceof AnnotatedParameterizedType ) { /** * Finds type use annotation constraints defined on the type argument. */ - private Set> findTypeUseConstraints(Member member, AnnotatedType typeArgument, TypeVariable typeVariable, TypeArgumentLocation location, Type type) { + private Set> findTypeUseConstraints(Constrainable constrainable, AnnotatedType typeArgument, TypeVariable typeVariable, TypeArgumentLocation location, Type type) { Set> constraints = Arrays.stream( typeArgument.getAnnotations() ) - .flatMap( a -> findConstraintAnnotations( member, a, ElementType.TYPE_USE ).stream() ) + .flatMap( a -> findConstraintAnnotations( constrainable, a, ElementType.TYPE_USE ).stream() ) .map( d -> createTypeArgumentMetaConstraint( d, location, typeVariable, type ) ) .collect( Collectors.toSet() ); @@ -801,7 +811,7 @@ private CascadingMetaDataBuilder getCascadingMetaData(Type type, AnnotatedElemen * The location of a type argument before it is really considered a constraint location. *

* It avoids initializing a constraint location if we did not find any constraints. This is especially useful in - * a Java 9 environment as {@link ConstraintLocation#forProperty(Member) tries to make the {@code Member} accessible + * a Java 9 environment as {@link ConstraintLocation#forProperty(Property)} tries to make the {@code Member} accessible * which might not be possible (for instance for {@code java.util} classes). */ private interface TypeArgumentLocation { @@ -820,7 +830,7 @@ private TypeArgumentExecutableParameterLocation(Executable executable, int index @Override public ConstraintLocation toConstraintLocation() { - return ConstraintLocation.forParameter( executable, index ); + return ConstraintLocation.forParameter( JavaBeanExecutable.of( executable ), index ); } } @@ -833,7 +843,7 @@ private TypeArgumentFieldLocation(Field field) { @Override public ConstraintLocation toConstraintLocation() { - return ConstraintLocation.forField( field ); + return ConstraintLocation.forProperty( new JavaBeanField( field ) ); } } @@ -846,7 +856,7 @@ private TypeArgumentReturnValueLocation(Executable executable) { @Override public ConstraintLocation toConstraintLocation() { - return ConstraintLocation.forReturnValue( executable ); + return ConstraintLocation.forReturnValue( JavaBeanExecutable.of( executable ) ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java index 8069e49cd3..f7d6b0c63f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java @@ -10,8 +10,6 @@ import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; -import java.lang.reflect.Executable; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -21,9 +19,9 @@ import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder; import org.hibernate.validator.internal.metadata.core.MetaConstraint; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.CollectionHelper; -import org.hibernate.validator.internal.util.ReflectionHelper; -import org.hibernate.validator.internal.util.StringHelper; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; import org.hibernate.validator.internal.util.stereotypes.Immutable; @@ -40,7 +38,7 @@ public class ConstrainedExecutable extends AbstractConstrainedElement { private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() ); - private final Executable executable; + private final Callable callable; /** * Constrained-related meta data for this executable's parameters. @@ -59,7 +57,7 @@ public class ConstrainedExecutable extends AbstractConstrainedElement { * Creates a new executable meta data object for a parameter-less executable. * * @param source The source of meta data. - * @param executable The represented executable. + * @param callable The represented executable. * @param returnValueConstraints Type arguments constraints, if any. * @param typeArgumentConstraints The type argument constraints on the return value of the represented executable, * if any. @@ -67,13 +65,13 @@ public class ConstrainedExecutable extends AbstractConstrainedElement { */ public ConstrainedExecutable( ConfigurationSource source, - Executable executable, + Callable callable, Set> returnValueConstraints, Set> typeArgumentConstraints, CascadingMetaDataBuilder cascadingMetaDataBuilder) { this( source, - executable, + callable, Collections.emptyList(), Collections.>emptySet(), returnValueConstraints, @@ -86,7 +84,7 @@ public ConstrainedExecutable( * Creates a new executable meta data object. * * @param source The source of meta data. - * @param executable The represented executable. + * @param callable The represented executable. * @param parameterMetaData A list with parameter meta data. The length must correspond with the number of * parameters of the represented executable. So this list may be empty (in case of a parameterless executable), but * never {@code null}. @@ -98,7 +96,7 @@ public ConstrainedExecutable( */ public ConstrainedExecutable( ConfigurationSource source, - Executable executable, + Callable callable, List parameterMetaData, Set> crossParameterConstraints, Set> returnValueConstraints, @@ -106,18 +104,18 @@ public ConstrainedExecutable( CascadingMetaDataBuilder cascadingMetaDataBuilder) { super( source, - ( executable instanceof Constructor ) ? ConstrainedElementKind.CONSTRUCTOR : ConstrainedElementKind.METHOD, + callable.isConstructor() ? ConstrainedElementKind.CONSTRUCTOR : ConstrainedElementKind.METHOD, returnValueConstraints, typeArgumentConstraints, cascadingMetaDataBuilder ); - this.executable = executable; + this.callable = callable; - if ( parameterMetaData.size() != executable.getParameterTypes().length ) { + if ( parameterMetaData.size() != callable.getParameterTypes().length ) { throw LOG.getInvalidLengthOfParameterMetaDataListException( - executable, - executable.getParameterTypes().length, + callable, + callable.getParameterTypes().length, parameterMetaData.size() ); } @@ -125,7 +123,7 @@ public ConstrainedExecutable( this.crossParameterConstraints = CollectionHelper.toImmutableSet( crossParameterConstraints ); this.parameterMetaData = CollectionHelper.toImmutableList( parameterMetaData ); this.hasParameterConstraints = hasParameterConstraints( parameterMetaData ) || !crossParameterConstraints.isEmpty(); - this.isGetterMethod = ReflectionHelper.isGetterMethod( executable ); + this.isGetterMethod = callable instanceof Property; } /** @@ -142,7 +140,7 @@ public ConstrainedExecutable( public ConstrainedParameter getParameterMetaData(int parameterIndex) { if ( parameterIndex < 0 || parameterIndex > parameterMetaData.size() - 1 ) { throw LOG.getInvalidExecutableParameterIndexException( - executable, + callable, parameterIndex ); } @@ -202,13 +200,13 @@ public boolean isGetterMethod() { return isGetterMethod; } - public Executable getExecutable() { - return executable; + public Callable getCallable() { + return callable; } @Override public String toString() { - return "ConstrainedExecutable [executable=" + StringHelper.toShortString( executable ) + return "ConstrainedExecutable [executable=" + callable + ", parameterMetaData=" + parameterMetaData + ", hasParameterConstraints=" + hasParameterConstraints + "]"; } @@ -284,7 +282,7 @@ public ConstrainedExecutable merge(ConstrainedExecutable other) { return new ConstrainedExecutable( mergedSource, - executable, + callable, mergedParameterMetaData, mergedCrossParameterConstraints, mergedReturnValueConstraints, @@ -307,8 +305,7 @@ private Set> getDescriptors(Iterable> public int hashCode() { final int prime = 31; int result = super.hashCode(); - result = prime * result - + ( ( executable == null ) ? 0 : executable.hashCode() ); + result = prime * result + callable.hashCode(); return result; } @@ -324,12 +321,7 @@ public boolean equals(Object obj) { return false; } ConstrainedExecutable other = (ConstrainedExecutable) obj; - if ( executable == null ) { - if ( other.executable != null ) { - return false; - } - } - else if ( !executable.equals( other.executable ) ) { + if ( !callable.equals( other.callable ) ) { return false; } return true; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java index cc889ae089..e9f996c89f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java @@ -6,12 +6,11 @@ */ package org.hibernate.validator.internal.metadata.raw; -import java.lang.reflect.Field; import java.util.Set; import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder; import org.hibernate.validator.internal.metadata.core.MetaConstraint; -import org.hibernate.validator.internal.util.StringHelper; +import org.hibernate.validator.internal.properties.Property; /** * Represents a field of a Java type and all its associated meta-data relevant @@ -19,45 +18,45 @@ * * @author Gunnar Morling * @author Guillaume Smet + * @author Marko Bekhta */ public class ConstrainedField extends AbstractConstrainedElement { - private final Field field; + private final Property property; /** * Creates a new field meta data object. * * @param source The source of meta data. - * @param field The represented field. + * @param property The represented field. * @param constraints The constraints of the represented field, if any. * @param typeArgumentConstraints Type arguments constraints, if any. * @param cascadingMetaDataBuilder The cascaded validation metadata for this element and its container elements. */ public ConstrainedField(ConfigurationSource source, - Field field, - Set> constraints, - Set> typeArgumentConstraints, - CascadingMetaDataBuilder cascadingMetaDataBuilder) { + Property property, + Set> constraints, + Set> typeArgumentConstraints, + CascadingMetaDataBuilder cascadingMetaDataBuilder) { super( source, ConstrainedElementKind.FIELD, constraints, typeArgumentConstraints, cascadingMetaDataBuilder ); - this.field = field; - } + this.property = property; - public Field getField() { - return field; } + public Property getProperty() { + return property; + } @Override public String toString() { - return "ConstrainedField [field=" + StringHelper.toShortString( field ) + "]"; + return "ConstrainedField [property=" + property.getName() + "]"; } @Override public int hashCode() { - final int prime = 31; int result = super.hashCode(); - result = prime * result + ( ( field == null ) ? 0 : field.hashCode() ); + result = 31 * result + this.property.hashCode(); return result; } @@ -73,14 +72,6 @@ public boolean equals(Object obj) { return false; } ConstrainedField other = (ConstrainedField) obj; - if ( field == null ) { - if ( other.field != null ) { - return false; - } - } - else if ( !field.equals( other.field ) ) { - return false; - } - return true; + return this.property.equals( other.property ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedParameter.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedParameter.java index d8d161d764..dab9ac417c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedParameter.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedParameter.java @@ -8,7 +8,6 @@ import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; -import java.lang.reflect.Executable; import java.lang.reflect.Type; import java.util.Collections; import java.util.HashSet; @@ -16,6 +15,7 @@ import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder; import org.hibernate.validator.internal.metadata.core.MetaConstraint; +import org.hibernate.validator.internal.properties.Callable; /** * Contains constraint-related meta-data for one method parameter. @@ -25,17 +25,17 @@ */ public class ConstrainedParameter extends AbstractConstrainedElement { - private final Executable executable; + private final Callable callable; private final Type type; private final int index; public ConstrainedParameter(ConfigurationSource source, - Executable executable, + Callable callable, Type type, int index) { this( source, - executable, + callable, type, index, Collections.>emptySet(), @@ -48,7 +48,7 @@ public ConstrainedParameter(ConfigurationSource source, * Creates a new parameter meta data object. * * @param source The source of meta data. - * @param executable The executable of the represented method parameter. + * @param callable The executable of the represented method parameter. * @param type the parameter type * @param index the index of the parameter * @param constraints The constraints of the represented method parameter, if @@ -57,7 +57,7 @@ public ConstrainedParameter(ConfigurationSource source, * @param cascadingMetaDataBuilder The cascaded validation metadata for this element and its container elements. */ public ConstrainedParameter(ConfigurationSource source, - Executable executable, + Callable callable, Type type, int index, Set> constraints, @@ -71,7 +71,7 @@ public ConstrainedParameter(ConfigurationSource source, cascadingMetaDataBuilder ); - this.executable = executable; + this.callable = callable; this.type = type; this.index = index; } @@ -80,8 +80,8 @@ public Type getType() { return type; } - public Executable getExecutable() { - return executable; + public Callable getCallable() { + return callable; } public int getIndex() { @@ -109,7 +109,7 @@ public ConstrainedParameter merge(ConstrainedParameter other) { return new ConstrainedParameter( mergedSource, - executable, + callable, type, index, mergedConstraints, @@ -130,7 +130,7 @@ public String toString() { String constraintsAsString = sb.length() > 0 ? sb.substring( 0, sb.length() - 2 ) : sb.toString(); - return "ParameterMetaData [executable=" + executable + ", index=" + index + "], constraints=[" + return "ParameterMetaData [callable=" + callable + ", index=" + index + "], constraints=[" + constraintsAsString + "]"; } @@ -139,7 +139,7 @@ public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + index; - result = prime * result + ( ( executable == null ) ? 0 : executable.hashCode() ); + result = prime * result + callable.hashCode(); return result; } @@ -158,12 +158,7 @@ public boolean equals(Object obj) { if ( index != other.index ) { return false; } - if ( executable == null ) { - if ( other.executable != null ) { - return false; - } - } - else if ( !executable.equals( other.executable ) ) { + else if ( !callable.equals( other.callable ) ) { return false; } return true; diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java new file mode 100644 index 0000000000..b25586c4b1 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java @@ -0,0 +1,41 @@ +/* + * 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.properties; + +import java.lang.reflect.Type; + +import org.hibernate.validator.internal.util.ExecutableHelper; +import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; + +/** + * @author Marko Bekhta + */ +public interface Callable extends Constrainable { + + boolean hasReturnValue(); + + boolean hasParameters(); + + Class[] getParameterTypes(); + + Type[] getGenericParameterTypes(); + + String getParameterName(ExecutableParameterNameProvider parameterNameProvider, int parameterIndex); + + boolean isPrivate(); + + boolean isConstructor(); + + String getSignature(); + + Type getTypeOfParameter(int parameterIndex); + + boolean overrides(ExecutableHelper executableHelper, Callable superTypeMethod); + + boolean isResolvedToSameMethodInHierarchy(ExecutableHelper executableHelper, Class mainSubType, Callable superTypeMethod); + +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Constrainable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Constrainable.java new file mode 100644 index 0000000000..a4ab094455 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Constrainable.java @@ -0,0 +1,28 @@ +/* + * 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.properties; + +import java.lang.reflect.Type; + +/** + * @author Marko Bekhta + */ +public interface Constrainable { + + String getName(); + + Class getDeclaringClass(); + + Type getTypeForValidatorResolution(); + + Type getType(); + + @SuppressWarnings("unchecked") + default T as(Class clazz) { + return ( (T) this ); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/ConstrainableType.java b/engine/src/main/java/org/hibernate/validator/internal/properties/ConstrainableType.java new file mode 100644 index 0000000000..01356e09de --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/ConstrainableType.java @@ -0,0 +1,14 @@ +/* + * 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.properties; + +/** + * @author Marko Bekhta + */ +public interface ConstrainableType { + +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Property.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Property.java new file mode 100644 index 0000000000..f6f1d4c288 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Property.java @@ -0,0 +1,17 @@ +/* + * 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.properties; + +/** + * @author Marko Bekhta + */ +public interface Property extends Constrainable { + + Object getValueFrom(Object bean); + + String getPropertyName(); +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBean.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBean.java new file mode 100644 index 0000000000..ff9dd436dc --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBean.java @@ -0,0 +1,37 @@ +/* + * 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.properties.javabean; + +import java.util.Arrays; +import java.util.stream.Stream; + +import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.ConstrainableType; +import org.hibernate.validator.internal.util.ReflectionHelper; + +/** + * @author Marko Bekhta + */ +public class JavaBean implements ConstrainableType { + + private final Class clazz; + + public JavaBean(Class clazz) { + this.clazz = clazz; + } + + public Stream getFieldProperties() { + return Arrays.stream( clazz.getDeclaredFields() ) + .map( JavaBeanField::new ); + } + + public Stream getGetterProperties() { + return Arrays.stream( clazz.getDeclaredMethods() ) + .filter( ReflectionHelper::isGetterMethod ) + .map( JavaBeanGetter::new ); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java new file mode 100644 index 0000000000..afe1e9211a --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java @@ -0,0 +1,187 @@ +/* + * 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.properties.javabean; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.util.ExecutableHelper; +import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; +import org.hibernate.validator.internal.util.ReflectionHelper; +import org.hibernate.validator.internal.util.TypeHelper; + +/** + * @author Marko Bekhta + */ +public class JavaBeanExecutable implements Callable { + + protected final Executable executable; + private final Type typeForValidatorResolution; + private final String name; + private final boolean hasParameters; + private final boolean hasReturnValue; + private final Type type; + + JavaBeanExecutable(Executable executable) { + this.executable = executable; + this.name = executable.getName(); + this.type = ReflectionHelper.typeOf( executable ); + this.typeForValidatorResolution = ReflectionHelper.boxedType( type ); + this.hasParameters = executable.getParameterTypes().length > 0; + this.hasReturnValue = hasReturnValue( executable ); + } + + public static JavaBeanExecutable of(Executable executable) { + if ( ReflectionHelper.isGetterMethod( executable ) ) { + return new JavaBeanGetter( (Method) executable ); + } + else { + return new JavaBeanExecutable( executable ); + } + } + + @Override + public boolean hasReturnValue() { + return hasReturnValue; + } + + @Override + public boolean hasParameters() { + return hasParameters; + } + + @Override + public String getName() { + return name; + } + + @Override + public Class getDeclaringClass() { + return executable.getDeclaringClass(); + } + + @Override + public Type getTypeForValidatorResolution() { + return typeForValidatorResolution; + } + + @Override + public Type getType() { + return type; + } + + @Override + public Class[] getParameterTypes() { + return executable.getParameterTypes(); + } + + @Override + public Type[] getGenericParameterTypes() { + return executable.getGenericParameterTypes(); + } + + @Override + public String getParameterName(ExecutableParameterNameProvider parameterNameProvider, int parameterIndex) { + return parameterNameProvider.getParameterNames( executable ).get( parameterIndex ); + } + + @Override + public boolean isPrivate() { + return Modifier.isPrivate( executable.getModifiers() ); + } + + @Override + public boolean isConstructor() { + return executable instanceof Constructor; + } + + @Override + public String getSignature() { + return ExecutableHelper.getSignature( executable ); + } + + @Override + public Type getTypeOfParameter(int parameterIndex) { + Type[] genericParameterTypes = executable.getGenericParameterTypes(); + + // getGenericParameterTypes() doesn't return synthetic parameters; in this case fall back to getParameterTypes() + if ( parameterIndex >= genericParameterTypes.length ) { + genericParameterTypes = executable.getParameterTypes(); + } + + Type type = genericParameterTypes[parameterIndex]; + + if ( type instanceof TypeVariable ) { + type = TypeHelper.getErasedType( type ); + } + return type; + } + + @Override + public boolean overrides(ExecutableHelper executableHelper, Callable superTypeMethod) { + return executableHelper.overrides( ( (Method) this.executable ), ( (Method) ( (JavaBeanExecutable) superTypeMethod ).executable ) ); + } + + @Override + public boolean isResolvedToSameMethodInHierarchy(ExecutableHelper executableHelper, Class mainSubType, Callable superTypeMethod) { + return executableHelper.isResolvedToSameMethodInHierarchy( mainSubType, ( (Method) this.executable ), ( (Method) ( (JavaBeanExecutable) superTypeMethod ).executable ) ); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || this.getClass() != o.getClass() ) { + return false; + } + + JavaBeanExecutable that = (JavaBeanExecutable) o; + + if ( this.hasParameters != that.hasParameters ) { + return false; + } + if ( this.hasReturnValue != that.hasReturnValue ) { + return false; + } + if ( !this.executable.equals( that.executable ) ) { + return false; + } + if ( !this.typeForValidatorResolution.equals( that.typeForValidatorResolution ) ) { + return false; + } + if ( !this.name.equals( that.name ) ) { + return false; + } + return this.type.equals( that.type ); + } + + @Override + public int hashCode() { + int result = this.executable.hashCode(); + result = 31 * result + this.typeForValidatorResolution.hashCode(); + result = 31 * result + this.name.hashCode(); + result = 31 * result + ( this.hasParameters ? 1 : 0 ); + result = 31 * result + ( this.hasReturnValue ? 1 : 0 ); + result = 31 * result + this.type.hashCode(); + return result; + } + + private boolean hasReturnValue(Executable executable) { + if ( executable instanceof Constructor ) { + return true; + } + else { + return ( (Method) executable ).getGenericReturnType() != void.class; + } + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java similarity index 52% rename from engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java rename to engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java index 4e8c21f963..8ea4eb2067 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java @@ -4,52 +4,38 @@ * License: Apache License, Version 2.0 * See the license.txt file in the root directory or . */ -package org.hibernate.validator.internal.metadata.location; +package org.hibernate.validator.internal.properties.javabean; import java.lang.reflect.Field; -import java.lang.reflect.Member; import java.lang.reflect.Type; import java.security.AccessController; import java.security.PrivilegedAction; import org.hibernate.validator.HibernateValidatorPermission; -import org.hibernate.validator.internal.engine.path.PathImpl; -import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; +import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.ReflectionHelper; -import org.hibernate.validator.internal.util.StringHelper; import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredField; /** - * Field constraint location. - * - * @author Hardy Ferentschik - * @author Gunnar Morling + * @author Marko Bekhta */ -public class FieldConstraintLocation implements ConstraintLocation { +public class JavaBeanField implements Property { - /** - * The member the constraint was defined on. - */ private final Field field; - - private final Field accessibleField; - - /** - * The property name associated with the member. - */ - private final String propertyName; - - /** - * The type to be used for validator resolution for constraints at this location. - */ + private final String name; private final Type typeForValidatorResolution; + private final Type type; + public JavaBeanField(Field field) { + this.field = getAccessible( field ); + this.name = field.getName(); + this.type = ReflectionHelper.typeOf( field ); + this.typeForValidatorResolution = ReflectionHelper.boxedType( this.type ); + } - FieldConstraintLocation(Field field) { - this.field = field; - this.accessibleField = getAccessible( field ); - this.propertyName = ReflectionHelper.getPropertyName( field ); - this.typeForValidatorResolution = ReflectionHelper.boxedType( ReflectionHelper.typeOf( field ) ); + @Override + public String getName() { + return name; } @Override @@ -58,12 +44,8 @@ public Class getDeclaringClass() { } @Override - public Member getMember() { - return field; - } - - public String getPropertyName() { - return propertyName; + public Type getType() { + return type; } @Override @@ -72,19 +54,13 @@ public Type getTypeForValidatorResolution() { } @Override - public void appendTo(ExecutableParameterNameProvider parameterNameProvider, PathImpl path) { - path.addPropertyNode( propertyName ); + public Object getValueFrom(Object bean) { + return ReflectionHelper.getValue( field, bean ); } @Override - public Object getValue(Object parent) { - return ReflectionHelper.getValue( accessibleField, parent ); - } - - @Override - public String toString() { - return "FieldConstraintLocation [member=" + StringHelper.toShortString( field ) + ", typeForValidatorResolution=" - + StringHelper.toShortString( typeForValidatorResolution ) + "]"; + public String getPropertyName() { + return getName(); } @Override @@ -92,26 +68,30 @@ public boolean equals(Object o) { if ( this == o ) { return true; } - if ( o == null || getClass() != o.getClass() ) { + if ( o == null || this.getClass() != o.getClass() ) { return false; } - FieldConstraintLocation that = (FieldConstraintLocation) o; + JavaBeanField that = (JavaBeanField) o; - if ( field != null ? !field.equals( that.field ) : that.field != null ) { + if ( !this.field.equals( that.field ) ) { return false; } - if ( !typeForValidatorResolution.equals( that.typeForValidatorResolution ) ) { + if ( !this.name.equals( that.name ) ) { return false; } - - return true; + if ( !this.typeForValidatorResolution.equals( that.typeForValidatorResolution ) ) { + return false; + } + return this.type.equals( that.type ); } @Override public int hashCode() { - int result = field != null ? field.hashCode() : 0; - result = 31 * result + typeForValidatorResolution.hashCode(); + int result = this.field.hashCode(); + result = 31 * result + this.name.hashCode(); + result = 31 * result + this.typeForValidatorResolution.hashCode(); + result = 31 * result + this.type.hashCode(); return result; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java similarity index 52% rename from engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java rename to engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java index 129772a320..113aca02a5 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java @@ -4,7 +4,7 @@ * License: Apache License, Version 2.0 * See the license.txt file in the root directory or . */ -package org.hibernate.validator.internal.metadata.location; +package org.hibernate.validator.internal.properties.javabean; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -12,36 +12,19 @@ import java.security.PrivilegedAction; import org.hibernate.validator.HibernateValidatorPermission; -import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.ReflectionHelper; -import org.hibernate.validator.internal.util.StringHelper; import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredMethod; /** - * Getter method constraint location. - * - * @author Hardy Ferentschik - * @author Gunnar Morling + * @author Marko Bekhta */ -public class GetterConstraintLocation implements ConstraintLocation { - - /** - * The method the constraint was defined on. - */ - private final Method method; +public class JavaBeanGetter extends JavaBeanExecutable implements Property { - private final Method accessibleMethod; - - /** - * The property name associated with the method. - */ - private final String propertyName; + private static final Class[] PARAMETER_TYPES = new Class[0]; - /** - * The type to be used for validator resolution for constraints at this location. - */ - private final Type typeForValidatorResolution; + private final String name; /** * The class of the method for which the constraint was defined. @@ -51,48 +34,58 @@ public class GetterConstraintLocation implements ConstraintLocation { */ private final Class declaringClass; + public JavaBeanGetter(Method method) { + super( getAccessible( method ) ); + this.name = ReflectionHelper.getPropertyName( method ); + this.declaringClass = method.getDeclaringClass(); + } - GetterConstraintLocation( Class declaringClass, Method method ) { - this.method = method; - this.accessibleMethod = getAccessible( method ); - this.propertyName = ReflectionHelper.getPropertyName( method ); - this.typeForValidatorResolution = ReflectionHelper.boxedType( ReflectionHelper.typeOf( method ) ); + public JavaBeanGetter(Class declaringClass, Method method) { + super( getAccessible( method ) ); + this.name = ReflectionHelper.getPropertyName( method ); this.declaringClass = declaringClass; } @Override - public Class getDeclaringClass() { - return declaringClass; + public Object getValueFrom(Object bean) { + return ReflectionHelper.getValue( (Method) executable, bean ); } @Override - public Method getMember() { - return method; + public String getPropertyName() { + return name; } - public String getPropertyName() { - return propertyName; + @Override + public boolean hasReturnValue() { + // getters should always have a return value + return true; } @Override - public Type getTypeForValidatorResolution() { - return typeForValidatorResolution; + public boolean hasParameters() { + // getters should never have parameters + return false; } @Override - public void appendTo(ExecutableParameterNameProvider parameterNameProvider, PathImpl path) { - path.addPropertyNode( propertyName ); + public Class[] getParameterTypes() { + return PARAMETER_TYPES; } @Override - public Object getValue(Object parent) { - return ReflectionHelper.getValue( accessibleMethod, parent ); + public Type[] getGenericParameterTypes() { + return PARAMETER_TYPES; } @Override - public String toString() { - return "GetterConstraintLocation [method=" + StringHelper.toShortString( method ) + ", typeForValidatorResolution=" - + StringHelper.toShortString( typeForValidatorResolution ) + "]"; + public String getParameterName(ExecutableParameterNameProvider parameterNameProvider, int parameterIndex) { + throw new IllegalStateException( "Getters cannot have parameters" ); + } + + @Override + public Class getDeclaringClass() { + return declaringClass; } @Override @@ -100,26 +93,22 @@ public boolean equals(Object o) { if ( this == o ) { return true; } - if ( o == null || getClass() != o.getClass() ) { + if ( o == null || this.getClass() != o.getClass() ) { return false; } - - GetterConstraintLocation that = (GetterConstraintLocation) o; - - if ( method != null ? !method.equals( that.method ) : that.method != null ) { - return false; - } - if ( !typeForValidatorResolution.equals( that.typeForValidatorResolution ) ) { + if ( !super.equals( o ) ) { return false; } - return true; + JavaBeanGetter that = (JavaBeanGetter) o; + + return this.name.equals( that.name ); } @Override public int hashCode() { - int result = method.hashCode(); - result = 31 * result + typeForValidatorResolution.hashCode(); + int result = super.hashCode(); + result = 31 * result + this.name.hashCode(); return result; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/package-info.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/package-info.java new file mode 100644 index 0000000000..410921fdeb --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/package-info.java @@ -0,0 +1,8 @@ +/* + * 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.properties.javabean; diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/ExecutableHelper.java b/engine/src/main/java/org/hibernate/validator/internal/util/ExecutableHelper.java index 0ae6378a5a..cd5e1247a6 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/ExecutableHelper.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/ExecutableHelper.java @@ -17,6 +17,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.classhierarchy.Filters; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; @@ -46,6 +47,10 @@ public ExecutableHelper(TypeResolutionHelper typeResolutionHelper) { this.typeResolver = typeResolutionHelper.getTypeResolver(); } + public boolean overrides(Callable subTypeMethod, Callable superTypeMethod) { + return subTypeMethod.overrides( this, superTypeMethod ); + } + /** * Checks, whether {@code subTypeMethod} overrides {@code superTypeMethod}. * diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index d0cba30970..41bd6883f3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -48,10 +48,13 @@ import org.hibernate.validator.internal.engine.messageinterpolation.parser.MessageDescriptorFormatException; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.logging.formatter.ArrayOfClassesObjectFormatter; import org.hibernate.validator.internal.util.logging.formatter.ClassObjectFormatter; import org.hibernate.validator.internal.util.logging.formatter.CollectionOfClassesObjectFormatter; import org.hibernate.validator.internal.util.logging.formatter.CollectionOfObjectsToStringFormatter; +import org.hibernate.validator.internal.util.logging.formatter.ConstrainableFormatter; import org.hibernate.validator.internal.util.logging.formatter.DurationFormatter; import org.hibernate.validator.internal.util.logging.formatter.ExecutableFormatter; import org.hibernate.validator.internal.util.logging.formatter.ObjectArrayFormatter; @@ -248,14 +251,13 @@ GroupDefinitionException getUnableToExpandDefaultGroupListException(@FormatWith( GroupDefinitionException getWrongDefaultGroupSequenceProviderTypeException(@FormatWith(ClassObjectFormatter.class) Class beanClass); @Message(id = 56, value = "Method or constructor %1$s doesn't have a parameter with index %2$d.") - IllegalArgumentException getInvalidExecutableParameterIndexException(@FormatWith(ExecutableFormatter.class) Executable executable, int index); + IllegalArgumentException getInvalidExecutableParameterIndexException(@FormatWith(ConstrainableFormatter.class) Callable callable, int index); @Message(id = 59, value = "Unable to retrieve annotation parameter value.") ValidationException getUnableToRetrieveAnnotationParameterValueException(@Cause Exception e); - @Message(id = 62, - value = "Method or constructor %1$s has %2$s parameters, but the passed list of parameter meta data has a size of %3$s.") - IllegalArgumentException getInvalidLengthOfParameterMetaDataListException(@FormatWith(ExecutableFormatter.class) Executable executable, int nbParameters, int listSize); + @Message(id = 62, value = "Method or constructor %1$s has %2$s parameters, but the passed list of parameter meta data has a size of %3$s.") + IllegalArgumentException getInvalidLengthOfParameterMetaDataListException(@FormatWith(ConstrainableFormatter.class) Callable callable, int nbParameters, int listSize); @Message(id = 63, value = "Unable to instantiate %s.") ValidationException getUnableToInstantiateException(@FormatWith(ClassObjectFormatter.class) Class clazz, @Cause Exception e); @@ -461,11 +463,11 @@ ConstraintDeclarationException getMultipleGroupConversionsForSameSourceException @Message(id = 131, value = "A method return value must not be marked for cascaded validation more than once in a class hierarchy, but the following two methods are marked as such: %s, %s.") - ConstraintDeclarationException getMethodReturnValueMustNotBeMarkedMoreThanOnceForCascadedValidationException(@FormatWith(ExecutableFormatter.class) Executable executable1, @FormatWith(ExecutableFormatter.class) Executable executable2); + ConstraintDeclarationException getMethodReturnValueMustNotBeMarkedMoreThanOnceForCascadedValidationException(Callable callable1, Callable callable2); @Message(id = 132, value = "Void methods must not be constrained or marked for cascaded validation, but method %s is.") - ConstraintDeclarationException getVoidMethodsMustNotBeConstrainedException(@FormatWith(ExecutableFormatter.class) Executable executable); + ConstraintDeclarationException getVoidMethodsMustNotBeConstrainedException(@FormatWith(ConstrainableFormatter.class) Callable callable); @Message(id = 133, value = "%1$s does not contain a constructor with the parameter types %2$s.") ValidationException getBeanDoesNotContainConstructorException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @@ -500,7 +502,7 @@ ConstraintDeclarationException getImplicitConstraintTargetInAmbiguousConfigurati @Message(id = 142, value = "Cross parameter constraint %1$s is illegally placed on a parameterless method or constructor '%2$s'.") ConstraintDeclarationException getCrossParameterConstraintOnMethodWithoutParametersException( - @FormatWith(ClassObjectFormatter.class) Class constraint, @FormatWith(ExecutableFormatter.class) Executable executable); + @FormatWith(ClassObjectFormatter.class) Class constraint, @FormatWith(ConstrainableFormatter.class) Constrainable executable); @Message(id = 143, value = "Cross parameter constraint %1$s is illegally placed on class level.") @@ -509,7 +511,7 @@ ConstraintDeclarationException getCrossParameterConstraintOnMethodWithoutParamet @Message(id = 144, value = "Cross parameter constraint %1$s is illegally placed on field '%2$s'.") ConstraintDeclarationException getCrossParameterConstraintOnFieldException(@FormatWith(ClassObjectFormatter.class) Class constraint, - Member field); + @FormatWith(ConstrainableFormatter.class) Constrainable field); @Message(id = 146, value = "No parameter nodes may be added since path %s doesn't refer to a cross-parameter constraint.") @@ -535,11 +537,11 @@ UnexpectedTypeException getMultipleValidatorsForSameTypeException(@FormatWith(Cl @Message(id = 151, value = "A method overriding another method must not redefine the parameter constraint configuration, but method %2$s redefines the configuration of %1$s.") - ConstraintDeclarationException getParameterConfigurationAlteredInSubTypeException(@FormatWith(ExecutableFormatter.class) Executable superMethod, @FormatWith(ExecutableFormatter.class) Executable subMethod); + ConstraintDeclarationException getParameterConfigurationAlteredInSubTypeException(@FormatWith(ConstrainableFormatter.class) Callable superMethod, @FormatWith(ConstrainableFormatter.class) Callable subMethod); @Message(id = 152, value = "Two methods defined in parallel types must not declare parameter constraints, if they are overridden by the same method, but methods %s and %s both define parameter constraints.") - ConstraintDeclarationException getParameterConstraintsDefinedInMethodsFromParallelTypesException(@FormatWith(ExecutableFormatter.class) Executable method1, @FormatWith(ExecutableFormatter.class) Executable method2); + ConstraintDeclarationException getParameterConstraintsDefinedInMethodsFromParallelTypesException(@FormatWith(ConstrainableFormatter.class) Callable method1, @FormatWith(ConstrainableFormatter.class) Callable method2); @Message(id = 153, value = "The constraint %1$s used ConstraintTarget#%2$s but is not specified on a method or constructor.") @@ -581,7 +583,7 @@ ConstraintDefinitionException getValidatorForCrossParameterConstraintMustEitherV @Message(id = 161, value = "Two methods defined in parallel types must not define group conversions for a cascaded method return value, if they are overridden by the same method, but methods %s and %s both define parameter constraints.") - ConstraintDeclarationException getMethodsFromParallelTypesMustNotDefineGroupConversionsForCascadedReturnValueException(@FormatWith(ExecutableFormatter.class) Executable method1, @FormatWith(ExecutableFormatter.class) Executable method2); + ConstraintDeclarationException getMethodsFromParallelTypesMustNotDefineGroupConversionsForCascadedReturnValueException(@FormatWith(ConstrainableFormatter.class) Callable method1, @FormatWith(ConstrainableFormatter.class) Callable method2); @Message(id = 162, value = "The validated type %1$s does not specify the constructor/method: %2$s") @@ -625,15 +627,15 @@ ConstraintDefinitionException getValidatorForCrossParameterConstraintMustEitherV @Message(id = 173, value = "Method %2$s of type %1$s is configured more than once via the programmatic constraint declaration API.") - ValidationException getMethodHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, String method); + ValidationException getMethodHasAlreadyBeenConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, String method); @Message(id = 174, value = "Parameter %3$s of method or constructor %2$s of type %1$s is configured more than once via the programmatic constraint declaration API.") - ValidationException getParameterHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ExecutableFormatter.class) Executable executable, int parameterIndex); + ValidationException getParameterHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ConstrainableFormatter.class) Callable callable, int parameterIndex); @Message(id = 175, value = "The return value of method or constructor %2$s of type %1$s is configured more than once via the programmatic constraint declaration API.") - ValidationException getReturnValueHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ExecutableFormatter.class) Executable executable); + ValidationException getReturnValueHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ConstrainableFormatter.class) Callable callable); @Message(id = 176, value = "Constructor %2$s of type %1$s is configured more than once via the programmatic constraint declaration API.") @@ -641,7 +643,7 @@ ConstraintDefinitionException getValidatorForCrossParameterConstraintMustEitherV @Message(id = 177, value = "Cross-parameter constraints for the method or constructor %2$s of type %1$s are declared more than once via the programmatic constraint declaration API.") - ValidationException getCrossParameterElementHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ExecutableFormatter.class) Executable executable); + ValidationException getCrossParameterElementHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ConstrainableFormatter.class) Callable callable); @Message(id = 178, value = "Multiplier cannot be negative: %d.") IllegalArgumentException getMultiplierCannotBeNegativeException(int multiplier); @@ -714,7 +716,7 @@ ConstraintDeclarationException getInconsistentValueUnwrappingConfigurationBetwee ValueExtractorDefinitionException getValueExtractorDeclaresExtractedValueMultipleTimesException(@FormatWith(ClassObjectFormatter.class) Class extractorType); @Message(id = 205, value = "Invalid unwrapping configuration for constraint %2$s on %1$s. You can only define one of 'Unwrapping.Skip' or 'Unwrapping.Unwrap'.") - ConstraintDeclarationException getInvalidUnwrappingConfigurationForConstraintException(Member member, @FormatWith(ClassObjectFormatter.class) Class constraint); + ConstraintDeclarationException getInvalidUnwrappingConfigurationForConstraintException(@FormatWith(ConstrainableFormatter.class) Constrainable constrainable, @FormatWith(ClassObjectFormatter.class) Class constraint); @Message(id = 206, value = "Unable to instantiate value extractor class %s.") ValidationException getUnableToInstantiateValueExtractorClassException(String valueExtractorClassName, @Cause ValidationException e); diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/formatter/ConstrainableFormatter.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/formatter/ConstrainableFormatter.java new file mode 100644 index 0000000000..d5f8ea6f1a --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/formatter/ConstrainableFormatter.java @@ -0,0 +1,39 @@ +/* + * 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.util.logging.formatter; + +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.util.ExecutableHelper; + +/** + * Used with JBoss Logging to display executables in log messages. + * + * @author Marko Bekhta + */ +public class ConstrainableFormatter { + + private final String stringRepresentation; + + public ConstrainableFormatter(Constrainable constrainable) { + String name = constrainable.getName(); + if ( constrainable instanceof Callable ) { + name = constrainable.getDeclaringClass().getSimpleName() + "#" + name; + Class[] parameterTypes = ( (Callable) constrainable ).getParameterTypes(); + + this.stringRepresentation = ExecutableHelper.getExecutableAsString( name, parameterTypes ); + } + else { + this.stringRepresentation = name; + } + } + + @Override + public String toString() { + return stringRepresentation; + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedConstructorStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedConstructorStaxBuilder.java index d29312b7b8..1807e03322 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedConstructorStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedConstructorStaxBuilder.java @@ -26,6 +26,7 @@ import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; +import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.logging.Log; @@ -84,6 +85,7 @@ ConstrainedExecutable build(Class beanClass, List> alreadyProc parameterTypes ); } + JavaBeanExecutable executable = JavaBeanExecutable.of( constructor ); if ( alreadyProcessedConstructors.contains( constructor ) ) { throw LOG.getConstructorIsDefinedTwiceInMappingXmlForBeanException( constructor, beanClass ); @@ -95,7 +97,7 @@ ConstrainedExecutable build(Class beanClass, List> alreadyProc // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsOnMember( - constructor, + executable, ignoreAnnotations.get() ); } @@ -103,21 +105,21 @@ ConstrainedExecutable build(Class beanClass, List> alreadyProc List constrainedParameters = CollectionHelper.newArrayList( constrainedParameterStaxBuilders.size() ); for ( int index = 0; index < constrainedParameterStaxBuilders.size(); index++ ) { ConstrainedParameterStaxBuilder builder = constrainedParameterStaxBuilders.get( index ); - constrainedParameters.add( builder.build( constructor, index ) ); + constrainedParameters.add( builder.build( executable, index ) ); } Set> crossParameterConstraints = getCrossParameterStaxBuilder() - .map( builder -> builder.build( constructor ) ).orElse( Collections.emptySet() ); + .map( builder -> builder.build( executable ) ).orElse( Collections.emptySet() ); // parse the return value Set> returnValueConstraints = new HashSet<>(); Set> returnValueTypeArgumentConstraints = new HashSet<>(); - CascadingMetaDataBuilder cascadingMetaDataBuilder = getReturnValueStaxBuilder().map( builder -> builder.build( constructor, returnValueConstraints, returnValueTypeArgumentConstraints ) ) + CascadingMetaDataBuilder cascadingMetaDataBuilder = getReturnValueStaxBuilder().map( builder -> builder.build( executable, returnValueConstraints, returnValueTypeArgumentConstraints ) ) .orElse( CascadingMetaDataBuilder.nonCascading() ); return new ConstrainedExecutable( ConfigurationSource.XML, - constructor, + executable, constrainedParameters, crossParameterConstraints, returnValueConstraints, diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java index 8b2a8a97be..5244d464e7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java @@ -24,6 +24,7 @@ import org.hibernate.validator.internal.metadata.location.ConstraintLocation; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.logging.Log; @@ -69,17 +70,19 @@ ConstrainedField build(Class beanClass, List alreadyProcessedFieldNam alreadyProcessedFieldNames.add( mainAttributeValue ); } Field field = findField( beanClass, mainAttributeValue ); - ConstraintLocation constraintLocation = ConstraintLocation.forField( field ); + JavaBeanField property = new JavaBeanField( field ); + ConstraintLocation constraintLocation = ConstraintLocation.forProperty( property ); + Set> metaConstraints = constraintTypeStaxBuilders.stream() .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.FIELD, null ) ) .collect( Collectors.toSet() ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( - ReflectionHelper.typeOf( field ), constraintLocation ); + property.getType(), constraintLocation ); ConstrainedField constrainedField = new ConstrainedField( ConfigurationSource.XML, - field, + property, metaConstraints, containerElementTypeConfiguration.getMetaConstraints(), getCascadingMetaData( containerElementTypeConfiguration.getTypeParametersCascadingMetaData(), ReflectionHelper.typeOf( field ) ) @@ -88,7 +91,7 @@ ConstrainedField build(Class beanClass, List alreadyProcessedFieldNam // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsOnMember( - field, + property, ignoreAnnotations.get() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java index ba1b607ffd..b809befab9 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java @@ -26,6 +26,9 @@ import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; +import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.logging.Log; @@ -71,7 +74,8 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedGet alreadyProcessedGetterNames.add( mainAttributeValue ); } Method getter = findGetter( beanClass, mainAttributeValue ); - ConstraintLocation constraintLocation = ConstraintLocation.forGetter( beanClass, getter ); + Property property = new JavaBeanGetter( beanClass, getter ); + ConstraintLocation constraintLocation = ConstraintLocation.forProperty( property ); Set> metaConstraints = constraintTypeStaxBuilders.stream() .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.METHOD, null ) ) @@ -82,7 +86,7 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedGet ConstrainedExecutable constrainedGetter = new ConstrainedExecutable( ConfigurationSource.XML, - getter, + property.as( Callable.class ), Collections.emptyList(), Collections.>emptySet(), metaConstraints, @@ -93,7 +97,7 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedGet // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsOnMember( - getter, + property, ignoreAnnotations.get() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedMethodStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedMethodStaxBuilder.java index ede789a730..f1876750c4 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedMethodStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedMethodStaxBuilder.java @@ -26,6 +26,7 @@ import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; +import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.logging.Log; @@ -96,11 +97,12 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedMet else { alreadyProcessedMethods.add( method ); } + JavaBeanExecutable executable = JavaBeanExecutable.of( method ); // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsOnMember( - method, + executable, ignoreAnnotations.get() ); } @@ -108,21 +110,21 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedMet List constrainedParameters = CollectionHelper.newArrayList( constrainedParameterStaxBuilders.size() ); for ( int index = 0; index < constrainedParameterStaxBuilders.size(); index++ ) { ConstrainedParameterStaxBuilder builder = constrainedParameterStaxBuilders.get( index ); - constrainedParameters.add( builder.build( method, index ) ); + constrainedParameters.add( builder.build( executable, index ) ); } Set> crossParameterConstraints = getCrossParameterStaxBuilder() - .map( builder -> builder.build( method ) ).orElse( Collections.emptySet() ); + .map( builder -> builder.build( executable ) ).orElse( Collections.emptySet() ); // parse the return value Set> returnValueConstraints = new HashSet<>(); Set> returnValueTypeArgumentConstraints = new HashSet<>(); - CascadingMetaDataBuilder cascadingMetaDataBuilder = getReturnValueStaxBuilder().map( builder -> builder.build( method, returnValueConstraints, returnValueTypeArgumentConstraints ) ) + CascadingMetaDataBuilder cascadingMetaDataBuilder = getReturnValueStaxBuilder().map( builder -> builder.build( executable, returnValueConstraints, returnValueTypeArgumentConstraints ) ) .orElse( CascadingMetaDataBuilder.nonCascading() ); return new ConstrainedExecutable( ConfigurationSource.XML, - method, + executable, constrainedParameters, crossParameterConstraints, returnValueConstraints, diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java index cf5a77d690..5344231f1c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java @@ -7,7 +7,6 @@ package org.hibernate.validator.internal.xml.mapping; import java.lang.invoke.MethodHandles; -import java.lang.reflect.Executable; import java.lang.reflect.Type; import java.util.Optional; import java.util.Set; @@ -23,7 +22,7 @@ import org.hibernate.validator.internal.metadata.location.ConstraintLocation; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; -import org.hibernate.validator.internal.util.ReflectionHelper; +import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; @@ -68,10 +67,10 @@ public Class getParameterType(Class beanClass) { } } - ConstrainedParameter build(Executable executable, int index) { + ConstrainedParameter build(Callable callable, int index) { - ConstraintLocation constraintLocation = ConstraintLocation.forParameter( executable, index ); - Type type = ReflectionHelper.typeOf( executable, index ); + ConstraintLocation constraintLocation = ConstraintLocation.forParameter( callable, index ); + Type type = callable.getTypeOfParameter( index ); Set> metaConstraints = constraintTypeStaxBuilders.stream() .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.PARAMETER, null ) ) @@ -82,7 +81,7 @@ ConstrainedParameter build(Executable executable, int index) { // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsOnParameter( - executable, + callable, index, ignoreAnnotations.get() ); @@ -90,7 +89,7 @@ ConstrainedParameter build(Executable executable, int index) { ConstrainedParameter constrainedParameter = new ConstrainedParameter( ConfigurationSource.XML, - executable, + callable, type, index, metaConstraints, diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstraintTypeStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstraintTypeStaxBuilder.java index 862a1226ad..3292210ac0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstraintTypeStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstraintTypeStaxBuilder.java @@ -148,8 +148,8 @@ MetaConstraint build(ConstraintLocation constraintLoca // we set initially ConstraintOrigin.DEFINED_LOCALLY for all xml configured constraints // later we will make copies of this constraint descriptor when needed and adjust the ConstraintOrigin - ConstraintDescriptorImpl constraintDescriptor = new ConstraintDescriptorImpl( - constraintHelper, constraintLocation.getMember(), annotationDescriptor, type, constraintType + ConstraintDescriptorImpl constraintDescriptor = new ConstraintDescriptorImpl<>( + constraintHelper, constraintLocation.getConstrainable(), annotationDescriptor, type, constraintType ); return MetaConstraints.create( typeResolutionHelper, valueExtractorManager, constraintDescriptor, constraintLocation ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java index 30397e1009..ce40f9625f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java @@ -6,7 +6,6 @@ */ package org.hibernate.validator.internal.xml.mapping; -import java.lang.reflect.Executable; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -24,6 +23,7 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.xml.AbstractStaxBuilder; @@ -83,9 +83,9 @@ private ConstraintTypeStaxBuilder getNewConstraintTypeStaxBuilder() { return new ConstraintTypeStaxBuilder( classLoadingHelper, constraintHelper, typeResolutionHelper, valueExtractorManager, defaultPackageStaxBuilder ); } - Set> build(Executable executable) { + Set> build(Callable callable) { - ConstraintLocation constraintLocation = ConstraintLocation.forCrossParameter( executable ); + ConstraintLocation constraintLocation = ConstraintLocation.forCrossParameter( callable ); Set> crossParameterConstraints = constraintTypeStaxBuilders.stream() .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.METHOD, ConstraintType.CROSS_PARAMETER ) ) @@ -94,7 +94,7 @@ Set> build(Executable executable) { // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsForCrossParameterConstraint( - executable, + callable, ignoreAnnotations.get() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java index 85cae903e2..b9458a5fdf 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java @@ -6,7 +6,7 @@ */ package org.hibernate.validator.internal.xml.mapping; -import java.lang.reflect.Executable; +import java.lang.annotation.ElementType; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -20,8 +20,7 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.util.ExecutableHelper; -import org.hibernate.validator.internal.util.ReflectionHelper; +import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.xml.mapping.ContainerElementTypeConfigurationBuilder.ContainerElementTypeConfiguration; @@ -51,27 +50,27 @@ protected String getAcceptableQName() { } CascadingMetaDataBuilder build( - Executable executable, + Callable callable, Set> returnValueConstraints, Set> returnValueTypeArgumentConstraints) { - ConstraintLocation constraintLocation = ConstraintLocation.forReturnValue( executable ); + ConstraintLocation constraintLocation = ConstraintLocation.forReturnValue( callable ); returnValueConstraints.addAll( constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, ExecutableHelper.getElementType( executable ), ConstraintDescriptorImpl.ConstraintType.GENERIC ) ) + .map( builder -> builder.build( constraintLocation, callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD, ConstraintDescriptorImpl.ConstraintType.GENERIC ) ) .collect( Collectors.toSet() ) ); - ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( ReflectionHelper.typeOf( executable ), constraintLocation ); + ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( callable.getType(), constraintLocation ); returnValueTypeArgumentConstraints.addAll( containerElementTypeConfiguration.getMetaConstraints() ); // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsForReturnValue( - executable, + callable, ignoreAnnotations.get() ); } - return getCascadingMetaData( containerElementTypeConfiguration.getTypeParametersCascadingMetaData(), ReflectionHelper.typeOf( executable ) ); + return getCascadingMetaData( containerElementTypeConfiguration.getTypeParametersCascadingMetaData(), callable.getType() ); } } diff --git a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java index d0fc924caa..ae7fd8a3f5 100644 --- a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java @@ -556,7 +556,7 @@ private BeanConfiguration getBeanConfiguration(Class type) { private ConstrainedField getConstrainedField(BeanConfiguration beanConfiguration, String fieldName) { for ( ConstrainedElement constrainedElement : beanConfiguration.getConstrainedElements() ) { if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD && - ( (ConstrainedField) constrainedElement ).getField().getName().equals( fieldName ) ) { + ( (ConstrainedField) constrainedElement ).getProperty().getPropertyName().equals( fieldName ) ) { return (ConstrainedField) constrainedElement; } } @@ -567,7 +567,7 @@ private ConstrainedField getConstrainedField(BeanConfiguration beanConfigurat private ConstrainedExecutable getConstrainedExecutable(BeanConfiguration beanConfiguration, String executableName) { for ( ConstrainedElement constrainedElement : beanConfiguration.getConstrainedElements() ) { if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD && - ( (ConstrainedExecutable) constrainedElement ).getExecutable().getName().equals( executableName ) ) { + ( (ConstrainedExecutable) constrainedElement ).getCallable().getName().equals( executableName ) ) { return (ConstrainedExecutable) constrainedElement; } } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/failfast/FailFastTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/failfast/FailFastTest.java index 1098e29f1f..29721e713f 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/failfast/FailFastTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/failfast/FailFastTest.java @@ -162,8 +162,9 @@ public void testFailFastMethodValidationSetOnValidatorFactory() { fail(); } catch (ConstraintViolationException e) { - assertThat( e.getConstraintViolations() ).containsOnlyViolations( - violationOf( NotBlank.class ) + assertThat( e.getConstraintViolations() ).containsOneOfViolations( + violationOf( NotBlank.class ), + violationOf( Min.class ) ); } } @@ -212,8 +213,9 @@ public void testFailFastMethodValidationSetWithProperty() { fail(); } catch (ConstraintViolationException e) { - assertThat( e.getConstraintViolations() ).containsOnlyViolations( - violationOf( NotBlank.class ) + assertThat( e.getConstraintViolations() ).containsOneOfViolations( + violationOf( NotBlank.class ), + violationOf( Min.class ) ); } } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java index 29cfcc5550..16fc4e3062 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java @@ -20,6 +20,7 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraints; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.testutil.TestForIssue; @@ -49,14 +50,14 @@ public void setUp() throws Exception { @TestForIssue(jiraKey = "HV-930") public void two_meta_constraints_for_the_same_constraint_should_be_equal() throws Exception { ConstraintDescriptorImpl constraintDescriptor1 = new ConstraintDescriptorImpl<>( - constraintHelper, barMethod, constraintAnnotationDescriptor, METHOD + constraintHelper, JavaBeanExecutable.of( barMethod ), constraintAnnotationDescriptor, METHOD ); ConstraintLocation location1 = ConstraintLocation.forClass( Foo.class ); MetaConstraint metaConstraint1 = MetaConstraints.create( typeResolutionHelper, valueExtractorManager, constraintDescriptor1, location1 ); ConstraintDescriptorImpl constraintDescriptor2 = new ConstraintDescriptorImpl<>( - constraintHelper, barMethod, constraintAnnotationDescriptor, METHOD + constraintHelper, JavaBeanExecutable.of( barMethod ), constraintAnnotationDescriptor, METHOD ); ConstraintLocation location2 = ConstraintLocation.forClass( Foo.class ); MetaConstraint metaConstraint2 = MetaConstraints.create( typeResolutionHelper, valueExtractorManager, constraintDescriptor2, location2 ); diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/location/ConstraintLocationTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/location/ConstraintLocationTest.java index 8e424bbd4a..acf7934c4b 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/location/ConstraintLocationTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/location/ConstraintLocationTest.java @@ -11,6 +11,7 @@ import java.lang.reflect.Method; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.testutil.TestForIssue; import org.testng.annotations.Test; @@ -32,8 +33,8 @@ public void two_constraint_locations_for_the_same_type_should_be_equal() { @TestForIssue(jiraKey = "HV-930") public void two_constraint_locations_for_the_same_member_should_be_equal() throws Exception { Method getter = Foo.class.getMethod( "getBar" ); - ConstraintLocation location1 = ConstraintLocation.forGetter( getter ); - ConstraintLocation location2 = ConstraintLocation.forGetter( getter ); + ConstraintLocation location1 = ConstraintLocation.forProperty( new JavaBeanGetter( getter ) ); + ConstraintLocation location2 = ConstraintLocation.forProperty( new JavaBeanGetter( getter ) ); assertEquals( location1, location2, "Two constraint locations for the same type should be equal" ); } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTest.java index 9953a487f8..95d3561fd9 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTest.java @@ -40,6 +40,7 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; +import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.testutil.TestForIssue; import org.joda.time.DateMidnight; @@ -101,11 +102,13 @@ public void testGetCrossParameterMetaData() throws Exception { assertThat( createEvent.getConstraints() ).as( "No return value constraints expected" ).isEmpty(); assertThat( createEvent.getCrossParameterConstraints() ).hasSize( 1 ); - assertThat( createEvent.getExecutable() ).isEqualTo( - Calendar.class.getMethod( - "createEvent", - DateMidnight.class, - DateMidnight.class + assertThat( createEvent.getCallable() ).isEqualTo( + JavaBeanExecutable.of( + Calendar.class.getMethod( + "createEvent", + DateMidnight.class, + DateMidnight.class + ) ) ); diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTestBase.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTestBase.java index fca67eae25..7a9e68def8 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTestBase.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTestBase.java @@ -16,6 +16,9 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; +import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; /** * @author Gunnar Morling @@ -59,14 +62,22 @@ protected ConstrainedType findConstrainedType(BeanConfiguration beanConfi protected ConstrainedElement findConstrainedElement(BeanConfiguration beanConfiguration, Member member) { + Constrainable constrainable; + if ( member instanceof Field ) { + constrainable = new JavaBeanField( (Field) member ); + } + else { + constrainable = JavaBeanExecutable.of( (Executable) member ); + } + for ( ConstrainedElement constrainedElement : beanConfiguration.getConstrainedElements() ) { if ( member instanceof Executable && constrainedElement instanceof ConstrainedExecutable ) { - if ( member.equals( ( (ConstrainedExecutable) constrainedElement ).getExecutable() ) ) { + if ( constrainable.equals( ( (ConstrainedExecutable) constrainedElement ).getCallable() ) ) { return constrainedElement; } } - else if ( member instanceof Field && constrainedElement instanceof ConstrainedField ) { - if ( member.equals( ( (ConstrainedField) constrainedElement ).getField() ) ) { + else if ( constrainedElement instanceof ConstrainedField ) { + if ( constrainable.equals( ( (ConstrainedField) constrainedElement ).getProperty() ) ) { return constrainedElement; } } diff --git a/test-utils/src/main/java/org/hibernate/validator/testutil/ConstraintViolationAssert.java b/test-utils/src/main/java/org/hibernate/validator/testutil/ConstraintViolationAssert.java index 1316865371..cf234f1bc7 100644 --- a/test-utils/src/main/java/org/hibernate/validator/testutil/ConstraintViolationAssert.java +++ b/test-utils/src/main/java/org/hibernate/validator/testutil/ConstraintViolationAssert.java @@ -263,6 +263,21 @@ public ConstraintViolationSetAssert describedAs(String description, Object... ar public void containsOnlyViolations(ViolationExpectation... expectedViolations) { isNotNull(); + List actualViolations = getActualViolationExpectations( expectedViolations ); + + Assertions.assertThat( actualViolations ).containsExactlyInAnyOrder( expectedViolations ); + } + + public void containsOneOfViolations(ViolationExpectation... expectedViolations) { + isNotNull(); + + List actualViolations = getActualViolationExpectations( expectedViolations ); + + Assertions.assertThat( actualViolations ).hasSize( 1 ); + Assertions.assertThat( expectedViolations ).contains( actualViolations.get( 0 ) ); + } + + private List getActualViolationExpectations(ViolationExpectation[] expectedViolations) { List actualViolations = new ArrayList<>(); ViolationExpectationPropertiesToTest referencePropertiesToTest; @@ -284,7 +299,7 @@ public void containsOnlyViolations(ViolationExpectation... expectedViolations) { actualViolations.add( new ViolationExpectation( violation, referencePropertiesToTest ) ); } - Assertions.assertThat( actualViolations ).containsExactlyInAnyOrder( expectedViolations ); + return actualViolations; } public void containsOnlyPaths(PathExpectation... paths) { From af67fd7294a3d431521a4481c85ebcf93dfd9e07 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 7 Jun 2018 12:13:35 +0200 Subject: [PATCH 02/24] HV-1623 Reintroduce field and getter constraint locations --- .../cfg/context/ConfiguredConstraint.java | 5 ++++- .../PropertyConstraintMappingContextImpl.java | 5 ++++- .../metadata/aggregated/PropertyMetaData.java | 9 ++++---- .../metadata/location/ConstraintLocation.java | 11 +++++++--- .../FieldPropertyConstraintLocation.java | 21 ++++++++++++++++++ .../GetterPropertyConstraintLocation.java | 21 ++++++++++++++++++ .../location/PropertyConstraintLocation.java | 15 ++++++------- .../provider/AnnotationMetaDataProvider.java | 22 +++++++++---------- .../mapping/ConstrainedFieldStaxBuilder.java | 10 ++++----- .../mapping/ConstrainedGetterStaxBuilder.java | 10 ++++----- .../location/ConstraintLocationTest.java | 4 ++-- 11 files changed, 92 insertions(+), 41 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java index 3f47510fca..c2f07e008a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java @@ -23,6 +23,7 @@ import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.annotation.AnnotationDescriptor; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.internal.util.logging.Log; @@ -59,7 +60,9 @@ static ConfiguredConstraint forType(ConstraintDef ConfiguredConstraint forProperty(ConstraintDef constraint, Property property) { return new ConfiguredConstraint<>( constraint, - ConstraintLocation.forProperty( property ), + property instanceof JavaBeanField + ? ConstraintLocation.forField( property.as( JavaBeanField.class ) ) + : ConstraintLocation.forGetter( property.as( JavaBeanGetter.class ) ), property instanceof JavaBeanField ? ElementType.FIELD : ElementType.METHOD ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java index 95e51deec5..10fe537c9f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java @@ -24,6 +24,7 @@ import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.TypeResolutionHelper; /** @@ -47,7 +48,9 @@ final class PropertyConstraintMappingContextImpl super( typeContext.getConstraintMapping(), property.getType() ); this.typeContext = typeContext; this.property = property; - this.location = ConstraintLocation.forProperty( property ); + this.location = property instanceof JavaBeanField + ? ConstraintLocation.forField( property.as( JavaBeanField.class ) ) + : ConstraintLocation.forGetter( property.as( JavaBeanGetter.class ) ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 7282c947f7..9568a38dbd 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -31,7 +31,7 @@ import org.hibernate.validator.internal.metadata.descriptor.PropertyDescriptorImpl; import org.hibernate.validator.internal.metadata.facets.Cascadable; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.metadata.location.PropertyConstraintLocation; +import org.hibernate.validator.internal.metadata.location.GetterPropertyConstraintLocation; import org.hibernate.validator.internal.metadata.location.TypeArgumentConstraintLocation; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; @@ -41,6 +41,7 @@ import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredMethod; @@ -243,7 +244,7 @@ protected Set> adaptConstraints(ConstrainedElement constrained return constraints; } - ConstraintLocation getterConstraintLocation = ConstraintLocation.forProperty( ( (ConstrainedExecutable) constrainedElement ).getCallable().as( Property.class ) ); + ConstraintLocation getterConstraintLocation = ConstraintLocation.forGetter( ( (ConstrainedExecutable) constrainedElement ).getCallable().as( JavaBeanGetter.class ) ); // convert return value locations into getter locations for usage within this meta-data return constraints.stream() @@ -257,7 +258,7 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint // fast track if it's a regular constraint if ( !(constraint.getLocation() instanceof TypeArgumentConstraintLocation) ) { // Change the constraint location to a GetterConstraintLocation if it is not already one - if ( constraint.getLocation() instanceof PropertyConstraintLocation ) { + if ( constraint.getLocation() instanceof GetterPropertyConstraintLocation ) { converted = constraint.getLocation(); } else { @@ -284,7 +285,7 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint for ( ConstraintLocation location : locationStack ) { if ( !(location instanceof TypeArgumentConstraintLocation) ) { // Change the constraint location to a GetterConstraintLocation if it is not already one - if ( location instanceof PropertyConstraintLocation ) { + if ( location instanceof GetterPropertyConstraintLocation ) { converted = location; } else { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index a5626998c5..54aafdbd5a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -12,7 +12,8 @@ import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; -import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; /** @@ -38,8 +39,12 @@ static ConstraintLocation forClass(Class declaringClass) { return new BeanConstraintLocation( declaringClass ); } - static ConstraintLocation forProperty(Property property) { - return new PropertyConstraintLocation( property ); + static ConstraintLocation forField(JavaBeanField field) { + return new FieldPropertyConstraintLocation( field ); + } + + static ConstraintLocation forGetter(JavaBeanGetter getter) { + return new GetterPropertyConstraintLocation( getter ); } static ConstraintLocation forTypeArgument(ConstraintLocation delegate, TypeVariable typeParameter, Type typeOfAnnotatedElement) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java new file mode 100644 index 0000000000..2cdb6840cc --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java @@ -0,0 +1,21 @@ +/* + * 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.metadata.location; + +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; + +/** + * Field property constraint location. + * + * @author Marko Bekhta + */ +public class FieldPropertyConstraintLocation extends PropertyConstraintLocation { + + FieldPropertyConstraintLocation(JavaBeanField javaBeanGetter) { + super( javaBeanGetter ); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java new file mode 100644 index 0000000000..2d450be8bf --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java @@ -0,0 +1,21 @@ +/* + * 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.metadata.location; + +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; + +/** + * Getter property constraint location. + * + * @author Marko Bekhta + */ +public class GetterPropertyConstraintLocation extends PropertyConstraintLocation { + + GetterPropertyConstraintLocation(JavaBeanGetter javaBeanGetter) { + super( javaBeanGetter ); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java index 78b9ccc4b0..b64181c185 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java @@ -9,23 +9,22 @@ import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; -import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; /** - * Property constraint location. + * An abstract property constraint location. * * @author Marko Bekhta */ -public class PropertyConstraintLocation implements ConstraintLocation { +public abstract class PropertyConstraintLocation implements ConstraintLocation { /** * The member the constraint was defined on. */ - private final Property property; + private final T property; - PropertyConstraintLocation(Property property) { + PropertyConstraintLocation(T property) { this.property = property; } @@ -35,7 +34,7 @@ public Class getDeclaringClass() { } @Override - public Constrainable getConstrainable() { + public T getConstrainable() { return property; } @@ -60,7 +59,7 @@ public Object getValue(Object parent) { @Override public String toString() { - return "PropertyConstraintLocation [property=" + property + "]"; + return getClass().getSimpleName() + " [property=" + property + "]"; } @Override @@ -72,7 +71,7 @@ public boolean equals(Object o) { return false; } - PropertyConstraintLocation that = (PropertyConstraintLocation) o; + PropertyConstraintLocation that = (PropertyConstraintLocation) o; if ( !property.equals( that.property ) ) { return false; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index 12aeaa9e06..9f36621a08 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -218,46 +218,46 @@ private Set getFieldMetaData(Class beanClass) { Set propertyMetaData = newHashSet(); for ( Field field : run( GetDeclaredFields.action( beanClass ) ) ) { - Property property = new JavaBeanField( field ); + JavaBeanField javaBeanField = new JavaBeanField( field ); // HV-172 if ( Modifier.isStatic( field.getModifiers() ) || - annotationProcessingOptions.areMemberConstraintsIgnoredFor( property ) || + annotationProcessingOptions.areMemberConstraintsIgnoredFor( javaBeanField ) || field.isSynthetic() ) { continue; } - propertyMetaData.add( findPropertyMetaData( field, property ) ); + propertyMetaData.add( findPropertyMetaData( field, javaBeanField ) ); } return propertyMetaData; } - private ConstrainedField findPropertyMetaData(Field field, Property property) { + private ConstrainedField findPropertyMetaData(Field field, JavaBeanField javaBeanField) { Set> constraints = convertToMetaConstraints( - findConstraints( field, ElementType.FIELD, property ), - property + findConstraints( field, ElementType.FIELD, javaBeanField ), + javaBeanField ); CascadingMetaDataBuilder cascadingMetaDataBuilder = findCascadingMetaData( field ); - Set> typeArgumentsConstraints = findTypeAnnotationConstraints( field, property ); + Set> typeArgumentsConstraints = findTypeAnnotationConstraints( field, javaBeanField ); return new ConstrainedField( ConfigurationSource.ANNOTATION, - property, + javaBeanField, constraints, typeArgumentsConstraints, cascadingMetaDataBuilder ); } - private Set> convertToMetaConstraints(List> constraintDescriptors, Property property) { + private Set> convertToMetaConstraints(List> constraintDescriptors, JavaBeanField javaBeanField) { if ( constraintDescriptors.isEmpty() ) { return Collections.emptySet(); } Set> constraints = newHashSet(); - ConstraintLocation location = ConstraintLocation.forProperty( property ); + ConstraintLocation location = ConstraintLocation.forField( javaBeanField ); for ( ConstraintDescriptorImpl constraintDescription : constraintDescriptors ) { constraints.add( MetaConstraints.create( typeResolutionHelper, valueExtractorManager, constraintDescription, location ) ); @@ -843,7 +843,7 @@ private TypeArgumentFieldLocation(Field field) { @Override public ConstraintLocation toConstraintLocation() { - return ConstraintLocation.forProperty( new JavaBeanField( field ) ); + return ConstraintLocation.forField( new JavaBeanField( field ) ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java index 5244d464e7..1126e715ab 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java @@ -70,19 +70,19 @@ ConstrainedField build(Class beanClass, List alreadyProcessedFieldNam alreadyProcessedFieldNames.add( mainAttributeValue ); } Field field = findField( beanClass, mainAttributeValue ); - JavaBeanField property = new JavaBeanField( field ); - ConstraintLocation constraintLocation = ConstraintLocation.forProperty( property ); + JavaBeanField javaBeanField = new JavaBeanField( field ); + ConstraintLocation constraintLocation = ConstraintLocation.forField( javaBeanField ); Set> metaConstraints = constraintTypeStaxBuilders.stream() .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.FIELD, null ) ) .collect( Collectors.toSet() ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( - property.getType(), constraintLocation ); + javaBeanField.getType(), constraintLocation ); ConstrainedField constrainedField = new ConstrainedField( ConfigurationSource.XML, - property, + javaBeanField, metaConstraints, containerElementTypeConfiguration.getMetaConstraints(), getCascadingMetaData( containerElementTypeConfiguration.getTypeParametersCascadingMetaData(), ReflectionHelper.typeOf( field ) ) @@ -91,7 +91,7 @@ ConstrainedField build(Class beanClass, List alreadyProcessedFieldNam // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsOnMember( - property, + javaBeanField, ignoreAnnotations.get() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java index b809befab9..fbe4766597 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java @@ -26,8 +26,6 @@ import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; -import org.hibernate.validator.internal.properties.Callable; -import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; @@ -74,8 +72,8 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedGet alreadyProcessedGetterNames.add( mainAttributeValue ); } Method getter = findGetter( beanClass, mainAttributeValue ); - Property property = new JavaBeanGetter( beanClass, getter ); - ConstraintLocation constraintLocation = ConstraintLocation.forProperty( property ); + JavaBeanGetter javaBeanGetter = new JavaBeanGetter( beanClass, getter ); + ConstraintLocation constraintLocation = ConstraintLocation.forGetter( javaBeanGetter ); Set> metaConstraints = constraintTypeStaxBuilders.stream() .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.METHOD, null ) ) @@ -86,7 +84,7 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedGet ConstrainedExecutable constrainedGetter = new ConstrainedExecutable( ConfigurationSource.XML, - property.as( Callable.class ), + javaBeanGetter, Collections.emptyList(), Collections.>emptySet(), metaConstraints, @@ -97,7 +95,7 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedGet // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsOnMember( - property, + javaBeanGetter, ignoreAnnotations.get() ); } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/location/ConstraintLocationTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/location/ConstraintLocationTest.java index acf7934c4b..0bbca776e3 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/location/ConstraintLocationTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/location/ConstraintLocationTest.java @@ -33,8 +33,8 @@ public void two_constraint_locations_for_the_same_type_should_be_equal() { @TestForIssue(jiraKey = "HV-930") public void two_constraint_locations_for_the_same_member_should_be_equal() throws Exception { Method getter = Foo.class.getMethod( "getBar" ); - ConstraintLocation location1 = ConstraintLocation.forProperty( new JavaBeanGetter( getter ) ); - ConstraintLocation location2 = ConstraintLocation.forProperty( new JavaBeanGetter( getter ) ); + ConstraintLocation location1 = ConstraintLocation.forGetter( new JavaBeanGetter( getter ) ); + ConstraintLocation location2 = ConstraintLocation.forGetter( new JavaBeanGetter( getter ) ); assertEquals( location1, location2, "Two constraint locations for the same type should be equal" ); } From 556d27783cdb8bab9d98ab220bc49ab11811635d Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Tue, 5 Jun 2018 23:25:12 +0200 Subject: [PATCH 03/24] HV-1623 Clean ups around cascadable properties in PropertyMetaData --- .../metadata/aggregated/FieldCascadable.java | 43 +++++++++++++++++++ .../metadata/aggregated/GetterCascadable.java | 43 +++++++++++++++++++ .../aggregated/PropertyCascadable.java | 32 ++++++++------ .../metadata/aggregated/PropertyMetaData.java | 34 +++++++-------- 4 files changed, 121 insertions(+), 31 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java new file mode 100644 index 0000000000..37d82ff6da --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java @@ -0,0 +1,43 @@ +/* + * 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.metadata.aggregated; + +import java.lang.annotation.ElementType; + +import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; +import org.hibernate.validator.internal.metadata.facets.Cascadable; +import org.hibernate.validator.internal.properties.Property; + +/** + * A {@link Cascadable} backed by a field of a Java bean. + * + * @author Gunnar Morling + * @author Marko Bekhta + */ +public class FieldCascadable extends PropertyCascadable { + + FieldCascadable(Property property, CascadingMetaData cascadingMetaData) { + super( property, cascadingMetaData ); + } + + @Override + public ElementType getElementType() { + return ElementType.FIELD; + } + + public static class Builder extends PropertyCascadable.Builder { + + protected Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { + super( valueExtractorManager, property, cascadingMetaDataBuilder ); + } + + @Override + protected Cascadable create(Property property, CascadingMetaData cascadingMetaData) { + return new FieldCascadable( property, cascadingMetaData ); + } + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java new file mode 100644 index 0000000000..fbb379ab2e --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java @@ -0,0 +1,43 @@ +/* + * 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.metadata.aggregated; + +import java.lang.annotation.ElementType; + +import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; +import org.hibernate.validator.internal.metadata.facets.Cascadable; +import org.hibernate.validator.internal.properties.Property; + +/** + * A {@link Cascadable} backed by a getter of a Java bean. + * + * @author Gunnar Morling + * @author Marko Bekhta + */ +public class GetterCascadable extends PropertyCascadable { + + GetterCascadable(Property property, CascadingMetaData cascadingMetaData) { + super( property, cascadingMetaData ); + } + + @Override + public ElementType getElementType() { + return ElementType.METHOD; + } + + public static class Builder extends PropertyCascadable.Builder { + + protected Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { + super( valueExtractorManager, property, cascadingMetaDataBuilder ); + } + + @Override + protected Cascadable create(Property property, CascadingMetaData cascadingMetaData) { + return new GetterCascadable( property, cascadingMetaData ); + } + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java index 7afa0fd018..eafc89bbb3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java @@ -6,14 +6,13 @@ */ package org.hibernate.validator.internal.metadata.aggregated; -import java.lang.annotation.ElementType; import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.facets.Cascadable; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Property; -import org.hibernate.validator.internal.properties.javabean.JavaBeanField; /** * A {@link Cascadable} backed by a field of a Java bean. @@ -21,23 +20,16 @@ * @author Gunnar Morling * @author Marko Bekhta */ -public class PropertyCascadable implements Cascadable { +public abstract class PropertyCascadable implements Cascadable { private final Property property; private final Type cascadableType; private final CascadingMetaData cascadingMetaData; - private final ElementType elementType; PropertyCascadable(Property property, CascadingMetaData cascadingMetaData) { this.property = property; this.cascadableType = property.getType(); this.cascadingMetaData = cascadingMetaData; - this.elementType = property instanceof JavaBeanField ? ElementType.FIELD : ElementType.METHOD; - } - - @Override - public ElementType getElementType() { - return elementType; } @Override @@ -60,13 +52,13 @@ public CascadingMetaData getCascadingMetaData() { return cascadingMetaData; } - public static class Builder implements Cascadable.Builder { + public abstract static class Builder implements Cascadable.Builder { private final ValueExtractorManager valueExtractorManager; private final Property property; private CascadingMetaDataBuilder cascadingMetaDataBuilder; - public Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { + protected Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { this.valueExtractorManager = valueExtractorManager; this.property = property; this.cascadingMetaDataBuilder = cascadingMetaDataBuilder; @@ -78,8 +70,20 @@ public void mergeCascadingMetaData(CascadingMetaDataBuilder cascadingMetaData) { } @Override - public PropertyCascadable build() { - return new PropertyCascadable( property, cascadingMetaDataBuilder.build( valueExtractorManager, property ) ); + public Cascadable build() { + return create( property, cascadingMetaDataBuilder.build( valueExtractorManager, property ) ); + } + + protected abstract Cascadable create(Property property, CascadingMetaData build); + + public static Cascadable.Builder builder(ConstrainedElementKind constrainedElementKind, ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { + if ( ConstrainedElementKind.FIELD == constrainedElementKind ) { + return new FieldCascadable.Builder( valueExtractorManager, property, cascadingMetaDataBuilder ); + } + else if ( ConstrainedElementKind.METHOD == constrainedElementKind ) { + return new GetterCascadable.Builder( valueExtractorManager, property, cascadingMetaDataBuilder ); + } + throw new IllegalStateException( "It should either be field or method." ); } } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 9568a38dbd..3ef5565d16 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -38,7 +39,6 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; -import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; @@ -211,31 +211,31 @@ public final void add(ConstrainedElement constrainedElement) { if ( constrainedElement.getCascadingMetaDataBuilder().isMarkedForCascadingOnAnnotatedObjectOrContainerElements() || constrainedElement.getCascadingMetaDataBuilder().hasGroupConversionsOnAnnotatedObjectOrContainerElements() ) { - if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { - Property property = ( (ConstrainedField) constrainedElement ).getProperty(); - Cascadable.Builder builder = cascadableBuilders.get( property ); + Optional constrainable = getConstrainableFromConstrainedElement( constrainedElement ); + + if ( constrainable.isPresent() ) { + Property property = constrainable.get().as( Property.class ); + Cascadable.Builder builder = cascadableBuilders.get( property ); if ( builder == null ) { - builder = new PropertyCascadable.Builder( valueExtractorManager, property, constrainedElement.getCascadingMetaDataBuilder() ); + builder = PropertyCascadable.Builder.builder( constrainedElement.getKind(), valueExtractorManager, property, constrainedElement.getCascadingMetaDataBuilder() ); cascadableBuilders.put( property, builder ); } else { builder.mergeCascadingMetaData( constrainedElement.getCascadingMetaDataBuilder() ); } } - else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { - Callable method = ( (ConstrainedExecutable) constrainedElement ).getCallable(); - Cascadable.Builder builder = cascadableBuilders.get( method ); + } + } - if ( builder == null ) { - builder = new PropertyCascadable.Builder( valueExtractorManager, method.as( Property.class ), constrainedElement.getCascadingMetaDataBuilder() ); - cascadableBuilders.put( method, builder ); - } - else { - builder.mergeCascadingMetaData( constrainedElement.getCascadingMetaDataBuilder() ); - } - } + private Optional getConstrainableFromConstrainedElement(ConstrainedElement constrainedElement) { + if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { + return Optional.of( ( (ConstrainedField) constrainedElement ).getProperty() ); + } + else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { + return Optional.of( ( (ConstrainedExecutable) constrainedElement ).getCallable() ); } + return Optional.empty(); } @Override @@ -256,7 +256,7 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint ConstraintLocation converted = null; // fast track if it's a regular constraint - if ( !(constraint.getLocation() instanceof TypeArgumentConstraintLocation) ) { + if ( !( constraint.getLocation() instanceof TypeArgumentConstraintLocation ) ) { // Change the constraint location to a GetterConstraintLocation if it is not already one if ( constraint.getLocation() instanceof GetterPropertyConstraintLocation ) { converted = constraint.getLocation(); From dbffebaa431e001939f4ead5a404fc748ad79e95 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 30 May 2018 22:09:50 +0200 Subject: [PATCH 04/24] HV-1623 Remove redundant check in ConfiguredConstraint - based on the usage of the method we cannot receive methods into it, hence the check can be removed. And also the method can be named more specific to represent what it is really should be doing. --- .../internal/cfg/context/ConfiguredConstraint.java | 10 +++------- .../context/PropertyConstraintMappingContextImpl.java | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java index c2f07e008a..87c1bb0ace 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java @@ -21,9 +21,7 @@ import org.hibernate.validator.cfg.ConstraintDef; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; import org.hibernate.validator.internal.properties.Callable; -import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; -import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.annotation.AnnotationDescriptor; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.internal.util.logging.Log; @@ -57,13 +55,11 @@ static ConfiguredConstraint forType(ConstraintDef( constraint, ConstraintLocation.forClass( beanType ), ElementType.TYPE ); } - static ConfiguredConstraint forProperty(ConstraintDef constraint, Property property) { + static ConfiguredConstraint forFieldProperty(ConstraintDef constraint, JavaBeanField javaBeanField) { return new ConfiguredConstraint<>( constraint, - property instanceof JavaBeanField - ? ConstraintLocation.forField( property.as( JavaBeanField.class ) ) - : ConstraintLocation.forGetter( property.as( JavaBeanGetter.class ) ), - property instanceof JavaBeanField ? ElementType.FIELD : ElementType.METHOD + ConstraintLocation.forField( javaBeanField ), + ElementType.FIELD ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java index 10fe537c9f..7443605991 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java @@ -62,8 +62,8 @@ protected PropertyConstraintMappingContextImpl getThis() { public PropertyConstraintMappingContext constraint(ConstraintDef definition) { if ( property instanceof JavaBeanField ) { super.addConstraint( - ConfiguredConstraint.forProperty( - definition, property + ConfiguredConstraint.forFieldProperty( + definition, property.as( JavaBeanField.class ) ) ); } From 3063210aef4ab476efc2d9d714b24dad921095d1 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 30 May 2018 22:21:38 +0200 Subject: [PATCH 05/24] HV-1623 Clean up property metadata - changed Constrainable to Property to better represent the intended objects to be processed by the builder - removed unused parameters, fields and methods --- .../metadata/aggregated/PropertyMetaData.java | 34 ++----------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 3ef5565d16..eda2d4b0f8 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -6,10 +6,7 @@ */ package org.hibernate.validator.internal.metadata.aggregated; -import java.lang.reflect.Method; import java.lang.reflect.Type; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayDeque; import java.util.Collections; import java.util.Deque; @@ -24,7 +21,6 @@ import javax.validation.ElementKind; -import org.hibernate.validator.HibernateValidatorPermission; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.MetaConstraint; @@ -44,7 +40,6 @@ import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; -import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredMethod; import org.hibernate.validator.internal.util.stereotypes.Immutable; /** @@ -72,8 +67,7 @@ private PropertyMetaData(String propertyName, Type type, Set> constraints, Set> containerElementsConstraints, - Set cascadables, - boolean cascadingProperty) { + Set cascadables) { super( propertyName, type, @@ -158,9 +152,8 @@ public static class Builder extends MetaDataBuilder { ); private final String propertyName; - private final Map cascadableBuilders = new HashMap<>(); + private final Map cascadableBuilders = new HashMap<>(); private final Type propertyType; - private boolean cascadingProperty = false; public Builder(Class beanClass, ConstrainedField constrainedProperty, ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { @@ -207,8 +200,6 @@ public boolean accepts(ConstrainedElement constrainedElement) { public final void add(ConstrainedElement constrainedElement) { super.add( constrainedElement ); - cascadingProperty = cascadingProperty || constrainedElement.getCascadingMetaDataBuilder().isCascading(); - if ( constrainedElement.getCascadingMetaDataBuilder().isMarkedForCascadingOnAnnotatedObjectOrContainerElements() || constrainedElement.getCascadingMetaDataBuilder().hasGroupConversionsOnAnnotatedObjectOrContainerElements() ) { @@ -316,24 +307,6 @@ else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { return null; } - /** - * Returns an accessible copy of the given member. - */ - private Method getAccessible(Method original) { - SecurityManager sm = System.getSecurityManager(); - if ( sm != null ) { - sm.checkPermission( HibernateValidatorPermission.ACCESS_PRIVATE_MEMBERS ); - } - - Class clazz = original.getDeclaringClass(); - - return run( GetDeclaredMethod.andMakeAccessible( clazz, original.getName() ) ); - } - - private T run(PrivilegedAction action) { - return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run(); - } - @Override public PropertyMetaData build() { Set cascadables = cascadableBuilders.values() @@ -346,8 +319,7 @@ public PropertyMetaData build() { propertyType, adaptOriginsAndImplicitGroups( getDirectConstraints() ), adaptOriginsAndImplicitGroups( getContainerElementConstraints() ), - cascadables, - cascadingProperty + cascadables ); } } From 660b64c17f7e3882a6e3a473412a27327203c9c2 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 30 May 2018 22:31:32 +0200 Subject: [PATCH 06/24] HV-1623 Add additional checks before casting --- .../metadata/aggregated/PropertyMetaData.java | 19 +++++++++++++++++-- .../validator/internal/util/logging/Log.java | 4 ++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index eda2d4b0f8..8150ea009b 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -6,6 +6,7 @@ */ package org.hibernate.validator.internal.metadata.aggregated; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Type; import java.util.ArrayDeque; import java.util.Collections; @@ -40,6 +41,8 @@ import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; +import org.hibernate.validator.internal.util.logging.Log; +import org.hibernate.validator.internal.util.logging.LoggerFactory; import org.hibernate.validator.internal.util.stereotypes.Immutable; /** @@ -60,6 +63,8 @@ */ public class PropertyMetaData extends AbstractConstraintMetaData { + private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() ); + @Immutable private final Set cascadables; @@ -221,10 +226,20 @@ public final void add(ConstrainedElement constrainedElement) { private Optional getConstrainableFromConstrainedElement(ConstrainedElement constrainedElement) { if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { - return Optional.of( ( (ConstrainedField) constrainedElement ).getProperty() ); + if ( constrainedElement instanceof ConstrainedField ) { + return Optional.of( ( (ConstrainedField) constrainedElement ).getProperty() ); + } + else { + LOG.getUnexpectedConstraintElementType( ConstrainedField.class, constrainedElement.getClass() ); + } } else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { - return Optional.of( ( (ConstrainedExecutable) constrainedElement ).getCallable() ); + if ( constrainedElement instanceof ConstrainedExecutable ) { + return Optional.of( ( (ConstrainedExecutable) constrainedElement ).getCallable() ); + } + else { + LOG.getUnexpectedConstraintElementType( ConstrainedExecutable.class, constrainedElement.getClass() ); + } } return Optional.empty(); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index 41bd6883f3..09f355ab3e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -63,6 +63,7 @@ import org.hibernate.validator.spi.scripting.ScriptEvaluationException; import org.hibernate.validator.spi.scripting.ScriptEvaluatorFactory; import org.hibernate.validator.spi.scripting.ScriptEvaluatorNotFoundException; + import org.jboss.logging.BasicLogger; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.FormatWith; @@ -857,4 +858,7 @@ ConstraintDefinitionException getConstraintValidatorDefinitionConstraintMismatch @FormatWith(ClassObjectFormatter.class) Class> constraintValidatorImplementationType, @FormatWith(ClassObjectFormatter.class) Class registeredConstraintAnnotationType, @FormatWith(TypeFormatter.class) Type declaredConstraintAnnotationType); + + @Message(id = 244, value = "ConstrainedElement expected class was %1$s, but instead received %2$s.") + AssertionError getUnexpectedConstraintElementType(@FormatWith(ClassObjectFormatter.class) Class expecting, @FormatWith(ClassObjectFormatter.class) Class got); } From 0b0835c8de391c93021b3b1d1742b8a5995c0b12 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 30 May 2018 23:08:24 +0200 Subject: [PATCH 07/24] HV-1623 Remove ConstrainableFormatter and push the logic to toString implementations --- .../javabean/JavaBeanExecutable.java | 8 ++++ .../properties/javabean/JavaBeanField.java | 5 +++ .../validator/internal/util/logging/Log.java | 25 ++++++------ .../formatter/ConstrainableFormatter.java | 39 ------------------- 4 files changed, 25 insertions(+), 52 deletions(-) delete mode 100644 engine/src/main/java/org/hibernate/validator/internal/util/logging/formatter/ConstrainableFormatter.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java index afe1e9211a..d7285fcb41 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java @@ -176,6 +176,14 @@ public int hashCode() { return result; } + @Override + public String toString() { + return ExecutableHelper.getExecutableAsString( + getDeclaringClass().getSimpleName() + "#" + name, + getParameterTypes() + ); + } + private boolean hasReturnValue(Executable executable) { if ( executable instanceof Constructor ) { return true; diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java index 8ea4eb2067..67271d68c9 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java @@ -95,6 +95,11 @@ public int hashCode() { return result; } + @Override + public String toString() { + return getName(); + } + /** * Returns an accessible copy of the given member. */ diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index 09f355ab3e..18a6f24df3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -54,7 +54,6 @@ import org.hibernate.validator.internal.util.logging.formatter.ClassObjectFormatter; import org.hibernate.validator.internal.util.logging.formatter.CollectionOfClassesObjectFormatter; import org.hibernate.validator.internal.util.logging.formatter.CollectionOfObjectsToStringFormatter; -import org.hibernate.validator.internal.util.logging.formatter.ConstrainableFormatter; import org.hibernate.validator.internal.util.logging.formatter.DurationFormatter; import org.hibernate.validator.internal.util.logging.formatter.ExecutableFormatter; import org.hibernate.validator.internal.util.logging.formatter.ObjectArrayFormatter; @@ -252,13 +251,13 @@ GroupDefinitionException getUnableToExpandDefaultGroupListException(@FormatWith( GroupDefinitionException getWrongDefaultGroupSequenceProviderTypeException(@FormatWith(ClassObjectFormatter.class) Class beanClass); @Message(id = 56, value = "Method or constructor %1$s doesn't have a parameter with index %2$d.") - IllegalArgumentException getInvalidExecutableParameterIndexException(@FormatWith(ConstrainableFormatter.class) Callable callable, int index); + IllegalArgumentException getInvalidExecutableParameterIndexException(Callable callable, int index); @Message(id = 59, value = "Unable to retrieve annotation parameter value.") ValidationException getUnableToRetrieveAnnotationParameterValueException(@Cause Exception e); @Message(id = 62, value = "Method or constructor %1$s has %2$s parameters, but the passed list of parameter meta data has a size of %3$s.") - IllegalArgumentException getInvalidLengthOfParameterMetaDataListException(@FormatWith(ConstrainableFormatter.class) Callable callable, int nbParameters, int listSize); + IllegalArgumentException getInvalidLengthOfParameterMetaDataListException(Callable callable, int nbParameters, int listSize); @Message(id = 63, value = "Unable to instantiate %s.") ValidationException getUnableToInstantiateException(@FormatWith(ClassObjectFormatter.class) Class clazz, @Cause Exception e); @@ -468,7 +467,7 @@ ConstraintDeclarationException getMultipleGroupConversionsForSameSourceException @Message(id = 132, value = "Void methods must not be constrained or marked for cascaded validation, but method %s is.") - ConstraintDeclarationException getVoidMethodsMustNotBeConstrainedException(@FormatWith(ConstrainableFormatter.class) Callable callable); + ConstraintDeclarationException getVoidMethodsMustNotBeConstrainedException(Callable callable); @Message(id = 133, value = "%1$s does not contain a constructor with the parameter types %2$s.") ValidationException getBeanDoesNotContainConstructorException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @@ -503,7 +502,7 @@ ConstraintDeclarationException getImplicitConstraintTargetInAmbiguousConfigurati @Message(id = 142, value = "Cross parameter constraint %1$s is illegally placed on a parameterless method or constructor '%2$s'.") ConstraintDeclarationException getCrossParameterConstraintOnMethodWithoutParametersException( - @FormatWith(ClassObjectFormatter.class) Class constraint, @FormatWith(ConstrainableFormatter.class) Constrainable executable); + @FormatWith(ClassObjectFormatter.class) Class constraint, Constrainable executable); @Message(id = 143, value = "Cross parameter constraint %1$s is illegally placed on class level.") @@ -512,7 +511,7 @@ ConstraintDeclarationException getCrossParameterConstraintOnMethodWithoutParamet @Message(id = 144, value = "Cross parameter constraint %1$s is illegally placed on field '%2$s'.") ConstraintDeclarationException getCrossParameterConstraintOnFieldException(@FormatWith(ClassObjectFormatter.class) Class constraint, - @FormatWith(ConstrainableFormatter.class) Constrainable field); + Constrainable field); @Message(id = 146, value = "No parameter nodes may be added since path %s doesn't refer to a cross-parameter constraint.") @@ -538,11 +537,11 @@ UnexpectedTypeException getMultipleValidatorsForSameTypeException(@FormatWith(Cl @Message(id = 151, value = "A method overriding another method must not redefine the parameter constraint configuration, but method %2$s redefines the configuration of %1$s.") - ConstraintDeclarationException getParameterConfigurationAlteredInSubTypeException(@FormatWith(ConstrainableFormatter.class) Callable superMethod, @FormatWith(ConstrainableFormatter.class) Callable subMethod); + ConstraintDeclarationException getParameterConfigurationAlteredInSubTypeException(Callable superMethod, Callable subMethod); @Message(id = 152, value = "Two methods defined in parallel types must not declare parameter constraints, if they are overridden by the same method, but methods %s and %s both define parameter constraints.") - ConstraintDeclarationException getParameterConstraintsDefinedInMethodsFromParallelTypesException(@FormatWith(ConstrainableFormatter.class) Callable method1, @FormatWith(ConstrainableFormatter.class) Callable method2); + ConstraintDeclarationException getParameterConstraintsDefinedInMethodsFromParallelTypesException(Callable method1, Callable method2); @Message(id = 153, value = "The constraint %1$s used ConstraintTarget#%2$s but is not specified on a method or constructor.") @@ -584,7 +583,7 @@ ConstraintDefinitionException getValidatorForCrossParameterConstraintMustEitherV @Message(id = 161, value = "Two methods defined in parallel types must not define group conversions for a cascaded method return value, if they are overridden by the same method, but methods %s and %s both define parameter constraints.") - ConstraintDeclarationException getMethodsFromParallelTypesMustNotDefineGroupConversionsForCascadedReturnValueException(@FormatWith(ConstrainableFormatter.class) Callable method1, @FormatWith(ConstrainableFormatter.class) Callable method2); + ConstraintDeclarationException getMethodsFromParallelTypesMustNotDefineGroupConversionsForCascadedReturnValueException(Callable method1, Callable method2); @Message(id = 162, value = "The validated type %1$s does not specify the constructor/method: %2$s") @@ -632,11 +631,11 @@ ConstraintDefinitionException getValidatorForCrossParameterConstraintMustEitherV @Message(id = 174, value = "Parameter %3$s of method or constructor %2$s of type %1$s is configured more than once via the programmatic constraint declaration API.") - ValidationException getParameterHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ConstrainableFormatter.class) Callable callable, int parameterIndex); + ValidationException getParameterHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, Callable callable, int parameterIndex); @Message(id = 175, value = "The return value of method or constructor %2$s of type %1$s is configured more than once via the programmatic constraint declaration API.") - ValidationException getReturnValueHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ConstrainableFormatter.class) Callable callable); + ValidationException getReturnValueHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, Callable callable); @Message(id = 176, value = "Constructor %2$s of type %1$s is configured more than once via the programmatic constraint declaration API.") @@ -644,7 +643,7 @@ ConstraintDefinitionException getValidatorForCrossParameterConstraintMustEitherV @Message(id = 177, value = "Cross-parameter constraints for the method or constructor %2$s of type %1$s are declared more than once via the programmatic constraint declaration API.") - ValidationException getCrossParameterElementHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, @FormatWith(ConstrainableFormatter.class) Callable callable); + ValidationException getCrossParameterElementHasAlreadyBeConfiguredViaProgrammaticApiException(@FormatWith(ClassObjectFormatter.class) Class beanClass, Callable callable); @Message(id = 178, value = "Multiplier cannot be negative: %d.") IllegalArgumentException getMultiplierCannotBeNegativeException(int multiplier); @@ -717,7 +716,7 @@ ConstraintDeclarationException getInconsistentValueUnwrappingConfigurationBetwee ValueExtractorDefinitionException getValueExtractorDeclaresExtractedValueMultipleTimesException(@FormatWith(ClassObjectFormatter.class) Class extractorType); @Message(id = 205, value = "Invalid unwrapping configuration for constraint %2$s on %1$s. You can only define one of 'Unwrapping.Skip' or 'Unwrapping.Unwrap'.") - ConstraintDeclarationException getInvalidUnwrappingConfigurationForConstraintException(@FormatWith(ConstrainableFormatter.class) Constrainable constrainable, @FormatWith(ClassObjectFormatter.class) Class constraint); + ConstraintDeclarationException getInvalidUnwrappingConfigurationForConstraintException(Constrainable constrainable, @FormatWith(ClassObjectFormatter.class) Class constraint); @Message(id = 206, value = "Unable to instantiate value extractor class %s.") ValidationException getUnableToInstantiateValueExtractorClassException(String valueExtractorClassName, @Cause ValidationException e); diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/formatter/ConstrainableFormatter.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/formatter/ConstrainableFormatter.java deleted file mode 100644 index d5f8ea6f1a..0000000000 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/formatter/ConstrainableFormatter.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.util.logging.formatter; - -import org.hibernate.validator.internal.properties.Callable; -import org.hibernate.validator.internal.properties.Constrainable; -import org.hibernate.validator.internal.util.ExecutableHelper; - -/** - * Used with JBoss Logging to display executables in log messages. - * - * @author Marko Bekhta - */ -public class ConstrainableFormatter { - - private final String stringRepresentation; - - public ConstrainableFormatter(Constrainable constrainable) { - String name = constrainable.getName(); - if ( constrainable instanceof Callable ) { - name = constrainable.getDeclaringClass().getSimpleName() + "#" + name; - Class[] parameterTypes = ( (Callable) constrainable ).getParameterTypes(); - - this.stringRepresentation = ExecutableHelper.getExecutableAsString( name, parameterTypes ); - } - else { - this.stringRepresentation = name; - } - } - - @Override - public String toString() { - return stringRepresentation; - } -} From fc0824a2d990390f8e8fced3143e3f524bdb1398 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 31 May 2018 20:19:16 +0200 Subject: [PATCH 08/24] HV-1623 Wrap ElementType with ConstraintLocationKind --- .../cfg/context/ConfiguredConstraint.java | 31 ++++++++++------- .../ConstraintMappingContextImplBase.java | 2 +- ...erElementConstraintMappingContextImpl.java | 2 +- .../internal/engine/ValidatorImpl.java | 2 +- .../metadata/aggregated/BeanMetaDataImpl.java | 4 +-- .../aggregated/ExecutableMetaData.java | 17 ++++++---- .../metadata/aggregated/MetaDataBuilder.java | 2 +- .../metadata/core/MetaConstraint.java | 8 ++--- .../descriptor/ConstraintDescriptorImpl.java | 33 +++++++++---------- .../descriptor/ElementDescriptorImpl.java | 4 +-- .../metadata/location/ConstraintLocation.java | 21 ++++++++++++ .../provider/AnnotationMetaDataProvider.java | 20 ++++++----- .../metadata/raw/ConstrainedExecutable.java | 2 +- .../internal/properties/Callable.java | 3 +- .../javabean/JavaBeanExecutable.java | 7 ++-- .../ClassConstraintTypeStaxBuilder.java | 3 +- .../mapping/ConstrainedFieldStaxBuilder.java | 3 +- .../mapping/ConstrainedGetterStaxBuilder.java | 3 +- .../ConstrainedParameterStaxBuilder.java | 3 +- .../mapping/ConstraintTypeStaxBuilder.java | 5 +-- .../ContainerElementTypeStaxBuilder.java | 2 +- .../mapping/CrossParameterStaxBuilder.java | 3 +- .../xml/mapping/ReturnValueStaxBuilder.java | 5 +-- ...ssionLanguageMessageInterpolationTest.java | 5 +-- ...ResourceBundleMessageInterpolatorTest.java | 9 ++--- .../metadata/core/MetaConstraintTest.java | 7 ++-- .../AnnotationMetaDataProviderTest.java | 5 +-- 27 files changed, 129 insertions(+), 82 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java index 87c1bb0ace..3b2cbfdb6a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java @@ -7,7 +7,6 @@ package org.hibernate.validator.internal.cfg.context; import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.Type; @@ -20,6 +19,8 @@ import org.hibernate.validator.cfg.AnnotationDef; import org.hibernate.validator.cfg.ConstraintDef; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.util.annotation.AnnotationDescriptor; @@ -43,41 +44,41 @@ class ConfiguredConstraint { private final ConstraintDef constraint; private final ConstraintLocation location; - private final ElementType elementType; + private final ConstraintLocationKind kind; - private ConfiguredConstraint(ConstraintDef constraint, ConstraintLocation location, ElementType elementType) { + private ConfiguredConstraint(ConstraintDef constraint, ConstraintLocation location, ConstraintLocationKind kind) { this.constraint = constraint; this.location = location; - this.elementType = elementType; + this.kind = kind; } static ConfiguredConstraint forType(ConstraintDef constraint, Class beanType) { - return new ConfiguredConstraint<>( constraint, ConstraintLocation.forClass( beanType ), ElementType.TYPE ); + return new ConfiguredConstraint<>( constraint, ConstraintLocation.forClass( beanType ), ConstraintLocationKind.TYPE ); } static ConfiguredConstraint forFieldProperty(ConstraintDef constraint, JavaBeanField javaBeanField) { return new ConfiguredConstraint<>( constraint, ConstraintLocation.forField( javaBeanField ), - ElementType.FIELD + ConstraintLocationKind.FIELD ); } public static ConfiguredConstraint forParameter(ConstraintDef constraint, Callable callable, int parameterIndex) { return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forParameter( callable, parameterIndex ), callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD + constraint, ConstraintLocation.forParameter( callable, parameterIndex ), getConstraintLocationKindFromCallable( callable ) ); } public static ConfiguredConstraint forExecutable(ConstraintDef constraint, Callable callable) { return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forReturnValue( callable ), callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD + constraint, ConstraintLocation.forReturnValue( callable ), getConstraintLocationKindFromCallable( callable ) ); } public static ConfiguredConstraint forCrossParameter(ConstraintDef constraint, Callable callable) { return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forCrossParameter( callable ), callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD + constraint, ConstraintLocation.forCrossParameter( callable ), getConstraintLocationKindFromCallable( callable ) ); } @@ -85,7 +86,7 @@ public static ConfiguredConstraint forTypeArgument(Con return new ConfiguredConstraint<>( constraint, ConstraintLocation.forTypeArgument( delegate, typeArgument, typeOfAnnotatedElement ), - ElementType.TYPE_USE + ConstraintLocationKind.TYPE_USE ); } @@ -115,8 +116,14 @@ public String toString() { return constraint.toString(); } - public ElementType getElementType() { - return elementType; + public ConstraintLocationKind getConstraintLocationKind() { + return kind; + } + + private static ConstraintLocationKind getConstraintLocationKindFromCallable(Callable callable) { + return callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR + ? ConstraintLocationKind.CONSTRUCTOR + : ConstraintLocationKind.METHOD; } /** diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java index ec6257bd05..ed8582e4c7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java @@ -75,7 +75,7 @@ private MetaConstraint asMetaConstraint(ConfiguredCons constraintHelper, config.getLocation().getConstrainable(), config.createAnnotationDescriptor(), - config.getElementType(), + config.getConstraintLocationKind(), getConstraintType() ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java index 755b09f7ce..e9e05526a7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java @@ -239,7 +239,7 @@ private MetaConstraint asMetaConstraint(ConfiguredCons constraintHelper, config.getLocation().getConstrainable(), config.createAnnotationDescriptor(), - config.getElementType(), + config.getConstraintLocationKind(), getConstraintType() ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 202c758875..5ec5c85f0b 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -1283,7 +1283,7 @@ private boolean isValidationRequired(BaseBeanValidationContext validationCont validationContext, valueContext.getCurrentBean(), valueContext.getPropertyPath(), - metaConstraint.getElementType() + metaConstraint.getConstraintLocationKind().getElementType() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java index 26f691a72d..331c116a1e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java @@ -9,7 +9,6 @@ import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; -import java.lang.annotation.ElementType; import java.lang.invoke.MethodHandles; import java.lang.reflect.Executable; import java.util.ArrayList; @@ -39,6 +38,7 @@ import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.descriptor.ExecutableDescriptorImpl; import org.hibernate.validator.internal.metadata.facets.Cascadable; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.metadata.raw.BeanConfiguration; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; @@ -399,7 +399,7 @@ private static BeanDescriptor createBeanDescriptor(Class beanClass, Set> getClassLevelConstraintsAsDescriptors(Set> constraints) { return constraints.stream() - .filter( c -> c.getElementType() == ElementType.TYPE ) + .filter( c -> c.getConstraintLocationKind() == ConstraintLocationKind.TYPE ) .map( MetaConstraint::getDescriptor ) .collect( Collectors.toSet() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java index d8c2df456c..a073d5056f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java @@ -28,6 +28,7 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.descriptor.ExecutableDescriptorImpl; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; import org.hibernate.validator.internal.properties.Callable; @@ -255,7 +256,7 @@ public static class Builder extends MetaDataBuilder { /** * Either CONSTRUCTOR or METHOD. */ - private final ConstrainedElement.ConstrainedElementKind kind; + private final ConstrainedElementKind kind; private final Set constrainedExecutables = newHashSet(); private Callable callable; private final boolean isGetterMethod; @@ -311,7 +312,7 @@ public boolean accepts(ConstrainedElement constrainedElement) { } private boolean isResolvedToSameMethodInHierarchy(Callable first, Callable other) { - if ( first.isConstructor() || other.isConstructor() ) { + if ( isConstructor( first ) || isConstructor( other ) ) { return first.equals( other ); } @@ -319,13 +320,17 @@ private boolean isResolvedToSameMethodInHierarchy(Callable first, Callable other } private boolean overrides(Callable first, Callable other) { - if ( first.isConstructor() || other.isConstructor() ) { + if ( isConstructor( first ) || isConstructor( other ) ) { return false; } return executableHelper.overrides( first, other ); } + private boolean isConstructor(Callable callable) { + return callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR; + } + @Override public final void add(ConstrainedElement constrainedElement) { super.add( constrainedElement ); @@ -380,11 +385,11 @@ public ExecutableMetaData build() { assertCorrectnessOfConfiguration(); return new ExecutableMetaData( - kind == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? callable.getDeclaringClass().getSimpleName() : callable.getName(), + kind == ConstrainedElementKind.CONSTRUCTOR ? callable.getDeclaringClass().getSimpleName() : callable.getName(), callable.getType(), callable.getParameterTypes(), - kind == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? ElementKind.CONSTRUCTOR : ElementKind.METHOD, - kind == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? Collections.singleton( callable.getSignature() ) : + kind == ConstrainedElementKind.CONSTRUCTOR ? ElementKind.CONSTRUCTOR : ElementKind.METHOD, + kind == ConstrainedElementKind.CONSTRUCTOR ? Collections.singleton( callable.getSignature() ) : CollectionHelper.toImmutableSet( signatures ), adaptOriginsAndImplicitGroups( getDirectConstraints() ), adaptOriginsAndImplicitGroups( getContainerElementConstraints() ), diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/MetaDataBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/MetaDataBuilder.java index 66e756da06..cecf054f94 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/MetaDataBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/MetaDataBuilder.java @@ -131,7 +131,7 @@ private MetaConstraint adaptOriginAndImplicitGroup(Met constraintHelper, constraint.getLocation().getConstrainable(), constraint.getDescriptor().getAnnotationDescriptor(), - constraint.getElementType(), + constraint.getConstraintLocationKind(), constraintClass.isInterface() ? constraintClass : null, definedIn, constraint.getDescriptor().getConstraintType() diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/MetaConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/MetaConstraint.java index a08f40a6b9..5fb3c1623b 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/MetaConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/MetaConstraint.java @@ -7,7 +7,6 @@ package org.hibernate.validator.internal.metadata.core; import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.List; @@ -23,6 +22,7 @@ import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorHelper; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.util.StringHelper; import org.hibernate.validator.internal.util.stereotypes.Immutable; @@ -100,8 +100,8 @@ public final ConstraintDescriptorImpl getDescriptor() { return constraintTree.getDescriptor(); } - public final ElementType getElementType() { - return constraintTree.getDescriptor().getElementType(); + public final ConstraintLocationKind getConstraintLocationKind() { + return constraintTree.getDescriptor().getConstraintLocationKind(); } public boolean validateConstraint(ValidationContext validationContext, ValueContext valueContext) { @@ -123,7 +123,7 @@ public boolean validateConstraint(ValidationContext validationContext, ValueC } private boolean doValidateConstraint(ValidationContext executionContext, ValueContext valueContext) { - valueContext.setElementType( getElementType() ); + valueContext.setElementType( getConstraintLocationKind().getElementType() ); boolean validationResult = constraintTree.validateConstraints( executionContext, valueContext ); return validationResult; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java index edecfb516c..692bb389c9 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java @@ -12,7 +12,6 @@ import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -45,6 +44,7 @@ import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorDescriptor; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.ConstraintOrigin; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.properties.Property; @@ -132,7 +132,7 @@ public class ConstraintDescriptorImpl implements Constrain * Describes on which level ({@code TYPE}, {@code METHOD}, {@code FIELD}) the constraint was * defined on. */ - private final ElementType elementType; + private final ConstraintLocationKind constraintLocationKind; /** * The origin of the constraint. Defined on the actual root class or somewhere in the class hierarchy @@ -165,12 +165,12 @@ public class ConstraintDescriptorImpl implements Constrain public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, - ElementType type, + ConstraintLocationKind kind, Class implicitGroup, ConstraintOrigin definedOn, ConstraintType externalConstraintType) { this.annotationDescriptor = annotationDescriptor; - this.elementType = type; + this.constraintLocationKind = kind; this.definedOn = definedOn; this.isReportAsSingleInvalidConstraint = annotationDescriptor.getType().isAnnotationPresent( ReportAsSingleViolation.class @@ -206,7 +206,6 @@ public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, this.constraintType = determineConstraintType( annotationDescriptor.getType(), constrainable, - type, !genericValidatorDescriptors.isEmpty(), !crossParameterValidatorDescriptors.isEmpty(), externalConstraintType @@ -228,16 +227,16 @@ public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, - ElementType type) { - this( constraintHelper, constrainable, annotationDescriptor, type, null, ConstraintOrigin.DEFINED_LOCALLY, null ); + ConstraintLocationKind kind) { + this( constraintHelper, constrainable, annotationDescriptor, kind, null, ConstraintOrigin.DEFINED_LOCALLY, null ); } public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, - ElementType type, + ConstraintLocationKind kind, ConstraintType constraintType) { - this( constraintHelper, constrainable, annotationDescriptor, type, null, ConstraintOrigin.DEFINED_LOCALLY, constraintType ); + this( constraintHelper, constrainable, annotationDescriptor, kind, null, ConstraintOrigin.DEFINED_LOCALLY, constraintType ); } public ConstraintAnnotationDescriptor getAnnotationDescriptor() { @@ -313,8 +312,8 @@ public boolean isReportAsSingleViolation() { return isReportAsSingleInvalidConstraint; } - public ElementType getElementType() { - return elementType; + public ConstraintLocationKind getConstraintLocationKind() { + return constraintLocationKind; } public ConstraintOrigin getDefinedOn() { @@ -361,7 +360,7 @@ public String toString() { sb.append( ", payloads=" ).append( payloads ); sb.append( ", hasComposingConstraints=" ).append( composingConstraints.isEmpty() ); sb.append( ", isReportAsSingleInvalidConstraint=" ).append( isReportAsSingleInvalidConstraint ); - sb.append( ", elementType=" ).append( elementType ); + sb.append( ", constraintLocationKind=" ).append( constraintLocationKind ); sb.append( ", definedOn=" ).append( definedOn ); sb.append( ", groups=" ).append( groups ); sb.append( ", attributes=" ).append( annotationDescriptor.getAttributes() ); @@ -389,7 +388,6 @@ public String toString() { * * * @param constrainable The annotated member - * @param elementType The type of the annotated element * @param hasGenericValidators Whether the constraint has at least one generic validator or * not * @param hasCrossParameterValidator Whether the constraint has a cross-parameter validator @@ -400,13 +398,12 @@ public String toString() { */ private ConstraintType determineConstraintType(Class constraintAnnotationType, Constrainable constrainable, - ElementType elementType, boolean hasGenericValidators, boolean hasCrossParameterValidator, ConstraintType externalConstraintType) { ConstraintTarget constraintTarget = validationAppliesTo; ConstraintType constraintType = null; - boolean isExecutable = isExecutable( elementType ); + boolean isExecutable = isExecutable( constraintLocationKind ); //target explicitly set to RETURN_VALUE if ( constraintTarget == ConstraintTarget.RETURN_VALUE ) { @@ -533,8 +530,8 @@ private void validateComposingConstraintTypes() { } } - private boolean isExecutable(ElementType elementType) { - return elementType == ElementType.METHOD || elementType == ElementType.CONSTRUCTOR; + private boolean isExecutable(ConstraintLocationKind locationKind) { + return locationKind == ConstraintLocationKind.METHOD || locationKind == ConstraintLocationKind.CONSTRUCTOR; } @SuppressWarnings("unchecked") @@ -744,7 +741,7 @@ annotationType, run( GetAnnotationAttributes.action( constraintAnnotation ) ) } return new ConstraintDescriptorImpl<>( - constraintHelper, constrainable, annotationDescriptorBuilder.build(), elementType, null, definedOn, constraintType + constraintHelper, constrainable, annotationDescriptorBuilder.build(), constraintLocationKind, null, definedOn, constraintType ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ElementDescriptorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ElementDescriptorImpl.java index d80a1972f2..0c865382fa 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ElementDescriptorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ElementDescriptorImpl.java @@ -142,7 +142,7 @@ public boolean hasConstraints() { private void addMatchingDescriptorsForGroup(Class group, Set> matchingDescriptors) { for ( ConstraintDescriptorImpl descriptor : constraintDescriptors ) { - if ( definedInSet.contains( descriptor.getDefinedOn() ) && elementTypes.contains( descriptor.getElementType() ) + if ( definedInSet.contains( descriptor.getDefinedOn() ) && elementTypes.contains( descriptor.getConstraintLocationKind().getElementType() ) && descriptor.getGroups().contains( group ) ) { matchingDescriptors.add( descriptor ); } @@ -160,7 +160,7 @@ private void findMatchingDescriptors(Set> matchingDescri } else { for ( ConstraintDescriptorImpl descriptor : constraintDescriptors ) { - if ( definedInSet.contains( descriptor.getDefinedOn() ) && elementTypes.contains( descriptor.getElementType() ) ) { + if ( definedInSet.contains( descriptor.getDefinedOn() ) && elementTypes.contains( descriptor.getConstraintLocationKind().getElementType() ) ) { matchingDescriptors.add( descriptor ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index 54aafdbd5a..6e97299d98 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -6,6 +6,7 @@ */ package org.hibernate.validator.internal.metadata.location; +import java.lang.annotation.ElementType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -95,4 +96,24 @@ static ConstraintLocation forParameter(Callable callable, int index) { * object array for a {@link ParameterConstraintLocation}. */ Object getValue(Object parent); + + enum ConstraintLocationKind { + TYPE( ElementType.TYPE ), + CONSTRUCTOR( ElementType.CONSTRUCTOR ), + METHOD( ElementType.METHOD ), + PARAMETER( ElementType.PARAMETER ), + FIELD( ElementType.FIELD ), + TYPE_USE( ElementType.TYPE_USE ), + ; + + private final ElementType elementType; + + ConstraintLocationKind(ElementType elementType) { + this.elementType = elementType; + } + + public ElementType getElementType() { + return elementType; + } + } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index 9f36621a08..cfa173174e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -12,7 +12,6 @@ import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES; import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; import java.lang.invoke.MethodHandles; import java.lang.reflect.AccessibleObject; import java.lang.reflect.AnnotatedArrayType; @@ -56,6 +55,7 @@ import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.metadata.raw.BeanConfiguration; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; @@ -234,7 +234,7 @@ private Set getFieldMetaData(Class beanClass) { private ConstrainedField findPropertyMetaData(Field field, JavaBeanField javaBeanField) { Set> constraints = convertToMetaConstraints( - findConstraints( field, ElementType.FIELD, javaBeanField ), + findConstraints( field, ConstraintLocationKind.FIELD, javaBeanField ), javaBeanField ); @@ -307,7 +307,9 @@ private ConstrainedExecutable findExecutableMetaData(Executable executable) { Map>> executableConstraints = findConstraints( executable, - callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD, + callable.getConstrainedElementKind() == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR + ? ConstraintLocationKind.CONSTRUCTOR + : ConstraintLocationKind.METHOD, callable ).stream().collect( Collectors.groupingBy( ConstraintDescriptorImpl::getConstraintType ) ); @@ -424,7 +426,7 @@ private List getParameterMetaData(Executable executable, C for ( Annotation parameterAnnotation : parameterAnnotations ) { // collect constraints if this annotation is a constraint annotation List> constraints = findConstraintAnnotations( - callable, parameterAnnotation, ElementType.PARAMETER + callable, parameterAnnotation, ConstraintLocationKind.PARAMETER ); for ( ConstraintDescriptorImpl constraintDescriptorImpl : constraints ) { parameterConstraints.add( @@ -464,7 +466,7 @@ private List getParameterMetaData(Executable executable, C * * @return A list of constraint descriptors for all constraint specified for the given member. */ - private List> findConstraints(Member member, ElementType type, Constrainable constrainable) { + private List> findConstraints(Member member, ConstraintLocationKind type, Constrainable constrainable) { List> metaData = newArrayList(); for ( Annotation annotation : ( (AccessibleObject) member ).getDeclaredAnnotations() ) { metaData.addAll( findConstraintAnnotations( constrainable, annotation, type ) ); @@ -484,7 +486,7 @@ private List> findConstraints(Member member, Element private List> findClassLevelConstraints(Class beanClass) { List> metaData = newArrayList(); for ( Annotation annotation : beanClass.getDeclaredAnnotations() ) { - metaData.addAll( findConstraintAnnotations( null, annotation, ElementType.TYPE ) ); + metaData.addAll( findConstraintAnnotations( null, annotation, ConstraintLocationKind.TYPE ) ); } return metaData; } @@ -503,7 +505,7 @@ private List> findClassLevelConstraints(Class bea protected List> findConstraintAnnotations( Constrainable constrainable, A annotation, - ElementType type) { + ConstraintLocationKind type) { // HV-1049 and HV-1311 - Ignore annotations from the JDK (jdk.internal.* and java.*); They cannot be constraint // annotations so skip them right here, as for the proper check we'd need package access permission for @@ -561,7 +563,7 @@ private Map, Class> getGroupConversions(ConvertGroup groupConversion private ConstraintDescriptorImpl buildConstraintDescriptor(Constrainable constrainable, A annotation, - ElementType type) { + ConstraintLocationKind type) { return new ConstraintDescriptorImpl<>( constraintHelper, constrainable, @@ -785,7 +787,7 @@ else if ( annotatedType instanceof AnnotatedParameterizedType ) { */ private Set> findTypeUseConstraints(Constrainable constrainable, AnnotatedType typeArgument, TypeVariable typeVariable, TypeArgumentLocation location, Type type) { Set> constraints = Arrays.stream( typeArgument.getAnnotations() ) - .flatMap( a -> findConstraintAnnotations( constrainable, a, ElementType.TYPE_USE ).stream() ) + .flatMap( a -> findConstraintAnnotations( constrainable, a, ConstraintLocationKind.TYPE_USE ).stream() ) .map( d -> createTypeArgumentMetaConstraint( d, location, typeVariable, type ) ) .collect( Collectors.toSet() ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java index f7d6b0c63f..1f8e989cd3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java @@ -104,7 +104,7 @@ public ConstrainedExecutable( CascadingMetaDataBuilder cascadingMetaDataBuilder) { super( source, - callable.isConstructor() ? ConstrainedElementKind.CONSTRUCTOR : ConstrainedElementKind.METHOD, + callable.getConstrainedElementKind(), returnValueConstraints, typeArgumentConstraints, cascadingMetaDataBuilder diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java index b25586c4b1..9095262992 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java @@ -8,6 +8,7 @@ import java.lang.reflect.Type; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -28,7 +29,7 @@ public interface Callable extends Constrainable { boolean isPrivate(); - boolean isConstructor(); + ConstrainedElementKind getConstrainedElementKind(); String getSignature(); diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java index d7285fcb41..3622c6db42 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java @@ -13,6 +13,7 @@ import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -30,6 +31,7 @@ public class JavaBeanExecutable implements Callable { private final boolean hasParameters; private final boolean hasReturnValue; private final Type type; + private final ConstrainedElementKind kind; JavaBeanExecutable(Executable executable) { this.executable = executable; @@ -38,6 +40,7 @@ public class JavaBeanExecutable implements Callable { this.typeForValidatorResolution = ReflectionHelper.boxedType( type ); this.hasParameters = executable.getParameterTypes().length > 0; this.hasReturnValue = hasReturnValue( executable ); + this.kind = executable instanceof Constructor ? ConstrainedElementKind.CONSTRUCTOR : ConstrainedElementKind.METHOD; } public static JavaBeanExecutable of(Executable executable) { @@ -100,8 +103,8 @@ public boolean isPrivate() { } @Override - public boolean isConstructor() { - return executable instanceof Constructor; + public ConstrainedElementKind getConstrainedElementKind() { + return kind; } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ClassConstraintTypeStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ClassConstraintTypeStaxBuilder.java index c75a851b14..1d059154eb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ClassConstraintTypeStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ClassConstraintTypeStaxBuilder.java @@ -24,6 +24,7 @@ import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; import org.hibernate.validator.internal.util.TypeResolutionHelper; @@ -103,7 +104,7 @@ ConstrainedType build(Class beanClass) { ConstraintLocation constraintLocation = ConstraintLocation.forClass( beanClass ); Set> metaConstraints = constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.TYPE, null ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.TYPE, null ) ) .collect( Collectors.toSet() ); // ignore annotation diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java index 1126e715ab..bb0a350084 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedFieldStaxBuilder.java @@ -22,6 +22,7 @@ import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; @@ -74,7 +75,7 @@ ConstrainedField build(Class beanClass, List alreadyProcessedFieldNam ConstraintLocation constraintLocation = ConstraintLocation.forField( javaBeanField ); Set> metaConstraints = constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.FIELD, null ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.FIELD, null ) ) .collect( Collectors.toSet() ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java index fbe4766597..11bc792d33 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java @@ -23,6 +23,7 @@ import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; @@ -76,7 +77,7 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedGet ConstraintLocation constraintLocation = ConstraintLocation.forGetter( javaBeanGetter ); Set> metaConstraints = constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.METHOD, null ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.METHOD, null ) ) .collect( Collectors.toSet() ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java index 5344231f1c..3d4eb1a090 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java @@ -20,6 +20,7 @@ import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; import org.hibernate.validator.internal.properties.Callable; @@ -73,7 +74,7 @@ ConstrainedParameter build(Callable callable, int index) { Type type = callable.getTypeOfParameter( index ); Set> metaConstraints = constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.PARAMETER, null ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.PARAMETER, null ) ) .collect( Collectors.toSet() ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( type, constraintLocation ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstraintTypeStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstraintTypeStaxBuilder.java index 3292210ac0..10557668cb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstraintTypeStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstraintTypeStaxBuilder.java @@ -35,6 +35,7 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraints; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.annotation.AnnotationDescriptor; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; @@ -112,7 +113,7 @@ protected void add(XMLEventReader xmlEventReader, XMLEvent xmlEvent) throws XMLS } @SuppressWarnings("unchecked") - MetaConstraint build(ConstraintLocation constraintLocation, java.lang.annotation.ElementType type, ConstraintDescriptorImpl.ConstraintType constraintType) { + MetaConstraint build(ConstraintLocation constraintLocation, ConstraintLocationKind kind, ConstraintDescriptorImpl.ConstraintType constraintType) { String defaultPackage = defaultPackageStaxBuilder.build().orElse( "" ); Class annotationClass; @@ -149,7 +150,7 @@ MetaConstraint build(ConstraintLocation constraintLoca // we set initially ConstraintOrigin.DEFINED_LOCALLY for all xml configured constraints // later we will make copies of this constraint descriptor when needed and adjust the ConstraintOrigin ConstraintDescriptorImpl constraintDescriptor = new ConstraintDescriptorImpl<>( - constraintHelper, constraintLocation.getConstrainable(), annotationDescriptor, type, constraintType + constraintHelper, constraintLocation.getConstrainable(), annotationDescriptor, kind, constraintType ); return MetaConstraints.create( typeResolutionHelper, valueExtractorManager, constraintDescriptor, constraintLocation ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ContainerElementTypeStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ContainerElementTypeStaxBuilder.java index 1c24591a22..eeb2d16a6d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ContainerElementTypeStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ContainerElementTypeStaxBuilder.java @@ -163,7 +163,7 @@ public ContainerElementTypeConfiguration build(Set con .map( builder -> builder.build( containerElementTypeConstraintLocation, - java.lang.annotation.ElementType.TYPE_USE, + ConstraintLocation.ConstraintLocationKind.TYPE_USE, null ) ), diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java index ce40f9625f..c92463cf95 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java @@ -23,6 +23,7 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.xml.AbstractStaxBuilder; @@ -88,7 +89,7 @@ Set> build(Callable callable) { ConstraintLocation constraintLocation = ConstraintLocation.forCrossParameter( callable ); Set> crossParameterConstraints = constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, java.lang.annotation.ElementType.METHOD, ConstraintType.CROSS_PARAMETER ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.METHOD, ConstraintType.CROSS_PARAMETER ) ) .collect( Collectors.toSet() ); // ignore annotations diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java index b9458a5fdf..c3e2eb0136 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java @@ -6,7 +6,6 @@ */ package org.hibernate.validator.internal.xml.mapping; -import java.lang.annotation.ElementType; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -20,6 +19,8 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.xml.mapping.ContainerElementTypeConfigurationBuilder.ContainerElementTypeConfiguration; @@ -56,7 +57,7 @@ CascadingMetaDataBuilder build( ConstraintLocation constraintLocation = ConstraintLocation.forReturnValue( callable ); returnValueConstraints.addAll( constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, callable.isConstructor() ? ElementType.CONSTRUCTOR : ElementType.METHOD, ConstraintDescriptorImpl.ConstraintType.GENERIC ) ) + .map( builder -> builder.build( constraintLocation, callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR ? ConstraintLocationKind.CONSTRUCTOR : ConstraintLocationKind.METHOD, ConstraintDescriptorImpl.ConstraintType.GENERIC ) ) .collect( Collectors.toSet() ) ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( callable.getType(), constraintLocation ); diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java index b9515ff476..c869c51c9b 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java @@ -18,6 +18,7 @@ import org.hibernate.validator.internal.engine.MessageInterpolatorContext; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; import org.hibernate.validator.testutil.TestForIssue; @@ -44,7 +45,7 @@ public void setUp() { new ConstraintHelper(), null, notNullAnnotationDescriptorBuilder.build(), - java.lang.annotation.ElementType.FIELD + ConstraintLocationKind.FIELD ); ConstraintAnnotationDescriptor.Builder sizeAnnotationDescriptorBuilder = new ConstraintAnnotationDescriptor.Builder<>( Size.class ); @@ -52,7 +53,7 @@ public void setUp() { new ConstraintHelper(), null, sizeAnnotationDescriptorBuilder.build(), - java.lang.annotation.ElementType.FIELD + ConstraintLocationKind.FIELD ); interpolatorUnderTest = new ResourceBundleMessageInterpolator(); diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java index 889120f615..29bdf5ff3a 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java @@ -27,6 +27,7 @@ import org.hibernate.validator.internal.engine.MessageInterpolatorContext; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator; @@ -54,7 +55,7 @@ public void setUp() { new ConstraintHelper(), null, descriptorBuilder.build(), - java.lang.annotation.ElementType.FIELD + ConstraintLocationKind.FIELD ); ConstraintAnnotationDescriptor.Builder sizeAnnotationDescriptorBuilder = new ConstraintAnnotationDescriptor.Builder( Size.class ); @@ -62,7 +63,7 @@ public void setUp() { new ConstraintHelper(), null, sizeAnnotationDescriptorBuilder.build(), - java.lang.annotation.ElementType.FIELD + ConstraintLocationKind.FIELD ); } @@ -216,7 +217,7 @@ public void testRecursiveMessageInterpolation() { new ConstraintHelper(), null, descriptorBuilder.build(), - java.lang.annotation.ElementType.FIELD + ConstraintLocationKind.FIELD ); interpolator = new ResourceBundleMessageInterpolator( @@ -245,7 +246,7 @@ public void testCorrectMessageInterpolationIfParameterCannotBeReplaced() { new ConstraintHelper(), null, maxDescriptor, - java.lang.annotation.ElementType.FIELD + ConstraintLocationKind.FIELD ); interpolator = new ResourceBundleMessageInterpolator( diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java index 16fc4e3062..436f7e8b3a 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java @@ -6,7 +6,6 @@ */ package org.hibernate.validator.test.internal.metadata.core; -import static java.lang.annotation.ElementType.METHOD; import static org.testng.Assert.assertEquals; import java.lang.reflect.Method; @@ -20,10 +19,12 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraints; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.testutil.TestForIssue; + import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -50,14 +51,14 @@ public void setUp() throws Exception { @TestForIssue(jiraKey = "HV-930") public void two_meta_constraints_for_the_same_constraint_should_be_equal() throws Exception { ConstraintDescriptorImpl constraintDescriptor1 = new ConstraintDescriptorImpl<>( - constraintHelper, JavaBeanExecutable.of( barMethod ), constraintAnnotationDescriptor, METHOD + constraintHelper, JavaBeanExecutable.of( barMethod ), constraintAnnotationDescriptor, ConstraintLocationKind.METHOD ); ConstraintLocation location1 = ConstraintLocation.forClass( Foo.class ); MetaConstraint metaConstraint1 = MetaConstraints.create( typeResolutionHelper, valueExtractorManager, constraintDescriptor1, location1 ); ConstraintDescriptorImpl constraintDescriptor2 = new ConstraintDescriptorImpl<>( - constraintHelper, JavaBeanExecutable.of( barMethod ), constraintAnnotationDescriptor, METHOD + constraintHelper, JavaBeanExecutable.of( barMethod ), constraintAnnotationDescriptor, ConstraintLocationKind.METHOD ); ConstraintLocation location2 = ConstraintLocation.forClass( Foo.class ); MetaConstraint metaConstraint2 = MetaConstraints.create( typeResolutionHelper, valueExtractorManager, constraintDescriptor2, location2 ); diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTest.java index 95d3561fd9..47dc49bc44 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTest.java @@ -12,7 +12,6 @@ import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -33,6 +32,7 @@ import org.hibernate.validator.internal.metadata.core.AnnotationProcessingOptionsImpl; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.MetaConstraint; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider; import org.hibernate.validator.internal.metadata.raw.BeanConfiguration; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; @@ -43,6 +43,7 @@ import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.testutil.TestForIssue; + import org.joda.time.DateMidnight; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -79,7 +80,7 @@ public void testGetConstructorMetaData() throws Exception { MetaConstraint constraint = constructor.getConstraints().iterator().next(); assertThat( constraint.getDescriptor().getAnnotation().annotationType() ).isEqualTo( NotNull.class ); - assertThat( constraint.getElementType() ).isEqualTo( ElementType.CONSTRUCTOR ); + assertThat( constraint.getConstraintLocationKind() ).isEqualTo( ConstraintLocationKind.CONSTRUCTOR ); } @Test From 93768991f778646a7f48ce1a67e2b6648203ad5e Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 1 Jun 2018 19:49:07 +0200 Subject: [PATCH 09/24] HV-1623 More abstraction work around executables --- ...xecutableConstraintMappingContextImpl.java | 2 +- ...ParameterConstraintMappingContextImpl.java | 4 +- .../TypeConstraintMappingContextImpl.java | 18 +- .../location/ParameterConstraintLocation.java | 2 +- .../provider/AnnotationMetaDataProvider.java | 190 ++++++++---------- .../metadata/raw/ConstrainedExecutable.java | 4 +- .../internal/properties/Callable.java | 9 +- .../JavaBeanAnnotatedConstrainable.java | 16 ++ .../javabean/JavaBeanAnnotatedElement.java | 34 ++++ .../javabean/JavaBeanConstructor.java | 32 +++ .../javabean/JavaBeanExecutable.java | 138 ++++++++----- .../properties/javabean/JavaBeanField.java | 30 ++- .../properties/javabean/JavaBeanGetter.java | 17 +- .../properties/javabean/JavaBeanMethod.java | 32 +++ .../javabean/JavaBeanParameter.java | 75 +++++++ .../ConstrainedConstructorStaxBuilder.java | 16 +- .../mapping/ConstrainedMethodStaxBuilder.java | 2 +- .../ConstrainedParameterStaxBuilder.java | 2 +- 18 files changed, 421 insertions(+), 202 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanAnnotatedConstrainable.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanAnnotatedElement.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanConstructor.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanMethod.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanParameter.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ExecutableConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ExecutableConstraintMappingContextImpl.java index 9cb9d826a2..503c284637 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ExecutableConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ExecutableConstraintMappingContextImpl.java @@ -130,7 +130,7 @@ private List getParameters(ConstraintHelper constraintHelp new ConstrainedParameter( ConfigurationSource.API, callable, - callable.getTypeOfParameter( i ), + callable.getParameterGenericType( i ), i ) ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ParameterConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ParameterConstraintMappingContextImpl.java index 1f8bc55dc5..314b23f1c7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ParameterConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ParameterConstraintMappingContextImpl.java @@ -40,7 +40,7 @@ final class ParameterConstraintMappingContextImpl ParameterConstraintMappingContextImpl(ExecutableConstraintMappingContextImpl executableContext, int parameterIndex) { super( executableContext.getTypeContext().getConstraintMapping(), - executableContext.callable.getGenericParameterTypes()[parameterIndex] + executableContext.callable.getParameterGenericType( parameterIndex ) ); this.executableContext = executableContext; @@ -121,7 +121,7 @@ public ContainerElementConstraintMappingContext containerElementType(int index, public ConstrainedParameter build(ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { - Type parameterType = executableContext.getCallable().getTypeOfParameter( parameterIndex ); + Type parameterType = executableContext.getCallable().getParameterGenericType( parameterIndex ); return new ConstrainedParameter( ConfigurationSource.API, diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index 7bc3b920ac..13fa7bd741 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -33,9 +33,9 @@ import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; -import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanConstructor; import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; @@ -154,17 +154,17 @@ public MethodConstraintMappingContext method(String name, Class... parameterT throw LOG.getBeanDoesNotContainMethodException( beanClass, name, parameterTypes ); } - Callable callable = JavaBeanExecutable.of( method ); + JavaBeanExecutable javaBeanExecutable = JavaBeanExecutable.of( method ); - if ( configuredMembers.contains( callable ) ) { + if ( configuredMembers.contains( javaBeanExecutable ) ) { throw LOG.getMethodHasAlreadyBeenConfiguredViaProgrammaticApiException( beanClass, ExecutableHelper.getExecutableAsString( name, parameterTypes ) ); } - MethodConstraintMappingContextImpl context = new MethodConstraintMappingContextImpl( this, callable ); - configuredMembers.add( callable ); + MethodConstraintMappingContextImpl context = new MethodConstraintMappingContextImpl( this, javaBeanExecutable ); + configuredMembers.add( javaBeanExecutable ); executableContexts.add( context ); return context; @@ -181,9 +181,9 @@ public ConstructorConstraintMappingContext constructor(Class... parameterType ); } - Callable callable = JavaBeanExecutable.of( constructor ); + JavaBeanConstructor javaBeanConstructor = new JavaBeanConstructor( constructor ); - if ( configuredMembers.contains( callable ) ) { + if ( configuredMembers.contains( javaBeanConstructor ) ) { throw LOG.getConstructorHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, ExecutableHelper.getExecutableAsString( beanClass.getSimpleName(), parameterTypes ) @@ -192,9 +192,9 @@ public ConstructorConstraintMappingContext constructor(Class... parameterType ConstructorConstraintMappingContextImpl context = new ConstructorConstraintMappingContextImpl( this, - callable + javaBeanConstructor ); - configuredMembers.add( callable ); + configuredMembers.add( javaBeanConstructor ); executableContexts.add( context ); return context; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java index c51b9308aa..f7ee26cac0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java @@ -29,7 +29,7 @@ public class ParameterConstraintLocation implements ConstraintLocation { public ParameterConstraintLocation(Callable callable, int index) { this.callable = callable; this.index = index; - this.typeForValidatorResolution = ReflectionHelper.boxedType( callable.getTypeOfParameter( index ) ); + this.typeForValidatorResolution = ReflectionHelper.boxedType( callable.getParameterGenericType( index ) ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index cfa173174e..ad4b3d408f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -13,18 +13,13 @@ import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandles; -import java.lang.reflect.AccessibleObject; import java.lang.reflect.AnnotatedArrayType; -import java.lang.reflect.AnnotatedElement; import java.lang.reflect.AnnotatedParameterizedType; import java.lang.reflect.AnnotatedType; -import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.Field; -import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.lang.reflect.Parameter; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -66,8 +61,11 @@ import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.javabean.JavaBeanAnnotatedConstrainable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanAnnotatedElement; import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; +import org.hibernate.validator.internal.properties.javabean.JavaBeanParameter; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; @@ -227,19 +225,19 @@ private Set getFieldMetaData(Class beanClass) { continue; } - propertyMetaData.add( findPropertyMetaData( field, javaBeanField ) ); + propertyMetaData.add( findPropertyMetaData( javaBeanField ) ); } return propertyMetaData; } - private ConstrainedField findPropertyMetaData(Field field, JavaBeanField javaBeanField) { + private ConstrainedField findPropertyMetaData(JavaBeanField javaBeanField) { Set> constraints = convertToMetaConstraints( - findConstraints( field, ConstraintLocationKind.FIELD, javaBeanField ), + findConstraints( javaBeanField, ConstraintLocationKind.FIELD ), javaBeanField ); - CascadingMetaDataBuilder cascadingMetaDataBuilder = findCascadingMetaData( field ); - Set> typeArgumentsConstraints = findTypeAnnotationConstraints( field, javaBeanField ); + CascadingMetaDataBuilder cascadingMetaDataBuilder = findCascadingMetaData( javaBeanField ); + Set> typeArgumentsConstraints = findTypeAnnotationConstraints( javaBeanField ); return new ConstrainedField( ConfigurationSource.ANNOTATION, @@ -302,25 +300,24 @@ private Set getMetaData(Executable[] executableElements) * given element. */ private ConstrainedExecutable findExecutableMetaData(Executable executable) { - Callable callable = JavaBeanExecutable.of( executable ); - List parameterConstraints = getParameterMetaData( executable, callable ); + JavaBeanExecutable javaBeanExecutable = JavaBeanExecutable.of( executable ); + List parameterConstraints = getParameterMetaData( javaBeanExecutable ); Map>> executableConstraints = findConstraints( - executable, - callable.getConstrainedElementKind() == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR + javaBeanExecutable, + javaBeanExecutable.getConstrainedElementKind() == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR ? ConstraintLocationKind.CONSTRUCTOR - : ConstraintLocationKind.METHOD, - callable + : ConstraintLocationKind.METHOD ).stream().collect( Collectors.groupingBy( ConstraintDescriptorImpl::getConstraintType ) ); Set> crossParameterConstraints; - if ( annotationProcessingOptions.areCrossParameterConstraintsIgnoredFor( callable ) ) { + if ( annotationProcessingOptions.areCrossParameterConstraintsIgnoredFor( javaBeanExecutable ) ) { crossParameterConstraints = Collections.emptySet(); } else { crossParameterConstraints = convertToMetaConstraints( executableConstraints.get( ConstraintType.CROSS_PARAMETER ), - callable + javaBeanExecutable ); } @@ -328,25 +325,23 @@ private ConstrainedExecutable findExecutableMetaData(Executable executable) { Set> typeArgumentsConstraints; CascadingMetaDataBuilder cascadingMetaDataBuilder; - if ( annotationProcessingOptions.areReturnValueConstraintsIgnoredFor( callable ) ) { + if ( annotationProcessingOptions.areReturnValueConstraintsIgnoredFor( javaBeanExecutable ) ) { returnValueConstraints = Collections.emptySet(); typeArgumentsConstraints = Collections.emptySet(); cascadingMetaDataBuilder = CascadingMetaDataBuilder.nonCascading(); } else { - AnnotatedType annotatedReturnType = executable.getAnnotatedReturnType(); - - typeArgumentsConstraints = findTypeAnnotationConstraints( executable, callable, annotatedReturnType ); + typeArgumentsConstraints = findTypeAnnotationConstraints( javaBeanExecutable ); returnValueConstraints = convertToMetaConstraints( executableConstraints.get( ConstraintType.GENERIC ), - callable + javaBeanExecutable ); - cascadingMetaDataBuilder = findCascadingMetaData( executable, annotatedReturnType ); + cascadingMetaDataBuilder = findCascadingMetaData( javaBeanExecutable ); } return new ConstrainedExecutable( ConfigurationSource.ANNOTATION, - callable, + javaBeanExecutable, parameterConstraints, crossParameterConstraints, returnValueConstraints, @@ -377,25 +372,24 @@ private Set> convertToMetaConstraints(List getParameterMetaData(Executable executable, Callable callable) { - if ( executable.getParameterCount() == 0 ) { + private List getParameterMetaData(JavaBeanExecutable javaBeanExecutable) { + if ( !javaBeanExecutable.hasParameters() ) { return Collections.emptyList(); } - Parameter[] parameters = executable.getParameters(); + List parameters = javaBeanExecutable.getParameters(); - List metaData = new ArrayList<>( parameters.length ); + List metaData = new ArrayList<>( parameters.size() ); int i = 0; - for ( Parameter parameter : parameters ) { + for ( JavaBeanParameter parameter : parameters ) { Annotation[] parameterAnnotations; try { - parameterAnnotations = parameter.getAnnotations(); + parameterAnnotations = parameter.getDeclaredAnnotations(); } catch (ArrayIndexOutOfBoundsException ex) { LOG.warn( MESSAGES.constraintOnConstructorOfNonStaticInnerClass(), ex ); @@ -404,13 +398,12 @@ private List getParameterMetaData(Executable executable, C Set> parameterConstraints = newHashSet(); - if ( annotationProcessingOptions.areParameterConstraintsIgnoredFor( callable, i ) ) { - Type type = ReflectionHelper.typeOf( executable, i ); + if ( annotationProcessingOptions.areParameterConstraintsIgnoredFor( javaBeanExecutable, i ) ) { metaData.add( new ConstrainedParameter( ConfigurationSource.ANNOTATION, - callable, - type, + javaBeanExecutable, + parameter.getGenericType(), i, parameterConstraints, Collections.emptySet(), @@ -421,12 +414,12 @@ private List getParameterMetaData(Executable executable, C continue; } - ConstraintLocation location = ConstraintLocation.forParameter( callable, i ); + ConstraintLocation location = ConstraintLocation.forParameter( javaBeanExecutable, i ); for ( Annotation parameterAnnotation : parameterAnnotations ) { // collect constraints if this annotation is a constraint annotation List> constraints = findConstraintAnnotations( - callable, parameterAnnotation, ConstraintLocationKind.PARAMETER + javaBeanExecutable, parameterAnnotation, ConstraintLocationKind.PARAMETER ); for ( ConstraintDescriptorImpl constraintDescriptorImpl : constraints ) { parameterConstraints.add( @@ -435,16 +428,14 @@ private List getParameterMetaData(Executable executable, C } } - AnnotatedType parameterAnnotatedType = parameter.getAnnotatedType(); - - Set> typeArgumentsConstraints = findTypeAnnotationConstraintsForExecutableParameter( executable, callable, i, parameterAnnotatedType ); - CascadingMetaDataBuilder cascadingMetaData = findCascadingMetaData( executable, parameters, i, parameterAnnotatedType ); + Set> typeArgumentsConstraints = findTypeAnnotationConstraintsForExecutableParameter( parameter ); + CascadingMetaDataBuilder cascadingMetaData = findCascadingMetaData( parameter ); metaData.add( new ConstrainedParameter( ConfigurationSource.ANNOTATION, - callable, - ReflectionHelper.typeOf( executable, i ), + javaBeanExecutable, + parameter.getGenericType(), i, parameterConstraints, typeArgumentsConstraints, @@ -461,14 +452,14 @@ private List getParameterMetaData(Executable executable, C * Finds all constraint annotations defined for the given member and returns them in a list of * constraint descriptors. * - * @param member The member to check for constraints annotations. + * @param constrainable The constrainable to check for constraint annotations. * @param type The element type the constraint/annotation is placed on. * * @return A list of constraint descriptors for all constraint specified for the given member. */ - private List> findConstraints(Member member, ConstraintLocationKind type, Constrainable constrainable) { + private List> findConstraints(JavaBeanAnnotatedConstrainable constrainable, ConstraintLocationKind type) { List> metaData = newArrayList(); - for ( Annotation annotation : ( (AccessibleObject) member ).getDeclaredAnnotations() ) { + for ( Annotation annotation : constrainable.getDeclaredAnnotations() ) { metaData.addAll( findConstraintAnnotations( constrainable, annotation, type ) ); } @@ -528,10 +519,10 @@ else if ( constraintHelper.isMultiValueConstraint( annotationType ) ) { .collect( Collectors.toList() ); } - private Map, Class> getGroupConversions(AnnotatedElement annotatedElement) { + private Map, Class> getGroupConversions(AnnotatedType annotatedType) { return getGroupConversions( - annotatedElement.getAnnotation( ConvertGroup.class ), - annotatedElement.getAnnotation( ConvertGroup.List.class ) + annotatedType.getAnnotation( ConvertGroup.class ), + annotatedType.getAnnotation( ConvertGroup.List.class ) ); } @@ -585,35 +576,31 @@ private T run(PrivilegedAction action) { /** * Finds type arguments constraints for fields. */ - protected Set> findTypeAnnotationConstraints(Field field, Property property) { + protected Set> findTypeAnnotationConstraints(JavaBeanField javaBeanField) { return findTypeArgumentsConstraints( - property, - new TypeArgumentFieldLocation( field ), - field.getAnnotatedType() + javaBeanField, + new TypeArgumentFieldLocation( javaBeanField ), + javaBeanField.getAnnotatedType() ); } /** * Finds type arguments constraints for method return values. */ - protected Set> findTypeAnnotationConstraints(Executable executable, Callable callable, AnnotatedType annotatedReturnType) { + protected Set> findTypeAnnotationConstraints(JavaBeanExecutable javaBeanExecutable) { return findTypeArgumentsConstraints( - callable, - new TypeArgumentReturnValueLocation( executable ), - annotatedReturnType + javaBeanExecutable, + new TypeArgumentReturnValueLocation( javaBeanExecutable ), + javaBeanExecutable.getAnnotatedType() ); } - private CascadingMetaDataBuilder findCascadingMetaData(Executable executable, Parameter[] parameters, int i, AnnotatedType parameterAnnotatedType) { - Parameter parameter = parameters[i]; - TypeVariable[] typeParameters = parameter.getType().getTypeParameters(); - - Map, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData = getTypeParametersCascadingMetadata( parameterAnnotatedType, - typeParameters ); + private CascadingMetaDataBuilder findCascadingMetaData(JavaBeanParameter javaBeanParameter) { + Map, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData = getTypeParametersCascadingMetadata( javaBeanParameter.getAnnotatedType(), + javaBeanParameter.getTypeParameters() ); try { - return getCascadingMetaData( ReflectionHelper.typeOf( parameter.getDeclaringExecutable(), i ), - parameter, containerElementTypesCascadingMetaData ); + return getCascadingMetaData( javaBeanParameter, containerElementTypesCascadingMetaData ); } catch (ArrayIndexOutOfBoundsException ex) { LOG.warn( MESSAGES.constraintOnConstructorOfNonStaticInnerClass(), ex ); @@ -621,29 +608,19 @@ private CascadingMetaDataBuilder findCascadingMetaData(Executable executable, Pa } } - private CascadingMetaDataBuilder findCascadingMetaData(Field field) { - TypeVariable[] typeParameters = field.getType().getTypeParameters(); - AnnotatedType annotatedType = field.getAnnotatedType(); - - Map, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData = getTypeParametersCascadingMetadata( annotatedType, typeParameters ); + private CascadingMetaDataBuilder findCascadingMetaData(JavaBeanField javaBeanField) { + Map, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData = getTypeParametersCascadingMetadata( + javaBeanField.getAnnotatedType(), + javaBeanField.getTypeParameters() ); - return getCascadingMetaData( ReflectionHelper.typeOf( field ), field, containerElementTypesCascadingMetaData ); + return getCascadingMetaData( javaBeanField, containerElementTypesCascadingMetaData ); } - private CascadingMetaDataBuilder findCascadingMetaData(Executable executable, AnnotatedType annotatedReturnType) { - TypeVariable[] typeParameters; - - if ( executable instanceof Method ) { - typeParameters = ( (Method) executable ).getReturnType().getTypeParameters(); - } - else { - typeParameters = ( (Constructor) executable ).getDeclaringClass().getTypeParameters(); - } - - Map, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData = getTypeParametersCascadingMetadata( annotatedReturnType, - typeParameters ); + private CascadingMetaDataBuilder findCascadingMetaData(JavaBeanExecutable javaBeanExecutable) { + Map, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData = getTypeParametersCascadingMetadata( javaBeanExecutable.getAnnotatedType(), + javaBeanExecutable.getTypeParameters() ); - return getCascadingMetaData( ReflectionHelper.typeOf( executable ), executable, containerElementTypesCascadingMetaData ); + return getCascadingMetaData( javaBeanExecutable, containerElementTypesCascadingMetaData ); } private Map, CascadingMetaDataBuilder> getTypeParametersCascadingMetadata(AnnotatedType annotatedType, @@ -714,17 +691,16 @@ else if ( annotatedType instanceof AnnotatedParameterizedType ) { /** * Finds type arguments constraints for parameters. * - * @param executable the executable - * @param i the parameter index + * @param javaBeanParameter the parameter * * @return a set of type arguments constraints, or an empty set if no constrained type arguments are found */ - protected Set> findTypeAnnotationConstraintsForExecutableParameter(Executable executable, Callable callable, int i, AnnotatedType parameterAnnotatedType) { + protected Set> findTypeAnnotationConstraintsForExecutableParameter(JavaBeanParameter javaBeanParameter) { try { return findTypeArgumentsConstraints( - callable, - new TypeArgumentExecutableParameterLocation( executable, i ), - parameterAnnotatedType + javaBeanParameter.getExecutable(), + new TypeArgumentExecutableParameterLocation( javaBeanParameter.getExecutable(), javaBeanParameter.getIndex() ), + javaBeanParameter.getAnnotatedType() ); } catch (ArrayIndexOutOfBoundsException ex) { @@ -803,10 +779,10 @@ private MetaConstraint createTypeArgumentMetaConstrain return MetaConstraints.create( typeResolutionHelper, valueExtractorManager, descriptor, constraintLocation ); } - private CascadingMetaDataBuilder getCascadingMetaData(Type type, AnnotatedElement annotatedElement, + private CascadingMetaDataBuilder getCascadingMetaData(JavaBeanAnnotatedElement annotatedElement, Map, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData) { - return CascadingMetaDataBuilder.annotatedObject( type, annotatedElement.isAnnotationPresent( Valid.class ), containerElementTypesCascadingMetaData, - getGroupConversions( annotatedElement ) ); + return CascadingMetaDataBuilder.annotatedObject( annotatedElement.getType(), annotatedElement.isAnnotationPresent( Valid.class ), + containerElementTypesCascadingMetaData, getGroupConversions( annotatedElement.getAnnotatedType() ) ); } /** @@ -821,44 +797,44 @@ private interface TypeArgumentLocation { } private static class TypeArgumentExecutableParameterLocation implements TypeArgumentLocation { - private final Executable executable; + private final JavaBeanExecutable javaBeanExecutable; private final int index; - private TypeArgumentExecutableParameterLocation(Executable executable, int index) { - this.executable = executable; + private TypeArgumentExecutableParameterLocation(JavaBeanExecutable javaBeanExecutable, int index) { + this.javaBeanExecutable = javaBeanExecutable; this.index = index; } @Override public ConstraintLocation toConstraintLocation() { - return ConstraintLocation.forParameter( JavaBeanExecutable.of( executable ), index ); + return ConstraintLocation.forParameter( javaBeanExecutable, index ); } } private static class TypeArgumentFieldLocation implements TypeArgumentLocation { - private final Field field; + private final JavaBeanField javaBeanField; - private TypeArgumentFieldLocation(Field field) { - this.field = field; + private TypeArgumentFieldLocation(JavaBeanField javaBeanField) { + this.javaBeanField = javaBeanField; } @Override public ConstraintLocation toConstraintLocation() { - return ConstraintLocation.forField( new JavaBeanField( field ) ); + return ConstraintLocation.forField( javaBeanField ); } } private static class TypeArgumentReturnValueLocation implements TypeArgumentLocation { - private final Executable executable; + private final JavaBeanExecutable javaBeanExecutable; - private TypeArgumentReturnValueLocation(Executable executable) { - this.executable = executable; + private TypeArgumentReturnValueLocation(JavaBeanExecutable javaBeanExecutable) { + this.javaBeanExecutable = javaBeanExecutable; } @Override public ConstraintLocation toConstraintLocation() { - return ConstraintLocation.forReturnValue( JavaBeanExecutable.of( executable ) ); + return ConstraintLocation.forReturnValue( javaBeanExecutable ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java index 1f8e989cd3..0c42157833 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java @@ -112,10 +112,10 @@ public ConstrainedExecutable( this.callable = callable; - if ( parameterMetaData.size() != callable.getParameterTypes().length ) { + if ( parameterMetaData.size() != callable.getParameterCount() ) { throw LOG.getInvalidLengthOfParameterMetaDataListException( callable, - callable.getParameterTypes().length, + callable.getParameterCount(), parameterMetaData.size() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java index 9095262992..2e72191a1d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java @@ -14,6 +14,7 @@ /** * @author Marko Bekhta + * @author Guillaume Smet */ public interface Callable extends Constrainable { @@ -21,9 +22,11 @@ public interface Callable extends Constrainable { boolean hasParameters(); - Class[] getParameterTypes(); + int getParameterCount(); + + Type getParameterGenericType(int index); - Type[] getGenericParameterTypes(); + Class[] getParameterTypes(); String getParameterName(ExecutableParameterNameProvider parameterNameProvider, int parameterIndex); @@ -33,8 +36,6 @@ public interface Callable extends Constrainable { String getSignature(); - Type getTypeOfParameter(int parameterIndex); - boolean overrides(ExecutableHelper executableHelper, Callable superTypeMethod); boolean isResolvedToSameMethodInHierarchy(ExecutableHelper executableHelper, Class mainSubType, Callable superTypeMethod); diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanAnnotatedConstrainable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanAnnotatedConstrainable.java new file mode 100644 index 0000000000..55589a6c4a --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanAnnotatedConstrainable.java @@ -0,0 +1,16 @@ +/* + * 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.properties.javabean; + +import org.hibernate.validator.internal.properties.Constrainable; + +/** + * @author Guillaume Smet + */ +public interface JavaBeanAnnotatedConstrainable extends Constrainable, JavaBeanAnnotatedElement { + +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanAnnotatedElement.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanAnnotatedElement.java new file mode 100644 index 0000000000..11a99d3eab --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanAnnotatedElement.java @@ -0,0 +1,34 @@ +/* + * 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.properties.javabean; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +/** + * @author Guillaume Smet + */ +public interface JavaBeanAnnotatedElement { + + Type getType(); + + AnnotatedType getAnnotatedType(); + + Annotation[] getDeclaredAnnotations(); + + Type getGenericType(); + + TypeVariable[] getTypeParameters(); + + A getAnnotation(Class annotationClass); + + default boolean isAnnotationPresent(Class annotationClass) { + return getAnnotation( annotationClass ) != null; + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanConstructor.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanConstructor.java new file mode 100644 index 0000000000..2ffbce8677 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanConstructor.java @@ -0,0 +1,32 @@ +/* + * 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.properties.javabean; + +import java.lang.reflect.Constructor; +import java.lang.reflect.TypeVariable; + +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; + +/** + * @author Guillaume Smet + */ +public class JavaBeanConstructor extends JavaBeanExecutable> { + + public JavaBeanConstructor(Constructor executable) { + super( executable, true ); + } + + @Override + public ConstrainedElementKind getConstrainedElementKind() { + return ConstrainedElementKind.CONSTRUCTOR; + } + + @Override + public TypeVariable[] getTypeParameters() { + return executable.getDeclaringClass().getTypeParameters(); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java index 3622c6db42..1d69c8e629 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java @@ -6,15 +6,21 @@ */ package org.hibernate.validator.internal.properties.javabean; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedType; import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.ReflectionHelper; @@ -22,34 +28,52 @@ /** * @author Marko Bekhta + * @author Guillaume Smet */ -public class JavaBeanExecutable implements Callable { +public abstract class JavaBeanExecutable implements Callable, JavaBeanAnnotatedConstrainable { - protected final Executable executable; + protected final T executable; private final Type typeForValidatorResolution; private final String name; - private final boolean hasParameters; private final boolean hasReturnValue; private final Type type; - private final ConstrainedElementKind kind; + private final List parameters; - JavaBeanExecutable(Executable executable) { + JavaBeanExecutable(T executable, boolean hasReturnValue) { this.executable = executable; this.name = executable.getName(); this.type = ReflectionHelper.typeOf( executable ); this.typeForValidatorResolution = ReflectionHelper.boxedType( type ); - this.hasParameters = executable.getParameterTypes().length > 0; - this.hasReturnValue = hasReturnValue( executable ); - this.kind = executable instanceof Constructor ? ConstrainedElementKind.CONSTRUCTOR : ConstrainedElementKind.METHOD; + this.hasReturnValue = hasReturnValue; + + if ( executable.getParameterCount() > 0 ) { + List parameters = new ArrayList<>( executable.getParameterCount() ); + + Parameter[] parameterArray = executable.getParameters(); + Class[] parameterTypes = executable.getParameterTypes(); + Type[] genericParameterTypes = executable.getGenericParameterTypes(); + + for ( int i = 0; i < parameterArray.length; i++ ) { + parameters.add( new JavaBeanParameter( this, i, parameterArray[i], parameterTypes[i], + getParameterGenericType( parameterTypes, genericParameterTypes, i ) ) ); + } + this.parameters = CollectionHelper.toImmutableList( parameters ); + } + else { + this.parameters = Collections.emptyList(); + } } - public static JavaBeanExecutable of(Executable executable) { + public static JavaBeanExecutable of(Executable executable) { + if ( executable instanceof Constructor ) { + return new JavaBeanConstructor( (Constructor) executable ); + } + if ( ReflectionHelper.isGetterMethod( executable ) ) { return new JavaBeanGetter( (Method) executable ); } - else { - return new JavaBeanExecutable( executable ); - } + + return new JavaBeanMethod( (Method) executable ); } @Override @@ -59,7 +83,7 @@ public boolean hasReturnValue() { @Override public boolean hasParameters() { - return hasParameters; + return !parameters.isEmpty(); } @Override @@ -83,60 +107,67 @@ public Type getType() { } @Override - public Class[] getParameterTypes() { - return executable.getParameterTypes(); + public String getParameterName(ExecutableParameterNameProvider parameterNameProvider, int parameterIndex) { + return parameterNameProvider.getParameterNames( executable ).get( parameterIndex ); } @Override - public Type[] getGenericParameterTypes() { - return executable.getGenericParameterTypes(); + public boolean isPrivate() { + return Modifier.isPrivate( executable.getModifiers() ); } @Override - public String getParameterName(ExecutableParameterNameProvider parameterNameProvider, int parameterIndex) { - return parameterNameProvider.getParameterNames( executable ).get( parameterIndex ); + public String getSignature() { + return ExecutableHelper.getSignature( executable ); } @Override - public boolean isPrivate() { - return Modifier.isPrivate( executable.getModifiers() ); + public Annotation[] getDeclaredAnnotations() { + return executable.getDeclaredAnnotations(); } @Override - public ConstrainedElementKind getConstrainedElementKind() { - return kind; + public boolean overrides(ExecutableHelper executableHelper, Callable superTypeMethod) { + return executableHelper.overrides( ( (Method) this.executable ), ( (Method) ( (JavaBeanExecutable) superTypeMethod ).executable ) ); } @Override - public String getSignature() { - return ExecutableHelper.getSignature( executable ); + public boolean isResolvedToSameMethodInHierarchy(ExecutableHelper executableHelper, Class mainSubType, Callable superTypeMethod) { + return executableHelper.isResolvedToSameMethodInHierarchy( mainSubType, ( (Method) this.executable ), ( (Method) ( (JavaBeanExecutable) superTypeMethod ).executable ) ); } @Override - public Type getTypeOfParameter(int parameterIndex) { - Type[] genericParameterTypes = executable.getGenericParameterTypes(); + public Type getGenericType() { + return ReflectionHelper.typeOf( executable ); + } - // getGenericParameterTypes() doesn't return synthetic parameters; in this case fall back to getParameterTypes() - if ( parameterIndex >= genericParameterTypes.length ) { - genericParameterTypes = executable.getParameterTypes(); - } + @Override + public AnnotatedType getAnnotatedType() { + return executable.getAnnotatedReturnType(); + } - Type type = genericParameterTypes[parameterIndex]; + @Override + public A getAnnotation(Class annotationClass) { + return executable.getAnnotation( annotationClass ); + } - if ( type instanceof TypeVariable ) { - type = TypeHelper.getErasedType( type ); - } - return type; + public List getParameters() { + return parameters; } @Override - public boolean overrides(ExecutableHelper executableHelper, Callable superTypeMethod) { - return executableHelper.overrides( ( (Method) this.executable ), ( (Method) ( (JavaBeanExecutable) superTypeMethod ).executable ) ); + public Type getParameterGenericType(int index) { + return parameters.get( index ).getGenericType(); } @Override - public boolean isResolvedToSameMethodInHierarchy(ExecutableHelper executableHelper, Class mainSubType, Callable superTypeMethod) { - return executableHelper.isResolvedToSameMethodInHierarchy( mainSubType, ( (Method) this.executable ), ( (Method) ( (JavaBeanExecutable) superTypeMethod ).executable ) ); + public int getParameterCount() { + return parameters.size(); + } + + @Override + public Class[] getParameterTypes() { + return executable.getParameterTypes(); } @Override @@ -148,11 +179,8 @@ public boolean equals(Object o) { return false; } - JavaBeanExecutable that = (JavaBeanExecutable) o; + JavaBeanExecutable that = (JavaBeanExecutable) o; - if ( this.hasParameters != that.hasParameters ) { - return false; - } if ( this.hasReturnValue != that.hasReturnValue ) { return false; } @@ -173,7 +201,6 @@ public int hashCode() { int result = this.executable.hashCode(); result = 31 * result + this.typeForValidatorResolution.hashCode(); result = 31 * result + this.name.hashCode(); - result = 31 * result + ( this.hasParameters ? 1 : 0 ); result = 31 * result + ( this.hasReturnValue ? 1 : 0 ); result = 31 * result + this.type.hashCode(); return result; @@ -183,16 +210,25 @@ public int hashCode() { public String toString() { return ExecutableHelper.getExecutableAsString( getDeclaringClass().getSimpleName() + "#" + name, - getParameterTypes() + executable.getParameterTypes() ); } - private boolean hasReturnValue(Executable executable) { - if ( executable instanceof Constructor ) { - return true; + private static Type getParameterGenericType(Type[] parameterTypes, Type[] genericParameterTypes, int parameterIndex) { + // getGenericParameterTypes() doesn't return synthetic parameters; in this case fall back to getParameterTypes() + Type[] typesToConsider; + if ( parameterIndex >= genericParameterTypes.length ) { + typesToConsider = parameterTypes; } else { - return ( (Method) executable ).getGenericReturnType() != void.class; + typesToConsider = genericParameterTypes; } + + Type type = typesToConsider[parameterIndex]; + + if ( type instanceof TypeVariable ) { + type = TypeHelper.getErasedType( type ); + } + return type; } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java index 67271d68c9..c6013a8de0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java @@ -6,8 +6,11 @@ */ package org.hibernate.validator.internal.properties.javabean; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedType; import java.lang.reflect.Field; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.security.AccessController; import java.security.PrivilegedAction; @@ -19,7 +22,7 @@ /** * @author Marko Bekhta */ -public class JavaBeanField implements Property { +public class JavaBeanField implements Property, JavaBeanAnnotatedConstrainable { private final Field field; private final String name; @@ -63,6 +66,31 @@ public String getPropertyName() { return getName(); } + @Override + public AnnotatedType getAnnotatedType() { + return field.getAnnotatedType(); + } + + @Override + public Annotation[] getDeclaredAnnotations() { + return field.getDeclaredAnnotations(); + } + + @Override + public A getAnnotation(Class annotationClass) { + return field.getAnnotation( annotationClass ); + } + + @Override + public Type getGenericType() { + return ReflectionHelper.typeOf( field ); + } + + @Override + public TypeVariable[] getTypeParameters() { + return field.getType().getTypeParameters(); + } + @Override public boolean equals(Object o) { if ( this == o ) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java index 113aca02a5..65ec83aa8b 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java @@ -7,7 +7,6 @@ package org.hibernate.validator.internal.properties.javabean; import java.lang.reflect.Method; -import java.lang.reflect.Type; import java.security.AccessController; import java.security.PrivilegedAction; @@ -20,9 +19,7 @@ /** * @author Marko Bekhta */ -public class JavaBeanGetter extends JavaBeanExecutable implements Property { - - private static final Class[] PARAMETER_TYPES = new Class[0]; +public class JavaBeanGetter extends JavaBeanMethod implements Property { private final String name; @@ -48,7 +45,7 @@ public JavaBeanGetter(Class declaringClass, Method method) { @Override public Object getValueFrom(Object bean) { - return ReflectionHelper.getValue( (Method) executable, bean ); + return ReflectionHelper.getValue( executable, bean ); } @Override @@ -68,16 +65,6 @@ public boolean hasParameters() { return false; } - @Override - public Class[] getParameterTypes() { - return PARAMETER_TYPES; - } - - @Override - public Type[] getGenericParameterTypes() { - return PARAMETER_TYPES; - } - @Override public String getParameterName(ExecutableParameterNameProvider parameterNameProvider, int parameterIndex) { throw new IllegalStateException( "Getters cannot have parameters" ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanMethod.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanMethod.java new file mode 100644 index 0000000000..166af53e8d --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanMethod.java @@ -0,0 +1,32 @@ +/* + * 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.properties.javabean; + +import java.lang.reflect.Method; +import java.lang.reflect.TypeVariable; + +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; + +/** + * @author Guillaume Smet + */ +public class JavaBeanMethod extends JavaBeanExecutable { + + JavaBeanMethod(Method method) { + super( method, method.getGenericReturnType() != void.class ); + } + + @Override + public ConstrainedElementKind getConstrainedElementKind() { + return ConstrainedElementKind.METHOD; + } + + @Override + public TypeVariable[] getTypeParameters() { + return executable.getReturnType().getTypeParameters(); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanParameter.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanParameter.java new file mode 100644 index 0000000000..416b842c79 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanParameter.java @@ -0,0 +1,75 @@ +/* + * 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.properties.javabean; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Parameter; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +/** + * @author Guillaume Smet + */ +public class JavaBeanParameter implements JavaBeanAnnotatedElement { + + private final JavaBeanExecutable executable; + + private final int index; + + private final Parameter parameter; + + private final Class type; + + private final Type genericType; + + JavaBeanParameter(JavaBeanExecutable executable, int index, Parameter parameter, Class type, Type genericType) { + this.executable = executable; + this.index = index; + this.parameter = parameter; + this.type = type; + this.genericType = genericType; + } + + public JavaBeanExecutable getExecutable() { + return executable; + } + + public int getIndex() { + return index; + } + + @Override + public Class getType() { + return type; + } + + @Override + public AnnotatedType getAnnotatedType() { + return parameter.getAnnotatedType(); + } + + @Override + public Annotation[] getDeclaredAnnotations() { + return parameter.getDeclaredAnnotations(); + } + + @Override + public Type getGenericType() { + return genericType; + } + + @Override + public TypeVariable[] getTypeParameters() { + return parameter.getType().getTypeParameters(); + } + + @Override + public A getAnnotation(Class annotationClass) { + return parameter.getAnnotation( annotationClass ); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedConstructorStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedConstructorStaxBuilder.java index 1807e03322..dd8da3e3e3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedConstructorStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedConstructorStaxBuilder.java @@ -26,7 +26,7 @@ import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; -import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanConstructor; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.logging.Log; @@ -85,7 +85,8 @@ ConstrainedExecutable build(Class beanClass, List> alreadyProc parameterTypes ); } - JavaBeanExecutable executable = JavaBeanExecutable.of( constructor ); + + JavaBeanConstructor javaBeanConstructor = new JavaBeanConstructor( constructor ); if ( alreadyProcessedConstructors.contains( constructor ) ) { throw LOG.getConstructorIsDefinedTwiceInMappingXmlForBeanException( constructor, beanClass ); @@ -97,7 +98,7 @@ ConstrainedExecutable build(Class beanClass, List> alreadyProc // ignore annotations if ( ignoreAnnotations.isPresent() ) { annotationProcessingOptions.ignoreConstraintAnnotationsOnMember( - executable, + javaBeanConstructor, ignoreAnnotations.get() ); } @@ -105,21 +106,22 @@ ConstrainedExecutable build(Class beanClass, List> alreadyProc List constrainedParameters = CollectionHelper.newArrayList( constrainedParameterStaxBuilders.size() ); for ( int index = 0; index < constrainedParameterStaxBuilders.size(); index++ ) { ConstrainedParameterStaxBuilder builder = constrainedParameterStaxBuilders.get( index ); - constrainedParameters.add( builder.build( executable, index ) ); + constrainedParameters.add( builder.build( javaBeanConstructor, index ) ); } Set> crossParameterConstraints = getCrossParameterStaxBuilder() - .map( builder -> builder.build( executable ) ).orElse( Collections.emptySet() ); + .map( builder -> builder.build( javaBeanConstructor ) ).orElse( Collections.emptySet() ); // parse the return value Set> returnValueConstraints = new HashSet<>(); Set> returnValueTypeArgumentConstraints = new HashSet<>(); - CascadingMetaDataBuilder cascadingMetaDataBuilder = getReturnValueStaxBuilder().map( builder -> builder.build( executable, returnValueConstraints, returnValueTypeArgumentConstraints ) ) + CascadingMetaDataBuilder cascadingMetaDataBuilder = getReturnValueStaxBuilder() + .map( builder -> builder.build( javaBeanConstructor, returnValueConstraints, returnValueTypeArgumentConstraints ) ) .orElse( CascadingMetaDataBuilder.nonCascading() ); return new ConstrainedExecutable( ConfigurationSource.XML, - executable, + javaBeanConstructor, constrainedParameters, crossParameterConstraints, returnValueConstraints, diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedMethodStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedMethodStaxBuilder.java index f1876750c4..4a78d244bc 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedMethodStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedMethodStaxBuilder.java @@ -97,7 +97,7 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedMet else { alreadyProcessedMethods.add( method ); } - JavaBeanExecutable executable = JavaBeanExecutable.of( method ); + JavaBeanExecutable executable = JavaBeanExecutable.of( method ); // ignore annotations if ( ignoreAnnotations.isPresent() ) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java index 3d4eb1a090..5cc0cb2f65 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedParameterStaxBuilder.java @@ -71,7 +71,7 @@ public Class getParameterType(Class beanClass) { ConstrainedParameter build(Callable callable, int index) { ConstraintLocation constraintLocation = ConstraintLocation.forParameter( callable, index ); - Type type = callable.getTypeOfParameter( index ); + Type type = callable.getParameterGenericType( index ); Set> metaConstraints = constraintTypeStaxBuilders.stream() .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.PARAMETER, null ) ) From f44ecb4e267591ea6d193bf3aed7426c28dd727a Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 4 Jun 2018 11:48:40 +0200 Subject: [PATCH 10/24] HV-1623 Propagate ConstraintLocationKind as far as possible --- .../engine/ConstraintViolationImpl.java | 72 +++++++++---------- .../internal/engine/ValidatorImpl.java | 32 +++++---- .../internal/engine/ValueContext.java | 16 ++--- .../BeanValidationContext.java | 1 - .../ParameterExecutableValidationContext.java | 1 - .../PropertyValidationContext.java | 1 - ...eturnValueExecutableValidationContext.java | 1 - .../metadata/aggregated/FieldCascadable.java | 7 +- .../metadata/aggregated/GetterCascadable.java | 7 +- .../aggregated/ParameterMetaData.java | 6 +- .../aggregated/ReturnValueMetaData.java | 6 +- .../metadata/core/MetaConstraint.java | 2 +- .../descriptor/ConstraintDescriptorImpl.java | 14 ++-- .../internal/metadata/facets/Cascadable.java | 8 +-- 14 files changed, 81 insertions(+), 93 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java index 59e3ee04c9..69aa6d1619 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java @@ -7,7 +7,6 @@ package org.hibernate.validator.internal.engine; import java.io.Serializable; -import java.lang.annotation.ElementType; import java.lang.invoke.MethodHandles; import java.util.Map; @@ -45,17 +44,16 @@ public class ConstraintViolationImpl implements HibernateConstraintViolation< private final int hashCode; public static ConstraintViolation forBeanValidation(String messageTemplate, - Map messageParameters, - Map expressionVariables, - String interpolatedMessage, - Class rootBeanClass, - T rootBean, - Object leafBeanInstance, - Object value, - Path propertyPath, - ConstraintDescriptor constraintDescriptor, - ElementType elementType, - Object dynamicPayload) { + Map messageParameters, + Map expressionVariables, + String interpolatedMessage, + Class rootBeanClass, + T rootBean, + Object leafBeanInstance, + Object value, + Path propertyPath, + ConstraintDescriptor constraintDescriptor, + Object dynamicPayload) { return new ConstraintViolationImpl<>( messageTemplate, messageParameters, @@ -67,7 +65,6 @@ public static ConstraintViolation forBeanValidation(String messageTemplat value, propertyPath, constraintDescriptor, - elementType, null, null, dynamicPayload @@ -75,18 +72,17 @@ public static ConstraintViolation forBeanValidation(String messageTemplat } public static ConstraintViolation forParameterValidation(String messageTemplate, - Map messageParameters, - Map expressionVariables, - String interpolatedMessage, - Class rootBeanClass, - T rootBean, - Object leafBeanInstance, - Object value, - Path propertyPath, - ConstraintDescriptor constraintDescriptor, - ElementType elementType, - Object[] executableParameters, - Object dynamicPayload) { + Map messageParameters, + Map expressionVariables, + String interpolatedMessage, + Class rootBeanClass, + T rootBean, + Object leafBeanInstance, + Object value, + Path propertyPath, + ConstraintDescriptor constraintDescriptor, + Object[] executableParameters, + Object dynamicPayload) { return new ConstraintViolationImpl<>( messageTemplate, messageParameters, @@ -98,7 +94,6 @@ public static ConstraintViolation forParameterValidation(String messageTe value, propertyPath, constraintDescriptor, - elementType, executableParameters, null, dynamicPayload @@ -106,18 +101,17 @@ public static ConstraintViolation forParameterValidation(String messageTe } public static ConstraintViolation forReturnValueValidation(String messageTemplate, - Map messageParameters, - Map expressionVariables, - String interpolatedMessage, - Class rootBeanClass, - T rootBean, - Object leafBeanInstance, - Object value, - Path propertyPath, - ConstraintDescriptor constraintDescriptor, - ElementType elementType, - Object executableReturnValue, - Object dynamicPayload) { + Map messageParameters, + Map expressionVariables, + String interpolatedMessage, + Class rootBeanClass, + T rootBean, + Object leafBeanInstance, + Object value, + Path propertyPath, + ConstraintDescriptor constraintDescriptor, + Object executableReturnValue, + Object dynamicPayload) { return new ConstraintViolationImpl<>( messageTemplate, messageParameters, @@ -129,7 +123,6 @@ public static ConstraintViolation forReturnValueValidation(String message value, propertyPath, constraintDescriptor, - elementType, null, executableReturnValue, dynamicPayload @@ -146,7 +139,6 @@ private ConstraintViolationImpl(String messageTemplate, Object value, Path propertyPath, ConstraintDescriptor constraintDescriptor, - ElementType elementType, Object[] executableParameters, Object executableReturnValue, Object dynamicPayload) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 5ec5c85f0b..9bbe13193e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -8,7 +8,6 @@ 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; @@ -63,6 +62,7 @@ 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.ConstraintLocationKind; import org.hibernate.validator.internal.util.Contracts; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ReflectionHelper; @@ -552,8 +552,8 @@ private void validateCascadedConstraints(BaseBeanValidationContext validation for ( Cascadable cascadable : validatable.getCascadables() ) { valueContext.appendNode( cascadable ); - ElementType elementType = cascadable.getElementType(); - if ( isCascadeRequired( validationContext, valueContext.getCurrentBean(), valueContext.getPropertyPath(), elementType ) ) { + if ( isCascadeRequired( validationContext, valueContext.getCurrentBean(), valueContext.getPropertyPath(), + cascadable.getConstraintLocationKind() ) ) { Object value = getCascadableValue( validationContext, valueContext.getCurrentBean(), cascadable ); CascadingMetaData cascadingMetaData = cascadable.getCascadingMetaData(); @@ -1283,12 +1283,13 @@ private boolean isValidationRequired(BaseBeanValidationContext validationCont validationContext, valueContext.getCurrentBean(), valueContext.getPropertyPath(), - metaConstraint.getConstraintLocationKind().getElementType() + metaConstraint.getConstraintLocationKind() ); } - private boolean isReachable(BaseBeanValidationContext validationContext, Object traversableObject, PathImpl path, ElementType type) { - if ( needToCallTraversableResolver( path, type ) ) { + private boolean isReachable(BaseBeanValidationContext validationContext, Object traversableObject, PathImpl path, + ConstraintLocationKind constraintLocationKind) { + if ( needToCallTraversableResolver( path, constraintLocationKind ) ) { return true; } @@ -1299,7 +1300,7 @@ private boolean isReachable(BaseBeanValidationContext validationContext, Obje path.getLeafNode(), validationContext.getRootBeanClass(), pathToObject, - type + constraintLocationKind.getElementType() ); } catch (RuntimeException e) { @@ -1307,23 +1308,24 @@ private boolean isReachable(BaseBeanValidationContext validationContext, Obje } } - private boolean needToCallTraversableResolver(PathImpl path, ElementType type) { + private boolean needToCallTraversableResolver(PathImpl path, ConstraintLocationKind constraintLocationKind) { // as the TraversableResolver interface is designed right now it does not make sense to call it when // there is no traversable object hosting the property to be accessed. For this reason we don't call the resolver // for class level constraints (ElementType.TYPE) or top level method parameters or return values. // see also BV expert group discussion - http://lists.jboss.org/pipermail/beanvalidation-dev/2013-January/000722.html - return isClassLevelConstraint( type ) + return isClassLevelConstraint( constraintLocationKind ) || isCrossParameterValidation( path ) || isParameterValidation( path ) || isReturnValueValidation( path ); } - private boolean isCascadeRequired(BaseBeanValidationContext validationContext, Object traversableObject, PathImpl path, ElementType type) { - if ( needToCallTraversableResolver( path, type ) ) { + private boolean isCascadeRequired(BaseBeanValidationContext validationContext, Object traversableObject, PathImpl path, + ConstraintLocationKind constraintLocationKind) { + if ( needToCallTraversableResolver( path, constraintLocationKind ) ) { return true; } - boolean isReachable = isReachable( validationContext, traversableObject, path, type ); + boolean isReachable = isReachable( validationContext, traversableObject, path, constraintLocationKind ); if ( !isReachable ) { return false; } @@ -1335,7 +1337,7 @@ private boolean isCascadeRequired(BaseBeanValidationContext validationContext path.getLeafNode(), validationContext.getRootBeanClass(), pathToObject, - type + constraintLocationKind.getElementType() ); } catch (RuntimeException e) { @@ -1343,8 +1345,8 @@ private boolean isCascadeRequired(BaseBeanValidationContext validationContext } } - private boolean isClassLevelConstraint(ElementType type) { - return ElementType.TYPE.equals( type ); + private boolean isClassLevelConstraint(ConstraintLocationKind constraintLocationKind) { + return ConstraintLocationKind.TYPE.equals( constraintLocationKind ); } private boolean isCrossParameterValidation(PathImpl path) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java index 88ba7f7d35..024b5419ec 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java @@ -6,7 +6,6 @@ */ package org.hibernate.validator.internal.engine; -import java.lang.annotation.ElementType; import java.lang.reflect.TypeVariable; import javax.validation.groups.Default; @@ -19,6 +18,7 @@ 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.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.TypeVariables; @@ -67,9 +67,9 @@ public class ValueContext { private final Validatable currentValidatable; /** - * The {@code ElementType} the constraint was defined on + * The {@code ConstraintLocationKind} the constraint was defined on */ - private ElementType elementType; + private ConstraintLocationKind constraintLocationKind; public static ValueContext getLocalExecutionContext(BeanMetaDataManager beanMetaDataManager, ExecutableParameterNameProvider parameterNameProvider, T value, Validatable validatable, PathImpl propertyPath) { @@ -199,12 +199,12 @@ public final boolean validatingDefault() { return getCurrentGroup() != null && getCurrentGroup().getName().equals( Default.class.getName() ); } - public final ElementType getElementType() { - return elementType; + public final ConstraintLocationKind getConstraintLocationKind() { + return constraintLocationKind; } - public final void setElementType(ElementType elementType) { - this.elementType = elementType; + public final void setConstraintLocationKind(ConstraintLocationKind constraintLocationKind) { + this.constraintLocationKind = constraintLocationKind; } public final ValueState getCurrentValueState() { @@ -225,7 +225,7 @@ public String toString() { sb.append( ", propertyPath=" ).append( propertyPath ); sb.append( ", currentGroup=" ).append( currentGroup ); sb.append( ", currentValue=" ).append( currentValue ); - sb.append( ", elementType=" ).append( elementType ); + sb.append( ", constraintLocationKind=" ).append( constraintLocationKind ); sb.append( '}' ); return sb.toString(); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/BeanValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/BeanValidationContext.java index 3aaee06783..3a6afdb698 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/BeanValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/BeanValidationContext.java @@ -61,7 +61,6 @@ protected ConstraintViolation createConstraintViolation( localContext.getCurrentValidatedValue(), propertyPath, constraintDescriptor, - localContext.getElementType(), constraintViolationCreationContext.getDynamicPayload() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/ParameterExecutableValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/ParameterExecutableValidationContext.java index c581746598..c7eaa48498 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/ParameterExecutableValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/ParameterExecutableValidationContext.java @@ -129,7 +129,6 @@ protected ConstraintViolation createConstraintViolation( valueContext.getCurrentValidatedValue(), propertyPath, constraintDescriptor, - valueContext.getElementType(), executableParameters, constraintViolationCreationContext.getDynamicPayload() ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java index 04e37dfecb..c16acc1deb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java @@ -94,7 +94,6 @@ protected ConstraintViolation createConstraintViolation( localContext.getCurrentValidatedValue(), propertyPath, constraintDescriptor, - localContext.getElementType(), constraintViolationCreationContext.getDynamicPayload() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/ReturnValueExecutableValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/ReturnValueExecutableValidationContext.java index 1c2455fa4d..da619edddc 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/ReturnValueExecutableValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/ReturnValueExecutableValidationContext.java @@ -101,7 +101,6 @@ protected ConstraintViolation createConstraintViolation(String messageTemplat valueContext.getCurrentValidatedValue(), propertyPath, constraintDescriptor, - valueContext.getElementType(), executableReturnValue, constraintViolationCreationContext.getDynamicPayload() ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java index 37d82ff6da..7021170530 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java @@ -6,10 +6,9 @@ */ package org.hibernate.validator.internal.metadata.aggregated; -import java.lang.annotation.ElementType; - import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.facets.Cascadable; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.properties.Property; /** @@ -25,8 +24,8 @@ public class FieldCascadable extends PropertyCascadable { } @Override - public ElementType getElementType() { - return ElementType.FIELD; + public ConstraintLocationKind getConstraintLocationKind() { + return ConstraintLocationKind.FIELD; } public static class Builder extends PropertyCascadable.Builder { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java index fbb379ab2e..b9e7e6bcae 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java @@ -6,10 +6,9 @@ */ package org.hibernate.validator.internal.metadata.aggregated; -import java.lang.annotation.ElementType; - import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.facets.Cascadable; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.properties.Property; /** @@ -25,8 +24,8 @@ public class GetterCascadable extends PropertyCascadable { } @Override - public ElementType getElementType() { - return ElementType.METHOD; + public ConstraintLocationKind getConstraintLocationKind() { + return ConstraintLocationKind.METHOD; } public static class Builder extends PropertyCascadable.Builder { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java index c40e659fb1..839d12f812 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java @@ -6,7 +6,6 @@ */ package org.hibernate.validator.internal.metadata.aggregated; -import java.lang.annotation.ElementType; import java.lang.reflect.Type; import java.util.List; import java.util.Set; @@ -20,6 +19,7 @@ import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.descriptor.ParameterDescriptorImpl; import org.hibernate.validator.internal.metadata.facets.Cascadable; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; @@ -64,8 +64,8 @@ public int getIndex() { } @Override - public ElementType getElementType() { - return ElementType.PARAMETER; + public ConstraintLocationKind getConstraintLocationKind() { + return ConstraintLocationKind.PARAMETER; } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java index 6e9062b131..aac44bf57f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java @@ -6,7 +6,6 @@ */ package org.hibernate.validator.internal.metadata.aggregated; -import java.lang.annotation.ElementType; import java.lang.reflect.Type; import java.util.Collections; import java.util.List; @@ -20,6 +19,7 @@ import org.hibernate.validator.internal.metadata.descriptor.ReturnValueDescriptorImpl; import org.hibernate.validator.internal.metadata.facets.Cascadable; import org.hibernate.validator.internal.metadata.facets.Validatable; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.util.stereotypes.Immutable; /** @@ -67,8 +67,8 @@ public boolean hasCascadables() { } @Override - public ElementType getElementType() { - return ElementType.METHOD; + public ConstraintLocationKind getConstraintLocationKind() { + return ConstraintLocationKind.METHOD; } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/MetaConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/MetaConstraint.java index 5fb3c1623b..de3a33005a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/MetaConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/MetaConstraint.java @@ -123,7 +123,7 @@ public boolean validateConstraint(ValidationContext validationContext, ValueC } private boolean doValidateConstraint(ValidationContext executionContext, ValueContext valueContext) { - valueContext.setElementType( getConstraintLocationKind().getElementType() ); + valueContext.setConstraintLocationKind( getConstraintLocationKind() ); boolean validationResult = constraintTree.validateConstraints( executionContext, valueContext ); return validationResult; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java index 692bb389c9..e8b69be279 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java @@ -129,7 +129,7 @@ public class ConstraintDescriptorImpl implements Constrain private final boolean isReportAsSingleInvalidConstraint; /** - * Describes on which level ({@code TYPE}, {@code METHOD}, {@code FIELD}) the constraint was + * Describes on which level ({@code TYPE}, {@code METHOD}, {@code FIELD}...) the constraint was * defined on. */ private final ConstraintLocationKind constraintLocationKind; @@ -165,12 +165,12 @@ public class ConstraintDescriptorImpl implements Constrain public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, - ConstraintLocationKind kind, + ConstraintLocationKind constraintLocationKind, Class implicitGroup, ConstraintOrigin definedOn, ConstraintType externalConstraintType) { this.annotationDescriptor = annotationDescriptor; - this.constraintLocationKind = kind; + this.constraintLocationKind = constraintLocationKind; this.definedOn = definedOn; this.isReportAsSingleInvalidConstraint = annotationDescriptor.getType().isAnnotationPresent( ReportAsSingleViolation.class @@ -227,16 +227,16 @@ public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, - ConstraintLocationKind kind) { - this( constraintHelper, constrainable, annotationDescriptor, kind, null, ConstraintOrigin.DEFINED_LOCALLY, null ); + ConstraintLocationKind constraintLocationKind) { + this( constraintHelper, constrainable, annotationDescriptor, constraintLocationKind, null, ConstraintOrigin.DEFINED_LOCALLY, null ); } public ConstraintDescriptorImpl(ConstraintHelper constraintHelper, Constrainable constrainable, ConstraintAnnotationDescriptor annotationDescriptor, - ConstraintLocationKind kind, + ConstraintLocationKind constraintLocationKind, ConstraintType constraintType) { - this( constraintHelper, constrainable, annotationDescriptor, kind, null, ConstraintOrigin.DEFINED_LOCALLY, constraintType ); + this( constraintHelper, constrainable, annotationDescriptor, constraintLocationKind, null, ConstraintOrigin.DEFINED_LOCALLY, constraintType ); } public ConstraintAnnotationDescriptor getAnnotationDescriptor() { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java index f63ed55c9b..fd5864a3d2 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java @@ -6,12 +6,12 @@ */ package org.hibernate.validator.internal.metadata.facets; -import java.lang.annotation.ElementType; import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaData; import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; /** * Provides a unified view on cascadable elements of all kinds, be it properties @@ -24,11 +24,11 @@ public interface Cascadable { /** - * Returns the element type of the cascadable. + * Returns the constraint location kind of the cascadable. * - * @return Returns the element type of the cascadable. + * @return Returns the constraint location kind of the cascadable. */ - ElementType getElementType(); + ConstraintLocationKind getConstraintLocationKind(); /** * Returns the data type of this cascadable, e.g. the type of a bean property or the From 418e01051875267ff7a8b381f4c7bc6b46c766ca Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 4 Jun 2018 12:17:19 +0200 Subject: [PATCH 11/24] HV-1623 Encapsulate ConstraintLocationKind inside ConstraintLocation --- .../cfg/context/ConfiguredConstraint.java | 40 ++++--------------- .../ConstraintMappingContextImplBase.java | 2 +- ...erElementConstraintMappingContextImpl.java | 2 +- .../location/BeanConstraintLocation.java | 6 +++ .../metadata/location/ConstraintLocation.java | 5 +++ .../CrossParameterConstraintLocation.java | 16 +++++++- .../FieldPropertyConstraintLocation.java | 5 +++ .../GetterPropertyConstraintLocation.java | 5 +++ .../location/ParameterConstraintLocation.java | 13 +++++- .../location/PropertyConstraintLocation.java | 1 + .../ReturnValueConstraintLocation.java | 14 ++++++- .../TypeArgumentConstraintLocation.java | 5 +++ 12 files changed, 76 insertions(+), 38 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java index 3b2cbfdb6a..3798389f52 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java @@ -19,8 +19,6 @@ import org.hibernate.validator.cfg.AnnotationDef; import org.hibernate.validator.cfg.ConstraintDef; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.util.annotation.AnnotationDescriptor; @@ -34,6 +32,7 @@ * related to its location (bean type etc.). * * @author Gunnar Morling + * @author Guillaume Smet */ class ConfiguredConstraint { @@ -44,49 +43,36 @@ class ConfiguredConstraint { private final ConstraintDef constraint; private final ConstraintLocation location; - private final ConstraintLocationKind kind; - private ConfiguredConstraint(ConstraintDef constraint, ConstraintLocation location, ConstraintLocationKind kind) { + private ConfiguredConstraint(ConstraintDef constraint, ConstraintLocation location) { this.constraint = constraint; this.location = location; - this.kind = kind; } static ConfiguredConstraint forType(ConstraintDef constraint, Class beanType) { - return new ConfiguredConstraint<>( constraint, ConstraintLocation.forClass( beanType ), ConstraintLocationKind.TYPE ); + return new ConfiguredConstraint<>( constraint, ConstraintLocation.forClass( beanType ) ); } static ConfiguredConstraint forFieldProperty(ConstraintDef constraint, JavaBeanField javaBeanField) { - return new ConfiguredConstraint<>( - constraint, - ConstraintLocation.forField( javaBeanField ), - ConstraintLocationKind.FIELD - ); + return new ConfiguredConstraint<>( constraint, ConstraintLocation.forField( javaBeanField ) ); } public static ConfiguredConstraint forParameter(ConstraintDef constraint, Callable callable, int parameterIndex) { - return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forParameter( callable, parameterIndex ), getConstraintLocationKindFromCallable( callable ) - ); + return new ConfiguredConstraint<>( constraint, ConstraintLocation.forParameter( callable, parameterIndex ) ); } public static ConfiguredConstraint forExecutable(ConstraintDef constraint, Callable callable) { - return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forReturnValue( callable ), getConstraintLocationKindFromCallable( callable ) - ); + return new ConfiguredConstraint<>( constraint, ConstraintLocation.forReturnValue( callable ) ); } public static ConfiguredConstraint forCrossParameter(ConstraintDef constraint, Callable callable) { - return new ConfiguredConstraint<>( - constraint, ConstraintLocation.forCrossParameter( callable ), getConstraintLocationKindFromCallable( callable ) - ); + return new ConfiguredConstraint<>( constraint, ConstraintLocation.forCrossParameter( callable ) ); } public static ConfiguredConstraint forTypeArgument(ConstraintDef constraint, ConstraintLocation delegate, TypeVariable typeArgument, Type typeOfAnnotatedElement) { return new ConfiguredConstraint<>( constraint, - ConstraintLocation.forTypeArgument( delegate, typeArgument, typeOfAnnotatedElement ), - ConstraintLocationKind.TYPE_USE + ConstraintLocation.forTypeArgument( delegate, typeArgument, typeOfAnnotatedElement ) ); } @@ -116,16 +102,6 @@ public String toString() { return constraint.toString(); } - public ConstraintLocationKind getConstraintLocationKind() { - return kind; - } - - private static ConstraintLocationKind getConstraintLocationKindFromCallable(Callable callable) { - return callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR - ? ConstraintLocationKind.CONSTRUCTOR - : ConstraintLocationKind.METHOD; - } - /** * Runs the given privileged action, using a privileged block if required. * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java index ed8582e4c7..3598e1d70f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstraintMappingContextImplBase.java @@ -75,7 +75,7 @@ private MetaConstraint asMetaConstraint(ConfiguredCons constraintHelper, config.getLocation().getConstrainable(), config.createAnnotationDescriptor(), - config.getConstraintLocationKind(), + config.getLocation().getKind(), getConstraintType() ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java index e9e05526a7..2b5f20f630 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java @@ -239,7 +239,7 @@ private MetaConstraint asMetaConstraint(ConfiguredCons constraintHelper, config.getLocation().getConstrainable(), config.createAnnotationDescriptor(), - config.getConstraintLocationKind(), + config.getLocation().getKind(), getConstraintType() ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/BeanConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/BeanConstraintLocation.java index d6d8f3a0ab..0ff0fd218f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/BeanConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/BeanConstraintLocation.java @@ -18,6 +18,7 @@ * * @author Hardy Ferentschik * @author Gunnar Morling + * @author Guillaume Smet */ class BeanConstraintLocation implements ConstraintLocation { @@ -66,6 +67,11 @@ public Object getValue(Object parent) { return parent; } + @Override + public ConstraintLocationKind getKind() { + return ConstraintLocationKind.TYPE; + } + @Override public String toString() { return "BeanConstraintLocation [declaringClass=" + declaringClass + ", typeForValidatorResolution=" + typeForValidatorResolution + "]"; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index 6e97299d98..d8197f5560 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -97,6 +97,11 @@ static ConstraintLocation forParameter(Callable callable, int index) { */ Object getValue(Object parent); + /** + * Returns the nature of the constraint location. + */ + ConstraintLocationKind getKind(); + enum ConstraintLocationKind { TYPE( ElementType.TYPE ), CONSTRUCTOR( ElementType.CONSTRUCTOR ), diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java index 549ab73e1e..04ef4d100e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java @@ -9,6 +9,7 @@ import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -18,13 +19,19 @@ * * @author Hardy Ferentschik * @author Gunnar Morling + * @author Guillaume Smet */ class CrossParameterConstraintLocation implements ConstraintLocation { private final Callable callable; - CrossParameterConstraintLocation(Callable executable) { - this.callable = executable; + private final ConstraintLocationKind kind; + + CrossParameterConstraintLocation(Callable callable) { + this.callable = callable; + this.kind = callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR + ? ConstraintLocationKind.CONSTRUCTOR + : ConstraintLocationKind.METHOD; } @Override @@ -52,6 +59,11 @@ public Object getValue(Object parent) { return parent; } + @Override + public ConstraintLocationKind getKind() { + return kind; + } + @Override public String toString() { return "CrossParameterConstraintLocation [callable=" + callable + "]"; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java index 2cdb6840cc..4687132dea 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java @@ -18,4 +18,9 @@ public class FieldPropertyConstraintLocation extends PropertyConstraintLocation< FieldPropertyConstraintLocation(JavaBeanField javaBeanGetter) { super( javaBeanGetter ); } + + @Override + public ConstraintLocationKind getKind() { + return ConstraintLocationKind.FIELD; + } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java index 2d450be8bf..12e2b42bab 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java @@ -18,4 +18,9 @@ public class GetterPropertyConstraintLocation extends PropertyConstraintLocation GetterPropertyConstraintLocation(JavaBeanGetter javaBeanGetter) { super( javaBeanGetter ); } + + @Override + public ConstraintLocationKind getKind() { + return ConstraintLocationKind.METHOD; + } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java index f7ee26cac0..a732e556aa 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java @@ -9,6 +9,7 @@ import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -19,17 +20,22 @@ * * @author Hardy Ferentschik * @author Gunnar Morling + * @author Guillaume Smet */ public class ParameterConstraintLocation implements ConstraintLocation { private final Callable callable; private final int index; private final Type typeForValidatorResolution; + private final ConstraintLocationKind kind; public ParameterConstraintLocation(Callable callable, int index) { this.callable = callable; this.index = index; this.typeForValidatorResolution = ReflectionHelper.boxedType( callable.getParameterGenericType( index ) ); + this.kind = callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR + ? ConstraintLocationKind.CONSTRUCTOR + : ConstraintLocationKind.METHOD; } @Override @@ -61,9 +67,14 @@ public Object getValue(Object parent) { return ( (Object[]) parent )[index]; } + @Override + public ConstraintLocationKind getKind() { + return kind; + } + @Override public String toString() { - return "ParameterConstraintLocation [executable=" + callable + ", index=" + index + "]"; + return "ParameterConstraintLocation [callable=" + callable + ", index=" + index + "]"; } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java index b64181c185..a9f0f17b64 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java @@ -16,6 +16,7 @@ * An abstract property constraint location. * * @author Marko Bekhta + * @author Guillaume Smet */ public abstract class PropertyConstraintLocation implements ConstraintLocation { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java index 30c66c5889..9203e4a9d5 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java @@ -9,6 +9,7 @@ import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -19,13 +20,19 @@ * @author Hardy Ferentschik * @author Gunnar Morling * @author Marko Bekhta + * @author Guillaume Smet */ class ReturnValueConstraintLocation implements ConstraintLocation { private final Callable callable; + private final ConstraintLocationKind kind; + ReturnValueConstraintLocation(Callable callable) { this.callable = callable; + this.kind = callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR + ? ConstraintLocationKind.CONSTRUCTOR + : ConstraintLocationKind.METHOD; } @Override @@ -53,9 +60,14 @@ public Object getValue(Object parent) { return parent; } + @Override + public ConstraintLocationKind getKind() { + return kind; + } + @Override public String toString() { - return "ReturnValueConstraintLocation [executable=" + callable + "]"; + return "ReturnValueConstraintLocation [callable=" + callable + "]"; } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/TypeArgumentConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/TypeArgumentConstraintLocation.java index d470c8c8bd..0f82da3644 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/TypeArgumentConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/TypeArgumentConstraintLocation.java @@ -87,6 +87,11 @@ public ConstraintLocation getOuterDelegate() { return outerDelegate; } + @Override + public ConstraintLocationKind getKind() { + return ConstraintLocationKind.TYPE_USE; + } + @Override public String toString() { return "TypeArgumentValueConstraintLocation [typeForValidatorResolution=" + StringHelper.toShortString( typeForValidatorResolution ) From 8bb498e600d819563aabbddc657bec49defa9d9b Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Tue, 5 Jun 2018 00:02:51 +0200 Subject: [PATCH 12/24] HV-1623 Extract class-level metadata from property metadata case --- .../metadata/aggregated/BeanMetaDataImpl.java | 21 ++-- .../metadata/aggregated/ClassMetaData.java | 111 ++++++++++++++++++ .../metadata/aggregated/PropertyMetaData.java | 11 -- .../descriptor/ClassDescriptorImpl.java | 37 ++++++ .../provider/AnnotationMetaDataProvider.java | 2 - 5 files changed, 160 insertions(+), 22 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ClassMetaData.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ClassDescriptorImpl.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java index 331c116a1e..cfb93a43e3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java @@ -196,6 +196,7 @@ public BeanMetaDataImpl(Class beanClass, Set tmpUnconstrainedExecutables = newHashSet(); boolean hasConstraints = false; + Set> allMetaConstraints = newHashSet(); for ( ConstraintMetaData constraintMetaData : constraintMetaDataSet ) { boolean elementHasConstraints = constraintMetaData.isCascading() || constraintMetaData.isConstrained(); @@ -204,6 +205,9 @@ public BeanMetaDataImpl(Class beanClass, if ( constraintMetaData.getKind() == ElementKind.PROPERTY ) { propertyMetaDataSet.add( (PropertyMetaData) constraintMetaData ); } + else if ( constraintMetaData.getKind() == ElementKind.BEAN ) { + allMetaConstraints.addAll( ( (ClassMetaData) constraintMetaData ).getAllConstraints() ); + } else { ExecutableMetaData executableMetaData = (ExecutableMetaData) constraintMetaData; if ( elementHasConstraints ) { @@ -216,7 +220,6 @@ public BeanMetaDataImpl(Class beanClass, } Set cascadedProperties = newHashSet(); - Set> allMetaConstraints = newHashSet(); for ( PropertyMetaData propertyMetaData : propertyMetaDataSet ) { propertyMetaDataMap.put( propertyMetaData.getName(), propertyMetaData ); @@ -696,7 +699,7 @@ private static class BuilderDelegate { private final TypeResolutionHelper typeResolutionHelper; private final ValueExtractorManager valueExtractorManager; private final ExecutableParameterNameProvider parameterNameProvider; - private MetaDataBuilder propertyBuilder; + private MetaDataBuilder metaDataBuilder; private ExecutableMetaData.Builder methodBuilder; private final MethodValidationConfiguration methodValidationConfiguration; private final int hashCode; @@ -723,7 +726,7 @@ public BuilderDelegate( switch ( constrainedElement.getKind() ) { case FIELD: ConstrainedField constrainedField = (ConstrainedField) constrainedElement; - propertyBuilder = new PropertyMetaData.Builder( + metaDataBuilder = new PropertyMetaData.Builder( beanClass, constrainedField, constraintHelper, @@ -752,7 +755,7 @@ public BuilderDelegate( } if ( constrainedExecutable.isGetterMethod() ) { - propertyBuilder = new PropertyMetaData.Builder( + metaDataBuilder = new PropertyMetaData.Builder( beanClass, constrainedExecutable, constraintHelper, @@ -763,7 +766,7 @@ public BuilderDelegate( break; case TYPE: ConstrainedType constrainedType = (ConstrainedType) constrainedElement; - propertyBuilder = new PropertyMetaData.Builder( + metaDataBuilder = new ClassMetaData.Builder( beanClass, constrainedType, constraintHelper, @@ -784,8 +787,8 @@ public boolean add(ConstrainedElement constrainedElement) { added = true; } - if ( propertyBuilder != null && propertyBuilder.accepts( constrainedElement ) ) { - propertyBuilder.add( constrainedElement ); + if ( metaDataBuilder != null && metaDataBuilder.accepts( constrainedElement ) ) { + metaDataBuilder.add( constrainedElement ); if ( !added && constrainedElement.getKind() == ConstrainedElementKind.METHOD && methodBuilder == null ) { ConstrainedExecutable constrainedMethod = (ConstrainedExecutable) constrainedElement; @@ -810,8 +813,8 @@ public boolean add(ConstrainedElement constrainedElement) { public Set build() { Set metaDataSet = newHashSet(); - if ( propertyBuilder != null ) { - metaDataSet.add( propertyBuilder.build() ); + if ( metaDataBuilder != null ) { + metaDataSet.add( metaDataBuilder.build() ); } if ( methodBuilder != null ) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ClassMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ClassMetaData.java new file mode 100644 index 0000000000..b6ea598143 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ClassMetaData.java @@ -0,0 +1,111 @@ +/* + * 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.metadata.aggregated; + +import java.util.List; +import java.util.Set; + +import javax.validation.ElementKind; + +import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; +import org.hibernate.validator.internal.metadata.core.ConstraintHelper; +import org.hibernate.validator.internal.metadata.core.MetaConstraint; +import org.hibernate.validator.internal.metadata.descriptor.ClassDescriptorImpl; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; +import org.hibernate.validator.internal.metadata.raw.ConstrainedType; +import org.hibernate.validator.internal.util.TypeResolutionHelper; + +/** + * Represents the constraint related meta data for a type i.e. class-level + * constraints. + * + * @author Gunnar Morling + * @author Guillaume Smet + * @author Marko Bekhta + */ +public class ClassMetaData extends AbstractConstraintMetaData { + + private ClassMetaData(Class beanClass, + Set> constraints, + Set> containerElementsConstraints) { + super( + beanClass.getSimpleName(), + beanClass, + constraints, + containerElementsConstraints, + false, + !constraints.isEmpty() || !containerElementsConstraints.isEmpty() + ); + } + + @Override + public ClassDescriptorImpl asDescriptor(boolean defaultGroupSequenceRedefined, List> defaultGroupSequence) { + return new ClassDescriptorImpl( + getType(), + asDescriptors( getDirectConstraints() ), + defaultGroupSequenceRedefined, + defaultGroupSequence + ); + } + + @Override + public String toString() { + return "ClassLevelMetaData [type=" + getType() + "]]"; + } + + @Override + public ElementKind getKind() { + return ElementKind.BEAN; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( !super.equals( obj ) ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + return true; + } + + public static class Builder extends MetaDataBuilder { + public Builder(Class beanClass, ConstrainedType constrainedType, ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, + ValueExtractorManager valueExtractorManager) { + super( beanClass, constraintHelper, typeResolutionHelper, valueExtractorManager ); + + add( constrainedType ); + } + + @Override + public boolean accepts(ConstrainedElement constrainedElement) { + return constrainedElement.getKind() == ConstrainedElement.ConstrainedElementKind.TYPE; + } + + @Override + public final void add(ConstrainedElement constrainedElement) { + super.add( constrainedElement ); + } + + @Override + public ClassMetaData build() { + return new ClassMetaData( + getBeanClass(), + adaptOriginsAndImplicitGroups( getDirectConstraints() ), + adaptOriginsAndImplicitGroups( getContainerElementConstraints() ) + ); + } + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 8150ea009b..f87e1c9b55 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -35,7 +35,6 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; -import org.hibernate.validator.internal.metadata.raw.ConstrainedType; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; @@ -151,7 +150,6 @@ public boolean equals(Object obj) { public static class Builder extends MetaDataBuilder { private static final EnumSet SUPPORTED_ELEMENT_KINDS = EnumSet.of( - ConstrainedElementKind.TYPE, ConstrainedElementKind.FIELD, ConstrainedElementKind.METHOD ); @@ -169,15 +167,6 @@ public Builder(Class beanClass, ConstrainedField constrainedProperty, Constra add( constrainedProperty ); } - public Builder(Class beanClass, ConstrainedType constrainedType, ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, - ValueExtractorManager valueExtractorManager) { - super( beanClass, constraintHelper, typeResolutionHelper, valueExtractorManager ); - - this.propertyName = null; - this.propertyType = null; - add( constrainedType ); - } - public Builder(Class beanClass, ConstrainedExecutable constrainedMethod, ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { super( beanClass, constraintHelper, typeResolutionHelper, valueExtractorManager ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ClassDescriptorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ClassDescriptorImpl.java new file mode 100644 index 0000000000..0d1f0017b4 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ClassDescriptorImpl.java @@ -0,0 +1,37 @@ +/* + * 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.metadata.descriptor; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Set; + +import javax.validation.metadata.ElementDescriptor; + +/** + * Describes a validated type class-level constraints. + * + * @author Marko Bekhta + */ +public class ClassDescriptorImpl extends ElementDescriptorImpl implements ElementDescriptor { + + public ClassDescriptorImpl(Type beanType, + Set> constraints, + boolean defaultGroupSequenceRedefined, + List> defaultGroupSequence) { + super( beanType, constraints, defaultGroupSequenceRedefined, defaultGroupSequence ); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append( getClass().getSimpleName() ); + sb.append( "{beanType=" ).append( getElementClass() ); + sb.append( '}' ); + return sb.toString(); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index ad4b3d408f..4afaa5e2fe 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -136,8 +136,6 @@ private BeanConfiguration retrieveBeanConfiguration(Class beanClass) { constrainedElements.addAll( getMethodMetaData( beanClass ) ); constrainedElements.addAll( getConstructorMetaData( beanClass ) ); - //TODO GM: currently class level constraints are represented by a PropertyMetaData. This - //works but seems somewhat unnatural Set> classLevelConstraints = getClassLevelConstraints( beanClass ); if ( !classLevelConstraints.isEmpty() ) { ConstrainedType classLevelMetaData = From cace416a5e74dc1f944c10efdeb823389307d2a0 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Tue, 5 Jun 2018 21:10:21 +0200 Subject: [PATCH 13/24] HV-1623 Create different programmatic mapping contexts for getter and field - create different implementations of PropertyConstraintMappingContextImpl for getter and field to separate the logic. --- ...dPropertyConstraintMappingContextImpl.java | 58 +++++++++++++ ...rPropertyConstraintMappingContextImpl.java | 52 ++++++++++++ .../PropertyConstraintMappingContextImpl.java | 83 ++++++++----------- .../TypeConstraintMappingContextImpl.java | 14 ++-- .../validator/internal/util/logging/Log.java | 3 + 5 files changed, 151 insertions(+), 59 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldPropertyConstraintMappingContextImpl.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterPropertyConstraintMappingContextImpl.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldPropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldPropertyConstraintMappingContextImpl.java new file mode 100644 index 0000000000..417d963c2d --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldPropertyConstraintMappingContextImpl.java @@ -0,0 +1,58 @@ +/* + * 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.cfg.context; + +import org.hibernate.validator.cfg.ConstraintDef; +import org.hibernate.validator.cfg.context.PropertyConstraintMappingContext; +import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; +import org.hibernate.validator.internal.metadata.core.ConstraintHelper; +import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; +import org.hibernate.validator.internal.metadata.raw.ConstrainedField; +import org.hibernate.validator.internal.properties.javabean.JavaBeanField; +import org.hibernate.validator.internal.util.TypeResolutionHelper; + +/** + * An implementation of {@link PropertyConstraintMappingContextImpl} for a field property. + * Represents a constraint mapping creational context which allows to configure the constraints + * for one of the bean's field properties. + * + * @author Marko Bekhta + */ +final class FieldPropertyConstraintMappingContextImpl extends PropertyConstraintMappingContextImpl { + + FieldPropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanField javaBeanField) { + super( typeContext, javaBeanField, ConstraintLocation.forField( javaBeanField ) ); + } + + @Override + public PropertyConstraintMappingContext constraint(ConstraintDef definition) { + super.addConstraint( + ConfiguredConstraint.forFieldProperty( + definition, getProperty() + ) + ); + return this; + } + + ConstrainedElement build(ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { + return new ConstrainedField( + ConfigurationSource.API, + getProperty(), + getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), + getTypeArgumentConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), + getCascadingMetaDataBuilder() + ); + } + + @Override + protected ConstraintType getConstraintType() { + return ConstraintType.GENERIC; + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterPropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterPropertyConstraintMappingContextImpl.java new file mode 100644 index 0000000000..1bfc8a1389 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterPropertyConstraintMappingContextImpl.java @@ -0,0 +1,52 @@ +/* + * 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.cfg.context; + +import org.hibernate.validator.cfg.ConstraintDef; +import org.hibernate.validator.cfg.context.PropertyConstraintMappingContext; +import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; +import org.hibernate.validator.internal.metadata.core.ConstraintHelper; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; +import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; +import org.hibernate.validator.internal.util.TypeResolutionHelper; + +/** + * An implementation of {@link PropertyConstraintMappingContextImpl} for a getter property. + * Represents a constraint mapping creational context which allows to configure the constraints + * for one of the bean's getter properties. + * + * @author Marko Bekhta + */ +final class GetterPropertyConstraintMappingContextImpl extends PropertyConstraintMappingContextImpl { + + GetterPropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanGetter javaBeanGetter) { + super( typeContext, javaBeanGetter, ConstraintLocation.forGetter( javaBeanGetter ) ); + } + + @Override + public PropertyConstraintMappingContext constraint(ConstraintDef definition) { + super.addConstraint( + ConfiguredConstraint.forExecutable( + definition, getProperty() + ) + ); + return this; + } + + ConstrainedElement build(ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { + return new ConstrainedExecutable( + ConfigurationSource.API, + getProperty(), + getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), + getTypeArgumentConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), + getCascadingMetaDataBuilder() + ); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java index 7443605991..64001f2709 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java @@ -7,8 +7,8 @@ package org.hibernate.validator.internal.cfg.context; import java.lang.annotation.ElementType; +import java.lang.invoke.MethodHandles; -import org.hibernate.validator.cfg.ConstraintDef; import org.hibernate.validator.cfg.context.ConstructorConstraintMappingContext; import org.hibernate.validator.cfg.context.ContainerElementConstraintMappingContext; import org.hibernate.validator.cfg.context.MethodConstraintMappingContext; @@ -17,15 +17,13 @@ import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; -import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; -import org.hibernate.validator.internal.metadata.raw.ConstrainedField; -import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.TypeResolutionHelper; +import org.hibernate.validator.internal.util.logging.Log; +import org.hibernate.validator.internal.util.logging.LoggerFactory; /** * Constraint mapping creational context which allows to configure the constraints for one bean property. @@ -33,24 +31,43 @@ * @author Hardy Ferentschik * @author Gunnar Morling * @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI + * @author Marko Bekhta */ -final class PropertyConstraintMappingContextImpl +abstract class PropertyConstraintMappingContextImpl extends CascadableConstraintMappingContextImplBase implements PropertyConstraintMappingContext { + private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() ); + private final TypeConstraintMappingContextImpl typeContext; // either Field or Method - private final Property property; + private final T property; private final ConstraintLocation location; - PropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Property property) { + static PropertyConstraintMappingContextImpl context(ElementType elementType, TypeConstraintMappingContextImpl typeContext, Property property) { + if ( elementType == ElementType.FIELD ) { + return new FieldPropertyConstraintMappingContextImpl( + typeContext, + property.as( JavaBeanField.class ) + ); + } + else if ( elementType == ElementType.METHOD ) { + return new GetterPropertyConstraintMappingContextImpl( + typeContext, + property.as( JavaBeanGetter.class ) + ); + } + else { + throw LOG.getUnexpectedElementType( elementType, ElementType.FIELD, ElementType.METHOD ); + } + } + + protected PropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, T property, ConstraintLocation location) { super( typeContext.getConstraintMapping(), property.getType() ); this.typeContext = typeContext; this.property = property; - this.location = property instanceof JavaBeanField - ? ConstraintLocation.forField( property.as( JavaBeanField.class ) ) - : ConstraintLocation.forGetter( property.as( JavaBeanGetter.class ) ); + this.location = location; } @Override @@ -58,25 +75,6 @@ protected PropertyConstraintMappingContextImpl getThis() { return this; } - @Override - public PropertyConstraintMappingContext constraint(ConstraintDef definition) { - if ( property instanceof JavaBeanField ) { - super.addConstraint( - ConfiguredConstraint.forFieldProperty( - definition, property.as( JavaBeanField.class ) - ) - ); - } - else { - super.addConstraint( - ConfiguredConstraint.forExecutable( - definition, property.as( Callable.class ) - ) - ); - } - return this; - } - @Override public PropertyConstraintMappingContext ignoreAnnotations() { return ignoreAnnotations( true ); @@ -113,29 +111,14 @@ public ContainerElementConstraintMappingContext containerElementType(int index, return super.containerElement( this, typeContext, location, index, nestedIndexes ); } - ConstrainedElement build(ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager) { - if ( property instanceof JavaBeanField ) { - return new ConstrainedField( - ConfigurationSource.API, - property, - getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), - getTypeArgumentConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), - getCascadingMetaDataBuilder() - ); - } - else { - return new ConstrainedExecutable( - ConfigurationSource.API, - property.as( Callable.class ), - getConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), - getTypeArgumentConstraints( constraintHelper, typeResolutionHelper, valueExtractorManager ), - getCascadingMetaDataBuilder() - ); - } - } + abstract ConstrainedElement build(ConstraintHelper constraintHelper, TypeResolutionHelper typeResolutionHelper, ValueExtractorManager valueExtractorManager); @Override protected ConstraintType getConstraintType() { return ConstraintType.GENERIC; } + + protected T getProperty() { + return property; + } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index 13fa7bd741..e2b1ff288e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -122,24 +122,20 @@ public PropertyConstraintMappingContext property(String property, ElementType el Contracts.assertNotNull( elementType, "The element type must not be null." ); Contracts.assertNotEmpty( property, MESSAGES.propertyNameMustNotBeEmpty() ); - Property member = getProperty( + Property foundProperty = getProperty( beanClass, property, elementType ); - if ( member == null || member.getDeclaringClass() != beanClass ) { + if ( foundProperty == null || foundProperty.getDeclaringClass() != beanClass ) { throw LOG.getUnableToFindPropertyWithAccessException( beanClass, property, elementType ); } - if ( configuredMembers.contains( member ) ) { + if ( configuredMembers.contains( foundProperty ) ) { throw LOG.getPropertyHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, property ); } - PropertyConstraintMappingContextImpl context = new PropertyConstraintMappingContextImpl( - this, - member - ); - - configuredMembers.add( member ); + PropertyConstraintMappingContextImpl context = PropertyConstraintMappingContextImpl.context( elementType, this, foundProperty ); + configuredMembers.add( foundProperty ); propertyContexts.add( context ); return context; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index 18a6f24df3..4267ee49e0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -860,4 +860,7 @@ ConstraintDefinitionException getConstraintValidatorDefinitionConstraintMismatch @Message(id = 244, value = "ConstrainedElement expected class was %1$s, but instead received %2$s.") AssertionError getUnexpectedConstraintElementType(@FormatWith(ClassObjectFormatter.class) Class expecting, @FormatWith(ClassObjectFormatter.class) Class got); + + @Message(id = 245, value = "Allowed ElementTypes are %2$s, but instead received %1$s.") + AssertionError getUnexpectedElementType(ElementType received, @FormatWith(ObjectArrayFormatter.class) ElementType... got); } From 34e9db95cedfdf02cb7d6940eaa8642f6cb8e263 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 6 Jun 2018 00:04:06 +0200 Subject: [PATCH 14/24] HV-1623 Make parameters more specific in programmatic API executable mapping contexts --- .../ConstructorConstraintMappingContextImpl.java | 4 ++-- .../context/MethodConstraintMappingContextImpl.java | 4 ++-- .../cfg/context/TypeConstraintMappingContextImpl.java | 9 +++++---- .../properties/javabean/JavaBeanExecutable.java | 10 +++++++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstructorConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstructorConstraintMappingContextImpl.java index 2b71b966a4..f062f38ab0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstructorConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConstructorConstraintMappingContextImpl.java @@ -7,7 +7,7 @@ package org.hibernate.validator.internal.cfg.context; import org.hibernate.validator.cfg.context.ConstructorConstraintMappingContext; -import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanConstructor; /** * Constraint mapping creational context representing a constructor. @@ -16,7 +16,7 @@ */ class ConstructorConstraintMappingContextImpl extends ExecutableConstraintMappingContextImpl implements ConstructorConstraintMappingContext { - ConstructorConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Callable constructor) { + ConstructorConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanConstructor constructor) { super( typeContext, constructor ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/MethodConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/MethodConstraintMappingContextImpl.java index 19e74b27db..7e8ae93bbe 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/MethodConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/MethodConstraintMappingContextImpl.java @@ -7,7 +7,7 @@ package org.hibernate.validator.internal.cfg.context; import org.hibernate.validator.cfg.context.MethodConstraintMappingContext; -import org.hibernate.validator.internal.properties.Callable; +import org.hibernate.validator.internal.properties.javabean.JavaBeanMethod; /** * Constraint mapping creational context representing a method. @@ -16,7 +16,7 @@ */ class MethodConstraintMappingContextImpl extends ExecutableConstraintMappingContextImpl implements MethodConstraintMappingContext { - MethodConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, Callable callable) { + MethodConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanMethod callable) { super( typeContext, callable ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index e2b1ff288e..2c05aed768 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -39,6 +39,7 @@ import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; +import org.hibernate.validator.internal.properties.javabean.JavaBeanMethod; import org.hibernate.validator.internal.util.Contracts; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ReflectionHelper; @@ -150,17 +151,17 @@ public MethodConstraintMappingContext method(String name, Class... parameterT throw LOG.getBeanDoesNotContainMethodException( beanClass, name, parameterTypes ); } - JavaBeanExecutable javaBeanExecutable = JavaBeanExecutable.of( method ); + JavaBeanMethod javaBeanMethod = JavaBeanExecutable.of( method ); - if ( configuredMembers.contains( javaBeanExecutable ) ) { + if ( configuredMembers.contains( javaBeanMethod ) ) { throw LOG.getMethodHasAlreadyBeenConfiguredViaProgrammaticApiException( beanClass, ExecutableHelper.getExecutableAsString( name, parameterTypes ) ); } - MethodConstraintMappingContextImpl context = new MethodConstraintMappingContextImpl( this, javaBeanExecutable ); - configuredMembers.add( javaBeanExecutable ); + MethodConstraintMappingContextImpl context = new MethodConstraintMappingContextImpl( this, javaBeanMethod ); + configuredMembers.add( javaBeanMethod ); executableContexts.add( context ); return context; diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java index 1d69c8e629..25e181ba23 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java @@ -69,11 +69,15 @@ public static JavaBeanExecutable of(Executable executable) { return new JavaBeanConstructor( (Constructor) executable ); } - if ( ReflectionHelper.isGetterMethod( executable ) ) { - return new JavaBeanGetter( (Method) executable ); + return of( ( (Method) executable ) ); + } + + public static JavaBeanMethod of(Method method) { + if ( ReflectionHelper.isGetterMethod( method ) ) { + return new JavaBeanGetter( method ); } - return new JavaBeanMethod( (Method) executable ); + return new JavaBeanMethod( method ); } @Override From cd64f2525b924135786f3ed190327f2afffe83bd Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 6 Jun 2018 23:43:30 +0200 Subject: [PATCH 15/24] HV-1623 Deprecate property() in programmatic API and introduce field() and getter() instead - add two new methods field() and getter() to replace deprecated property() - update property constraint mapping implementations to use generics and get rid of casting objects --- .../validator/cfg/context/PropertyTarget.java | 35 ++++++- ...erElementConstraintMappingContextImpl.java | 10 ++ .../PropertyConstraintMappingContextImpl.java | 35 ++----- .../TypeConstraintMappingContextImpl.java | 95 +++++++++++-------- .../test/cfg/ConstraintMappingTest.java | 23 +++++ 5 files changed, 132 insertions(+), 66 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/cfg/context/PropertyTarget.java b/engine/src/main/java/org/hibernate/validator/cfg/context/PropertyTarget.java index 3fae3760fa..3546ce6dd0 100644 --- a/engine/src/main/java/org/hibernate/validator/cfg/context/PropertyTarget.java +++ b/engine/src/main/java/org/hibernate/validator/cfg/context/PropertyTarget.java @@ -21,15 +21,46 @@ public interface PropertyTarget { *

* Until this method is called constraints apply on class level. After calling this method constraints * apply on the specified property with the given access type. - *

*

* A given property may only be configured once. - *

* * @param property The property on which to apply the following constraints (Java Bean notation). * @param type The access type (field/property). * * @return A creational context representing the selected property. + * + * @deprecated Since 6.1. Planned for removal. Use either {@link PropertyTarget#field(String)} or + * {@link PropertyTarget#getter(String)} instead. */ + @Deprecated PropertyConstraintMappingContext property(String property, ElementType type); + + /** + * Selects a field to which the next operations shall apply. + *

+ * Until this method is called constraints apply on class level. After calling this method constraints + * apply on the specified field property. + *

+ * A given field may only be configured once. + * + * @param property The field name that represents a property on which to apply the following constraints. + * + * @return A creational context representing the selected field property. + */ + PropertyConstraintMappingContext field(String property); + + /** + * Selects a getter to which the next operations shall apply. + *

+ * Until this method is called constraints apply on class level. After calling this method constraints + * apply on the specified getter property. + *

+ * A given getter may only be configured once. + * + * @param property The getter property name (using the Java Bean notation, e.g. {@code name} to address {@code getName()}) + * that represents a property on which to apply the following constraints. + * + * @return A creational context representing the selected getter property. + */ + PropertyConstraintMappingContext getter(String property); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java index 2b5f20f630..e3eb9f3338 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ContainerElementConstraintMappingContextImpl.java @@ -123,6 +123,16 @@ public PropertyConstraintMappingContext property(String property, ElementType el return typeContext.property( property, elementType ); } + @Override + public PropertyConstraintMappingContext field(String property) { + return typeContext.field( property ); + } + + @Override + public PropertyConstraintMappingContext getter(String property) { + return typeContext.getter( property ); + } + @Override public ConstructorConstraintMappingContext constructor(Class... parameterTypes) { return typeContext.constructor( parameterTypes ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java index 64001f2709..61f65e2fd7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java @@ -7,7 +7,6 @@ package org.hibernate.validator.internal.cfg.context; import java.lang.annotation.ElementType; -import java.lang.invoke.MethodHandles; import org.hibernate.validator.cfg.context.ConstructorConstraintMappingContext; import org.hibernate.validator.cfg.context.ContainerElementConstraintMappingContext; @@ -19,11 +18,7 @@ import org.hibernate.validator.internal.metadata.location.ConstraintLocation; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.properties.Property; -import org.hibernate.validator.internal.properties.javabean.JavaBeanField; -import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.TypeResolutionHelper; -import org.hibernate.validator.internal.util.logging.Log; -import org.hibernate.validator.internal.util.logging.LoggerFactory; /** * Constraint mapping creational context which allows to configure the constraints for one bean property. @@ -37,32 +32,12 @@ abstract class PropertyConstraintMappingContextImpl extends CascadableConstraintMappingContextImplBase implements PropertyConstraintMappingContext { - private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() ); - private final TypeConstraintMappingContextImpl typeContext; // either Field or Method private final T property; private final ConstraintLocation location; - static PropertyConstraintMappingContextImpl context(ElementType elementType, TypeConstraintMappingContextImpl typeContext, Property property) { - if ( elementType == ElementType.FIELD ) { - return new FieldPropertyConstraintMappingContextImpl( - typeContext, - property.as( JavaBeanField.class ) - ); - } - else if ( elementType == ElementType.METHOD ) { - return new GetterPropertyConstraintMappingContextImpl( - typeContext, - property.as( JavaBeanGetter.class ) - ); - } - else { - throw LOG.getUnexpectedElementType( elementType, ElementType.FIELD, ElementType.METHOD ); - } - } - protected PropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, T property, ConstraintLocation location) { super( typeContext.getConstraintMapping(), property.getType() ); this.typeContext = typeContext; @@ -91,6 +66,16 @@ public PropertyConstraintMappingContext property(String property, ElementType el return typeContext.property( property, elementType ); } + @Override + public PropertyConstraintMappingContext field(String property) { + return typeContext.field( property ); + } + + @Override + public PropertyConstraintMappingContext getter(String property) { + return typeContext.getter( property ); + } + @Override public ConstructorConstraintMappingContext constructor(Class... parameterTypes) { return typeContext.constructor( parameterTypes ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index 2c05aed768..6581084b0c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -34,7 +34,6 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; import org.hibernate.validator.internal.properties.Constrainable; -import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanConstructor; import org.hibernate.validator.internal.properties.javabean.JavaBeanExecutable; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; @@ -119,24 +118,58 @@ public TypeConstraintMappingContext defaultGroupSequenceProviderClass(Class clazz, String property, ElementType elementType) { + private JavaBeanField getFieldProperty(Class clazz, String property) { Contracts.assertNotNull( clazz, MESSAGES.classCannotBeNull() ); - if ( property == null || property.length() == 0 ) { - throw LOG.getPropertyNameCannotBeNullOrEmptyException(); - } + Field field = run( GetDeclaredField.action( clazz, property ) ); + return field == null ? null : new JavaBeanField( field ); + } - if ( !( ElementType.FIELD.equals( elementType ) || ElementType.METHOD.equals( elementType ) ) ) { - throw LOG.getElementTypeHasToBeFieldOrMethodException(); - } + private JavaBeanGetter getGetterProperty(Class clazz, String property) { + Contracts.assertNotNull( clazz, MESSAGES.classCannotBeNull() ); - if ( ElementType.FIELD.equals( elementType ) ) { - Field field = run( GetDeclaredField.action( clazz, property ) ); - return field == null ? null : new JavaBeanField( field ); - } - else { - Method method = null; - String methodName = property.substring( 0, 1 ).toUpperCase( Locale.ROOT ) + property.substring( 1 ); - for ( String prefix : ReflectionHelper.PROPERTY_ACCESSOR_PREFIXES ) { - method = run( GetMethod.action( clazz, prefix + methodName ) ); - if ( method != null ) { - break; - } + Method method = null; + String methodName = property.substring( 0, 1 ).toUpperCase( Locale.ROOT ) + property.substring( 1 ); + for ( String prefix : ReflectionHelper.PROPERTY_ACCESSOR_PREFIXES ) { + method = run( GetMethod.action( clazz, prefix + methodName ) ); + if ( method != null ) { + break; } - return method == null ? null : new JavaBeanGetter( method ); } + return method == null ? null : new JavaBeanGetter( method ); } /** diff --git a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java index ae7fd8a3f5..68a4b3af17 100644 --- a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java @@ -60,6 +60,7 @@ import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider; import org.hibernate.validator.testutils.ValidatorUtil; + import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -535,6 +536,28 @@ public void testProgrammaticAndAnnotationPropertyConstraintsAddUp() { ); } + @Test + public void testFieldAndGetterMethodsForProgrammaticConstraintDefinition() { + mapping.type( Marathon.class ) + .getter( "name" ) + .constraint( new SizeDef().min( 5 ) ) + .constraint( new SizeDef().min( 10 ) ) + .field( "runners" ) + .constraint( new SizeDef().max( 10 ).min( 1 ) ); + config.addMapping( mapping ); + Validator validator = config.buildValidatorFactory().getValidator(); + + Marathon marathon = new Marathon(); + marathon.setName( "Foo" ); + + Set> violations = validator.validate( marathon ); + assertThat( violations ).containsOnlyViolations( + violationOf( Size.class ).withMessage( "size must be between 10 and 2147483647" ), + violationOf( Size.class ).withMessage( "size must be between 5 and 2147483647" ), + violationOf( Size.class ).withMessage( "size must be between 1 and 10" ) + ); + } + private BeanConfiguration getBeanConfiguration(Class type) { Set> beanConfigurations = mapping.getBeanConfigurations( new ConstraintHelper(), From 49c11c6b7ce279def95c28117e9a1111e294c04a Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 7 Jun 2018 11:45:55 +0200 Subject: [PATCH 16/24] HV-1623 Replace empty check in Contracts with null and empty check at the same time - based on our usage of not empty check passed parameters should not be null as well hence the implementation of the check can use StringHelper.isNullOrEmptyString utility method. --- .../internal/cfg/context/TypeConstraintMappingContextImpl.java | 2 -- .../java/org/hibernate/validator/internal/util/Contracts.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index 6581084b0c..4aebdbc4a4 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -134,7 +134,6 @@ public PropertyConstraintMappingContext property(String property, ElementType el @Override public PropertyConstraintMappingContext field(String property) { - Contracts.assertNotNull( property, "The property name must not be null." ); Contracts.assertNotEmpty( property, MESSAGES.propertyNameMustNotBeEmpty() ); JavaBeanField javaBeanField = getFieldProperty( beanClass, property ); @@ -155,7 +154,6 @@ public PropertyConstraintMappingContext field(String property) { @Override public PropertyConstraintMappingContext getter(String property) { - Contracts.assertNotNull( property, "The property name must not be null." ); Contracts.assertNotEmpty( property, MESSAGES.propertyNameMustNotBeEmpty() ); JavaBeanGetter javaBeanGetter = getGetterProperty( beanClass, property ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/Contracts.java b/engine/src/main/java/org/hibernate/validator/internal/util/Contracts.java index dc57395795..b7164465c6 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/Contracts.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/Contracts.java @@ -75,7 +75,7 @@ public static void assertTrue(boolean condition, String message, Object... messa } public static void assertNotEmpty(String s, String message) { - if ( s.length() == 0 ) { + if ( StringHelper.isNullOrEmptyString( s ) ) { throw LOG.getIllegalArgumentException( message ); } } From 74758533ae753d29ddcdf0f04e42d5f406784f00 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 7 Jun 2018 14:49:59 +0200 Subject: [PATCH 17/24] HV-1623 Introduce getter as a constraint location kind --- .../metadata/aggregated/GetterCascadable.java | 2 +- .../descriptor/ConstraintDescriptorImpl.java | 6 +----- .../metadata/location/ConstraintLocation.java | 16 ++++++++++++++++ .../CrossParameterConstraintLocation.java | 5 +---- .../GetterPropertyConstraintLocation.java | 2 +- .../location/ParameterConstraintLocation.java | 5 +---- .../location/ReturnValueConstraintLocation.java | 5 +---- .../provider/AnnotationMetaDataProvider.java | 4 +--- .../mapping/ConstrainedGetterStaxBuilder.java | 2 +- .../xml/mapping/CrossParameterStaxBuilder.java | 2 +- .../xml/mapping/ReturnValueStaxBuilder.java | 3 +-- .../ConstraintValidatorInitializationHelper.java | 3 ++- 12 files changed, 28 insertions(+), 27 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java index b9e7e6bcae..ea3a398349 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java @@ -25,7 +25,7 @@ public class GetterCascadable extends PropertyCascadable { @Override public ConstraintLocationKind getConstraintLocationKind() { - return ConstraintLocationKind.METHOD; + return ConstraintLocationKind.GETTER; } public static class Builder extends PropertyCascadable.Builder { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java index e8b69be279..372e45dc44 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/descriptor/ConstraintDescriptorImpl.java @@ -403,7 +403,7 @@ private ConstraintType determineConstraintType(Class const ConstraintType externalConstraintType) { ConstraintTarget constraintTarget = validationAppliesTo; ConstraintType constraintType = null; - boolean isExecutable = isExecutable( constraintLocationKind ); + boolean isExecutable = constraintLocationKind.isExecutable(); //target explicitly set to RETURN_VALUE if ( constraintTarget == ConstraintTarget.RETURN_VALUE ) { @@ -530,10 +530,6 @@ private void validateComposingConstraintTypes() { } } - private boolean isExecutable(ConstraintLocationKind locationKind) { - return locationKind == ConstraintLocationKind.METHOD || locationKind == ConstraintLocationKind.CONSTRUCTOR; - } - @SuppressWarnings("unchecked") private static Set> buildPayloadSet(ConstraintAnnotationDescriptor annotationDescriptor) { Set> payloadSet = newHashSet(); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index d8197f5560..440d34317b 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -11,6 +11,7 @@ import java.lang.reflect.TypeVariable; import org.hibernate.validator.internal.engine.path.PathImpl; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; @@ -108,6 +109,7 @@ enum ConstraintLocationKind { METHOD( ElementType.METHOD ), PARAMETER( ElementType.PARAMETER ), FIELD( ElementType.FIELD ), + GETTER( ElementType.METHOD ), TYPE_USE( ElementType.TYPE_USE ), ; @@ -120,5 +122,19 @@ enum ConstraintLocationKind { public ElementType getElementType() { return elementType; } + + public boolean isExecutable() { + return this == CONSTRUCTOR || isMethod(); + } + + public boolean isMethod() { + return this == METHOD || this == GETTER; + } + + public static ConstraintLocationKind of(Callable callable) { + return callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR + ? ConstraintLocationKind.CONSTRUCTOR + : callable instanceof JavaBeanGetter ? ConstraintLocationKind.GETTER : ConstraintLocationKind.METHOD; + } } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java index 04ef4d100e..494a9c173b 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java @@ -9,7 +9,6 @@ import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -29,9 +28,7 @@ class CrossParameterConstraintLocation implements ConstraintLocation { CrossParameterConstraintLocation(Callable callable) { this.callable = callable; - this.kind = callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR - ? ConstraintLocationKind.CONSTRUCTOR - : ConstraintLocationKind.METHOD; + this.kind = ConstraintLocationKind.of( callable ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java index 12e2b42bab..0f40edd9fe 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java @@ -21,6 +21,6 @@ public class GetterPropertyConstraintLocation extends PropertyConstraintLocation @Override public ConstraintLocationKind getKind() { - return ConstraintLocationKind.METHOD; + return ConstraintLocationKind.GETTER; } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java index a732e556aa..415175b77a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java @@ -9,7 +9,6 @@ import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -33,9 +32,7 @@ public ParameterConstraintLocation(Callable callable, int index) { this.callable = callable; this.index = index; this.typeForValidatorResolution = ReflectionHelper.boxedType( callable.getParameterGenericType( index ) ); - this.kind = callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR - ? ConstraintLocationKind.CONSTRUCTOR - : ConstraintLocationKind.METHOD; + this.kind = ConstraintLocationKind.of( callable ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java index 9203e4a9d5..6532fa6a33 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java @@ -9,7 +9,6 @@ import java.lang.reflect.Type; import org.hibernate.validator.internal.engine.path.PathImpl; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -30,9 +29,7 @@ class ReturnValueConstraintLocation implements ConstraintLocation { ReturnValueConstraintLocation(Callable callable) { this.callable = callable; - this.kind = callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR - ? ConstraintLocationKind.CONSTRUCTOR - : ConstraintLocationKind.METHOD; + this.kind = ConstraintLocationKind.of( callable ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index 4afaa5e2fe..ec13ce0964 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -303,9 +303,7 @@ private ConstrainedExecutable findExecutableMetaData(Executable executable) { Map>> executableConstraints = findConstraints( javaBeanExecutable, - javaBeanExecutable.getConstrainedElementKind() == ConstrainedElement.ConstrainedElementKind.CONSTRUCTOR - ? ConstraintLocationKind.CONSTRUCTOR - : ConstraintLocationKind.METHOD + ConstraintLocationKind.of( javaBeanExecutable ) ).stream().collect( Collectors.groupingBy( ConstraintDescriptorImpl::getConstraintType ) ); Set> crossParameterConstraints; diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java index 11bc792d33..3969c10577 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ConstrainedGetterStaxBuilder.java @@ -77,7 +77,7 @@ ConstrainedExecutable build(Class beanClass, List alreadyProcessedGet ConstraintLocation constraintLocation = ConstraintLocation.forGetter( javaBeanGetter ); Set> metaConstraints = constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.METHOD, null ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.GETTER, null ) ) .collect( Collectors.toSet() ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java index c92463cf95..64e2a183b9 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java @@ -89,7 +89,7 @@ Set> build(Callable callable) { ConstraintLocation constraintLocation = ConstraintLocation.forCrossParameter( callable ); Set> crossParameterConstraints = constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.METHOD, ConstraintType.CROSS_PARAMETER ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.of( callable ), ConstraintType.CROSS_PARAMETER ) ) .collect( Collectors.toSet() ); // ignore annotations diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java index c3e2eb0136..56b27f5455 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java @@ -20,7 +20,6 @@ import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.xml.mapping.ContainerElementTypeConfigurationBuilder.ContainerElementTypeConfiguration; @@ -57,7 +56,7 @@ CascadingMetaDataBuilder build( ConstraintLocation constraintLocation = ConstraintLocation.forReturnValue( callable ); returnValueConstraints.addAll( constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR ? ConstraintLocationKind.CONSTRUCTOR : ConstraintLocationKind.METHOD, ConstraintDescriptorImpl.ConstraintType.GENERIC ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.of( callable ), ConstraintDescriptorImpl.ConstraintType.GENERIC ) ) .collect( Collectors.toSet() ) ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( callable.getType(), constraintLocation ); diff --git a/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java b/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java index ea3e4b917d..30dbe909d4 100644 --- a/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java +++ b/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java @@ -18,6 +18,7 @@ import org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; +import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.spi.scripting.ScriptEvaluator; import org.hibernate.validator.spi.scripting.ScriptEvaluatorFactory; @@ -40,7 +41,7 @@ public static ConstraintDescriptor descriptorFrom(Cons CONSTRAINT_HELPER, null, annotationDescriptor, - null + ConstraintLocationKind.GETTER ); } From e5b7c8d5a78814e6d0ef807ceae8095729c5a4dc Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 8 Jun 2018 18:16:34 +0200 Subject: [PATCH 18/24] HV-1623 Introduce ConstrainedElementKind.GETTER --- .../metadata/aggregated/BeanMetaDataImpl.java | 11 ++++-- .../aggregated/ExecutableMetaData.java | 6 ++-- .../aggregated/PropertyCascadable.java | 4 +-- .../metadata/aggregated/PropertyMetaData.java | 13 +++---- .../metadata/location/ConstraintLocation.java | 26 ++++++++++---- .../CrossParameterConstraintLocation.java | 2 +- .../location/ParameterConstraintLocation.java | 2 +- .../ReturnValueConstraintLocation.java | 2 +- .../provider/AnnotationMetaDataProvider.java | 2 +- .../metadata/raw/ConstrainedElement.java | 34 +++++++++++++------ .../metadata/raw/ConstrainedExecutable.java | 14 -------- .../properties/javabean/JavaBeanGetter.java | 8 ++++- .../mapping/CrossParameterStaxBuilder.java | 3 +- .../xml/mapping/ReturnValueStaxBuilder.java | 3 +- .../test/cfg/ConstraintMappingTest.java | 2 +- 15 files changed, 76 insertions(+), 56 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java index cfb93a43e3..059d34ba6c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/BeanMetaDataImpl.java @@ -15,6 +15,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; @@ -42,10 +43,10 @@ import org.hibernate.validator.internal.metadata.raw.BeanConfiguration; import org.hibernate.validator.internal.metadata.raw.ConfigurationSource; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; import org.hibernate.validator.internal.metadata.raw.ConstrainedType; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.ExecutableHelper; @@ -736,6 +737,7 @@ public BuilderDelegate( break; case CONSTRUCTOR: case METHOD: + case GETTER: ConstrainedExecutable constrainedExecutable = (ConstrainedExecutable) constrainedElement; Callable member = constrainedExecutable.getCallable(); @@ -754,7 +756,7 @@ public BuilderDelegate( ); } - if ( constrainedExecutable.isGetterMethod() ) { + if ( constrainedElement.getKind() == ConstrainedElementKind.GETTER ) { metaDataBuilder = new PropertyMetaData.Builder( beanClass, constrainedExecutable, @@ -774,6 +776,9 @@ public BuilderDelegate( valueExtractorManager ); break; + default: + throw new IllegalStateException( + String.format( Locale.ROOT, "Constrained element kind '%1$s' not supported here.", constrainedElement.getKind() ) ); } this.hashCode = buildHashCode(); @@ -790,7 +795,7 @@ public boolean add(ConstrainedElement constrainedElement) { if ( metaDataBuilder != null && metaDataBuilder.accepts( constrainedElement ) ) { metaDataBuilder.add( constrainedElement ); - if ( !added && constrainedElement.getKind() == ConstrainedElementKind.METHOD && methodBuilder == null ) { + if ( !added && constrainedElement.getKind().isMethod() && methodBuilder == null ) { ConstrainedExecutable constrainedMethod = (ConstrainedExecutable) constrainedElement; methodBuilder = new ExecutableMetaData.Builder( beanClass, diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java index a073d5056f..cd86946d31 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ExecutableMetaData.java @@ -254,12 +254,11 @@ public static class Builder extends MetaDataBuilder { private final Set signatures = newHashSet(); /** - * Either CONSTRUCTOR or METHOD. + * Either CONSTRUCTOR, METHOD or GETTER. */ private final ConstrainedElementKind kind; private final Set constrainedExecutables = newHashSet(); private Callable callable; - private final boolean isGetterMethod; private final Set> crossParameterConstraints = newHashSet(); private final Set rules; private boolean isConstrained = false; @@ -293,7 +292,6 @@ public Builder( this.kind = constrainedExecutable.getKind(); this.callable = constrainedExecutable.getCallable(); this.rules = methodValidationConfiguration.getConfiguredRuleSet(); - this.isGetterMethod = constrainedExecutable.isGetterMethod(); add( constrainedExecutable ); } @@ -397,7 +395,7 @@ public ExecutableMetaData build() { adaptOriginsAndImplicitGroups( crossParameterConstraints ), cascadingMetaDataBuilder.build( valueExtractorManager, callable ), isConstrained, - isGetterMethod + kind == ConstrainedElementKind.GETTER ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java index eafc89bbb3..a8acce09d0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java @@ -80,10 +80,10 @@ public static Cascadable.Builder builder(ConstrainedElementKind constrainedEleme if ( ConstrainedElementKind.FIELD == constrainedElementKind ) { return new FieldCascadable.Builder( valueExtractorManager, property, cascadingMetaDataBuilder ); } - else if ( ConstrainedElementKind.METHOD == constrainedElementKind ) { + else if ( ConstrainedElementKind.GETTER == constrainedElementKind ) { return new GetterCascadable.Builder( valueExtractorManager, property, cascadingMetaDataBuilder ); } - throw new IllegalStateException( "It should either be field or method." ); + throw new IllegalStateException( "It should be either a field or a getter." ); } } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index f87e1c9b55..3d372e1ed8 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -151,7 +151,7 @@ public static class Builder extends MetaDataBuilder { private static final EnumSet SUPPORTED_ELEMENT_KINDS = EnumSet.of( ConstrainedElementKind.FIELD, - ConstrainedElementKind.METHOD + ConstrainedElementKind.GETTER ); private final String propertyName; @@ -182,11 +182,6 @@ public boolean accepts(ConstrainedElement constrainedElement) { return false; } - if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD && - !( (ConstrainedExecutable) constrainedElement ).isGetterMethod() ) { - return false; - } - return Objects.equals( getPropertyName( constrainedElement ), propertyName ); } @@ -222,7 +217,7 @@ private Optional getConstrainableFromConstrainedElement(Constrain LOG.getUnexpectedConstraintElementType( ConstrainedField.class, constrainedElement.getClass() ); } } - else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { + else if ( constrainedElement.getKind() == ConstrainedElementKind.GETTER ) { if ( constrainedElement instanceof ConstrainedExecutable ) { return Optional.of( ( (ConstrainedExecutable) constrainedElement ).getCallable() ); } @@ -235,7 +230,7 @@ else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { @Override protected Set> adaptConstraints(ConstrainedElement constrainedElement, Set> constraints) { - if ( constraints.isEmpty() || constrainedElement.getKind() != ConstrainedElementKind.METHOD ) { + if ( constraints.isEmpty() || constrainedElement.getKind() != ConstrainedElementKind.GETTER ) { return constraints; } @@ -304,7 +299,7 @@ private String getPropertyName(ConstrainedElement constrainedElement) { if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { return ( (ConstrainedField) constrainedElement ).getProperty().getPropertyName(); } - else if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD ) { + else if ( constrainedElement.getKind() == ConstrainedElementKind.GETTER ) { return ( (ConstrainedExecutable) constrainedElement ).getCallable().as( Property.class ).getPropertyName(); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index 440d34317b..f5ae00de56 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -9,6 +9,7 @@ import java.lang.annotation.ElementType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; +import java.util.Locale; import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; @@ -110,8 +111,7 @@ enum ConstraintLocationKind { PARAMETER( ElementType.PARAMETER ), FIELD( ElementType.FIELD ), GETTER( ElementType.METHOD ), - TYPE_USE( ElementType.TYPE_USE ), - ; + TYPE_USE( ElementType.TYPE_USE ); private final ElementType elementType; @@ -131,10 +131,24 @@ public boolean isMethod() { return this == METHOD || this == GETTER; } - public static ConstraintLocationKind of(Callable callable) { - return callable.getConstrainedElementKind() == ConstrainedElementKind.CONSTRUCTOR - ? ConstraintLocationKind.CONSTRUCTOR - : callable instanceof JavaBeanGetter ? ConstraintLocationKind.GETTER : ConstraintLocationKind.METHOD; + public static ConstraintLocationKind of(ConstrainedElementKind constrainedElementKind) { + switch ( constrainedElementKind ) { + case CONSTRUCTOR: + return ConstraintLocationKind.CONSTRUCTOR; + case FIELD: + return ConstraintLocationKind.FIELD; + case METHOD: + return ConstraintLocationKind.METHOD; + case PARAMETER: + return ConstraintLocationKind.PARAMETER; + case TYPE: + return ConstraintLocationKind.TYPE; + case GETTER: + return ConstraintLocationKind.GETTER; + default: + throw new IllegalArgumentException( + String.format( Locale.ROOT, "Constrained element kind '%1$s' not supported.", constrainedElementKind ) ); + } } } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java index 494a9c173b..0f36fa5ed7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/CrossParameterConstraintLocation.java @@ -28,7 +28,7 @@ class CrossParameterConstraintLocation implements ConstraintLocation { CrossParameterConstraintLocation(Callable callable) { this.callable = callable; - this.kind = ConstraintLocationKind.of( callable ); + this.kind = ConstraintLocationKind.of( callable.getConstrainedElementKind() ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java index 415175b77a..29392b77ff 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ParameterConstraintLocation.java @@ -32,7 +32,7 @@ public ParameterConstraintLocation(Callable callable, int index) { this.callable = callable; this.index = index; this.typeForValidatorResolution = ReflectionHelper.boxedType( callable.getParameterGenericType( index ) ); - this.kind = ConstraintLocationKind.of( callable ); + this.kind = ConstraintLocationKind.of( callable.getConstrainedElementKind() ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java index 6532fa6a33..6ee7b3f924 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ReturnValueConstraintLocation.java @@ -29,7 +29,7 @@ class ReturnValueConstraintLocation implements ConstraintLocation { ReturnValueConstraintLocation(Callable callable) { this.callable = callable; - this.kind = ConstraintLocationKind.of( callable ); + this.kind = ConstraintLocationKind.of( callable.getConstrainedElementKind() ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index ec13ce0964..cac8cb06e7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -303,7 +303,7 @@ private ConstrainedExecutable findExecutableMetaData(Executable executable) { Map>> executableConstraints = findConstraints( javaBeanExecutable, - ConstraintLocationKind.of( javaBeanExecutable ) + ConstraintLocationKind.of( javaBeanExecutable.getConstrainedElementKind() ) ).stream().collect( Collectors.groupingBy( ConstraintDescriptorImpl::getConstraintType ) ); Set> crossParameterConstraints; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedElement.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedElement.java index fc7114ab4e..a1b1c456fd 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedElement.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedElement.java @@ -40,16 +40,6 @@ */ public interface ConstrainedElement extends Iterable> { - /** - * The kind of a {@link ConstrainedElement}. Can be used to determine an - * element's type when traversing over a collection of constrained elements. - * - * @author Gunnar Morling - */ - enum ConstrainedElementKind { - TYPE, FIELD, CONSTRUCTOR, METHOD, PARAMETER - } - /** * Returns the kind of this constrained element. * @@ -91,4 +81,28 @@ enum ConstrainedElementKind { * Returns the configuration source contributing this constrained element. */ ConfigurationSource getSource(); + + /** + * The kind of a {@link ConstrainedElement}. Can be used to determine an + * element's type when traversing over a collection of constrained elements. + * + * @author Gunnar Morling + */ + enum ConstrainedElementKind { + + TYPE, + FIELD, + CONSTRUCTOR, + METHOD, + PARAMETER, + GETTER; + + public boolean isExecutable() { + return this == CONSTRUCTOR || isMethod(); + } + + public boolean isMethod() { + return this == METHOD || this == GETTER; + } + } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java index 0c42157833..2d9a612929 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java @@ -20,7 +20,6 @@ import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder; import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.properties.Callable; -import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; @@ -51,8 +50,6 @@ public class ConstrainedExecutable extends AbstractConstrainedElement { @Immutable private final Set> crossParameterConstraints; - private final boolean isGetterMethod; - /** * Creates a new executable meta data object for a parameter-less executable. * @@ -123,7 +120,6 @@ public ConstrainedExecutable( this.crossParameterConstraints = CollectionHelper.toImmutableSet( crossParameterConstraints ); this.parameterMetaData = CollectionHelper.toImmutableList( parameterMetaData ); this.hasParameterConstraints = hasParameterConstraints( parameterMetaData ) || !crossParameterConstraints.isEmpty(); - this.isGetterMethod = callable instanceof Property; } /** @@ -190,16 +186,6 @@ public boolean hasParameterConstraints() { return hasParameterConstraints; } - /** - * Whether the represented executable is a JavaBeans getter executable or not. - * - * @return {@code True}, if this executable is a getter method, {@code false} - * otherwise. - */ - public boolean isGetterMethod() { - return isGetterMethod; - } - public Callable getCallable() { return callable; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java index 65ec83aa8b..722da007d5 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java @@ -11,6 +11,7 @@ import java.security.PrivilegedAction; import org.hibernate.validator.HibernateValidatorPermission; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.ReflectionHelper; @@ -67,7 +68,7 @@ public boolean hasParameters() { @Override public String getParameterName(ExecutableParameterNameProvider parameterNameProvider, int parameterIndex) { - throw new IllegalStateException( "Getters cannot have parameters" ); + throw new IllegalStateException( "Getters may not have parameters" ); } @Override @@ -75,6 +76,11 @@ public Class getDeclaringClass() { return declaringClass; } + @Override + public ConstrainedElementKind getConstrainedElementKind() { + return ConstrainedElementKind.GETTER; + } + @Override public boolean equals(Object o) { if ( this == o ) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java index 64e2a183b9..84119ecbd3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/CrossParameterStaxBuilder.java @@ -89,7 +89,8 @@ Set> build(Callable callable) { ConstraintLocation constraintLocation = ConstraintLocation.forCrossParameter( callable ); Set> crossParameterConstraints = constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.of( callable ), ConstraintType.CROSS_PARAMETER ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.of( callable.getConstrainedElementKind() ), + ConstraintType.CROSS_PARAMETER ) ) .collect( Collectors.toSet() ); // ignore annotations diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java index 56b27f5455..8157a2ba6d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/mapping/ReturnValueStaxBuilder.java @@ -56,7 +56,8 @@ CascadingMetaDataBuilder build( ConstraintLocation constraintLocation = ConstraintLocation.forReturnValue( callable ); returnValueConstraints.addAll( constraintTypeStaxBuilders.stream() - .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.of( callable ), ConstraintDescriptorImpl.ConstraintType.GENERIC ) ) + .map( builder -> builder.build( constraintLocation, ConstraintLocationKind.of( callable.getConstrainedElementKind() ), + ConstraintDescriptorImpl.ConstraintType.GENERIC ) ) .collect( Collectors.toSet() ) ); ContainerElementTypeConfiguration containerElementTypeConfiguration = getContainerElementTypeConfiguration( callable.getType(), constraintLocation ); diff --git a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java index 68a4b3af17..73f9d1632b 100644 --- a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java @@ -589,7 +589,7 @@ private ConstrainedField getConstrainedField(BeanConfiguration beanConfigurat private ConstrainedExecutable getConstrainedExecutable(BeanConfiguration beanConfiguration, String executableName) { for ( ConstrainedElement constrainedElement : beanConfiguration.getConstrainedElements() ) { - if ( constrainedElement.getKind() == ConstrainedElementKind.METHOD && + if ( constrainedElement.getKind().isMethod() && ( (ConstrainedExecutable) constrainedElement ).getCallable().getName().equals( executableName ) ) { return (ConstrainedExecutable) constrainedElement; } From 3a1944c09d5eddf2f3fd7340b84fa066ee3283cd Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 8 Jun 2018 19:06:19 +0200 Subject: [PATCH 19/24] HV-1623 Stop the propagation of JavaBeanField/Getter We don't need the elements to be typed so let's be looser to open the gate for JSON properties (which will probably simply be treated as fields). --- .../internal/cfg/context/ConfiguredConstraint.java | 7 ++++++- ...mpl.java => FieldConstraintMappingContextImpl.java} | 6 +++--- ...pl.java => GetterConstraintMappingContextImpl.java} | 6 +++--- .../cfg/context/TypeConstraintMappingContextImpl.java | 4 ++-- .../internal/metadata/aggregated/PropertyMetaData.java | 9 +++++---- .../internal/metadata/location/ConstraintLocation.java | 4 ++-- ...raintLocation.java => FieldConstraintLocation.java} | 8 ++++---- ...aintLocation.java => GetterConstraintLocation.java} | 8 ++++---- .../metadata/location/PropertyConstraintLocation.java | 10 +++++----- 9 files changed, 34 insertions(+), 28 deletions(-) rename engine/src/main/java/org/hibernate/validator/internal/cfg/context/{FieldPropertyConstraintMappingContextImpl.java => FieldConstraintMappingContextImpl.java} (88%) rename engine/src/main/java/org/hibernate/validator/internal/cfg/context/{GetterPropertyConstraintMappingContextImpl.java => GetterConstraintMappingContextImpl.java} (87%) rename engine/src/main/java/org/hibernate/validator/internal/metadata/location/{FieldPropertyConstraintLocation.java => FieldConstraintLocation.java} (63%) rename engine/src/main/java/org/hibernate/validator/internal/metadata/location/{GetterPropertyConstraintLocation.java => GetterConstraintLocation.java} (63%) diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java index 3798389f52..965c5711fa 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java @@ -21,6 +21,7 @@ import org.hibernate.validator.internal.metadata.location.ConstraintLocation; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.javabean.JavaBeanField; +import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.annotation.AnnotationDescriptor; import org.hibernate.validator.internal.util.annotation.ConstraintAnnotationDescriptor; import org.hibernate.validator.internal.util.logging.Log; @@ -53,10 +54,14 @@ static ConfiguredConstraint forType(ConstraintDef( constraint, ConstraintLocation.forClass( beanType ) ); } - static ConfiguredConstraint forFieldProperty(ConstraintDef constraint, JavaBeanField javaBeanField) { + static ConfiguredConstraint forField(ConstraintDef constraint, JavaBeanField javaBeanField) { return new ConfiguredConstraint<>( constraint, ConstraintLocation.forField( javaBeanField ) ); } + static ConfiguredConstraint forGetter(ConstraintDef constraint, JavaBeanGetter javaBeanGetter) { + return forExecutable( constraint, javaBeanGetter ); + } + public static ConfiguredConstraint forParameter(ConstraintDef constraint, Callable callable, int parameterIndex) { return new ConfiguredConstraint<>( constraint, ConstraintLocation.forParameter( callable, parameterIndex ) ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldPropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldConstraintMappingContextImpl.java similarity index 88% rename from engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldPropertyConstraintMappingContextImpl.java rename to engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldConstraintMappingContextImpl.java index 417d963c2d..04cb100abc 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldPropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldConstraintMappingContextImpl.java @@ -25,16 +25,16 @@ * * @author Marko Bekhta */ -final class FieldPropertyConstraintMappingContextImpl extends PropertyConstraintMappingContextImpl { +final class FieldConstraintMappingContextImpl extends PropertyConstraintMappingContextImpl { - FieldPropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanField javaBeanField) { + FieldConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanField javaBeanField) { super( typeContext, javaBeanField, ConstraintLocation.forField( javaBeanField ) ); } @Override public PropertyConstraintMappingContext constraint(ConstraintDef definition) { super.addConstraint( - ConfiguredConstraint.forFieldProperty( + ConfiguredConstraint.forField( definition, getProperty() ) ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterPropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterConstraintMappingContextImpl.java similarity index 87% rename from engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterPropertyConstraintMappingContextImpl.java rename to engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterConstraintMappingContextImpl.java index 1bfc8a1389..ab749aba1f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterPropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterConstraintMappingContextImpl.java @@ -24,16 +24,16 @@ * * @author Marko Bekhta */ -final class GetterPropertyConstraintMappingContextImpl extends PropertyConstraintMappingContextImpl { +final class GetterConstraintMappingContextImpl extends PropertyConstraintMappingContextImpl { - GetterPropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanGetter javaBeanGetter) { + GetterConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanGetter javaBeanGetter) { super( typeContext, javaBeanGetter, ConstraintLocation.forGetter( javaBeanGetter ) ); } @Override public PropertyConstraintMappingContext constraint(ConstraintDef definition) { super.addConstraint( - ConfiguredConstraint.forExecutable( + ConfiguredConstraint.forGetter( definition, getProperty() ) ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index 4aebdbc4a4..aa73b50aff 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -146,7 +146,7 @@ public PropertyConstraintMappingContext field(String property) { throw LOG.getPropertyHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, property ); } - PropertyConstraintMappingContextImpl context = new FieldPropertyConstraintMappingContextImpl( this, javaBeanField ); + PropertyConstraintMappingContextImpl context = new FieldConstraintMappingContextImpl( this, javaBeanField ); configuredMembers.add( javaBeanField ); propertyContexts.add( context ); return context; @@ -166,7 +166,7 @@ public PropertyConstraintMappingContext getter(String property) { throw LOG.getPropertyHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, property ); } - PropertyConstraintMappingContextImpl context = new GetterPropertyConstraintMappingContextImpl( this, javaBeanGetter ); + PropertyConstraintMappingContextImpl context = new GetterConstraintMappingContextImpl( this, javaBeanGetter ); configuredMembers.add( javaBeanGetter ); propertyContexts.add( context ); return context; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 3d372e1ed8..c630c6bfb8 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -29,7 +29,7 @@ import org.hibernate.validator.internal.metadata.descriptor.PropertyDescriptorImpl; import org.hibernate.validator.internal.metadata.facets.Cascadable; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.metadata.location.GetterPropertyConstraintLocation; +import org.hibernate.validator.internal.metadata.location.GetterConstraintLocation; import org.hibernate.validator.internal.metadata.location.TypeArgumentConstraintLocation; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; @@ -234,7 +234,8 @@ protected Set> adaptConstraints(ConstrainedElement constrained return constraints; } - ConstraintLocation getterConstraintLocation = ConstraintLocation.forGetter( ( (ConstrainedExecutable) constrainedElement ).getCallable().as( JavaBeanGetter.class ) ); + ConstraintLocation getterConstraintLocation = ConstraintLocation + .forGetter( ( (ConstrainedExecutable) constrainedElement ).getCallable().as( JavaBeanGetter.class ) ); // convert return value locations into getter locations for usage within this meta-data return constraints.stream() @@ -248,7 +249,7 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint // fast track if it's a regular constraint if ( !( constraint.getLocation() instanceof TypeArgumentConstraintLocation ) ) { // Change the constraint location to a GetterConstraintLocation if it is not already one - if ( constraint.getLocation() instanceof GetterPropertyConstraintLocation ) { + if ( constraint.getLocation() instanceof GetterConstraintLocation ) { converted = constraint.getLocation(); } else { @@ -275,7 +276,7 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint for ( ConstraintLocation location : locationStack ) { if ( !(location instanceof TypeArgumentConstraintLocation) ) { // Change the constraint location to a GetterConstraintLocation if it is not already one - if ( location instanceof GetterPropertyConstraintLocation ) { + if ( location instanceof GetterConstraintLocation ) { converted = location; } else { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index f5ae00de56..2a9a90d283 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -43,11 +43,11 @@ static ConstraintLocation forClass(Class declaringClass) { } static ConstraintLocation forField(JavaBeanField field) { - return new FieldPropertyConstraintLocation( field ); + return new FieldConstraintLocation( field ); } static ConstraintLocation forGetter(JavaBeanGetter getter) { - return new GetterPropertyConstraintLocation( getter ); + return new GetterConstraintLocation( getter ); } static ConstraintLocation forTypeArgument(ConstraintLocation delegate, TypeVariable typeParameter, Type typeOfAnnotatedElement) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java similarity index 63% rename from engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java rename to engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java index 4687132dea..594ae9dbef 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldPropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java @@ -6,17 +6,17 @@ */ package org.hibernate.validator.internal.metadata.location; -import org.hibernate.validator.internal.properties.javabean.JavaBeanField; +import org.hibernate.validator.internal.properties.Property; /** * Field property constraint location. * * @author Marko Bekhta */ -public class FieldPropertyConstraintLocation extends PropertyConstraintLocation { +public class FieldConstraintLocation extends PropertyConstraintLocation { - FieldPropertyConstraintLocation(JavaBeanField javaBeanGetter) { - super( javaBeanGetter ); + FieldConstraintLocation(Property field) { + super( field ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java similarity index 63% rename from engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java rename to engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java index 0f40edd9fe..07ab3ecbbd 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterPropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java @@ -6,17 +6,17 @@ */ package org.hibernate.validator.internal.metadata.location; -import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; +import org.hibernate.validator.internal.properties.Property; /** * Getter property constraint location. * * @author Marko Bekhta */ -public class GetterPropertyConstraintLocation extends PropertyConstraintLocation { +public class GetterConstraintLocation extends PropertyConstraintLocation { - GetterPropertyConstraintLocation(JavaBeanGetter javaBeanGetter) { - super( javaBeanGetter ); + GetterConstraintLocation(Property getter) { + super( getter ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java index a9f0f17b64..907b03fbe0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java @@ -18,14 +18,14 @@ * @author Marko Bekhta * @author Guillaume Smet */ -public abstract class PropertyConstraintLocation implements ConstraintLocation { +public abstract class PropertyConstraintLocation implements ConstraintLocation { /** * The member the constraint was defined on. */ - private final T property; + private final Property property; - PropertyConstraintLocation(T property) { + PropertyConstraintLocation(Property property) { this.property = property; } @@ -35,7 +35,7 @@ public Class getDeclaringClass() { } @Override - public T getConstrainable() { + public Property getConstrainable() { return property; } @@ -72,7 +72,7 @@ public boolean equals(Object o) { return false; } - PropertyConstraintLocation that = (PropertyConstraintLocation) o; + PropertyConstraintLocation that = (PropertyConstraintLocation) o; if ( !property.equals( that.property ) ) { return false; From ce6f342cc91aaa2dd83d607dc8767422cc70776d Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 8 Jun 2018 19:17:29 +0200 Subject: [PATCH 20/24] HV-1623 Rename a couple of classes to Abstract* --- ... => AbstractPropertyConstraintMappingContextImpl.java} | 6 +++--- .../cfg/context/FieldConstraintMappingContextImpl.java | 4 ++-- .../cfg/context/GetterConstraintMappingContextImpl.java | 4 ++-- .../cfg/context/TypeConstraintMappingContextImpl.java | 8 ++++---- .../validationcontext/PropertyValidationContext.java | 6 +++--- ...rtyCascadable.java => AbstractPropertyCascadable.java} | 6 +++--- .../internal/metadata/aggregated/FieldCascadable.java | 4 ++-- .../internal/metadata/aggregated/GetterCascadable.java | 4 ++-- .../internal/metadata/aggregated/PropertyMetaData.java | 2 +- ...ation.java => AbstractPropertyConstraintLocation.java} | 6 +++--- .../internal/metadata/location/ConstraintLocation.java | 2 +- .../metadata/location/FieldConstraintLocation.java | 2 +- .../metadata/location/GetterConstraintLocation.java | 2 +- 13 files changed, 28 insertions(+), 28 deletions(-) rename engine/src/main/java/org/hibernate/validator/internal/cfg/context/{PropertyConstraintMappingContextImpl.java => AbstractPropertyConstraintMappingContextImpl.java} (92%) rename engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/{PropertyCascadable.java => AbstractPropertyCascadable.java} (93%) rename engine/src/main/java/org/hibernate/validator/internal/metadata/location/{PropertyConstraintLocation.java => AbstractPropertyConstraintLocation.java} (88%) diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/AbstractPropertyConstraintMappingContextImpl.java similarity index 92% rename from engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java rename to engine/src/main/java/org/hibernate/validator/internal/cfg/context/AbstractPropertyConstraintMappingContextImpl.java index 61f65e2fd7..7d0e67ec4e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/AbstractPropertyConstraintMappingContextImpl.java @@ -28,7 +28,7 @@ * @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI * @author Marko Bekhta */ -abstract class PropertyConstraintMappingContextImpl +abstract class AbstractPropertyConstraintMappingContextImpl extends CascadableConstraintMappingContextImplBase implements PropertyConstraintMappingContext { @@ -38,7 +38,7 @@ abstract class PropertyConstraintMappingContextImpl private final T property; private final ConstraintLocation location; - protected PropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, T property, ConstraintLocation location) { + protected AbstractPropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, T property, ConstraintLocation location) { super( typeContext.getConstraintMapping(), property.getType() ); this.typeContext = typeContext; this.property = property; @@ -46,7 +46,7 @@ protected PropertyConstraintMappingContextImpl(TypeConstraintMappingContextImpl< } @Override - protected PropertyConstraintMappingContextImpl getThis() { + protected AbstractPropertyConstraintMappingContextImpl getThis() { return this; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldConstraintMappingContextImpl.java index 04cb100abc..bc77618fb6 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/FieldConstraintMappingContextImpl.java @@ -19,13 +19,13 @@ import org.hibernate.validator.internal.util.TypeResolutionHelper; /** - * An implementation of {@link PropertyConstraintMappingContextImpl} for a field property. + * An implementation of {@link AbstractPropertyConstraintMappingContextImpl} for a field property. * Represents a constraint mapping creational context which allows to configure the constraints * for one of the bean's field properties. * * @author Marko Bekhta */ -final class FieldConstraintMappingContextImpl extends PropertyConstraintMappingContextImpl { +final class FieldConstraintMappingContextImpl extends AbstractPropertyConstraintMappingContextImpl { FieldConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanField javaBeanField) { super( typeContext, javaBeanField, ConstraintLocation.forField( javaBeanField ) ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterConstraintMappingContextImpl.java index ab749aba1f..e78c2534cc 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/GetterConstraintMappingContextImpl.java @@ -18,13 +18,13 @@ import org.hibernate.validator.internal.util.TypeResolutionHelper; /** - * An implementation of {@link PropertyConstraintMappingContextImpl} for a getter property. + * An implementation of {@link AbstractPropertyConstraintMappingContextImpl} for a getter property. * Represents a constraint mapping creational context which allows to configure the constraints * for one of the bean's getter properties. * * @author Marko Bekhta */ -final class GetterConstraintMappingContextImpl extends PropertyConstraintMappingContextImpl { +final class GetterConstraintMappingContextImpl extends AbstractPropertyConstraintMappingContextImpl { GetterConstraintMappingContextImpl(TypeConstraintMappingContextImpl typeContext, JavaBeanGetter javaBeanGetter) { super( typeContext, javaBeanGetter, ConstraintLocation.forGetter( javaBeanGetter ) ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index aa73b50aff..0b7b01d7a1 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -69,7 +69,7 @@ public final class TypeConstraintMappingContextImpl extends ConstraintMapping private final Class beanClass; private final Set executableContexts = newHashSet(); - private final Set propertyContexts = newHashSet(); + private final Set propertyContexts = newHashSet(); private final Set configuredMembers = newHashSet(); private List> defaultGroupSequence; @@ -146,7 +146,7 @@ public PropertyConstraintMappingContext field(String property) { throw LOG.getPropertyHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, property ); } - PropertyConstraintMappingContextImpl context = new FieldConstraintMappingContextImpl( this, javaBeanField ); + AbstractPropertyConstraintMappingContextImpl context = new FieldConstraintMappingContextImpl( this, javaBeanField ); configuredMembers.add( javaBeanField ); propertyContexts.add( context ); return context; @@ -166,7 +166,7 @@ public PropertyConstraintMappingContext getter(String property) { throw LOG.getPropertyHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, property ); } - PropertyConstraintMappingContextImpl context = new GetterConstraintMappingContextImpl( this, javaBeanGetter ); + AbstractPropertyConstraintMappingContextImpl context = new GetterConstraintMappingContextImpl( this, javaBeanGetter ); configuredMembers.add( javaBeanGetter ); propertyContexts.add( context ); return context; @@ -258,7 +258,7 @@ private Set buildConstraintElements(ConstraintHelper constra } //properties - for ( PropertyConstraintMappingContextImpl propertyContext : propertyContexts ) { + for ( AbstractPropertyConstraintMappingContextImpl propertyContext : propertyContexts ) { elements.add( propertyContext.build( constraintHelper, typeResolutionHelper, valueExtractorManager ) ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java index c16acc1deb..eabacdfc2d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java @@ -23,7 +23,7 @@ import org.hibernate.validator.internal.metadata.aggregated.BeanMetaData; import org.hibernate.validator.internal.metadata.core.MetaConstraint; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; -import org.hibernate.validator.internal.metadata.location.PropertyConstraintLocation; +import org.hibernate.validator.internal.metadata.location.AbstractPropertyConstraintLocation; import org.hibernate.validator.internal.metadata.location.TypeArgumentConstraintLocation; /** @@ -71,8 +71,8 @@ private String getPropertyName(ConstraintLocation location) { location = ( (TypeArgumentConstraintLocation) location ).getOuterDelegate(); } - if ( location instanceof PropertyConstraintLocation ) { - return ( (PropertyConstraintLocation) location ).getPropertyName(); + if ( location instanceof AbstractPropertyConstraintLocation ) { + return ( (AbstractPropertyConstraintLocation) location ).getPropertyName(); } return null; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java similarity index 93% rename from engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java rename to engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java index a8acce09d0..3585f69cab 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java @@ -15,18 +15,18 @@ import org.hibernate.validator.internal.properties.Property; /** - * A {@link Cascadable} backed by a field of a Java bean. + * A {@link Cascadable} backed by a property of a Java bean. * * @author Gunnar Morling * @author Marko Bekhta */ -public abstract class PropertyCascadable implements Cascadable { +public abstract class AbstractPropertyCascadable implements Cascadable { private final Property property; private final Type cascadableType; private final CascadingMetaData cascadingMetaData; - PropertyCascadable(Property property, CascadingMetaData cascadingMetaData) { + AbstractPropertyCascadable(Property property, CascadingMetaData cascadingMetaData) { this.property = property; this.cascadableType = property.getType(); this.cascadingMetaData = cascadingMetaData; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java index 7021170530..e0d5fc48eb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java @@ -17,7 +17,7 @@ * @author Gunnar Morling * @author Marko Bekhta */ -public class FieldCascadable extends PropertyCascadable { +public class FieldCascadable extends AbstractPropertyCascadable { FieldCascadable(Property property, CascadingMetaData cascadingMetaData) { super( property, cascadingMetaData ); @@ -28,7 +28,7 @@ public ConstraintLocationKind getConstraintLocationKind() { return ConstraintLocationKind.FIELD; } - public static class Builder extends PropertyCascadable.Builder { + public static class Builder extends AbstractPropertyCascadable.Builder { protected Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { super( valueExtractorManager, property, cascadingMetaDataBuilder ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java index ea3a398349..8998a6ef1b 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java @@ -17,7 +17,7 @@ * @author Gunnar Morling * @author Marko Bekhta */ -public class GetterCascadable extends PropertyCascadable { +public class GetterCascadable extends AbstractPropertyCascadable { GetterCascadable(Property property, CascadingMetaData cascadingMetaData) { super( property, cascadingMetaData ); @@ -28,7 +28,7 @@ public ConstraintLocationKind getConstraintLocationKind() { return ConstraintLocationKind.GETTER; } - public static class Builder extends PropertyCascadable.Builder { + public static class Builder extends AbstractPropertyCascadable.Builder { protected Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { super( valueExtractorManager, property, cascadingMetaDataBuilder ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index c630c6bfb8..8ca3acca2a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -198,7 +198,7 @@ public final void add(ConstrainedElement constrainedElement) { Property property = constrainable.get().as( Property.class ); Cascadable.Builder builder = cascadableBuilders.get( property ); if ( builder == null ) { - builder = PropertyCascadable.Builder.builder( constrainedElement.getKind(), valueExtractorManager, property, constrainedElement.getCascadingMetaDataBuilder() ); + builder = AbstractPropertyCascadable.Builder.builder( constrainedElement.getKind(), valueExtractorManager, property, constrainedElement.getCascadingMetaDataBuilder() ); cascadableBuilders.put( property, builder ); } else { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java similarity index 88% rename from engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java rename to engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java index 907b03fbe0..edaf2d2c95 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/PropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java @@ -18,14 +18,14 @@ * @author Marko Bekhta * @author Guillaume Smet */ -public abstract class PropertyConstraintLocation implements ConstraintLocation { +public abstract class AbstractPropertyConstraintLocation implements ConstraintLocation { /** * The member the constraint was defined on. */ private final Property property; - PropertyConstraintLocation(Property property) { + AbstractPropertyConstraintLocation(Property property) { this.property = property; } @@ -72,7 +72,7 @@ public boolean equals(Object o) { return false; } - PropertyConstraintLocation that = (PropertyConstraintLocation) o; + AbstractPropertyConstraintLocation that = (AbstractPropertyConstraintLocation) o; if ( !property.equals( that.property ) ) { return false; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index 2a9a90d283..d3337e6ca2 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -94,7 +94,7 @@ static ConstraintLocation forParameter(Callable callable, int index) { /** * Obtains the value of this location from the parent. The type of the passed parent depends on the location type, - * e.g. a bean would be passed for a {@link PropertyConstraintLocation} but an + * e.g. a bean would be passed for a {@link AbstractPropertyConstraintLocation} but an * object array for a {@link ParameterConstraintLocation}. */ Object getValue(Object parent); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java index 594ae9dbef..aa64c61f96 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java @@ -13,7 +13,7 @@ * * @author Marko Bekhta */ -public class FieldConstraintLocation extends PropertyConstraintLocation { +public class FieldConstraintLocation extends AbstractPropertyConstraintLocation { FieldConstraintLocation(Property field) { super( field ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java index 07ab3ecbbd..4327813096 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java @@ -13,7 +13,7 @@ * * @author Marko Bekhta */ -public class GetterConstraintLocation extends PropertyConstraintLocation { +public class GetterConstraintLocation extends AbstractPropertyConstraintLocation { GetterConstraintLocation(Property getter) { super( getter ); From 6d7b067e48a2e9ffb75339e729ae7032bc1ca9bc Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 8 Jun 2018 20:05:23 +0200 Subject: [PATCH 21/24] HV-1623 Introduce Field and Getter as subclasses of Property --- ...tPropertyConstraintMappingContextImpl.java | 2 +- .../TypeConstraintMappingContextImpl.java | 8 +++--- .../PropertyValidationContext.java | 2 +- .../AbstractPropertyCascadable.java | 28 ++++++++++--------- .../metadata/aggregated/FieldCascadable.java | 18 ++++++------ .../metadata/aggregated/GetterCascadable.java | 18 ++++++------ .../metadata/aggregated/PropertyMetaData.java | 11 ++++---- .../AbstractPropertyConstraintLocation.java | 12 ++++---- .../metadata/location/ConstraintLocation.java | 8 +++--- .../location/FieldConstraintLocation.java | 6 ++-- .../location/GetterConstraintLocation.java | 6 ++-- .../metadata/raw/ConstrainedField.java | 20 ++++++------- .../internal/properties/Callable.java | 3 -- .../internal/properties/Constrainable.java | 4 +++ .../validator/internal/properties/Field.java | 20 +++++++++++++ .../validator/internal/properties/Getter.java | 20 +++++++++++++ .../properties/javabean/JavaBeanField.java | 3 +- .../properties/javabean/JavaBeanGetter.java | 4 +-- .../test/cfg/ConstraintMappingTest.java | 2 +- .../AnnotationMetaDataProviderTestBase.java | 2 +- 20 files changed, 120 insertions(+), 77 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/Field.java create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/Getter.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/AbstractPropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/AbstractPropertyConstraintMappingContextImpl.java index 7d0e67ec4e..1cab16b832 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/AbstractPropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/AbstractPropertyConstraintMappingContextImpl.java @@ -46,7 +46,7 @@ protected AbstractPropertyConstraintMappingContextImpl(TypeConstraintMappingCont } @Override - protected AbstractPropertyConstraintMappingContextImpl getThis() { + protected AbstractPropertyConstraintMappingContextImpl getThis() { return this; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java index 0b7b01d7a1..2b5c270ad4 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/TypeConstraintMappingContextImpl.java @@ -69,7 +69,7 @@ public final class TypeConstraintMappingContextImpl extends ConstraintMapping private final Class beanClass; private final Set executableContexts = newHashSet(); - private final Set propertyContexts = newHashSet(); + private final Set> propertyContexts = newHashSet(); private final Set configuredMembers = newHashSet(); private List> defaultGroupSequence; @@ -146,7 +146,7 @@ public PropertyConstraintMappingContext field(String property) { throw LOG.getPropertyHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, property ); } - AbstractPropertyConstraintMappingContextImpl context = new FieldConstraintMappingContextImpl( this, javaBeanField ); + FieldConstraintMappingContextImpl context = new FieldConstraintMappingContextImpl( this, javaBeanField ); configuredMembers.add( javaBeanField ); propertyContexts.add( context ); return context; @@ -166,7 +166,7 @@ public PropertyConstraintMappingContext getter(String property) { throw LOG.getPropertyHasAlreadyBeConfiguredViaProgrammaticApiException( beanClass, property ); } - AbstractPropertyConstraintMappingContextImpl context = new GetterConstraintMappingContextImpl( this, javaBeanGetter ); + GetterConstraintMappingContextImpl context = new GetterConstraintMappingContextImpl( this, javaBeanGetter ); configuredMembers.add( javaBeanGetter ); propertyContexts.add( context ); return context; @@ -258,7 +258,7 @@ private Set buildConstraintElements(ConstraintHelper constra } //properties - for ( AbstractPropertyConstraintMappingContextImpl propertyContext : propertyContexts ) { + for ( AbstractPropertyConstraintMappingContextImpl propertyContext : propertyContexts ) { elements.add( propertyContext.build( constraintHelper, typeResolutionHelper, valueExtractorManager ) ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java index eabacdfc2d..ba79e43a76 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/validationcontext/PropertyValidationContext.java @@ -72,7 +72,7 @@ private String getPropertyName(ConstraintLocation location) { } if ( location instanceof AbstractPropertyConstraintLocation ) { - return ( (AbstractPropertyConstraintLocation) location ).getPropertyName(); + return ( (AbstractPropertyConstraintLocation) location ).getPropertyName(); } return null; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java index 3585f69cab..6eaa887574 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java @@ -11,7 +11,8 @@ import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.facets.Cascadable; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; +import org.hibernate.validator.internal.properties.Field; +import org.hibernate.validator.internal.properties.Getter; import org.hibernate.validator.internal.properties.Property; /** @@ -20,13 +21,13 @@ * @author Gunnar Morling * @author Marko Bekhta */ -public abstract class AbstractPropertyCascadable implements Cascadable { +public abstract class AbstractPropertyCascadable implements Cascadable { - private final Property property; + private final T property; private final Type cascadableType; private final CascadingMetaData cascadingMetaData; - AbstractPropertyCascadable(Property property, CascadingMetaData cascadingMetaData) { + AbstractPropertyCascadable(T property, CascadingMetaData cascadingMetaData) { this.property = property; this.cascadableType = property.getType(); this.cascadingMetaData = cascadingMetaData; @@ -52,13 +53,13 @@ public CascadingMetaData getCascadingMetaData() { return cascadingMetaData; } - public abstract static class Builder implements Cascadable.Builder { + public abstract static class AbstractBuilder implements Cascadable.Builder { private final ValueExtractorManager valueExtractorManager; - private final Property property; + private final T property; private CascadingMetaDataBuilder cascadingMetaDataBuilder; - protected Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { + protected AbstractBuilder(ValueExtractorManager valueExtractorManager, T property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { this.valueExtractorManager = valueExtractorManager; this.property = property; this.cascadingMetaDataBuilder = cascadingMetaDataBuilder; @@ -74,14 +75,15 @@ public Cascadable build() { return create( property, cascadingMetaDataBuilder.build( valueExtractorManager, property ) ); } - protected abstract Cascadable create(Property property, CascadingMetaData build); + protected abstract Cascadable create(T property, CascadingMetaData build); - public static Cascadable.Builder builder(ConstrainedElementKind constrainedElementKind, ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { - if ( ConstrainedElementKind.FIELD == constrainedElementKind ) { - return new FieldCascadable.Builder( valueExtractorManager, property, cascadingMetaDataBuilder ); + public static Cascadable.Builder builder(ValueExtractorManager valueExtractorManager, Property property, + CascadingMetaDataBuilder cascadingMetaDataBuilder) { + if ( property instanceof Field ) { + return new FieldCascadable.Builder( valueExtractorManager, (Field) property, cascadingMetaDataBuilder ); } - else if ( ConstrainedElementKind.GETTER == constrainedElementKind ) { - return new GetterCascadable.Builder( valueExtractorManager, property, cascadingMetaDataBuilder ); + else if ( property instanceof Getter ) { + return new GetterCascadable.Builder( valueExtractorManager, (Getter) property, cascadingMetaDataBuilder ); } throw new IllegalStateException( "It should be either a field or a getter." ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java index e0d5fc48eb..c8ebe21304 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/FieldCascadable.java @@ -9,7 +9,7 @@ import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.facets.Cascadable; import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; -import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.Field; /** * A {@link Cascadable} backed by a field of a Java bean. @@ -17,10 +17,10 @@ * @author Gunnar Morling * @author Marko Bekhta */ -public class FieldCascadable extends AbstractPropertyCascadable { +public class FieldCascadable extends AbstractPropertyCascadable { - FieldCascadable(Property property, CascadingMetaData cascadingMetaData) { - super( property, cascadingMetaData ); + FieldCascadable(Field field, CascadingMetaData cascadingMetaData) { + super( field, cascadingMetaData ); } @Override @@ -28,15 +28,15 @@ public ConstraintLocationKind getConstraintLocationKind() { return ConstraintLocationKind.FIELD; } - public static class Builder extends AbstractPropertyCascadable.Builder { + public static class Builder extends AbstractPropertyCascadable.AbstractBuilder { - protected Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { - super( valueExtractorManager, property, cascadingMetaDataBuilder ); + protected Builder(ValueExtractorManager valueExtractorManager, Field field, CascadingMetaDataBuilder cascadingMetaDataBuilder) { + super( valueExtractorManager, field, cascadingMetaDataBuilder ); } @Override - protected Cascadable create(Property property, CascadingMetaData cascadingMetaData) { - return new FieldCascadable( property, cascadingMetaData ); + protected Cascadable create(Field field, CascadingMetaData cascadingMetaData) { + return new FieldCascadable( field, cascadingMetaData ); } } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java index 8998a6ef1b..ab5da7d89f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/GetterCascadable.java @@ -9,7 +9,7 @@ import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager; import org.hibernate.validator.internal.metadata.facets.Cascadable; import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind; -import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.Getter; /** * A {@link Cascadable} backed by a getter of a Java bean. @@ -17,10 +17,10 @@ * @author Gunnar Morling * @author Marko Bekhta */ -public class GetterCascadable extends AbstractPropertyCascadable { +public class GetterCascadable extends AbstractPropertyCascadable { - GetterCascadable(Property property, CascadingMetaData cascadingMetaData) { - super( property, cascadingMetaData ); + GetterCascadable(Getter getter, CascadingMetaData cascadingMetaData) { + super( getter, cascadingMetaData ); } @Override @@ -28,15 +28,15 @@ public ConstraintLocationKind getConstraintLocationKind() { return ConstraintLocationKind.GETTER; } - public static class Builder extends AbstractPropertyCascadable.Builder { + public static class Builder extends AbstractPropertyCascadable.AbstractBuilder { - protected Builder(ValueExtractorManager valueExtractorManager, Property property, CascadingMetaDataBuilder cascadingMetaDataBuilder) { - super( valueExtractorManager, property, cascadingMetaDataBuilder ); + protected Builder(ValueExtractorManager valueExtractorManager, Getter getter, CascadingMetaDataBuilder cascadingMetaDataBuilder) { + super( valueExtractorManager, getter, cascadingMetaDataBuilder ); } @Override - protected Cascadable create(Property property, CascadingMetaData cascadingMetaData) { - return new GetterCascadable( property, cascadingMetaData ); + protected Cascadable create(Getter getter, CascadingMetaData cascadingMetaData) { + return new GetterCascadable( getter, cascadingMetaData ); } } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 8ca3acca2a..36dd79ca76 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -162,8 +162,8 @@ public Builder(Class beanClass, ConstrainedField constrainedProperty, Constra ValueExtractorManager valueExtractorManager) { super( beanClass, constraintHelper, typeResolutionHelper, valueExtractorManager ); - this.propertyName = constrainedProperty.getProperty().getName(); - this.propertyType = constrainedProperty.getProperty().getType(); + this.propertyName = constrainedProperty.getField().getName(); + this.propertyType = constrainedProperty.getField().getType(); add( constrainedProperty ); } @@ -198,7 +198,8 @@ public final void add(ConstrainedElement constrainedElement) { Property property = constrainable.get().as( Property.class ); Cascadable.Builder builder = cascadableBuilders.get( property ); if ( builder == null ) { - builder = AbstractPropertyCascadable.Builder.builder( constrainedElement.getKind(), valueExtractorManager, property, constrainedElement.getCascadingMetaDataBuilder() ); + builder = AbstractPropertyCascadable.AbstractBuilder.builder( valueExtractorManager, property, + constrainedElement.getCascadingMetaDataBuilder() ); cascadableBuilders.put( property, builder ); } else { @@ -211,7 +212,7 @@ public final void add(ConstrainedElement constrainedElement) { private Optional getConstrainableFromConstrainedElement(ConstrainedElement constrainedElement) { if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { if ( constrainedElement instanceof ConstrainedField ) { - return Optional.of( ( (ConstrainedField) constrainedElement ).getProperty() ); + return Optional.of( ( (ConstrainedField) constrainedElement ).getField() ); } else { LOG.getUnexpectedConstraintElementType( ConstrainedField.class, constrainedElement.getClass() ); @@ -298,7 +299,7 @@ private MetaConstraint withGetterLocation(ConstraintLocation getterConstraint private String getPropertyName(ConstrainedElement constrainedElement) { if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { - return ( (ConstrainedField) constrainedElement ).getProperty().getPropertyName(); + return ( (ConstrainedField) constrainedElement ).getField().getPropertyName(); } else if ( constrainedElement.getKind() == ConstrainedElementKind.GETTER ) { return ( (ConstrainedExecutable) constrainedElement ).getCallable().as( Property.class ).getPropertyName(); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java index edaf2d2c95..d57de16325 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java @@ -18,14 +18,14 @@ * @author Marko Bekhta * @author Guillaume Smet */ -public abstract class AbstractPropertyConstraintLocation implements ConstraintLocation { +public abstract class AbstractPropertyConstraintLocation implements ConstraintLocation { /** - * The member the constraint was defined on. + * The property the constraint was defined on. */ - private final Property property; + private final T property; - AbstractPropertyConstraintLocation(Property property) { + AbstractPropertyConstraintLocation(T property) { this.property = property; } @@ -35,7 +35,7 @@ public Class getDeclaringClass() { } @Override - public Property getConstrainable() { + public T getConstrainable() { return property; } @@ -72,7 +72,7 @@ public boolean equals(Object o) { return false; } - AbstractPropertyConstraintLocation that = (AbstractPropertyConstraintLocation) o; + AbstractPropertyConstraintLocation that = (AbstractPropertyConstraintLocation) o; if ( !property.equals( that.property ) ) { return false; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java index d3337e6ca2..0084fbdde5 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/ConstraintLocation.java @@ -15,8 +15,8 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; -import org.hibernate.validator.internal.properties.javabean.JavaBeanField; -import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; +import org.hibernate.validator.internal.properties.Field; +import org.hibernate.validator.internal.properties.Getter; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; /** @@ -42,11 +42,11 @@ static ConstraintLocation forClass(Class declaringClass) { return new BeanConstraintLocation( declaringClass ); } - static ConstraintLocation forField(JavaBeanField field) { + static ConstraintLocation forField(Field field) { return new FieldConstraintLocation( field ); } - static ConstraintLocation forGetter(JavaBeanGetter getter) { + static ConstraintLocation forGetter(Getter getter) { return new GetterConstraintLocation( getter ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java index aa64c61f96..d7639c0646 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java @@ -6,16 +6,16 @@ */ package org.hibernate.validator.internal.metadata.location; -import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.Field; /** * Field property constraint location. * * @author Marko Bekhta */ -public class FieldConstraintLocation extends AbstractPropertyConstraintLocation { +public class FieldConstraintLocation extends AbstractPropertyConstraintLocation { - FieldConstraintLocation(Property field) { + FieldConstraintLocation(Field field) { super( field ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java index 4327813096..2dee31bf03 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/GetterConstraintLocation.java @@ -6,16 +6,16 @@ */ package org.hibernate.validator.internal.metadata.location; -import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.Getter; /** * Getter property constraint location. * * @author Marko Bekhta */ -public class GetterConstraintLocation extends AbstractPropertyConstraintLocation { +public class GetterConstraintLocation extends AbstractPropertyConstraintLocation { - GetterConstraintLocation(Property getter) { + GetterConstraintLocation(Getter getter) { super( getter ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java index e9f996c89f..143ad0fcc0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java @@ -10,7 +10,7 @@ import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder; import org.hibernate.validator.internal.metadata.core.MetaConstraint; -import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.Field; /** * Represents a field of a Java type and all its associated meta-data relevant @@ -22,41 +22,41 @@ */ public class ConstrainedField extends AbstractConstrainedElement { - private final Property property; + private final Field field; /** * Creates a new field meta data object. * * @param source The source of meta data. - * @param property The represented field. + * @param field The represented field. * @param constraints The constraints of the represented field, if any. * @param typeArgumentConstraints Type arguments constraints, if any. * @param cascadingMetaDataBuilder The cascaded validation metadata for this element and its container elements. */ public ConstrainedField(ConfigurationSource source, - Property property, + Field field, Set> constraints, Set> typeArgumentConstraints, CascadingMetaDataBuilder cascadingMetaDataBuilder) { super( source, ConstrainedElementKind.FIELD, constraints, typeArgumentConstraints, cascadingMetaDataBuilder ); - this.property = property; + this.field = field; } - public Property getProperty() { - return property; + public Field getField() { + return field; } @Override public String toString() { - return "ConstrainedField [property=" + property.getName() + "]"; + return "ConstrainedField [field=" + field.getName() + "]"; } @Override public int hashCode() { int result = super.hashCode(); - result = 31 * result + this.property.hashCode(); + result = 31 * result + this.field.hashCode(); return result; } @@ -72,6 +72,6 @@ public boolean equals(Object obj) { return false; } ConstrainedField other = (ConstrainedField) obj; - return this.property.equals( other.property ); + return this.field.equals( other.field ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java index 2e72191a1d..9ef259f46d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Callable.java @@ -8,7 +8,6 @@ import java.lang.reflect.Type; -import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.util.ExecutableHelper; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; @@ -32,8 +31,6 @@ public interface Callable extends Constrainable { boolean isPrivate(); - ConstrainedElementKind getConstrainedElementKind(); - String getSignature(); boolean overrides(ExecutableHelper executableHelper, Callable superTypeMethod); diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Constrainable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Constrainable.java index a4ab094455..0accde036d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/Constrainable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Constrainable.java @@ -8,6 +8,8 @@ import java.lang.reflect.Type; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; + /** * @author Marko Bekhta */ @@ -21,6 +23,8 @@ public interface Constrainable { Type getType(); + ConstrainedElementKind getConstrainedElementKind(); + @SuppressWarnings("unchecked") default T as(Class clazz) { return ( (T) this ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Field.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Field.java new file mode 100644 index 0000000000..65d72330da --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Field.java @@ -0,0 +1,20 @@ +/* + * 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.properties; + +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; + +/** + * @author Guillaume Smet + */ +public interface Field extends Property { + + @Override + default ConstrainedElementKind getConstrainedElementKind() { + return ConstrainedElementKind.FIELD; + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Getter.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Getter.java new file mode 100644 index 0000000000..fede3102bd --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Getter.java @@ -0,0 +1,20 @@ +/* + * 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.properties; + +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; + +/** + * @author Guillaume Smet + */ +public interface Getter extends Property { + + @Override + default ConstrainedElementKind getConstrainedElementKind() { + return ConstrainedElementKind.GETTER; + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java index c6013a8de0..d966cceb27 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java @@ -15,14 +15,13 @@ import java.security.PrivilegedAction; import org.hibernate.validator.HibernateValidatorPermission; -import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredField; /** * @author Marko Bekhta */ -public class JavaBeanField implements Property, JavaBeanAnnotatedConstrainable { +public class JavaBeanField implements org.hibernate.validator.internal.properties.Field, JavaBeanAnnotatedConstrainable { private final Field field; private final String name; diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java index 722da007d5..82f13915f0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java @@ -12,7 +12,7 @@ import org.hibernate.validator.HibernateValidatorPermission; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; -import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.Getter; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredMethod; @@ -20,7 +20,7 @@ /** * @author Marko Bekhta */ -public class JavaBeanGetter extends JavaBeanMethod implements Property { +public class JavaBeanGetter extends JavaBeanMethod implements Getter { private final String name; diff --git a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java index 73f9d1632b..d1924b6bfb 100644 --- a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java @@ -579,7 +579,7 @@ private BeanConfiguration getBeanConfiguration(Class type) { private ConstrainedField getConstrainedField(BeanConfiguration beanConfiguration, String fieldName) { for ( ConstrainedElement constrainedElement : beanConfiguration.getConstrainedElements() ) { if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD && - ( (ConstrainedField) constrainedElement ).getProperty().getPropertyName().equals( fieldName ) ) { + ( (ConstrainedField) constrainedElement ).getField().getPropertyName().equals( fieldName ) ) { return (ConstrainedField) constrainedElement; } } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTestBase.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTestBase.java index 7a9e68def8..bf6f716428 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTestBase.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/provider/AnnotationMetaDataProviderTestBase.java @@ -77,7 +77,7 @@ protected ConstrainedElement findConstrainedElement(BeanConfiguration beanCon } } else if ( constrainedElement instanceof ConstrainedField ) { - if ( constrainable.equals( ( (ConstrainedField) constrainedElement ).getProperty() ) ) { + if ( constrainable.equals( ( (ConstrainedField) constrainedElement ).getField() ) ) { return constrainedElement; } } From edb5efd06952cc022daddbc409aa05305418bee2 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Sat, 9 Jun 2018 10:40:06 +0200 Subject: [PATCH 22/24] HV-1623 Throw exception in case of unexpected constrainedElement class in property metadata - need to throw an exception rather than just create it - removed the usage of Optional as it isn't needed anymore --- .../metadata/aggregated/PropertyMetaData.java | 59 +++++++++---------- .../validator/internal/util/logging/Log.java | 5 +- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 36dd79ca76..fffa02635a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -16,7 +16,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -35,7 +34,7 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedExecutable; import org.hibernate.validator.internal.metadata.raw.ConstrainedField; -import org.hibernate.validator.internal.properties.Constrainable; +import org.hibernate.validator.internal.properties.Getter; import org.hibernate.validator.internal.properties.Property; import org.hibernate.validator.internal.properties.javabean.JavaBeanGetter; import org.hibernate.validator.internal.util.CollectionHelper; @@ -192,41 +191,39 @@ public final void add(ConstrainedElement constrainedElement) { if ( constrainedElement.getCascadingMetaDataBuilder().isMarkedForCascadingOnAnnotatedObjectOrContainerElements() || constrainedElement.getCascadingMetaDataBuilder().hasGroupConversionsOnAnnotatedObjectOrContainerElements() ) { - Optional constrainable = getConstrainableFromConstrainedElement( constrainedElement ); + Property property = getConstrainableFromConstrainedElement( constrainedElement ); - if ( constrainable.isPresent() ) { - Property property = constrainable.get().as( Property.class ); - Cascadable.Builder builder = cascadableBuilders.get( property ); - if ( builder == null ) { - builder = AbstractPropertyCascadable.AbstractBuilder.builder( valueExtractorManager, property, - constrainedElement.getCascadingMetaDataBuilder() ); - cascadableBuilders.put( property, builder ); - } - else { - builder.mergeCascadingMetaData( constrainedElement.getCascadingMetaDataBuilder() ); - } - } - } - } - - private Optional getConstrainableFromConstrainedElement(ConstrainedElement constrainedElement) { - if ( constrainedElement.getKind() == ConstrainedElementKind.FIELD ) { - if ( constrainedElement instanceof ConstrainedField ) { - return Optional.of( ( (ConstrainedField) constrainedElement ).getField() ); + Cascadable.Builder builder = cascadableBuilders.get( property ); + if ( builder == null ) { + builder = AbstractPropertyCascadable.AbstractBuilder.builder( valueExtractorManager, property, + constrainedElement.getCascadingMetaDataBuilder() ); + cascadableBuilders.put( property, builder ); } else { - LOG.getUnexpectedConstraintElementType( ConstrainedField.class, constrainedElement.getClass() ); + builder.mergeCascadingMetaData( constrainedElement.getCascadingMetaDataBuilder() ); } } - else if ( constrainedElement.getKind() == ConstrainedElementKind.GETTER ) { - if ( constrainedElement instanceof ConstrainedExecutable ) { - return Optional.of( ( (ConstrainedExecutable) constrainedElement ).getCallable() ); - } - else { - LOG.getUnexpectedConstraintElementType( ConstrainedExecutable.class, constrainedElement.getClass() ); - } + } + + private Property getConstrainableFromConstrainedElement(ConstrainedElement constrainedElement) { + switch ( constrainedElement.getKind() ) { + case FIELD: + if ( constrainedElement instanceof ConstrainedField ) { + return ( (ConstrainedField) constrainedElement ).getField(); + } + else { + throw LOG.getUnexpectedConstraintElementType( ConstrainedField.class, constrainedElement.getClass() ); + } + case GETTER: + if ( constrainedElement instanceof ConstrainedExecutable ) { + return ( (ConstrainedExecutable) constrainedElement ).getCallable().as( Getter.class ); + } + else { + throw LOG.getUnexpectedConstraintElementType( ConstrainedExecutable.class, constrainedElement.getClass() ); + } + default: + throw LOG.getUnsupportedConstraintElementType( constrainedElement.getKind() ); } - return Optional.empty(); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index 4267ee49e0..7a0da1e309 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -48,6 +48,7 @@ import org.hibernate.validator.internal.engine.messageinterpolation.parser.MessageDescriptorFormatException; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl.ConstraintType; import org.hibernate.validator.internal.metadata.location.ConstraintLocation; +import org.hibernate.validator.internal.metadata.raw.ConstrainedElement; import org.hibernate.validator.internal.properties.Callable; import org.hibernate.validator.internal.properties.Constrainable; import org.hibernate.validator.internal.util.logging.formatter.ArrayOfClassesObjectFormatter; @@ -861,6 +862,6 @@ ConstraintDefinitionException getConstraintValidatorDefinitionConstraintMismatch @Message(id = 244, value = "ConstrainedElement expected class was %1$s, but instead received %2$s.") AssertionError getUnexpectedConstraintElementType(@FormatWith(ClassObjectFormatter.class) Class expecting, @FormatWith(ClassObjectFormatter.class) Class got); - @Message(id = 245, value = "Allowed ElementTypes are %2$s, but instead received %1$s.") - AssertionError getUnexpectedElementType(ElementType received, @FormatWith(ObjectArrayFormatter.class) ElementType... got); + @Message(id = 245, value = "Allowed constraint element types are FIELD and GETTER, but instead received %1$s.") + AssertionError getUnsupportedConstraintElementType(ConstrainedElement.ConstrainedElementKind kind); } From 0332e6c416b7a806b10c8ea04466b041e549a5fc Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sat, 9 Jun 2018 14:17:11 +0200 Subject: [PATCH 23/24] HV-1623 Make the fields/getters accessible lazily --- .../AbstractPropertyCascadable.java | 5 +++- .../AbstractPropertyConstraintLocation.java | 6 +++- .../internal/properties/Property.java | 4 +-- .../internal/properties/PropertyAccessor.java | 15 ++++++++++ .../properties/javabean/JavaBeanField.java | 27 +++++++++++++---- .../properties/javabean/JavaBeanGetter.java | 29 ++++++++++++++----- 6 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/properties/PropertyAccessor.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java index 6eaa887574..1cb08aea79 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/AbstractPropertyCascadable.java @@ -14,6 +14,7 @@ import org.hibernate.validator.internal.properties.Field; import org.hibernate.validator.internal.properties.Getter; import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.PropertyAccessor; /** * A {@link Cascadable} backed by a property of a Java bean. @@ -24,11 +25,13 @@ public abstract class AbstractPropertyCascadable implements Cascadable { private final T property; + private final PropertyAccessor propertyAccessor; private final Type cascadableType; private final CascadingMetaData cascadingMetaData; AbstractPropertyCascadable(T property, CascadingMetaData cascadingMetaData) { this.property = property; + this.propertyAccessor = property.createAccessor(); this.cascadableType = property.getType(); this.cascadingMetaData = cascadingMetaData; } @@ -40,7 +43,7 @@ public Type getCascadableType() { @Override public Object getValue(Object parent) { - return property.getValueFrom( parent ); + return propertyAccessor.getValueFrom( parent ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java index d57de16325..3d7e105ea3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/AbstractPropertyConstraintLocation.java @@ -10,6 +10,7 @@ import org.hibernate.validator.internal.engine.path.PathImpl; import org.hibernate.validator.internal.properties.Property; +import org.hibernate.validator.internal.properties.PropertyAccessor; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; /** @@ -25,8 +26,11 @@ public abstract class AbstractPropertyConstraintLocation imp */ private final T property; + private final PropertyAccessor propertyAccessor; + AbstractPropertyConstraintLocation(T property) { this.property = property; + this.propertyAccessor = property.createAccessor(); } @Override @@ -55,7 +59,7 @@ public void appendTo(ExecutableParameterNameProvider parameterNameProvider, Path @Override public Object getValue(Object parent) { - return property.getValueFrom( parent ); + return propertyAccessor.getValueFrom( parent ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/Property.java b/engine/src/main/java/org/hibernate/validator/internal/properties/Property.java index f6f1d4c288..12018421e0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/Property.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/Property.java @@ -11,7 +11,7 @@ */ public interface Property extends Constrainable { - Object getValueFrom(Object bean); - String getPropertyName(); + + PropertyAccessor createAccessor(); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/PropertyAccessor.java b/engine/src/main/java/org/hibernate/validator/internal/properties/PropertyAccessor.java new file mode 100644 index 0000000000..b269dbb778 --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/PropertyAccessor.java @@ -0,0 +1,15 @@ +/* + * 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.properties; + +/** + * @author Guillaume Smet + */ +public interface PropertyAccessor { + + Object getValueFrom(Object bean); +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java index d966cceb27..11b15d7542 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java @@ -15,6 +15,7 @@ import java.security.PrivilegedAction; import org.hibernate.validator.HibernateValidatorPermission; +import org.hibernate.validator.internal.properties.PropertyAccessor; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredField; @@ -29,7 +30,7 @@ public class JavaBeanField implements org.hibernate.validator.internal.propertie private final Type type; public JavaBeanField(Field field) { - this.field = getAccessible( field ); + this.field = field; this.name = field.getName(); this.type = ReflectionHelper.typeOf( field ); this.typeForValidatorResolution = ReflectionHelper.boxedType( this.type ); @@ -55,11 +56,6 @@ public Type getTypeForValidatorResolution() { return typeForValidatorResolution; } - @Override - public Object getValueFrom(Object bean) { - return ReflectionHelper.getValue( field, bean ); - } - @Override public String getPropertyName() { return getName(); @@ -90,6 +86,11 @@ public TypeVariable[] getTypeParameters() { return field.getType().getTypeParameters(); } + @Override + public PropertyAccessor createAccessor() { + return new FieldAccessor( field ); + } + @Override public boolean equals(Object o) { if ( this == o ) { @@ -127,6 +128,20 @@ public String toString() { return getName(); } + private static class FieldAccessor implements PropertyAccessor { + + private Field accessibleField; + + private FieldAccessor(Field field) { + this.accessibleField = getAccessible( field ); + } + + @Override + public Object getValueFrom(Object bean) { + return ReflectionHelper.getValue( accessibleField, bean ); + } + } + /** * Returns an accessible copy of the given member. */ diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java index 82f13915f0..a7084b1f9e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanGetter.java @@ -13,6 +13,7 @@ import org.hibernate.validator.HibernateValidatorPermission; import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.properties.Getter; +import org.hibernate.validator.internal.properties.PropertyAccessor; import org.hibernate.validator.internal.util.ExecutableParameterNameProvider; import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredMethod; @@ -33,22 +34,17 @@ public class JavaBeanGetter extends JavaBeanMethod implements Getter { private final Class declaringClass; public JavaBeanGetter(Method method) { - super( getAccessible( method ) ); + super( method ); this.name = ReflectionHelper.getPropertyName( method ); this.declaringClass = method.getDeclaringClass(); } public JavaBeanGetter(Class declaringClass, Method method) { - super( getAccessible( method ) ); + super( method ); this.name = ReflectionHelper.getPropertyName( method ); this.declaringClass = declaringClass; } - @Override - public Object getValueFrom(Object bean) { - return ReflectionHelper.getValue( executable, bean ); - } - @Override public String getPropertyName() { return name; @@ -81,6 +77,11 @@ public ConstrainedElementKind getConstrainedElementKind() { return ConstrainedElementKind.GETTER; } + @Override + public PropertyAccessor createAccessor() { + return new GetterAccessor( executable ); + } + @Override public boolean equals(Object o) { if ( this == o ) { @@ -105,6 +106,20 @@ public int hashCode() { return result; } + private static class GetterAccessor implements PropertyAccessor { + + private Method accessibleGetter; + + private GetterAccessor(Method getter) { + this.accessibleGetter = getAccessible( getter ); + } + + @Override + public Object getValueFrom(Object bean) { + return ReflectionHelper.getValue( accessibleGetter, bean ); + } + } + /** * Returns an accessible copy of the given method. */ From be6861cbb11966bb117c70f2048568acf5ea8e4d Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 11 Jun 2018 10:17:11 +0200 Subject: [PATCH 24/24] HV-1623 Reduce the memory footprint of the new reflection abstraction --- .../provider/AnnotationMetaDataProvider.java | 9 +++++---- .../properties/javabean/JavaBeanExecutable.java | 12 +++--------- .../internal/properties/javabean/JavaBeanField.java | 8 +------- .../properties/javabean/JavaBeanParameter.java | 9 +-------- 4 files changed, 10 insertions(+), 28 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index cac8cb06e7..bb78e18691 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -424,7 +424,7 @@ private List getParameterMetaData(JavaBeanExecutable ja } } - Set> typeArgumentsConstraints = findTypeAnnotationConstraintsForExecutableParameter( parameter ); + Set> typeArgumentsConstraints = findTypeAnnotationConstraintsForExecutableParameter( javaBeanExecutable, parameter ); CascadingMetaDataBuilder cascadingMetaData = findCascadingMetaData( parameter ); metaData.add( @@ -691,11 +691,12 @@ else if ( annotatedType instanceof AnnotatedParameterizedType ) { * * @return a set of type arguments constraints, or an empty set if no constrained type arguments are found */ - protected Set> findTypeAnnotationConstraintsForExecutableParameter(JavaBeanParameter javaBeanParameter) { + protected Set> findTypeAnnotationConstraintsForExecutableParameter(JavaBeanExecutable javaBeanExecutable, + JavaBeanParameter javaBeanParameter) { try { return findTypeArgumentsConstraints( - javaBeanParameter.getExecutable(), - new TypeArgumentExecutableParameterLocation( javaBeanParameter.getExecutable(), javaBeanParameter.getIndex() ), + javaBeanExecutable, + new TypeArgumentExecutableParameterLocation( javaBeanExecutable, javaBeanParameter.getIndex() ), javaBeanParameter.getAnnotatedType() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java index 25e181ba23..baec5ef197 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanExecutable.java @@ -34,14 +34,12 @@ public abstract class JavaBeanExecutable implements Callab protected final T executable; private final Type typeForValidatorResolution; - private final String name; private final boolean hasReturnValue; private final Type type; private final List parameters; JavaBeanExecutable(T executable, boolean hasReturnValue) { this.executable = executable; - this.name = executable.getName(); this.type = ReflectionHelper.typeOf( executable ); this.typeForValidatorResolution = ReflectionHelper.boxedType( type ); this.hasReturnValue = hasReturnValue; @@ -54,7 +52,7 @@ public abstract class JavaBeanExecutable implements Callab Type[] genericParameterTypes = executable.getGenericParameterTypes(); for ( int i = 0; i < parameterArray.length; i++ ) { - parameters.add( new JavaBeanParameter( this, i, parameterArray[i], parameterTypes[i], + parameters.add( new JavaBeanParameter( i, parameterArray[i], parameterTypes[i], getParameterGenericType( parameterTypes, genericParameterTypes, i ) ) ); } this.parameters = CollectionHelper.toImmutableList( parameters ); @@ -92,7 +90,7 @@ public boolean hasParameters() { @Override public String getName() { - return name; + return executable.getName(); } @Override @@ -194,9 +192,6 @@ public boolean equals(Object o) { if ( !this.typeForValidatorResolution.equals( that.typeForValidatorResolution ) ) { return false; } - if ( !this.name.equals( that.name ) ) { - return false; - } return this.type.equals( that.type ); } @@ -204,7 +199,6 @@ public boolean equals(Object o) { public int hashCode() { int result = this.executable.hashCode(); result = 31 * result + this.typeForValidatorResolution.hashCode(); - result = 31 * result + this.name.hashCode(); result = 31 * result + ( this.hasReturnValue ? 1 : 0 ); result = 31 * result + this.type.hashCode(); return result; @@ -213,7 +207,7 @@ public int hashCode() { @Override public String toString() { return ExecutableHelper.getExecutableAsString( - getDeclaringClass().getSimpleName() + "#" + name, + getDeclaringClass().getSimpleName() + "#" + executable.getName(), executable.getParameterTypes() ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java index 11b15d7542..647a33a3de 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanField.java @@ -25,20 +25,18 @@ public class JavaBeanField implements org.hibernate.validator.internal.properties.Field, JavaBeanAnnotatedConstrainable { private final Field field; - private final String name; private final Type typeForValidatorResolution; private final Type type; public JavaBeanField(Field field) { this.field = field; - this.name = field.getName(); this.type = ReflectionHelper.typeOf( field ); this.typeForValidatorResolution = ReflectionHelper.boxedType( this.type ); } @Override public String getName() { - return name; + return field.getName(); } @Override @@ -105,9 +103,6 @@ public boolean equals(Object o) { if ( !this.field.equals( that.field ) ) { return false; } - if ( !this.name.equals( that.name ) ) { - return false; - } if ( !this.typeForValidatorResolution.equals( that.typeForValidatorResolution ) ) { return false; } @@ -117,7 +112,6 @@ public boolean equals(Object o) { @Override public int hashCode() { int result = this.field.hashCode(); - result = 31 * result + this.name.hashCode(); result = 31 * result + this.typeForValidatorResolution.hashCode(); result = 31 * result + this.type.hashCode(); return result; diff --git a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanParameter.java b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanParameter.java index 416b842c79..aae74c8e8d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanParameter.java +++ b/engine/src/main/java/org/hibernate/validator/internal/properties/javabean/JavaBeanParameter.java @@ -17,8 +17,6 @@ */ public class JavaBeanParameter implements JavaBeanAnnotatedElement { - private final JavaBeanExecutable executable; - private final int index; private final Parameter parameter; @@ -27,18 +25,13 @@ public class JavaBeanParameter implements JavaBeanAnnotatedElement { private final Type genericType; - JavaBeanParameter(JavaBeanExecutable executable, int index, Parameter parameter, Class type, Type genericType) { - this.executable = executable; + JavaBeanParameter(int index, Parameter parameter, Class type, Type genericType) { this.index = index; this.parameter = parameter; this.type = type; this.genericType = genericType; } - public JavaBeanExecutable getExecutable() { - return executable; - } - public int getIndex() { return index; }