Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ atlassian-ide-plugin.xml
.classpath
.project
.settings
.factorypath

# NetBeans specific files/directories
.nbattrs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.hibernate.validator.ap.checks.ConstraintCheckFactory;
import org.hibernate.validator.ap.checks.ConstraintChecks;
import org.hibernate.validator.ap.util.AnnotationApiHelper;
import org.hibernate.validator.ap.util.Configuration;
import org.hibernate.validator.ap.util.ConstraintHelper;
import org.hibernate.validator.ap.util.MessagerAdapter;

Expand All @@ -51,10 +52,10 @@ final class ConstraintAnnotationVisitor extends ElementKindVisitor6<Void, List<A
private final boolean verbose;

public ConstraintAnnotationVisitor(
ProcessingEnvironment processingEnvironment, MessagerAdapter messager, boolean verbose) {
ProcessingEnvironment processingEnvironment, MessagerAdapter messager, Configuration configuration) {

this.messager = messager;
this.verbose = verbose;
this.verbose = configuration.isVerbose();

AnnotationApiHelper annotationApiHelper = new AnnotationApiHelper(
processingEnvironment.getElementUtils(), processingEnvironment.getTypeUtils()
Expand All @@ -65,7 +66,10 @@ public ConstraintAnnotationVisitor(
);

constraintCheckFactory = new ConstraintCheckFactory(
processingEnvironment.getTypeUtils(), constraintHelper, annotationApiHelper
processingEnvironment.getTypeUtils(),
constraintHelper,
annotationApiHelper,
configuration.methodConstraintsSupported()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.hibernate.validator.ap;

import java.text.MessageFormat;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
Expand All @@ -30,50 +29,42 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;

import org.hibernate.validator.ap.util.AnnotationApiHelper;
import org.hibernate.validator.ap.util.Configuration;
import org.hibernate.validator.ap.util.MessagerAdapter;

/**
* An annotation processor for checking <a
* href="http://jcp.org/en/jsr/detail?id=303">Bean Validation</a> constraints.
* The processor supports the following options:
* <ul>
* <li><code>diagnosticKind</code>: the severity with which any occurred problems
* shall be reported. Must be given in form of the string representation of a
* value from {@link javax.tools.Diagnostic.Kind}, e.g.
* <li><code>diagnosticKind</code>: the severity with which any occurred
* problems shall be reported. Must be given in form of the string
* representation of a value from {@link javax.tools.Diagnostic.Kind}, e.g.
* "diagnosticKind=WARNING". Default is Kind.ERROR.</li>
* <li>TODO GM: validationMode: whether spec compliance shall be checked
* strictly or loosely (e.g. by allowing validators for parametrized types)</li>
* </ul>
* <li><code>verbose</code>: whether a verbose output shall be created or not.
* Must be given as String parsable by {@link Boolean#parseBoolean}. Default is
* <code>false</code>.</li>
* <li><code>methodConstraintsSupported</code>: Whether constraints at other
* methods than JavaBeans getter methods may be annotated with constraints or
* not. Must be given as String parsable by {@link Boolean#parseBoolean}. Can be
* set to <code>false</code> in order to allow only getter based property
* constraints but not method level constraints as supported by Hibernate
* Validator. Default is <code>true</code>.</li>
*
* @author Hardy Ferentschik
* @author Gunnar Morling
*/
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedOptions({
ConstraintValidationProcessor.DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME,
ConstraintValidationProcessor.VERBOSE_PROCESSOR_OPTION_NAME
@SupportedOptions( {
Configuration.DIAGNOSTIC_KIND_PROCESSOR_OPTION,
Configuration.VERBOSE_PROCESSOR_OPTION,
Configuration.METHOD_CONSTRAINTS_SUPPORTED_PROCESSOR_OPTION
})
public class ConstraintValidationProcessor extends AbstractProcessor {

/**
* The name of the processor option for setting the diagnostic kind to be
* used when reporting errors during annotation processing.
*/
public final static String DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME = "diagnosticKind";

/**
* The name of the processor option for activating verbose message reporting.
*/
public final static String VERBOSE_PROCESSOR_OPTION_NAME = "verbose";

/**
* The diagnostic kind to be used if no or an invalid kind is given as processor option.
*/
public final static Kind DEFAULT_DIAGNOSTIC_KIND = Kind.ERROR;
/**
* Whether this processor claims all processed annotations exclusively or not.
*/
Expand All @@ -85,17 +76,17 @@ public class ConstraintValidationProcessor extends AbstractProcessor {
private MessagerAdapter messager;

/**
* Whether logging information shall be put out in a verbose way or not.
* Provides access to this processor's configuration options.
*/
private boolean verbose;
private Configuration configuration;

@Override
public synchronized void init(ProcessingEnvironment processingEnv) {

super.init( processingEnv );

this.verbose = isVerbose();
messager = new MessagerAdapter( processingEnv.getMessager(), getDiagnosticKind() );
configuration = new Configuration( processingEnv.getOptions(), processingEnv.getMessager() );
messager = new MessagerAdapter( processingEnv.getMessager(), configuration.getDiagnosticKind() );
}

@Override
Expand All @@ -108,7 +99,7 @@ public boolean process(
);

ElementVisitor<Void, List<AnnotationMirror>> visitor = new ConstraintAnnotationVisitor(
processingEnv, messager, verbose
processingEnv, messager, configuration
);

for ( TypeElement oneAnnotation : annotations ) {
Expand All @@ -128,54 +119,4 @@ public boolean process(
return ANNOTATIONS_CLAIMED_EXCLUSIVELY;
}

/**
* Retrieves the diagnostic kind to be used for error messages. If given in processor options, it
* will be taken from there, otherwise the default value Kind.ERROR will be returned.
*
* @return The diagnostic kind to be used for error messages.
*/
private Kind getDiagnosticKind() {

String diagnosticKindFromOptions = processingEnv.getOptions()
.get( DIAGNOSTIC_KIND_PROCESSOR_OPTION_NAME );

if ( diagnosticKindFromOptions != null ) {
try {
return Kind.valueOf( diagnosticKindFromOptions );
}
catch ( IllegalArgumentException e ) {
super.processingEnv.getMessager().printMessage(
Kind.WARNING, MessageFormat.format(
"The given value {0} is no valid diagnostic kind. {1} will be used.",
diagnosticKindFromOptions,
DEFAULT_DIAGNOSTIC_KIND
)
);
}
}

return DEFAULT_DIAGNOSTIC_KIND;
}

/**
* Retrieves the value for the "verbose" property from the options.
*
* @return The value for the "verbose" property.
*/
private boolean isVerbose() {

boolean theValue = Boolean.parseBoolean( processingEnv.getOptions().get( VERBOSE_PROCESSOR_OPTION_NAME ) );

if ( theValue ) {
super.processingEnv.getMessager().printMessage(
Kind.NOTE, MessageFormat.format(
"Verbose reporting is activated. Some processing information will be displayed using diagnostic kind {0}.",
Kind.NOTE
)
);
}

return theValue;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public class ConstraintCheckFactory {

private final static SingleValuedChecks NULL_CHECKS = new SingleValuedChecks();

public ConstraintCheckFactory(Types typeUtils, ConstraintHelper constraintHelper, AnnotationApiHelper annotationApiHelper) {
public ConstraintCheckFactory(Types typeUtils, ConstraintHelper constraintHelper, AnnotationApiHelper annotationApiHelper, boolean methodConstraintsSupported) {

this.constraintHelper = constraintHelper;

Expand All @@ -80,16 +80,16 @@ public ConstraintCheckFactory(Types typeUtils, ConstraintHelper constraintHelper
methodChecks = CollectionHelper.newHashMap();
methodChecks.put(
AnnotationType.CONSTRAINT_ANNOTATION,
new SingleValuedChecks( new GetterCheck(), new StaticCheck(), new TypeCheck( constraintHelper ) )
new SingleValuedChecks( new GetterCheck(methodConstraintsSupported), new StaticCheck(), new TypeCheck( constraintHelper ) )
);
methodChecks.put(
AnnotationType.MULTI_VALUED_CONSTRAINT_ANNOTATION, new MultiValuedChecks(
constraintHelper, new GetterCheck(), new StaticCheck(), new TypeCheck( constraintHelper )
constraintHelper, new GetterCheck(methodConstraintsSupported), new StaticCheck(), new TypeCheck( constraintHelper )
)
);
methodChecks.put(
AnnotationType.GRAPH_VALIDATION_ANNOTATION,
new SingleValuedChecks( new GetterCheck(), new StaticCheck(), new PrimitiveCheck() )
new SingleValuedChecks( new GetterCheck(methodConstraintsSupported), new StaticCheck(), new PrimitiveCheck() )
);
methodChecks.put( AnnotationType.NO_CONSTRAINT_ANNOTATION, NULL_CHECKS );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,30 @@
* @author Gunnar Morling
*/
public class GetterCheck extends AbstractConstraintCheck {

private final boolean methodConstraintsSupported;

public GetterCheck(boolean methodConstraintsSupported) {
this.methodConstraintsSupported = methodConstraintsSupported;
}

public Set<ConstraintCheckError> checkMethod(ExecutableElement element,
AnnotationMirror annotation) {

if ( !isGetterMethod( element ) ) {
if ( !methodConstraintsSupported && !isGetterMethod( element ) ) {
return CollectionHelper.asSet(
new ConstraintCheckError(
element, annotation, "ONLY_GETTERS_MAY_BE_ANNOTATED"
)
);
}
else if (!hasReturnValue(element)) {
return CollectionHelper.asSet(
new ConstraintCheckError(
element, annotation, "ONLY_NON_VOID_METHODS_MAY_BE_ANNOTATED"
)
);
}

return Collections.emptySet();
}
Expand Down
Loading