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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Nov 30 10:59:09 EST 2009


Author: hardy.ferentschik
Date: 2009-11-30 10:59:09 -0500 (Mon, 30 Nov 2009)
New Revision: 18102

Added:
   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/
   validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/AnnotationApiHelper.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/
   validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/
   validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/
   validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/
   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
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/FieldLevelValidationUsingBuiltInConstraints.java
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/MethodLevelValidationUsingBuiltInConstraints.java
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CaseMode.java
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CheckCase.java
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CheckCaseValidator.java
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/FieldLevelValidationUsingCustomConstraints.java
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testutil/
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testutil/CompilerTestHelper.java
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/util/
   validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/util/DiagnosticExpection.java
Modified:
   validator/trunk/hibernate-validator-annotation-processor/pom.xml
   validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java
   validator/trunk/hibernate-validator-tck-runner/pom.xml
Log:
 HV-269 (patch from Gunnar)
Added first cut of annotation processor
Made some minor changes to how pathToBeanValidationApiJar is specified using the maven-dependecy-plugin

Modified: validator/trunk/hibernate-validator-annotation-processor/pom.xml
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/pom.xml	2009-11-30 13:37:31 UTC (rev 18101)
+++ validator/trunk/hibernate-validator-annotation-processor/pom.xml	2009-11-30 15:59:09 UTC (rev 18102)
@@ -19,8 +19,54 @@
                     <compilerArgument>-proc:none</compilerArgument>
                 </configuration>
             </plugin>
-		</plugins>
-	</build>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy</id>
+                        <phase>generate-test-sources</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <stripVersion>true</stripVersion>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>javax.validation</groupId>
+                                    <artifactId>validation-api</artifactId>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/lib</outputDirectory>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>            
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <systemProperties>
+                        <property>
+                            <name>testSourceBaseDir</name>
+                            <value>${basedir}/src/test/java</value>
+                        </property>
+                        <!-- 
+                        	Used to specify the class path for the JavaCompiler in tests. For some reason 
+							this is not required within eclipse. The JavaCompiler there has access to all dependencies
+							of the program by default.
+							TODO GM: find a better way to solve this issue
+						 -->
+                        <property>
+                        	<name>pathToBeanValidationApiJar</name>
+                        	<value>${project.build.directory}/lib/validation-api.jar</value>
+                        </property>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+    </plugins>
+    </build>
     <dependencies>
         <dependency>
             <groupId>org.hibernate</groupId>

