Author: gunnar.morling
Date: 2010-08-08 07:16:14 -0400 (Sun, 08 Aug 2010)
New Revision: 20123
Added:
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/TargetCheck.java
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/constrainttypes/ConstraintsWithIllegalTargets.java
Modified:
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/ConstraintCheckFactory.java
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/RetentionPolicyCheck.java
validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/AnnotationTypeValidationTest.java
Log:
HV-299: Check target element types for constraint annotation types
Modified:
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/ConstraintCheckFactory.java
===================================================================
---
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/ConstraintCheckFactory.java 2010-08-08
10:32:12 UTC (rev 20122)
+++
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/ConstraintCheckFactory.java 2010-08-08
11:16:14 UTC (rev 20123)
@@ -106,7 +106,7 @@
annotationTypeChecks.put(
AnnotationType.CONSTRAINT_META_ANNOTATION,
new SingleValuedChecks(
- new RetentionPolicyCheck( annotationApiHelper )
+ new RetentionPolicyCheck( annotationApiHelper ), new TargetCheck(
annotationApiHelper )
)
);
annotationTypeChecks.put( AnnotationType.NO_CONSTRAINT_ANNOTATION, NULL_CHECKS );
Modified:
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/RetentionPolicyCheck.java
===================================================================
---
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/RetentionPolicyCheck.java 2010-08-08
10:32:12 UTC (rev 20122)
+++
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/RetentionPolicyCheck.java 2010-08-08
11:16:14 UTC (rev 20123)
@@ -41,8 +41,7 @@
}
@Override
- public Set<ConstraintCheckError> checkAnnotationType(TypeElement element,
- AnnotationMirror annotation) {
+ public Set<ConstraintCheckError> checkAnnotationType(TypeElement element,
AnnotationMirror annotation) {
Retention retention = element.getAnnotation( Retention.class );
Added:
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/TargetCheck.java
===================================================================
---
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/TargetCheck.java
(rev 0)
+++
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/checks/TargetCheck.java 2010-08-08
11:16:14 UTC (rev 20123)
@@ -0,0 +1,91 @@
+// $Id: TargetCheck.java 19310 2010-04-27 22:51:17Z gunnar.morling $
+/*
+ * 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.checks;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.TypeElement;
+
+import org.hibernate.validator.ap.util.AnnotationApiHelper;
+import org.hibernate.validator.ap.util.CollectionHelper;
+
+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.ElementType.TYPE;
+
+/**
+ * Checks, that at least one of the {@link ElementType}s FIELD, METHOD, TYPE or
ANNOTATION_TYPE is specified
+ * using the {@link Target} meta-annotation for constraint annotation types.
+ *
+ * @author Gunnar Morling
+ */
+public class TargetCheck extends AbstractConstraintCheck {
+
+ private final AnnotationApiHelper annotationApiHelper;
+
+ /**
+ * Each constraint annotation type must be targeted at one of these element types at
least.
+ */
+ private final EnumSet<ElementType> supportedTypes = EnumSet.of( FIELD, METHOD,
TYPE, ANNOTATION_TYPE );
+
+ public TargetCheck(AnnotationApiHelper annotationApiHelper) {
+ this.annotationApiHelper = annotationApiHelper;
+ }
+
+ @Override
+ public Set<ConstraintCheckError> checkAnnotationType(TypeElement element,
AnnotationMirror annotation) {
+
+ Target target = element.getAnnotation( Target.class );
+
+ //no target given allows the annotation to be declared at any type
+ if ( target == null ) {
+ return Collections.emptySet();
+ }
+
+ if ( !containsAtLeastOneSupportedElementType( target ) ) {
+ return CollectionHelper.asSet(
+ new ConstraintCheckError(
+ element,
+ annotationApiHelper.getMirror( element.getAnnotationMirrors(), Target.class ),
+ "CONSTRAINT_TYPE_WITH_WRONG_TARGET"
+ )
+ );
+ }
+
+ return Collections.emptySet();
+ }
+
+ private boolean containsAtLeastOneSupportedElementType(Target target) {
+
+ ElementType[] elementTypes = target.value();
+
+ for ( ElementType oneElementType : elementTypes ) {
+ if ( supportedTypes.contains( oneElementType ) ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}
Modified:
validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties
===================================================================
---
validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties 2010-08-08
10:32:12 UTC (rev 20122)
+++
validator/trunk/hibernate-validator-annotation-processor/src/main/resources/org/hibernate/validator/ap/ValidationProcessorMessages.properties 2010-08-08
11:16:14 UTC (rev 20123)
@@ -11,4 +11,5 @@
INVALID_DIAGNOSTIC_KIND_GIVEN=The given value {0} is no valid diagnostic kind. Kind.ERROR
will be used.
ATVALID_NOT_ALLOWED_AT_PRIMITIVE_FIELD=Fields of a primitive type must not annotated with
@Valid.
ATVALID_NOT_ALLOWED_AT_METHOD_RETURNING_PRIMITIVE_TYPE=Methods returning a primitive type
must not annotated with @Valid.
-CONSTRAINT_TYPE_WITH_MISSING_OR_WRONG_RETENTION=Constraint annotation types must be
annotated with @Retention(RUNTIME).
\ No newline at end of file
+CONSTRAINT_TYPE_WITH_MISSING_OR_WRONG_RETENTION=Constraint annotation types must be
annotated with @Retention(RUNTIME).
+CONSTRAINT_TYPE_WITH_WRONG_TARGET=Constraint annotation types must have at least one of
the element types FIELD, METHOD, TYPE or ANNOTATION_TYPE as target.
\ No newline at end of file
Modified:
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/AnnotationTypeValidationTest.java
===================================================================
---
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/AnnotationTypeValidationTest.java 2010-08-08
10:32:12 UTC (rev 20122)
+++
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/AnnotationTypeValidationTest.java 2010-08-08
11:16:14 UTC (rev 20123)
@@ -24,6 +24,7 @@
import
org.hibernate.validator.ap.testmodel.constrainttypes.ConstraintWithWrongRetentionPolicy;
import
org.hibernate.validator.ap.testmodel.constrainttypes.ConstraintWithoutRetentionPolicy;
+import
org.hibernate.validator.ap.testmodel.constrainttypes.ConstraintsWithIllegalTargets;
import org.hibernate.validator.ap.testmodel.constrainttypes.ValidCustomerNumber;
import org.hibernate.validator.ap.util.DiagnosticExpectation;
@@ -76,4 +77,20 @@
assertThatDiagnosticsMatch( diagnostics, new DiagnosticExpectation( Kind.ERROR, 28 )
);
}
+ @Test
+ public void testThatConstraintAnnotationTypeWithWrongTargetCausesCompilationError() {
+
+ File sourceFile = compilerHelper.getSourceFile( ConstraintsWithIllegalTargets.class );
+
+ boolean compilationResult =
+ compilerHelper.compile( new ConstraintValidationProcessor(), diagnostics, sourceFile
);
+
+ assertFalse( compilationResult );
+ assertThatDiagnosticsMatch(
+ diagnostics,
+ new DiagnosticExpectation( Kind.ERROR, 42 ), new DiagnosticExpectation( Kind.ERROR,
52 )
+ );
+ }
+
+
}
Added:
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/constrainttypes/ConstraintsWithIllegalTargets.java
===================================================================
---
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/constrainttypes/ConstraintsWithIllegalTargets.java
(rev 0)
+++
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/testmodel/constrainttypes/ConstraintsWithIllegalTargets.java 2010-08-08
11:16:14 UTC (rev 20123)
@@ -0,0 +1,106 @@
+// $Id: ConstraintsWithIllegalTargets.java 19033 Aug 1, 2010 5:44:13 PM gunnar.morling $
+/*
+* 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.constrainttypes;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+/**
+ * @author Gunnar Morling
+ */
+public interface ConstraintsWithIllegalTargets {
+
+
+ /**
+ * Compilation error expected due to none supported target type being given.
+ */
+ @Constraint(validatedBy = { })
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ LOCAL_VARIABLE })
+ public @interface ConstraintWithWrongTarget {
+
+ }
+
+ /**
+ * Compilation error expected as no supported target type is given.
+ */
+ @Constraint(validatedBy = { })
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ })
+ public @interface ConstraintWithEmptyTarget {
+
+ }
+
+ /**
+ * No compilation error expected, as not specifying @Target allows this constraint for
all element types.
+ */
+ @Constraint(validatedBy = { })
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ConstraintWithDefaultTarget {
+
+ }
+
+ /**
+ * No compilation error expected, as supported target type FIELD is given.
+ */
+ @Constraint(validatedBy = { })
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ FIELD })
+ public @interface ConstraintWithAllowedTargetField {
+
+ }
+
+ /**
+ * No compilation error expected, as supported target type METHOD is given.
+ */
+ @Constraint(validatedBy = { })
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ METHOD })
+ public @interface ConstraintWithAllowedTargetMethod {
+
+ }
+
+ /**
+ * No compilation error expected, as supported target type TYPE is given.
+ */
+ @Constraint(validatedBy = { })
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ TYPE })
+ public @interface ConstraintWithAllowedTargetType {
+
+ }
+
+ /**
+ * No compilation error expected, as supported target type ANNOTATION_TYPE is given.
+ */
+ @Constraint(validatedBy = { })
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ ANNOTATION_TYPE })
+ public @interface ConstraintWithAllowedTargetAnnotationType {
+
+ }
+
+}
\ No newline at end of file