[hibernate-commits] Hibernate SVN: r19033 - in validator/trunk/hibernate-validator-annotation-processor/src: main/java/org/hibernate/validator/ap/util and 3 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Mar 19 17:27:16 EDT 2010


Author: hardy.ferentschik
Date: 2010-03-19 17:27:15 -0400 (Fri, 19 Mar 2010)
New Revision: 19033

Added:
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/ValidationUsingAtValidAnnotation.java
Modified:
   validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java
   validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/CollectionHelper.java
   validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/ConstraintHelper.java
   validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/ConstraintValidationProcessorTest.java
Log:
HV-294 Applied Gunnar's latest patch

Modified: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java	2010-03-19 05:49:48 UTC (rev 19032)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java	2010-03-19 21:27:15 UTC (rev 19033)
@@ -20,6 +20,7 @@
 import java.text.MessageFormat;
 import java.util.List;
 import java.util.ResourceBundle;
+
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.Element;
@@ -28,6 +29,8 @@
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.ElementKindVisitor6;
 import javax.tools.Diagnostic.Kind;
 
@@ -68,15 +71,13 @@
 
 	private final ConstraintHelper constraintHelper;
 
-	private final AnnotationApiHelper annotationApiHelper;
-
 	public ConstraintAnnotationVisitor(ProcessingEnvironment processingEnvironment) {
 
 		this.processingEnvironment = processingEnvironment;
 
 		errorMessages = ResourceBundle.getBundle( "org.hibernate.validator.ap.ValidationProcessorMessages" );
 
-		annotationApiHelper = new AnnotationApiHelper(
+		AnnotationApiHelper annotationApiHelper = new AnnotationApiHelper(
 				processingEnvironment.getElementUtils(), processingEnvironment.getTypeUtils()
 		);
 
@@ -118,7 +119,8 @@
 	 * specified at the given method. The following checks are performed:</p>
 	 * <ul>
 	 * <li>
-	 * The method must be a JavaBeans getter method (name starts with "is", "get" or "has", no parameters)
+	 * The method must be a JavaBeans getter method (name starts with "is", "get" or "has",
+	 * method has return type, but no parameters).
 	 * </li>
 	 * <li>
 	 * The return type of the method must be supported by the constraints.
@@ -134,18 +136,26 @@
 
 		for ( AnnotationMirror oneAnnotationMirror : mirrors ) {
 
-			if ( constraintHelper.isConstraintAnnotation( oneAnnotationMirror ) ) {
+			switch ( constraintHelper.getAnnotationType( oneAnnotationMirror ) ) {
 
-				checkConstraintAtMethod( method, oneAnnotationMirror );
+				case CONSTRAINT_ANNOTATION:
+					checkConstraintAtMethod( method, oneAnnotationMirror );
+					break;
+
+				case MULTI_VALUED_CONSTRAINT_ANNOTATION:
+					for ( AnnotationMirror onePartOfMultiValuedConstraint :
+							constraintHelper.getPartsOfMultiValuedConstraint( oneAnnotationMirror ) ) {
+
+						checkConstraintAtMethod( method, onePartOfMultiValuedConstraint );
+					}
+					break;
+
+				case GRAPH_VALIDATION_ANNOTATION:
+					checkGraphValidationAnnotationAtMethod( method, oneAnnotationMirror );
 			}
-			else if ( constraintHelper.isMultiValuedConstraint( oneAnnotationMirror ) ) {
-				for ( AnnotationMirror onePartOfMultiValuedConstraint : constraintHelper.getPartsOfMultiValuedConstraint(
-						oneAnnotationMirror
-				) ) {
-					checkConstraintAtMethod( method, onePartOfMultiValuedConstraint );
-				}
-			}
+
 		}
+
 		return null;
 	}
 
@@ -167,17 +177,23 @@
 
 		for ( AnnotationMirror oneAnnotationMirror : mirrors ) {
 
-			if ( constraintHelper.isConstraintAnnotation( oneAnnotationMirror ) ) {
+			switch ( constraintHelper.getAnnotationType( oneAnnotationMirror ) ) {
 
-				checkConstraintAtField( annotatedField, oneAnnotationMirror );
+				case CONSTRAINT_ANNOTATION:
+					checkConstraintAtField( annotatedField, oneAnnotationMirror );
+					break;
+
+				case MULTI_VALUED_CONSTRAINT_ANNOTATION:
+					for ( AnnotationMirror onePartOfMultiValuedConstraint :
+							constraintHelper.getPartsOfMultiValuedConstraint( oneAnnotationMirror ) ) {
+
+						checkConstraintAtField( annotatedField, onePartOfMultiValuedConstraint );
+					}
+					break;
+
+				case GRAPH_VALIDATION_ANNOTATION:
+					checkGraphValidationAnnotationAtField( annotatedField, oneAnnotationMirror );
 			}
-			else if ( constraintHelper.isMultiValuedConstraint( oneAnnotationMirror ) ) {
-				for ( AnnotationMirror onePartOfMultiValuedConstraint : constraintHelper.getPartsOfMultiValuedConstraint(
-						oneAnnotationMirror
-				) ) {
-					checkConstraintAtField( annotatedField, onePartOfMultiValuedConstraint );
-				}
-			}
 		}
 
 		return null;
@@ -195,8 +211,8 @@
 	// TODO GM: do a more complete check of constraint annotation type
 	// declarations:
 	// 
-	// - check, existence of groups(), message(), payload()
-	// - check, retention policy
+	// - check existence of groups(), message(), payload()
+	// - check retention policy
 	// - check, that the set of supported types is not empty
 	// - optionally check, that validated types resolve to non-parametrized types
 	@Override
@@ -205,18 +221,19 @@
 
 		for ( AnnotationMirror oneAnnotationMirror : mirrors ) {
 
-			if ( constraintHelper.isConstraintAnnotation( oneAnnotationMirror ) ) {
+			switch ( constraintHelper.getAnnotationType( oneAnnotationMirror ) ) {
 
-				checkConstraintAtAnnotationType( annotationType, oneAnnotationMirror );
+				case CONSTRAINT_ANNOTATION:
+					checkConstraintAtAnnotationType( annotationType, oneAnnotationMirror );
+					break;
 
-			}
-			else if ( constraintHelper.isMultiValuedConstraint( oneAnnotationMirror ) ) {
+				case MULTI_VALUED_CONSTRAINT_ANNOTATION:
+					for ( AnnotationMirror onePartOfMultiValuedConstraint :
+							constraintHelper.getPartsOfMultiValuedConstraint( oneAnnotationMirror ) ) {
 
-				for ( AnnotationMirror onePartOfMultiValuedConstraint : constraintHelper.getPartsOfMultiValuedConstraint(
-						oneAnnotationMirror
-				) ) {
-					checkConstraintAtAnnotationType( annotationType, onePartOfMultiValuedConstraint );
-				}
+						checkConstraintAtAnnotationType( annotationType, onePartOfMultiValuedConstraint );
+					}
+					break;
 			}
 		}
 
@@ -247,17 +264,20 @@
 
 		for ( AnnotationMirror oneAnnotationMirror : mirrors ) {
 
-			if ( constraintHelper.isConstraintAnnotation( oneAnnotationMirror ) ) {
+			switch ( constraintHelper.getAnnotationType( oneAnnotationMirror ) ) {
 
-				checkConstraintAtType( annotatedType, oneAnnotationMirror );
+				case CONSTRAINT_ANNOTATION:
+					checkConstraintAtType( annotatedType, oneAnnotationMirror );
+					break;
+
+				case MULTI_VALUED_CONSTRAINT_ANNOTATION:
+					for ( AnnotationMirror onePartOfMultiValuedConstraint :
+							constraintHelper.getPartsOfMultiValuedConstraint( oneAnnotationMirror ) ) {
+						checkConstraintAtType( annotatedType, onePartOfMultiValuedConstraint );
+					}
+					break;
 			}
-			else if ( constraintHelper.isMultiValuedConstraint( oneAnnotationMirror ) ) {
-				for ( AnnotationMirror onePartOfMultiValuedConstraint : constraintHelper.getPartsOfMultiValuedConstraint(
-						oneAnnotationMirror
-				) ) {
-					checkConstraintAtType( annotatedType, onePartOfMultiValuedConstraint );
-				}
-			}
+
 		}
 
 		return null;
@@ -298,8 +318,7 @@
 
 	private void checkConstraintAtMethod(ExecutableElement method, AnnotationMirror mirror) {
 
-		if ( !isJavaBeanGetterName( method.getSimpleName().toString() ) ||
-				hasParameters( method ) ) {
+		if ( !isGetterMethod( method ) ) {
 
 			reportError( method, mirror, "ONLY_GETTERS_MAY_BE_ANNOTATED" );
 
@@ -332,6 +351,69 @@
 
 	}
 
+	private void checkGraphValidationAnnotationAtField(
+			VariableElement annotatedField, AnnotationMirror annotationMirror) {
+
+		if ( isStaticElement( annotatedField ) ) {
+
+			reportError(
+					annotatedField, annotationMirror,
+					"STATIC_FIELDS_MAY_NOT_BE_ANNOTATED"
+			);
+
+			return;
+		}
+
+		if ( isPrimitiveType( annotatedField.asType() ) ) {
+
+			reportError(
+					annotatedField, annotationMirror,
+					"ATVALID_NOT_ALLOWED_AT_PRIMITIVE_FIELD"
+			);
+		}
+	}
+
+	private void checkGraphValidationAnnotationAtMethod(
+			ExecutableElement method, AnnotationMirror annotationMirror) {
+
+		if ( !isGetterMethod( method ) ) {
+
+			reportError(
+					method, annotationMirror,
+					"ONLY_GETTERS_MAY_BE_ANNOTATED"
+			);
+
+			return;
+		}
+
+		if ( isStaticElement( method ) ) {
+
+			reportError(
+					method, annotationMirror,
+					"STATIC_METHODS_MAY_NOT_BE_ANNOTATED"
+			);
+
+			return;
+		}
+
+		if ( isPrimitiveType( method.getReturnType() ) ) {
+
+			reportError(
+					method, annotationMirror,
+					"ATVALID_NOT_ALLOWED_AT_METHOD_RETURNING_PRIMITIVE_TYPE"
+			);
+		}
+	}
+
+	private boolean isGetterMethod(ExecutableElement method) {
+		return isJavaBeanGetterName( method.getSimpleName().toString() )
+				&& !hasParameters( method ) && hasReturnValue( method );
+	}
+
+	private boolean hasReturnValue(ExecutableElement method) {
+		return method.getReturnType().getKind() != TypeKind.VOID;
+	}
+
 	private boolean hasParameters(ExecutableElement method) {
 		return !method.getParameters().isEmpty();
 	}
@@ -344,6 +426,10 @@
 		return element.getModifiers().contains( Modifier.STATIC );
 	}
 
+	private boolean isPrimitiveType(TypeMirror typeMirror) {
+		return typeMirror.getKind().isPrimitive();
+	}
+
 	/**
 	 * Reports an error at the given location using the given message key and
 	 * optionally the given message parameters.
@@ -370,4 +456,4 @@
 		);
 	}
 
-}
\ No newline at end of file
+}

Modified: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/CollectionHelper.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/CollectionHelper.java	2010-03-19 05:49:48 UTC (rev 19032)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/CollectionHelper.java	2010-03-19 21:27:15 UTC (rev 19033)
@@ -25,7 +25,7 @@
 
 /**
  * Provides some methods for simplified collection instantiation.
- * 
+ *
  * @author Gunnar Morling
  */
 public class CollectionHelper {
@@ -33,18 +33,18 @@
 	public static <K, V> HashMap<K, V> newHashMap() {
 		return new HashMap<K, V>();
 	}
-	
+
 	public static <T> HashSet<T> newHashSet() {
 		return new HashSet<T>();
 	}
-	
+
 	public static <T> ArrayList<T> newArrayList() {
 		return new ArrayList<T>();
 	}
-	
-	public static <T> Set<T> asSet(T ...ts) {
-		
-		return new HashSet<T>(Arrays.asList(ts));
+
+	public static <T> Set<T> asSet(T... ts) {
+
+		return new HashSet<T>( Arrays.asList( ts ) );
 	}
-	
+
 }
\ No newline at end of file

Modified: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/ConstraintHelper.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/ConstraintHelper.java	2010-03-19 05:49:48 UTC (rev 19032)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/ConstraintHelper.java	2010-03-19 21:27:15 UTC (rev 19033)
@@ -37,6 +37,7 @@
 import javax.lang.model.util.Types;
 import javax.validation.Constraint;
 import javax.validation.ConstraintValidator;
+import javax.validation.Valid;
 import javax.validation.constraints.AssertFalse;
 import javax.validation.constraints.AssertTrue;
 import javax.validation.constraints.DecimalMax;
@@ -86,6 +87,41 @@
 	}
 
 	/**
+	 * The type of an annotation with respect to the BV API.
+	 *
+	 * @author Gunnar Morling
+	 */
+	public enum AnnotationType {
+
+		/**
+		 * Given annotation is a constraint annotation (e.g. @Min).
+		 */
+		CONSTRAINT_ANNOTATION,
+
+		/**
+		 * Given annotation is a multi-valued annotation (e.g.
+		 * <code>
+		 *
+		 * @List({
+		 * @Min(10),
+		 * @Min(value=20, groups= Special.class})
+		 * })
+		 * </code>.
+		 */
+		MULTI_VALUED_CONSTRAINT_ANNOTATION,
+
+		/**
+		 * Given annotation is the @Valid annotation.
+		 */
+		GRAPH_VALIDATION_ANNOTATION,
+
+		/**
+		 * Given annotation is not related to the BV API (e.g. @Resource).
+		 */
+		NO_CONSTRAINT_ANNOTATION
+	}
+
+	/**
 	 * The name of the package containing JSR 303 standard annotations
 	 * ("javax.validation.constraints").
 	 */
@@ -171,61 +207,27 @@
 	}
 
 	/**
-	 * Checks, whether the given annotation mirror represents a constraint
-	 * annotation or not. That's the case, if the given mirror is annotated with
-	 * the {@link Constraint} meta-annotation (which is only allowed at
-	 * annotation declarations).
+	 * Returns the {@link AnnotationType} of the given annotation.
 	 *
 	 * @param annotationMirror The annotation mirror of interest.
 	 *
-	 * @return True, if the given mirror represents a constraint annotation
-	 *         type, false otherwise.
+	 * @return The given mirror's annotation type.
 	 */
-	public boolean isConstraintAnnotation(AnnotationMirror annotationMirror) {
-		return isConstraintAnnotation(
-				annotationMirror.getAnnotationType()
-						.asElement()
-		);
-	}
+	public AnnotationType getAnnotationType(AnnotationMirror annotationMirror) {
 
-	/**
-	 * Checks, whether the given annotation mirror represents a multi-valued
-	 * constraint such as {@link javax.validation.constraints.Pattern.List}.
-	 * That is the case if the annotation has an array-typed attribute with name
-	 * "value", that exclusively contains constraint annotations.
-	 *
-	 * @param annotationMirror The annotation mirror of interest.
-	 *
-	 * @return True, if the given mirror represents a multi-valued constraint,
-	 *         false otherwise.
-	 */
-	public boolean isMultiValuedConstraint(AnnotationMirror annotationMirror) {
-
-		List<? extends AnnotationValue> annotationArrayValue = annotationApiHelper.getAnnotationArrayValue(
-				annotationMirror, "value"
-		);
-
-		for ( AnnotationValue oneAnnotationValue : annotationArrayValue ) {
-
-			Boolean isConstraintAnnotation = oneAnnotationValue.accept(
-					new SimpleAnnotationValueVisitor6<Boolean, Void>() {
-
-						@Override
-						public Boolean visitAnnotation(
-								AnnotationMirror a, Void p) {
-
-							return isConstraintAnnotation( a.getAnnotationType().asElement() );
-						}
-					}, null
-			);
-
-			//TODO GM: have all parts of the array to be constraint annotations?
-			if ( Boolean.TRUE != isConstraintAnnotation ) {
-				return false;
-			}
+		if ( isConstraintAnnotation( annotationMirror ) ) {
+			return AnnotationType.CONSTRAINT_ANNOTATION;
 		}
+		else if ( isMultiValuedConstraint( annotationMirror ) ) {
+			return AnnotationType.MULTI_VALUED_CONSTRAINT_ANNOTATION;
+		}
+		else if ( isGraphValidationAnnotation( annotationMirror ) ) {
+			return AnnotationType.GRAPH_VALIDATION_ANNOTATION;
+		}
+		else {
+			return AnnotationType.NO_CONSTRAINT_ANNOTATION;
+		}
 
-		return true;
 	}
 
 	/**
@@ -246,18 +248,19 @@
 
 		final List<AnnotationMirror> theValue = CollectionHelper.newArrayList();
 
-		for ( AnnotationValue oneValuePart : annotationApiHelper.getAnnotationArrayValue(
-				annotationMirror, "value"
-		) ) {
+		for ( AnnotationValue oneValuePart : annotationApiHelper
+				.getAnnotationArrayValue( annotationMirror, "value" ) ) {
 
 			oneValuePart.accept(
 					new SimpleAnnotationValueVisitor6<Void, Void>() {
 
 						@Override
-						public Void visitAnnotation(
-								AnnotationMirror a, Void p) {
+						public Void visitAnnotation(AnnotationMirror a, Void p) {
 
-							if ( isConstraintAnnotation( a.getAnnotationType().asElement() ) ) {
+							if ( isConstraintAnnotation(
+									a.getAnnotationType()
+											.asElement()
+							) ) {
 								theValue.add( a );
 							}
 
@@ -283,17 +286,103 @@
 	 * @return Whether the given constraint annotation may be specified at
 	 *         elements of the given type.
 	 */
-	public ConstraintCheckResult checkConstraint(DeclaredType constraintAnnotationType, TypeMirror typeOfAnnotatedElement) {
+	public ConstraintCheckResult checkConstraint(
+			DeclaredType constraintAnnotationType,
+			TypeMirror typeOfAnnotatedElement) {
 
-		return isBuiltInConstraint( constraintAnnotationType ) ?
-				checkBuiltInConstraint( constraintAnnotationType, typeOfAnnotatedElement ) :
-				checkCustomConstraint( constraintAnnotationType, typeOfAnnotatedElement );
+		return isBuiltInConstraint( constraintAnnotationType ) ? checkBuiltInConstraint(
+				constraintAnnotationType, typeOfAnnotatedElement
+		)
+				: checkCustomConstraint(
+				constraintAnnotationType,
+				typeOfAnnotatedElement
+		);
 	}
 
 	// ==================================
 	// private API below
 	// ==================================
 
+	/**
+	 * Checks, whether the given annotation mirror represents a constraint
+	 * annotation or not. That's the case, if the given mirror is annotated with
+	 * the {@link Constraint} meta-annotation (which is only allowed at
+	 * annotation declarations).
+	 *
+	 * @param annotationMirror The annotation mirror of interest.
+	 *
+	 * @return True, if the given mirror represents a constraint annotation
+	 *         type, false otherwise.
+	 */
+	private boolean isConstraintAnnotation(AnnotationMirror annotationMirror) {
+		return isConstraintAnnotation(
+				annotationMirror.getAnnotationType()
+						.asElement()
+		);
+	}
+
+	/**
+	 * Checks, whether the given annotation mirror represents a multi-valued
+	 * constraint such as {@link javax.validation.constraints.Pattern.List}.
+	 * That is the case if the annotation has an array-typed attribute with name
+	 * "value", that exclusively contains constraint annotations.
+	 *
+	 * @param annotationMirror The annotation mirror of interest.
+	 *
+	 * @return True, if the given mirror represents a multi-valued constraint,
+	 *         false otherwise.
+	 */
+	private boolean isMultiValuedConstraint(AnnotationMirror annotationMirror) {
+
+		List<? extends AnnotationValue> annotationArrayValue = annotationApiHelper.getAnnotationArrayValue(
+				annotationMirror, "value"
+		);
+
+		// a multi-valued constraint must have at least one value
+		if ( annotationArrayValue.isEmpty() ) {
+			return false;
+		}
+
+		for ( AnnotationValue oneAnnotationValue : annotationArrayValue ) {
+
+			Boolean isConstraintAnnotation = oneAnnotationValue.accept(
+					new SimpleAnnotationValueVisitor6<Boolean, Void>() {
+
+						@Override
+						public Boolean visitAnnotation(
+								AnnotationMirror a, Void p) {
+
+							return isConstraintAnnotation( a.getAnnotationType().asElement() );
+						}
+					}, null
+			);
+
+			//TODO GM: have all parts of the array to be constraint annotations?
+			if ( Boolean.TRUE != isConstraintAnnotation ) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Checks, whether the given mirror represents the {@link Valid} annotation.
+	 *
+	 * @param annotationMirror The annotation mirror of interest.
+	 *
+	 * @return True, if the given mirror represents the @Valid annotation, false
+	 *         otherwise.
+	 */
+	private boolean isGraphValidationAnnotation(
+			AnnotationMirror annotationMirror) {
+
+		return typeUtils.isSameType(
+				annotationMirror.getAnnotationType(),
+				annotationApiHelper.getMirrorForType( Valid.class )
+		);
+	}
+
 	private ConstraintCheckResult checkBuiltInConstraint(DeclaredType builtInAnnotationType, TypeMirror typeOfAnnotatedElement) {
 
 		Set<TypeMirror> allowedTypes = getAllowedTypesForBuiltInConstraint( builtInAnnotationType );
@@ -323,7 +412,7 @@
 	 * constraint-annotation is allowed.
 	 *
 	 * @param customAnnotationType A custom constraint type.
-	 * @param typeOfAnnotatedElement
+	 * @param typeOfAnnotatedElement The type of the annotated element
 	 *
 	 * @return A set with all types supported by the given constraint. May be
 	 *         empty in case of constraint composition, if there is no common
@@ -414,23 +503,44 @@
 				}, null
 		);
 
-		//contains the bindings of the type parameters from the implemented ConstraintValidator
-		//interface, e.g. "ConstraintValidator<CheckCase, String>"
+		TypeMirror supportedType;
+
+		supportedType = getSupportedTypeUsingAnnotationApi( validatorType );
+
+		// TODO GM: Due to HV-293 the type supported by a given validator can't
+		// always be determined when using
+		// the AP within Eclipse. As work around
+		// reflection might be used in such cases (meaning that the validator
+		// and its supported type have to be on
+		// the AP classpath, which normally wasn't required).
+
+		if ( supportedType == null ) {
+			throw new AssertionError(
+					"Couldn't determine the type supported by validator " + validatorType + "."
+			);
+		}
+		return supportedType;
+	}
+
+	private TypeMirror getSupportedTypeUsingAnnotationApi(
+			TypeMirror validatorType) {
+
+		// contains the bindings of the type parameters from the implemented
+		// ConstraintValidator
+		// interface, e.g. "ConstraintValidator<CheckCase, String>"
 		TypeMirror constraintValidatorImplementation = getConstraintValidatorSuperType( validatorType );
 
-		TypeMirror supportedType = constraintValidatorImplementation.accept(
+		return constraintValidatorImplementation.accept(
 				new TypeKindVisitor6<TypeMirror, Void>() {
 
 					@Override
 					public TypeMirror visitDeclared(DeclaredType constraintValidatorImplementation, Void p) {
-						//2nd type parameter contains the data type supported by current validator class, e.g. "String"
+						// 2nd type parameter contains the data type supported by current validator class, e.g. "String"
 						return constraintValidatorImplementation.getTypeArguments().get( 1 );
 					}
 
 				}, null
 		);
-
-		return supportedType;
 	}
 
 	private TypeMirror getConstraintValidatorSuperType(TypeMirror type) {
@@ -445,7 +555,7 @@
 			}
 		}
 
-		throw new AssertionError( "Class " + type + " specified in @Constraint.validatedBy doesn't implement ConstraintValidator." );
+		return null;
 	}
 
 	/**
@@ -542,4 +652,4 @@
 		return theValue;
 	}
 
-}
\ No newline at end of file
+}

Modified: validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties	2010-03-19 05:49:48 UTC (rev 19032)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties	2010-03-19 21:27:15 UTC (rev 19033)
@@ -9,3 +9,5 @@
 STATIC_METHODS_MAY_NOT_BE_ANNOTATED=Only non-static methods may be annotated with constraint annotations.
 STATIC_FIELDS_MAY_NOT_BE_ANNOTATED=Only non-static fields may be annotated with constraint annotations.
 INVALID_DIAGNOSTIC_KIND_GIVEN=The given value {0} is no valid diagnostic kind. Kind.ERROR will be used.
+ATVALID_NOT_ALLOWED_AT_PRIMITIVE_FIELD=Fields of a primitive type must not annotated with @Valid.
+ATVALID_NOT_ALLOWED_AT_METHOD_RETURNING_PRIMITIVE_TYPE=Methods returning a primitive type must not annotated with @Valid.

Modified: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/ConstraintValidationProcessorTest.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/ConstraintValidationProcessorTest.java	2010-03-19 05:49:48 UTC (rev 19032)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/ConstraintValidationProcessorTest.java	2010-03-19 21:27:15 UTC (rev 19033)
@@ -30,6 +30,7 @@
 import org.hibernate.validator.ap.testmodel.FieldLevelValidationUsingBuiltInConstraints;
 import org.hibernate.validator.ap.testmodel.MethodLevelValidationUsingBuiltInConstraints;
 import org.hibernate.validator.ap.testmodel.MultipleConstraintsOfSameType;
+import org.hibernate.validator.ap.testmodel.ValidationUsingAtValidAnnotation;
 import org.hibernate.validator.ap.testmodel.boxing.ValidLong;
 import org.hibernate.validator.ap.testmodel.boxing.ValidLongValidator;
 import org.hibernate.validator.ap.testmodel.boxing.ValidationUsingBoxing;
@@ -314,18 +315,37 @@
 
 		File sourceFile1 = compilerHelper.getSourceFile( MultipleConstraintsOfSameType.class );
 
-		boolean compilationResult =
-				compilerHelper.compile(
-						new ConstraintValidationProcessor(),
-						diagnostics,
-						sourceFile1
-				);
+		boolean compilationResult = compilerHelper.compile(
+				new ConstraintValidationProcessor(), diagnostics, sourceFile1
+		);
 
 		assertFalse( compilationResult );
 		assertThatDiagnosticsMatch(
-				diagnostics, new DiagnosticExpection(
-						Kind.ERROR, 33
-				), new DiagnosticExpection( Kind.ERROR, 33 )
+				diagnostics,
+				new DiagnosticExpection( Kind.ERROR, 33 ),
+				new DiagnosticExpection( Kind.ERROR, 33 )
 		);
 	}
+
+	@Test
+	public void testThatAtValidAnnotationGivenAtNotSupportedTypesCausesCompilationErrors() {
+
+		File sourceFile1 = compilerHelper.getSourceFile( ValidationUsingAtValidAnnotation.class );
+
+		boolean compilationResult = compilerHelper.compile(
+				new ConstraintValidationProcessor(), diagnostics, sourceFile1
+		);
+
+		assertFalse( compilationResult );
+		assertThatDiagnosticsMatch(
+				diagnostics,
+				new DiagnosticExpection( Kind.ERROR, 34 ),
+				new DiagnosticExpection( Kind.ERROR, 40 ),
+				new DiagnosticExpection( Kind.ERROR, 56 ),
+				new DiagnosticExpection( Kind.ERROR, 64 ),
+				new DiagnosticExpection( Kind.ERROR, 72 ),
+				new DiagnosticExpection( Kind.ERROR, 80 ),
+				new DiagnosticExpection( Kind.ERROR, 88 )
+		);
+	}
 }

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/ValidationUsingAtValidAnnotation.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/ValidationUsingAtValidAnnotation.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/ValidationUsingAtValidAnnotation.java	2010-03-19 21:27:15 UTC (rev 19033)
@@ -0,0 +1,91 @@
+// $Id: ValidationUsingAtValidAnnotation.java 18897 2010-02-25 19:12:35Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validator.ap.testmodel;
+
+import java.util.Collection;
+import javax.validation.Valid;
+
+public class ValidationUsingAtValidAnnotation {
+
+	@Valid
+	public Integer integer;
+
+	@Valid
+	public Collection<?> collection1;
+
+	/**
+	 * Not allowed (primitive type).
+	 */
+	@Valid
+	public int primitiveInt;
+
+	/**
+	 * Not allowed (static field).
+	 */
+	@Valid
+	public static Integer staticInteger;
+
+	@Valid
+	public Integer getInteger() {
+		return null;
+	}
+
+	@Valid
+	public Collection<?> getCollection() {
+		return null;
+	}
+
+	/**
+	 * Not allowed (primitive type).
+	 */
+	@Valid
+	public int getPrimitiveInt() {
+		return 0;
+	}
+
+	/**
+	 * Not allowed (static field).
+	 */
+	@Valid
+	public static Integer getStaticInteger() {
+		return null;
+	}
+
+	/**
+	 * Not allowed (no getter).
+	 */
+	@Valid
+	public Collection<?> getCollectionWithParams(int i) {
+		return null;
+	}
+
+	/**
+	 * Not allowed (no getter).
+	 */
+	@Valid
+	public Collection<?> setCollection() {
+		return null;
+	}
+
+	/**
+	 * Not allowed (no getter).
+	 */
+	@Valid
+	public void getVoid() {
+	}
+}



More information about the hibernate-commits mailing list