package ch.vorburger.learnapt;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Completion;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.JavaFileObject;
/**
* Example 'APT' Processor.
*
* @see http://wiki.netbeans.org/FaqApt
* @see http://www.javaspecialists.eu/archive/Issue167.html
* @see http://code.google.com/p/acris/wiki/CodeGenerationPlatform
* @see http://download.oracle.com/javase/6/docs/api/javax/annotation/processing/Processor.html
*
* @author Michael Vorburger
*/
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("ch.vorburger.learnapt.SomeAnnotation")
// ? @SupportedOptions()
// TODO @SupportedAnnotationTypes("*") is it called for EVERYTHING?
// "Set of elements which comes as first parameter holds all the java classes which are annotated with supported annotation (note: if the supportedAnnotationType is asterix "*" then the input set is empty and you have to fetch annotated java classes in your own)"
public class SampleProcessor extends AbstractProcessor {
/** "Each implementation of a Processor must provide a public no-argument constructor to be used by tools to instantiate the processor." */
public SampleProcessor() {}
// TODO getCompletions()
// @Override
// public Iterable<? extends Completion> getCompletions(Element element,
// AnnotationMirror annotation, ExecutableElement member,
// String userText) {
// // TODO Auto-generated method stub
// return super.getCompletions(element, annotation, member, userText);
// }
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
// TODO called twice? needs optimize?
System.out.println("processingOver: " + roundEnv.processingOver());
for (TypeElement element : annotations){
System.out.println(element.getQualifiedName());
this.processingEnv.getMessager().printMessage(Kind.WARNING, "Got you: " + element.getQualifiedName(), element);
}
for (Element e : roundEnv.getElementsAnnotatedWith(SomeAnnotation.class)) {
// if (e.getKind() != ElementKind.FIELD) {
// processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "Not a field", e);
// continue;
// }
this.processingEnv.getMessager().printMessage(Kind.WARNING, "Aha: " + e.toString(), e);
this.processingEnv.getMessager().printMessage(Kind.ERROR, "Test Error", e);
this.processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Test Mandatory Warning", e);
this.processingEnv.getMessager().printMessage(Kind.NOTE, "Test Note", e);
this.processingEnv.getMessager().printMessage(Kind.OTHER, "Test Other", e);
TypeElement clazz = (TypeElement) e; // NOT .getEnclosingElement();
String name = capitalize(e.getSimpleName().toString());
try {
// NOTE additional arg. to createSourceFile for originatingElements
JavaFileObject f = processingEnv.getFiler().createSourceFile(clazz.getQualifiedName() + "Extras", e);
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Creating " + f.toUri());
Writer w = f.openWriter();
try {
PrintWriter pw = new PrintWriter(w);
pw.println("package " + clazz.getEnclosingElement().getSimpleName() + ";");
// TODO @Generated
pw.println("public abstract class " + clazz.getSimpleName() + "Extras {");
pw.println(" protected " + clazz.getSimpleName() + "Extras() {}");
TypeMirror type = e.asType();
pw.println(" /** Handle something. */");
pw.println(" protected final void handle" + name + "(" + type + " value) {");
pw.println(" System.out.println(value);");
pw.println(" }");
pw.println("}");
pw.flush();
} finally {
w.close();
}
} catch (IOException x) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, x.toString());
}
}
return true; // TODO hm.. what if there are others?
}
private static String capitalize(String name) {
char[] c = name.toCharArray();
c[0] = Character.toUpperCase(c[0]);
return new String(c);
}
}