package io.trygvis.container.compiler; import io.trygvis.container.log.Log; import io.trygvis.persistence.SqlEntity; import io.trygvis.persistence.SqlEntitySet; import org.springframework.transaction.annotation.Transactional; import javax.annotation.processing.Completion; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.SourceVersion; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.persistence.Entity; import javax.tools.Diagnostic; import java.util.HashSet; import java.util.Set; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; import static javax.lang.model.util.ElementFilter.typesIn; public class MyProcessor implements Processor { private ProcessingEnvironment processingEnv; private Elements elements; private Types types; @Override public Set getSupportedOptions() { return emptySet(); } @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.RELEASE_7; } @Override public void init(ProcessingEnvironment processingEnv) { this.processingEnv = processingEnv; elements = processingEnv.getElementUtils(); types = processingEnv.getTypeUtils(); } @Override public Iterable getCompletions(Element element, AnnotationMirror annotation, ExecutableElement member, String userText) { return emptyList(); } @Override public Set getSupportedAnnotationTypes() { return new HashSet<>(asList( Transactional.class.getName(), Log.class.getName(), Entity.class.getName(), SqlEntitySet.class.getName())); } @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { System.out.println("io.trygvis.container.compiler.MyProcessor.process"); System.out.println("annotations = " + annotations); System.out.println("roundEnv = " + roundEnv); try { boolean claimed = work(roundEnv); System.out.println("claimed = " + claimed); return claimed; } catch (CompilerException e) { e.printStackTrace(System.err); Messager messager = processingEnv.getMessager(); messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage(), e.element); return true; } catch (InternalErrorException e) { e.printStackTrace(System.err); Messager messager = processingEnv.getMessager(); messager.printMessage(Diagnostic.Kind.ERROR, e.getMessage()); return true; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } } boolean first = true; public boolean work(RoundEnvironment roundEnv) throws Exception { if (!first) { return false; } first = false; TypeElement tx = elements.getTypeElement(Transactional.class.getCanonicalName()); TypeElement log = elements.getTypeElement(Log.class.getCanonicalName()); TypeElement entity = elements.getTypeElement(Entity.class.getCanonicalName()); EntityHandler entityHandler = new EntityHandler(processingEnv); Set sqlEntities = typesIn(roundEnv.getElementsAnnotatedWith(SqlEntity.class)); Set packages = ElementFilter.packagesIn(roundEnv.getElementsAnnotatedWith(SqlEntitySet.class)); entityHandler.phase1(sqlEntities, packages); for (Element element : roundEnv.getRootElements()) { System.out.println("Processing: " + element.asType()); for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { DeclaredType annotationType = annotationMirror.getAnnotationType(); if (types.isSameType(tx.asType(), annotationType)) { new TransactionalHandler(processingEnv).processTransactional((TypeElement) element); } if (types.isSameType(log.asType(), annotationType)) { new LogHandler(processingEnv).processLog((TypeElement) element); } if (types.isSameType(entity.asType(), annotationType)) { entityHandler.recordEntity((TypeElement) element); } } } entityHandler.phase3(); return true; } }