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/PropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/AbstractPropertyConstraintMappingContextImpl.java
similarity index 56%
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 dcb6681ce5..1cab16b832 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
@@ -7,12 +7,7 @@
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;
import org.hibernate.validator.cfg.context.ContainerElementConstraintMappingContext;
import org.hibernate.validator.cfg.context.MethodConstraintMappingContext;
@@ -21,11 +16,8 @@
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.util.ReflectionHelper;
+import org.hibernate.validator.internal.properties.Property;
import org.hibernate.validator.internal.util.TypeResolutionHelper;
/**
@@ -34,50 +26,27 @@
* @author Hardy Ferentschik
* @author Gunnar Morling
* @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI
+ * @author Marko Bekhta
*/
-final class PropertyConstraintMappingContextImpl
+abstract class AbstractPropertyConstraintMappingContextImpl
- * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary
- * privileged actions within HV's protection domain.
- */
- private
- * 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 forGetter(Getter getter) {
+ return new GetterConstraintLocation( getter );
}
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 +76,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,8 +94,61 @@ 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 AbstractPropertyConstraintLocation} but an
* object array for a {@link ParameterConstraintLocation}.
*/
Object getValue(Object parent);
+
+ /**
+ * Returns the nature of the constraint location.
+ */
+ ConstraintLocationKind getKind();
+
+ enum ConstraintLocationKind {
+ TYPE( ElementType.TYPE ),
+ CONSTRUCTOR( ElementType.CONSTRUCTOR ),
+ METHOD( ElementType.METHOD ),
+ PARAMETER( ElementType.PARAMETER ),
+ FIELD( ElementType.FIELD ),
+ GETTER( ElementType.METHOD ),
+ TYPE_USE( ElementType.TYPE_USE );
+
+ private final ElementType elementType;
+
+ ConstraintLocationKind(ElementType elementType) {
+ this.elementType = elementType;
+ }
+
+ public ElementType getElementType() {
+ return elementType;
+ }
+
+ public boolean isExecutable() {
+ return this == CONSTRUCTOR || isMethod();
+ }
+
+ public boolean isMethod() {
+ return this == METHOD || this == GETTER;
+ }
+
+ 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 0c127fbb0f..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
@@ -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;
/**
@@ -18,23 +18,27 @@
*
* @author Hardy Ferentschik
* @author Gunnar Morling
+ * @author Guillaume Smet
*/
class CrossParameterConstraintLocation implements ConstraintLocation {
- private final Executable executable;
+ private final Callable callable;
- CrossParameterConstraintLocation(Executable executable) {
- this.executable = executable;
+ private final ConstraintLocationKind kind;
+
+ CrossParameterConstraintLocation(Callable callable) {
+ this.callable = callable;
+ this.kind = ConstraintLocationKind.of( callable.getConstrainedElementKind() );
}
@Override
public Class> getDeclaringClass() {
- return executable.getDeclaringClass();
+ return callable.getDeclaringClass();
}
@Override
- public Member getMember() {
- return executable;
+ public Constrainable getConstrainable() {
+ return callable;
}
@Override
@@ -52,17 +56,19 @@ public Object getValue(Object parent) {
return parent;
}
+ @Override
+ public ConstraintLocationKind getKind() {
+ return kind;
+ }
+
@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 +83,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/FieldConstraintLocation.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/location/FieldConstraintLocation.java
index 4e8c21f963..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,136 +6,21 @@
*/
package org.hibernate.validator.internal.metadata.location;
-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.util.ReflectionHelper;
-import org.hibernate.validator.internal.util.StringHelper;
-import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredField;
+import org.hibernate.validator.internal.properties.Field;
/**
- * Field constraint location.
+ * Field property constraint location.
*
- * @author Hardy Ferentschik
- * @author Gunnar Morling
+ * @author Marko Bekhta
*/
-public class FieldConstraintLocation implements ConstraintLocation {
-
- /**
- * 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 Type typeForValidatorResolution;
-
+public class FieldConstraintLocation extends AbstractPropertyConstraintLocation
- * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary
- * privileged actions within HV's protection domain.
- */
- private static
- * It is usually the same as the declaring class of the method itself, except in the XML case when a user could
- * declare a constraint for a specific subclass.
- */
- private final Class> declaringClass;
-
-
- GetterConstraintLocation( Class> declaringClass, Method method ) {
- this.method = method;
- this.accessibleMethod = getAccessible( method );
- this.propertyName = ReflectionHelper.getPropertyName( method );
- this.typeForValidatorResolution = ReflectionHelper.boxedType( ReflectionHelper.typeOf( method ) );
- this.declaringClass = declaringClass;
- }
-
- @Override
- public Class> getDeclaringClass() {
- return declaringClass;
- }
-
- @Override
- public Method getMember() {
- return method;
- }
+public class GetterConstraintLocation extends AbstractPropertyConstraintLocation
- * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary
- * privileged actions within HV's protection domain.
- */
- private static
* 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 {
@@ -809,44 +794,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( 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( 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( executable );
+ return ConstraintLocation.forReturnValue( javaBeanExecutable );
}
}
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