package xapi.dev.model; import java.io.PrintWriter; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayDeque; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Filer; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import xapi.log.X_Log; @SupportedAnnotationTypes({"xapi.annotation.model.*"}) @SupportedSourceVersion(SourceVersion.RELEASE_7) public class ModelAnnotationProcessor extends AbstractProcessor{ public ModelAnnotationProcessor() {} protected Filer filer; @Override public final synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); filer = processingEnv.getFiler(); } @Override public boolean process( Set<? extends TypeElement> annotations, RoundEnvironment roundEnv ) { ClassLoader parentCl = ModelAnnotationProcessor.class.getClassLoader(); URL[] urls = ((URLClassLoader)parentCl).getURLs(); URLClassLoader cl = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader()); // X_Log.info(Arrays.asList(urls)); HashSet<String> annotatedTypes = new HashSet<String>(); HashSet<String> annotatedPackages = new HashSet<String>(); for (TypeElement anno : annotations) { for (Element element : roundEnv.getElementsAnnotatedWith(anno)) { Element e = element.getEnclosingElement(); if (e instanceof TypeElement) { annotatedTypes.add(((TypeElement)e).getQualifiedName().toString()); } else if (e instanceof PackageElement){ annotatedPackages.add(((PackageElement)e).getQualifiedName().toString()); } else { X_Log.warn("Ignored an enclosing element that was not a TypeElement or package element" ,e,e.getClass()); } } } for (String s : annotatedPackages) { X_Log.info("Model Package",s); } for (String modelCls : annotatedTypes) { Class<?> cls = loadClass(modelCls, cl); X_Log.info("Loaded model: ", cls); } if (roundEnv.processingOver()) try { } catch (Exception e) { e.printStackTrace(); System.err.println("Unable to generate model classes."); return false; } return true; } private Class<?> loadClass(String s, ClassLoader cl) { try{ return cl.loadClass(s); } catch (Throwable e) { // An inner class can do this. Just search backwards... int ind = s.lastIndexOf('.'); String tryLoad = s; ArrayDeque<String> stack = new ArrayDeque<String>(); while (ind != -1) { stack.add(tryLoad.substring(ind+1)); tryLoad = tryLoad.substring(0, ind); try { Class<?> cls = cl.loadClass(tryLoad); innerClassLoop: while (stack.size() > 0) { String next = stack.pop(); for (Class<?> inner : cls.getClasses()) { if (inner.getSimpleName().equals(next)) { cls = inner; continue innerClassLoop; } } throw new RuntimeException(new ClassNotFoundException( "Could not load class: "+s+"; ensure that it is public " + "and available on the classpath." )); } return cls; } catch (ClassNotFoundException ex) {} ind = tryLoad.lastIndexOf('.'); } } throw new RuntimeException(new ClassNotFoundException(s)); } protected Iterable<String> getPlatforms(Element element) { return Arrays.asList(""); } void dumpType(Element anno) { processingEnv.getElementUtils().printElements(new PrintWriter(System.out), anno); } }