TP-metaprogrammation-test/TP5/UtilityProcessor.java

69 lines
2.3 KiB
Java
Raw Permalink Normal View History

2023-06-21 18:09:35 +00:00
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<? extends TypeElement> 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;
}
}