Added: 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	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintAnnotationVisitor.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,124 @@
+// $Id: ConstraintAnnotationVisitor.java 17946 2009-11-06 18:23:48Z 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;
+
+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.ElementVisitor;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementKindVisitor6;
+import javax.tools.Diagnostic.Kind;
+
+import org.hibernate.validator.ap.util.ConstraintHelper;
+
+/**
+ * An {@link ElementVisitor} that visits elements (type declarations, methods
+ * and fields) annotated with constraint annotations from the Bean Validation
+ * API.
+ * 
+ * TODO GM: visit type declarations.
+ * 
+ * @author Gunnar Morling.
+ * 
+ */
+final class ConstraintAnnotationVisitor extends
+		ElementKindVisitor6<Void, List<AnnotationMirror>> {
+	
+	private ProcessingEnvironment processingEnvironment;
+	
+	private ResourceBundle errorMessages;
+
+	//TODO GM: make configurable using Options API
+	private Kind messagingKind = Kind.ERROR;
+
+	public ConstraintAnnotationVisitor(ProcessingEnvironment processingEnvironment) {
+		
+		this.processingEnvironment = processingEnvironment;
+		errorMessages = ResourceBundle.getBundle("org.hibernate.validator.ap.ValidationProcessorMessages");
+	}
+	
+	/**
+	 * <p>
+	 * Checks whether the given mirrors representing one or more constraint annotations are correctly
+	 * specified at the given method. The following checks are performed:</p>
+	 * <ul>
+	 * <li>
+	 * The method must be a JavaBeans getter method.
+	 * </li> 
+	 * <li>
+	 * TODO GM:
+	 * The return type of the method must be supported by the constraints.
+	 * </li>
+	 * </ul>
+	 */
+	@Override
+	public Void visitExecutableAsMethod(ExecutableElement element,
+			List<AnnotationMirror> mirrors) {
+		
+		for (AnnotationMirror oneAnnotationMirror : mirrors) {
+			if(!isJavaBeanGetterName(element.getSimpleName().toString())) {
+				
+				processingEnvironment.getMessager().printMessage(
+					messagingKind,
+					errorMessages.getString("ONLY_GETTERS_MAY_BE_ANNOTATED"), element, oneAnnotationMirror);
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * <p>
+	 * Checks whether the given mirrors representing one or more constraint annotations are correctly
+	 * specified at the given field. The following checks are performed:</p>
+	 * <ul>
+	 * <li>
+	 * The type of the field must be supported by the constraints.
+	 * </li>
+	 * </ul>
+	 */
+	@Override
+	public Void visitVariableAsField(VariableElement annotatedField, List<AnnotationMirror> mirrors) {
+		
+		for (AnnotationMirror oneAnnotationMirror : mirrors) {
+			
+			ConstraintHelper builtInConstraintHelper = 
+				new ConstraintHelper(processingEnvironment.getElementUtils(), processingEnvironment.getTypeUtils());
+			
+			boolean annotationAllowedAtElementType = 
+				builtInConstraintHelper.isAnnotationAllowedAtElement(oneAnnotationMirror.getAnnotationType(), annotatedField);
+			
+			if(!annotationAllowedAtElementType) {
+				processingEnvironment.getMessager().printMessage(
+					messagingKind,
+					MessageFormat.format(errorMessages.getString("NOT_SUPPORTED_TYPE"), oneAnnotationMirror.getAnnotationType().asElement().getSimpleName()), annotatedField, oneAnnotationMirror);
+			}
+		}
+		
+		return null;
+	}
+	
+	private boolean isJavaBeanGetterName(String name) {
+		return name.startsWith("is") || name.startsWith("has") || name.startsWith("get");
+	}
+	
+}
\ No newline at end of file

Modified: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java	2009-11-30 13:37:31 UTC (rev 18101)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -1,4 +1,4 @@
-// $Id: JPAMetaModelEntityProcessor.java 17946 2009-11-06 18:23:48Z hardy.ferentschik $
+// $Id: ConstraintValidationProcessor.java 17946 2009-11-06 18:23:48Z hardy.ferentschik $
 /*
 * JBoss, Home of Professional Open Source
 * Copyright 2009, Red Hat Middleware LLC, and individual contributors
@@ -17,52 +17,68 @@
 */
 package org.hibernate.validator.ap;
 
+import java.util.List;
+import java.util.Set;
 
-import java.util.Set;
 import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.Messager;
-import javax.annotation.processing.ProcessingEnvironment;
 import javax.annotation.processing.RoundEnvironment;
 import javax.annotation.processing.SupportedAnnotationTypes;
 import javax.annotation.processing.SupportedSourceVersion;
-import static javax.lang.model.SourceVersion.RELEASE_6;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.TypeElement;
 
-import javax.tools.Diagnostic;
+import org.hibernate.validator.ap.util.AnnotationApiHelper;
+import org.hibernate.validator.ap.util.ConstraintHelper;
 
 
 /**
  * Annotation processor for validating Bean Validation constraints.
  *
  * @author Hardy Ferentschik
+ * @author Gunnar Morling
  */
 @SupportedAnnotationTypes("*")
- at SupportedSourceVersion(RELEASE_6)
+ at SupportedSourceVersion(SourceVersion.RELEASE_6)
 public class ConstraintValidationProcessor extends AbstractProcessor {
-	private static final Boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = Boolean.FALSE;
-	private Messager messager;
-
-	public void init(ProcessingEnvironment env) {
-		super.init( env );
-		messager = env.getMessager();
-		messager.printMessage( Diagnostic.Kind.NOTE, "Init Processor " + this );
-	}
-
+	
+	/**
+	 * Whether this processor claims all processed annotations exclusively or not.
+	 */
+	private static final boolean ANNOTATIONS_CLAIMED_EXCLUSIVELY = false;
+	
+	
 	@Override
-	public boolean process(final Set<? extends TypeElement> annotations,
-						   final RoundEnvironment roundEnvironment) {
-
-		if ( roundEnvironment.processingOver() ) {
-			messager.printMessage( Diagnostic.Kind.NOTE, "Last processing round." );
-			return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
-		}
-
-		Set<? extends Element> elements = roundEnvironment.getRootElements();
-		for ( Element element : elements ) {
-			messager.printMessage( Diagnostic.Kind.NOTE, "Processing " + element.toString() );
-		}
-
-		return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
+	public boolean process(
+		final Set<? extends TypeElement> annotations,
+		final RoundEnvironment roundEnvironment) {
+		
+		AnnotationApiHelper typeHelper = new AnnotationApiHelper(processingEnv.getElementUtils(), processingEnv.getTypeUtils());
+		ConstraintAnnotationVisitor v = new ConstraintAnnotationVisitor(processingEnv);
+		ConstraintHelper constraintHelper = new ConstraintHelper(processingEnv.getElementUtils(), processingEnv.getTypeUtils());
+		
+		for (TypeElement oneAnnotation : annotations) {
+			
+			//only constraint annotations are relevant
+			if(!constraintHelper.isConstraintAnnotation(oneAnnotation)) {
+				continue;
+			}
+			
+			Set<? extends Element> elementsWithConstraintAnnotation = 
+				roundEnvironment.getElementsAnnotatedWith(oneAnnotation);
+			
+			for (Element oneAnnotatedElement : elementsWithConstraintAnnotation) {
+				
+				List<AnnotationMirror> mirrorsOfCurrentAnnotation = 
+					typeHelper.filterByType(oneAnnotatedElement.getAnnotationMirrors(), oneAnnotation.asType());
+				
+				
+				oneAnnotatedElement.accept(v, mirrorsOfCurrentAnnotation);			
+			}
+		}	
+		
+		return ANNOTATIONS_CLAIMED_EXCLUSIVELY;
 	}
+	
 }

Added: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/AnnotationApiHelper.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/AnnotationApiHelper.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/AnnotationApiHelper.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,99 @@
+// $Id: ConstraintHelper.java 17946 2009-11-06 18:23:48Z 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.util;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+/**
+ * A helper class providing some useful methods to work with types
+ * from the JSR-269-API.
+ * 
+ * @author Gunnar Morling
+ *
+ */
+public class AnnotationApiHelper {
+
+	private Elements elementUtils;
+	
+	private Types typeUtils;
+
+	public AnnotationApiHelper(Elements elementUtils, Types typeUtils) {
+
+		this.elementUtils = elementUtils;
+		this.typeUtils = typeUtils;
+	}
+	
+	/**
+	 * Returns a list containing those annotation mirrors from the input list,
+	 * which are of type <code>annotationType</code>. The input collection
+	 * remains untouched.
+	 * 
+	 * @param annotationMirrors
+	 *            A list of annotation mirrors.
+	 * @param annotationType
+	 *            The type to be compared against.
+	 * 
+	 * @return A list with those annotation mirrors from the input list, which
+	 *         are of type <code>annotationType</code>. May be empty but never
+	 *         null.
+	 */
+	public List<AnnotationMirror> filterByType(List<? extends AnnotationMirror> annotationMirrors, TypeMirror annotationType) {
+
+		List<AnnotationMirror> theValue = new ArrayList<AnnotationMirror>();
+
+		if(annotationMirrors == null || annotationType == null) {
+			return theValue;
+		}
+		
+		for (AnnotationMirror oneAnnotationMirror : annotationMirrors) {
+
+			if (typeUtils.isSameType(oneAnnotationMirror.getAnnotationType(), annotationType)) {
+				theValue.add(oneAnnotationMirror);
+			}
+		}
+
+		return theValue;
+	}
+	
+    public AnnotationMirror getMirror(List<? extends AnnotationMirror> annotationMirrors, Class<? extends Annotation> annotationClazz) {
+    	
+		if(annotationMirrors == null || annotationClazz == null) {
+			return null;
+		}
+		
+		for (AnnotationMirror oneAnnotationMirror : annotationMirrors) {
+
+			TypeElement typeElement = elementUtils.getTypeElement(annotationClazz.getCanonicalName());
+						
+			if (typeUtils.isSameType(oneAnnotationMirror.getAnnotationType(), typeElement.asType())) {
+				return oneAnnotationMirror;
+			}
+		}
+
+        return null;
+    }
+
+}

Added: 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	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/CollectionHelper.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,50 @@
+// $Id: CollectionHelper.java 17946 2009-11-06 18:23:48Z 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.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Provides some methods for simplified collection instantiation.
+ * 
+ * @author Gunnar Morling
+ */
+public class CollectionHelper {
+
+	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));
+	}
+	
+}
\ No newline at end of file

Added: 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	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/util/ConstraintHelper.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,295 @@
+// $Id: ConstraintHelper.java 17946 2009-11-06 18:23:48Z 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.util;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.validation.Constraint;
+import javax.validation.ConstraintValidator;
+import javax.validation.constraints.AssertTrue;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+/**
+ * Helper class that deals with all constraint-related stuff, such as
+ * determining whether a given annotation represents a constraint annotation or
+ * whether a given annotation is allowed to be declared at a given element.
+ * 
+ * @author Gunnar Morling
+ * 
+ */
+public class ConstraintHelper {
+
+	/**
+	 * The name of the package containing JSR 303 standard annotations
+	 * ("javax.validation.constraints").
+	 */
+	private final Name CONSTRAINT_ANNOTATION_PACKAGE_NAME;
+	
+	private static Map<Name, Set<TypeElement>> builtInConstraints;
+	
+	private Elements elementUtils;
+	
+	private Types typeUtils;
+
+	public ConstraintHelper(Elements elementUtils, Types typeUtils) {
+
+		this.elementUtils = elementUtils;
+		this.typeUtils = typeUtils;
+		
+		CONSTRAINT_ANNOTATION_PACKAGE_NAME = elementUtils.getName(Size.class.getPackage().getName());
+		
+		builtInConstraints = CollectionHelper.newHashMap();
+		
+		//TODO GM: register all types
+		registerAllowedTypesForBuiltInConstraint(Size.class, CollectionHelper.<Class<?>>asSet(Collection.class, String.class));
+		registerAllowedTypesForBuiltInConstraint(AssertTrue.class, CollectionHelper.<Class<?>>asSet(Boolean.class, boolean.class));
+		registerAllowedTypesForBuiltInConstraint(NotNull.class, CollectionHelper.<Class<?>>asSet(Object.class));
+		registerAllowedTypesForBuiltInConstraint(Min.class, CollectionHelper.<Class<?>>asSet(Integer.class, Long.class));
+	}
+
+	/**
+	 * Checks, whether the given type element represents a constraint annotation
+	 * or not. That's the case, if the given element is annotated with the
+	 * {@link Constraint} meta-annotation (which is only allowed at annotation
+	 * declarations).
+	 * 
+	 * @param The
+	 *            element of interest.
+	 * @return True, if the given element is a constraint annotation type, false
+	 *         otherwise.
+	 */
+	public boolean isConstraintAnnotation(TypeElement typeElement) {
+		return typeElement.getAnnotation(Constraint.class) != null;
+	}
+
+	public boolean isAnnotationAllowedAtElement(DeclaredType annotationType, Element annotatedElement) {
+		
+		Set<TypeElement> allowedTypesForConstraint = getAllowedTypesForConstraint(annotationType);
+		
+		if(allowedTypesForConstraint.isEmpty()) {
+			return false;
+		}
+		
+		Element typeElementOfAnnotatedElement = typeUtils.asElement(annotatedElement.asType());
+		
+		
+		if(allowedTypesForConstraint.contains(typeElementOfAnnotatedElement)) {
+			return true;
+		}
+		
+		List<? extends TypeMirror> directSupertypes = typeUtils.directSupertypes(annotatedElement.asType());
+		
+		while(!directSupertypes.isEmpty()) {
+			List<TypeMirror> nextSupertypes = CollectionHelper.newArrayList();
+			for (TypeMirror oneSuperType : directSupertypes) {
+				
+				Element oneSuperTypeAsElement = typeUtils.asElement(oneSuperType);
+				
+				if(allowedTypesForConstraint.contains(oneSuperTypeAsElement)) {
+					return true;
+				}
+				
+				nextSupertypes.addAll(typeUtils.directSupertypes(oneSuperType));
+			}
+			
+			directSupertypes = nextSupertypes;
+		}
+		
+		
+		return false;
+	}
+
+	// ==================================
+	// private API below
+	// ==================================
+	
+	/**
+	 * Returns a set with all those type elements, at which the given constraint annotation
+	 * type may be specified.
+	 * 
+	 * @param annotationType
+	 * @return
+	 */
+	private Set<TypeElement> getAllowedTypesForConstraint(DeclaredType annotationType) {
+		
+		if(isBuiltInConstraint(annotationType)) {
+			return getAllowedTypesFromBuiltInConstraint(annotationType);
+		}
+		else {
+			return getAllowedTypesFromCustomConstraint(annotationType);
+		}
+	}
+	
+	private Set<TypeElement> getAllowedTypesFromBuiltInConstraint(DeclaredType builtInAnnotationType) {
+		
+		Set<TypeElement> theValue = builtInConstraints.get(builtInAnnotationType.asElement().getSimpleName());
+		
+		if(theValue == null) {
+			theValue = Collections.emptySet();
+		}		
+		
+		return theValue;
+	}
+	
+	/**
+	 * Returns a set containing all those types, at which the specified custom
+	 * constraint-annotation is allowed.
+	 * 
+	 * @param customInAnnotationType
+	 *            A custom constraint type.
+	 * 
+	 * @return A set with all types supported by the given constraint. May be
+	 *         empty in case of constraint composition, if there is no common
+	 *         type supported by all composing constraints.
+	 * 
+	 *         TODO GM: consider constraint composition
+	 */
+	private Set<TypeElement> getAllowedTypesFromCustomConstraint(DeclaredType customInAnnotationType) {
+		
+		Set<TypeElement> theValue = CollectionHelper.newHashSet();
+		
+		//the Constraint meta-annotation at the type declaration, e.g. "@Constraint(validatedBy = CheckCaseValidator.class)"
+		AnnotationMirror constraintMetaAnnotation = getConstraintMetaAnnotation(customInAnnotationType);
+		
+		if(constraintMetaAnnotation == null) {
+			return theValue;
+		}
+		
+		//the validator classes, e.g. [CheckCaseValidator.class]
+		List<? extends AnnotationValue> validatorClassReferences = getValidatorClassesFromConstraintMetaAnnotation(constraintMetaAnnotation);
+
+		for (AnnotationValue oneValidatorClassReference : validatorClassReferences) {
+			
+			DeclaredType validatorType = (DeclaredType)oneValidatorClassReference.getValue();
+			
+			//contains the bindings of the type parameters from the implemented ConstraintValidator
+			//interface, e.g. "ConstraintValidator<CheckCase, String>"
+			DeclaredType constraintValidatorImplementation = getConstraintValidatorSuperType(validatorType);
+			
+			if(constraintValidatorImplementation != null) {
+					
+				//2nd type parameter contains the data type supported by current validator class, e.g. "String"
+				TypeMirror supportedTypeParameter = constraintValidatorImplementation.getTypeArguments().get(1);
+				theValue.add((TypeElement)typeUtils.asElement(supportedTypeParameter));
+			}
+		}
+		
+		return theValue;
+	}
+	
+	private DeclaredType getConstraintValidatorSuperType(DeclaredType type) {
+				
+		List<? extends TypeMirror> directSupertypes = typeUtils.directSupertypes(type);
+		
+		for (TypeMirror typeMirror : directSupertypes) {
+			if(typeUtils.asElement(typeMirror).getSimpleName().contentEquals(ConstraintValidator.class.getSimpleName())) {
+				return (DeclaredType)typeMirror;
+			}
+		}
+		
+		return null;
+	}
+	
+	/**
+	 * Retrieves the {@link Constraint} meta-annotation from the given constraint annotation.
+	 * 
+	 * @param annotationType A constraint type.
+	 * 
+	 * @return The Constraint meta-annotation or null if it isn't specified at the given type.
+	 */
+	private AnnotationMirror getConstraintMetaAnnotation(DeclaredType annotationType) {
+		
+		List<? extends AnnotationMirror> annotationMirrors = annotationType.asElement().getAnnotationMirrors();
+		
+		return new AnnotationApiHelper(elementUtils, typeUtils).getMirror(annotationMirrors, Constraint.class);
+	}
+	
+	private List<? extends AnnotationValue> getValidatorClassesFromConstraintMetaAnnotation(AnnotationMirror constraintMetaAnnotation) {
+		
+		Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = constraintMetaAnnotation.getElementValues();
+		
+		for (Entry<? extends ExecutableElement, ? extends AnnotationValue> oneElementValue : elementValues.entrySet()) {
+			
+			if(oneElementValue.getKey().getSimpleName().contentEquals("validatedBy")) {
+				
+				//this is save, as we know that the "validatedBy" attribute is an array of classes
+				@SuppressWarnings("unchecked")
+				List<? extends AnnotationValue> validatorClasses = (List<? extends AnnotationValue>)oneElementValue.getValue().getValue();
+				
+				return validatorClasses;
+			}
+		}
+		
+		return Collections.emptyList();
+	}
+	
+	private void registerAllowedTypesForBuiltInConstraint(Class<? extends Annotation> annotation, Set<Class<?>> allowedTypes) {
+		
+		Set<TypeElement> allowedTypesAsElements = CollectionHelper.newHashSet();
+		
+		for (Class<?> oneType : allowedTypes) {
+			TypeElement typeElement = elementUtils.getTypeElement(oneType.getCanonicalName());
+			
+			if(typeElement != null) {
+				allowedTypesAsElements.add(typeElement);
+			}
+		}
+
+		builtInConstraints.put(elementUtils.getName(annotation.getSimpleName()), allowedTypesAsElements);
+	}
+		
+	/**
+	 * Checks, whether the given type is a built-in constraint annotation (which
+	 * is the case, if is annotated with the {@link Constraint} meta-annotation
+	 * and is declared in the package <code>javax.validation.constraints</code>).
+	 * 
+	 * @param annotationType
+	 *            The type to check.
+	 * @return True, if the given type is a constraint annotation, false
+	 *         otherwise.
+	 */
+	private boolean isBuiltInConstraint(DeclaredType annotationType) {
+		
+		Element element = annotationType.asElement();
+		
+		if(element.getAnnotation(Constraint.class) == null) {
+			return false;
+		}
+		
+		return CONSTRAINT_ANNOTATION_PACKAGE_NAME.equals(elementUtils.getPackageOf(element).getQualifiedName());
+	}
+	
+}
\ No newline at end of file

Added: 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	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,6 @@
+# $Id: ValidationProcessorMessages.properties 17927 2009-11-05 09:51:52Z hardy.ferentschik $
+#
+# Contains error messages to be used by the ConstraintValidationProcessor.
+
+ONLY_GETTERS_MAY_BE_ANNOTATED=Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods.
+NOT_SUPPORTED_TYPE=The annotation @{0} is disallowed for this data type.
\ No newline at end of file

Added: 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	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/ConstraintValidationProcessorTest.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,111 @@
+// $Id: ConstraintValidationProcessorTest.java 17946 2009-11-06 18:23:48Z 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;
+
+import static org.hibernate.validator.ap.testutil.CompilerTestHelper.assertDiagnostics;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+import java.io.File;
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+import javax.tools.ToolProvider;
+import javax.tools.Diagnostic.Kind;
+
+import org.hibernate.validator.ap.testmodel.FieldLevelValidationUsingBuiltInConstraints;
+import org.hibernate.validator.ap.testmodel.MethodLevelValidationUsingBuiltInConstraints;
+import org.hibernate.validator.ap.testmodel.customconstraints.CaseMode;
+import org.hibernate.validator.ap.testmodel.customconstraints.CheckCase;
+import org.hibernate.validator.ap.testmodel.customconstraints.CheckCaseValidator;
+import org.hibernate.validator.ap.testmodel.customconstraints.FieldLevelValidationUsingCustomConstraints;
+import org.hibernate.validator.ap.testutil.CompilerTestHelper;
+import org.hibernate.validator.ap.util.DiagnosticExpection;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Test for {@link ConstraintValidationProcessor} using the Java compiler
+ * API as defined by JSR 199.
+ * 
+ * @author Gunnar Morling.
+ *
+ */
+public class ConstraintValidationProcessorTest {
+
+	private static CompilerTestHelper compilerHelper;
+	
+	@BeforeClass
+	public static void setUpCompilerHelper() {
+
+		String testSourceBaseDir = System.getProperty("testSourceBaseDir");
+		String pathToBeanValidationApiJar = System.getProperty("pathToBeanValidationApiJar");
+		
+		assertNotNull(testSourceBaseDir, "The system property testSourceBaseDir has to be set and point to the base directory of the test java sources.");
+		assertNotNull(pathToBeanValidationApiJar, "The system property pathToBeanValidationApiJar has to be set and point to the BV API Jars.");
+		
+		compilerHelper = 
+			new CompilerTestHelper(ToolProvider.getSystemJavaCompiler(), testSourceBaseDir, pathToBeanValidationApiJar);
+	}
+
+	@Test
+	public void fieldLevelValidationUsingBuiltInConstraints() {
+
+		DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
+		
+		File sourceFile = compilerHelper.getSourceFile(FieldLevelValidationUsingBuiltInConstraints.class);
+		
+		boolean compilationResult = 
+			compilerHelper.compile(new ConstraintValidationProcessor(), diagnostics, sourceFile);
+
+		assertFalse(compilationResult);
+		assertDiagnostics(diagnostics, new DiagnosticExpection(Kind.ERROR, 48));
+	}
+	
+	@Test
+	public void fieldLevelValidationUsingCustomConstraints() {
+
+		DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
+		
+		File sourceFile1 = compilerHelper.getSourceFile(FieldLevelValidationUsingCustomConstraints.class);
+		File sourceFile2 = compilerHelper.getSourceFile(CheckCase.class);
+		File sourceFile3 = compilerHelper.getSourceFile(CaseMode.class);
+		File sourceFile4 = compilerHelper.getSourceFile(CheckCaseValidator.class);
+		
+		boolean compilationResult = 
+			compilerHelper.compile(new ConstraintValidationProcessor(), diagnostics, sourceFile1, sourceFile2, sourceFile3, sourceFile4);
+
+		assertFalse(compilationResult);
+		assertDiagnostics(diagnostics, new DiagnosticExpection(Kind.ERROR, 30));
+	}
+	
+	@Test
+	public void methodLevelValidationUsingBuiltInConstraints() {
+
+		DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
+		
+		File sourceFile = compilerHelper.getSourceFile(MethodLevelValidationUsingBuiltInConstraints.class);
+		
+		boolean compilationResult = 
+			compilerHelper.compile(new ConstraintValidationProcessor(), diagnostics, sourceFile);
+
+		assertFalse(compilationResult);
+		assertDiagnostics(diagnostics, new DiagnosticExpection(Kind.ERROR, 32));
+	}
+	
+}
\ No newline at end of file

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/FieldLevelValidationUsingBuiltInConstraints.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/FieldLevelValidationUsingBuiltInConstraints.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/FieldLevelValidationUsingBuiltInConstraints.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,51 @@
+// $Id: FieldLevelValidationUsingBuiltInConstraints.java 17946 2009-11-06 18:23:48Z 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 java.util.Date;
+import java.util.List;
+
+import javax.validation.constraints.Size;
+
+public class FieldLevelValidationUsingBuiltInConstraints {
+
+	@Size(min=10)
+	public String string;
+	
+	@Size(min=10)
+	public Collection<String> collection;
+	
+	//TODO GM: support array-typed elements
+	
+//	@Size(min=10)
+//	public boolean[] array;
+	
+	/**
+	 * Allowed, as List extends Collection.
+	 */
+	@Size(min=10)
+	public List<String> list;
+	
+	/**
+	 * Not allowed.
+	 */
+	@Size(min=10)
+	public Date date;
+
+}

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/MethodLevelValidationUsingBuiltInConstraints.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/MethodLevelValidationUsingBuiltInConstraints.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/MethodLevelValidationUsingBuiltInConstraints.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,37 @@
+// $Id: MethodLevelValidationUsingBuiltInConstraints.java 17946 2009-11-06 18:23:48Z 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 javax.validation.constraints.Size;
+
+public class MethodLevelValidationUsingBuiltInConstraints {
+
+	@Size(min=10)
+	public String getString() {
+		return null;
+	}
+	
+	/**
+	 * Not allowed. Method is no getter.
+	 */
+	@Size(min=10)
+	public void setString() {
+		
+	}
+
+}

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CaseMode.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CaseMode.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CaseMode.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,26 @@
+// $Id: CaseMode.java 17946 2009-11-06 18:23:48Z 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.customconstraints;
+
+public enum CaseMode {
+
+	UPPER, 
+	
+	LOWER;
+
+}

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CheckCase.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CheckCase.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CheckCase.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,43 @@
+// $Id: CheckCase.java 17946 2009-11-06 18:23:48Z 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.customconstraints;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+
+ at Target( { METHOD, FIELD, ANNOTATION_TYPE })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = CheckCaseValidator.class)
+ at Documented
+public @interface CheckCase {
+
+    String message() default "{validator.checkcase}";
+
+    Class<?>[] groups() default {};
+    
+    CaseMode value();
+
+}

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CheckCaseValidator.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CheckCaseValidator.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/CheckCaseValidator.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,44 @@
+// $Id: CheckCaseValidator.java 17946 2009-11-06 18:23:48Z 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.customconstraints;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+public class CheckCaseValidator implements
+ConstraintValidator<CheckCase, String> {
+
+	private CaseMode caseMode;
+
+	public void initialize(CheckCase constraintAnnotation) {
+		this.caseMode = constraintAnnotation.value();
+	}
+
+	public boolean isValid(String object,
+			ConstraintValidatorContext constraintContext) {
+
+		if (object == null)
+			return true;
+
+		if (caseMode == CaseMode.UPPER)
+			return object.equals(object.toUpperCase());
+		else
+			return object.equals(object.toLowerCase());
+	}
+
+}

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/FieldLevelValidationUsingCustomConstraints.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/FieldLevelValidationUsingCustomConstraints.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/customconstraints/FieldLevelValidationUsingCustomConstraints.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,33 @@
+// $Id: FieldLevelValidationUsingCustomConstraints.java 17946 2009-11-06 18:23:48Z 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.customconstraints;
+
+import java.util.Date;
+
+public class FieldLevelValidationUsingCustomConstraints {
+
+	@CheckCase(CaseMode.UPPER)
+	public String string;
+	
+	/**
+	 * Not allowed.
+	 */
+	@CheckCase(CaseMode.UPPER)
+	public Date date;
+
+}

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testutil/CompilerTestHelper.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testutil/CompilerTestHelper.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testutil/CompilerTestHelper.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,105 @@
+// $Id: CompilerTestHelper.java 17946 2009-11-06 18:23:48Z 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.testutil;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.processing.Processor;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.JavaCompiler.CompilationTask;
+
+import org.hibernate.validator.ap.util.DiagnosticExpection;
+
+/**
+ * Infrastructure for unit tests based on the Java Compiler API.
+ * 
+ * @author Gunnar Morling
+ *
+ */
+public class CompilerTestHelper {
+
+	private final JavaCompiler compiler;
+	
+	private final String sourceBaseDir;
+
+	/**
+	 * TODO GM: How can JavaCompiler access all dependencies of the project? This works within
+	 * Eclipse, but not on the command line.
+	 */
+	private final String pathToBeanValidationApiJar;
+	
+	public CompilerTestHelper(JavaCompiler compiler, String sourceBaseDir, String pathToBeanValidationApiJar) {
+
+		this.compiler = compiler;
+		this.sourceBaseDir = sourceBaseDir;
+		this.pathToBeanValidationApiJar = pathToBeanValidationApiJar;
+	}
+
+	public File getSourceFile(Class<?> clazz) {
+		
+		String sourceFileName =
+			File.separator + clazz.getName().replace(".", File.separator) + ".java";
+		
+		return new File(sourceBaseDir + sourceFileName);
+	}
+	
+	public boolean compile(
+		Processor annotationProcessor, DiagnosticCollector<JavaFileObject> diagnostics, File... sourceFiles) {
+		
+		StandardJavaFileManager fileManager = 
+			compiler.getStandardFileManager(null, null, null);
+		
+		Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(sourceFiles);
+		List<String> optionList = new ArrayList<String>();
+		optionList.addAll(Arrays.asList("-classpath", pathToBeanValidationApiJar));
+
+		CompilationTask task = compiler.getTask(null, fileManager, diagnostics, optionList, null, compilationUnits);
+
+		task.setProcessors(Arrays.asList(annotationProcessor));
+		
+		return task.call();
+	}
+	
+	public static void assertDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics, DiagnosticExpection... expections) {
+		
+		if(expections == null) {
+			assertTrue(diagnostics.getDiagnostics().isEmpty());
+		}
+		else {
+			
+			assertEquals(diagnostics.getDiagnostics().size(), expections.length);
+			
+			int i = 0;
+			for (DiagnosticExpection oneExpection : expections) {
+				
+				assertEquals(diagnostics.getDiagnostics().get(i).getKind(), oneExpection.getKind());
+				assertEquals(diagnostics.getDiagnostics().get(i).getLineNumber(), oneExpection.getLineNumber());
+			}
+		}
+	}
+	
+}

