import javax.annotation.processing.*; import javax.lang.model.SourceVersion; import javax.lang.model.element.*; import javax.tools.Diagnostic.Kind; import java.lang.reflect.*; import java.lang.reflect.Modifier; import java.util.*; import java.lang.annotation.*; /** Check that a class marked {@code @Utility} is indeed a utility class. */ @SupportedAnnotationTypes("Utility") @SupportedSourceVersion(SourceVersion.RELEASE_11) public class UtilityProcessor extends AbstractProcessor { @Override public boolean process( Set annotations, RoundEnvironment roundingEnvironment) { Messager messager = processingEnv.getMessager(); messager.printMessage(Kind.NOTE, "UtilityProcessor executed."); messager.printMessage(Kind.WARNING, "The provided UtilityProcessor class is wrong. Correct it!"); for (TypeElement te : annotations) { for (Element elt : roundingEnvironment.getElementsAnnotatedWith(te)) { // check if elt is a class if (elt.getKind() == ElementKind.CLASS) { // Check that the class is declared final if (Modifier.isFinal(elt.getModifiers())) { Class cl = Class.forName(elt.getTagName()); // Check that enclosed elements are static Method[] methods = cl.getMethods(); for (Method method : methods) { if (!Modifier.isStatic(method.getModifiers())) { messager.printMessage(Kind.ERROR, "@Utility applies to class with STATIC mehthods only:", elt); break; } } // Check for constructors issues Constructor[] constructors = cl.getConstructors(); System.out.println("nb construct : " + constructors.length); if (constructors.length != 1) { messager.printMessage(Kind.ERROR, "@Utility applies to class with only ONE constructor only:", elt); break; } for (Constructor constructor : constructors) { if (Modifier.isPrivate(constructor.getModifiers())) { messager.printMessage(Kind.ERROR, "@Utility applies to class with only a PRIVATE constructor only:", elt); break; } } } else { messager.printMessage(Kind.ERROR, "@Utility applies to FINAL class only:", elt); } } else { messager.printMessage(Kind.ERROR, "@Utility applies to CLASS only:", elt); } } } return true; } }