Package org.hibernate.validator.ap

Source Code of org.hibernate.validator.ap.ConstraintAnnotationVisitor

/*
* 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.util.List;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementKindVisitor6;
import javax.tools.Diagnostic.Kind;

import org.hibernate.validator.ap.checks.ConstraintCheckError;
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;

/**
* An {@link javax.lang.model.element.ElementVisitor} that visits annotated elements (type declarations,
* methods and fields) and applies different {@link org.hibernate.validator.ap.checks.ConstraintCheck}s to them.
* Each {@link ConstraintCheckError} occurred will be reported using the
* {@link javax.annotation.processing.Messager} API.
*
* @author Gunnar Morling
*/
final class ConstraintAnnotationVisitor extends ElementKindVisitor6<Void, List<AnnotationMirror>> {

  private final MessagerAdapter messager;

  private final ConstraintCheckFactory constraintCheckFactory;

  private final boolean verbose;

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

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

    AnnotationApiHelper annotationApiHelper = new AnnotationApiHelper(
        processingEnvironment.getElementUtils(), processingEnvironment.getTypeUtils()
    );

    ConstraintHelper constraintHelper = new ConstraintHelper(
        processingEnvironment.getElementUtils(), processingEnvironment.getTypeUtils(), annotationApiHelper
    );

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

  /**
   * <p>
   * Checks whether the given annotations are correctly specified at the given
   * method. The following checks are performed:
   * </p>
   * <ul>
   * <li>
   * Constraint annotations may only be given at non-static, JavaBeans getter
   * methods which's return type is supported by the constraints.</li>
   * <li>
   * The <code>@Valid</code> annotation may only be given at non-static,
   * non-primitive JavaBeans getter methods.</li>
   * </ul>
   */
  @Override
  public Void visitExecutableAsMethod(ExecutableElement method,
                    List<AnnotationMirror> mirrors) {

    checkConstraints( method, mirrors );

    return null;
  }

  /**
   * <p>
   * Checks whether the given annotations are correctly specified at the given
   * field. The following checks are performed:
   * </p>
   * <ul>
   * <li>
   * Constraint annotations may only be given at non-static fields which's
   * type is supported by the constraints.</li>
   * <li>
   * The <code>@Valid</code> annotation may only be given at non-static,
   * non-primitive fields.</li>
   * </ul>
   */
  @Override
  public Void visitVariableAsField(VariableElement annotatedField, List<AnnotationMirror> mirrors) {

    checkConstraints( annotatedField, mirrors );

    return null;
  }

  /**
   * <p>
   * Checks whether the given annotations are correctly specified at the given
   * annotation type declaration. The following checks are performed:
   * </p>
   * <ul>
   * <li>
   * The only annotation types allowed to be annotated with other constraint
   * annotations are composed constraint annotation type declarations.</li>
   * </ul>
   */
  @Override
  public Void visitTypeAsAnnotationType(TypeElement annotationType,
                      List<AnnotationMirror> mirrors) {

    checkConstraints( annotationType, mirrors );

    return null;
  }

  /**
   * <p>
   * Checks whether the given annotations are correctly specified at the given
   * class type declaration. The following checks are performed:
   * </p>
   * <ul>
   * <li>
   * Constraint annotations may at types supported by the constraints.</li>
   * <li>
   * </ul>
   */
  @Override
  public Void visitTypeAsClass(TypeElement e, List<AnnotationMirror> p) {

    checkConstraints( e, p );
    return null;
  }

  /**
   * <p>
   * Checks whether the given annotations are correctly specified at the given
   * enum type declaration. The following checks are performed:
   * </p>
   * <ul>
   * <li>
   * Constraint annotations may at types supported by the constraints.</li>
   * <li>
   * </ul>
   */
  @Override
  public Void visitTypeAsEnum(TypeElement e, List<AnnotationMirror> p) {

    checkConstraints( e, p );
    return null;
  }

  /**
   * <p>
   * Checks whether the given annotations are correctly specified at the given
   * interface type declaration. The following checks are performed:
   * </p>
   * <ul>
   * <li>
   * Constraint annotations may at types supported by the constraints.</li>
   * <li>
   * </ul>
   */
  @Override
  public Void visitTypeAsInterface(TypeElement e, List<AnnotationMirror> p) {

    checkConstraints( e, p );
    return null;
  }

  /**
   * Retrieves the checks required for the given element and annotations,
   * executes them and reports all occurred errors.
   *
   * @param annotatedElement The element to check.
   * @param mirrors The annotations to check.
   */
  private void checkConstraints(Element annotatedElement, List<AnnotationMirror> mirrors) {

    for ( AnnotationMirror oneAnnotationMirror : mirrors ) {

      try {

        ConstraintChecks constraintChecks = constraintCheckFactory.getConstraintChecks(
            annotatedElement, oneAnnotationMirror
        );
        Set<ConstraintCheckError> errors = constraintChecks.execute( annotatedElement, oneAnnotationMirror );
        messager.reportErrors( errors );
      }
      //HV-293: if single constraints can't be properly checked, report this and
      //proceed with next constraints
      catch ( Exception e ) {

        if ( verbose ) {
          messager.getDelegate()
              .printMessage( Kind.NOTE, e.getMessage(), annotatedElement, oneAnnotationMirror );
        }
      }
    }
  }

}
TOP

Related Classes of org.hibernate.validator.ap.ConstraintAnnotationVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.