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("*")
-@SupportedSourceVersion(RELEASE_6)
+(a)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;
+
+@Target( { METHOD, FIELD, ANNOTATION_TYPE })
+@Retention(RUNTIME)
+@Constraint(validatedBy = CheckCaseValidator.class)
+@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>