Added: validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/util/DiagnosticExpection.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/util/DiagnosticExpection.java	                        (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/util/DiagnosticExpection.java	2009-11-30 15:59:09 UTC (rev 18102)
@@ -0,0 +1,47 @@
+// $Id: DiagnosticExpection.java 17946 2009-11-06 18:23:48Z 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.util;
+
+import javax.tools.Diagnostic;
+import javax.tools.Diagnostic.Kind;
+
+/**
+ * Expectation value to be matched against a given {@link Diagnostic}.
+ * 
+ * @author Gunnar Morling
+ */
+public class DiagnosticExpection {
+	
+	private final Kind kind;
+	
+	private final long lineNumber;
+	
+	public DiagnosticExpection(Kind kind, long lineNumber) {
+		
+		this.kind = kind;
+		this.lineNumber = lineNumber;
+	}
+
+	public Kind getKind() {
+		return kind;
+	}
+
+	public long getLineNumber() {
+		return lineNumber;
+	}
+}
\ No newline at end of file

Modified: validator/trunk/hibernate-validator-tck-runner/pom.xml
===================================================================
--- validator/trunk/hibernate-validator-tck-runner/pom.xml	2009-11-30 13:37:31 UTC (rev 18101)
+++ validator/trunk/hibernate-validator-tck-runner/pom.xml	2009-11-30 15:59:09 UTC (rev 18102)
@@ -32,7 +32,7 @@
         <dependency>
             <groupId>org.hibernate.jsr303.tck</groupId>
             <artifactId>jsr303-tck</artifactId>
-            <version>1.0.2.GA</version>
+            <version>1.0.3.GA</version>
         </dependency>
         <dependency>
             <groupId>org.jboss.test-harness</groupId>



More information about the hibernate-commits mailing list