0N/A/*
553N/A * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
553N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
553N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
553N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
553N/A * or visit www.oracle.com if you need additional information or have any
553N/A * questions.
0N/A */
0N/A
0N/Apackage javax.annotation.processing;
0N/A
0N/Aimport java.util.Set;
0N/Aimport java.util.HashSet;
0N/Aimport java.util.Collections;
0N/Aimport javax.lang.model.element.*;
0N/Aimport javax.lang.model.SourceVersion;
0N/Aimport javax.tools.Diagnostic;
0N/A
0N/A/**
0N/A * An abstract annotation processor designed to be a convenient
0N/A * superclass for most concrete annotation processors. This class
0N/A * examines annotation values to compute the {@linkplain
0N/A * #getSupportedOptions options}, {@linkplain
0N/A * #getSupportedAnnotationTypes annotations}, and {@linkplain
0N/A * #getSupportedSourceVersion source version} supported by its
0N/A * subtypes.
0N/A *
0N/A * <p>The getter methods may {@linkplain Messager#printMessage issue
0N/A * warnings} about noteworthy conditions using the facilities available
0N/A * after the processor has been {@linkplain #isInitialized
0N/A * initialized}.
0N/A *
0N/A * <p>Subclasses are free to override the implementation and
0N/A * specification of any of the methods in this class as long as the
0N/A * general {@link javax.annotation.processing.Processor Processor}
0N/A * contract for that method is obeyed.
0N/A *
0N/A * @author Joseph D. Darcy
0N/A * @author Scott Seligman
0N/A * @author Peter von der Ah&eacute;
0N/A * @since 1.6
0N/A */
0N/Apublic abstract class AbstractProcessor implements Processor {
0N/A /**
0N/A * Processing environment providing by the tool framework.
0N/A */
0N/A protected ProcessingEnvironment processingEnv;
0N/A private boolean initialized = false;
0N/A
0N/A /**
0N/A * Constructor for subclasses to call.
0N/A */
0N/A protected AbstractProcessor() {}
0N/A
0N/A /**
0N/A * If the processor class is annotated with {@link
0N/A * SupportedOptions}, return an unmodifiable set with the same set
0N/A * of strings as the annotation. If the class is not so
0N/A * annotated, an empty set is returned.
0N/A *
0N/A * @return the options recognized by this processor, or an empty
0N/A * set if none
0N/A */
0N/A public Set<String> getSupportedOptions() {
0N/A SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class);
0N/A if (so == null)
0N/A return Collections.emptySet();
0N/A else
0N/A return arrayToSet(so.value());
0N/A }
0N/A
0N/A /**
0N/A * If the processor class is annotated with {@link
0N/A * SupportedAnnotationTypes}, return an unmodifiable set with the
0N/A * same set of strings as the annotation. If the class is not so
0N/A * annotated, an empty set is returned.
0N/A *
0N/A * @return the names of the annotation types supported by this
0N/A * processor, or an empty set if none
0N/A */
0N/A public Set<String> getSupportedAnnotationTypes() {
0N/A SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class);
0N/A if (sat == null) {
0N/A if (isInitialized())
0N/A processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
0N/A "No SupportedAnnotationTypes annotation " +
0N/A "found on " + this.getClass().getName() +
0N/A ", returning an empty set.");
0N/A return Collections.emptySet();
0N/A }
0N/A else
0N/A return arrayToSet(sat.value());
0N/A }
0N/A
0N/A /**
0N/A * If the processor class is annotated with {@link
0N/A * SupportedSourceVersion}, return the source version in the
0N/A * annotation. If the class is not so annotated, {@link
0N/A * SourceVersion#RELEASE_6} is returned.
0N/A *
0N/A * @return the latest source version supported by this processor
0N/A */
0N/A public SourceVersion getSupportedSourceVersion() {
0N/A SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class);
0N/A SourceVersion sv = null;
0N/A if (ssv == null) {
0N/A sv = SourceVersion.RELEASE_6;
0N/A if (isInitialized())
0N/A processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
0N/A "No SupportedSourceVersion annotation " +
0N/A "found on " + this.getClass().getName() +
0N/A ", returning " + sv + ".");
0N/A } else
0N/A sv = ssv.value();
0N/A return sv;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Initializes the processor with the processing environment by
0N/A * setting the {@code processingEnv} field to the value of the
0N/A * {@code processingEnv} argument. An {@code
0N/A * IllegalStateException} will be thrown if this method is called
0N/A * more than once on the same object.
0N/A *
0N/A * @param processingEnv environment to access facilities the tool framework
0N/A * provides to the processor
0N/A * @throws IllegalStateException if this method is called more than once.
0N/A */
0N/A public synchronized void init(ProcessingEnvironment processingEnv) {
0N/A if (initialized)
0N/A throw new IllegalStateException("Cannot call init more than once.");
0N/A if (processingEnv == null)
0N/A throw new NullPointerException("Tool provided null ProcessingEnvironment");
0N/A
0N/A this.processingEnv = processingEnv;
0N/A initialized = true;
0N/A }
0N/A
0N/A /**
0N/A * {@inheritDoc}
0N/A */
0N/A public abstract boolean process(Set<? extends TypeElement> annotations,
0N/A RoundEnvironment roundEnv);
0N/A
0N/A /**
0N/A * Returns an empty iterable of completions.
0N/A *
0N/A * @param element {@inheritDoc}
0N/A * @param annotation {@inheritDoc}
0N/A * @param member {@inheritDoc}
0N/A * @param userText {@inheritDoc}
0N/A */
0N/A public Iterable<? extends Completion> getCompletions(Element element,
0N/A AnnotationMirror annotation,
0N/A ExecutableElement member,
0N/A String userText) {
0N/A return Collections.emptyList();
0N/A }
0N/A
0N/A /**
0N/A * Returns {@code true} if this object has been {@linkplain #init
0N/A * initialized}, {@code false} otherwise.
0N/A *
0N/A * @return {@code true} if this object has been initialized,
0N/A * {@code false} otherwise.
0N/A */
0N/A protected synchronized boolean isInitialized() {
0N/A return initialized;
0N/A }
0N/A
0N/A private static Set<String> arrayToSet(String[] array) {
0N/A assert array != null;
0N/A Set<String> set = new HashSet<String>(array.length);
0N/A for (String s : array)
0N/A set.add(s);
0N/A return Collections.unmodifiableSet(set);
0N/A }
0N/A}