5 import javax.annotation.processing.*;
7 import javax.lang.model.*;
8 import javax.lang.model.element.*;
9 import javax.lang.model.util.*;
11 @SupportedAnnotationTypes({"*"})
12 public class Collector extends AbstractProcessor {
13 private ProcessingEnvironment cfg;
15 private boolean verbose = false;
17 public void init(ProcessingEnvironment cfg) {
19 eu = cfg.getElementUtils();
22 private String tn(TypeElement el) {
23 return(eu.getBinaryName(el).toString());
26 private Set<String> getprev(TypeElement annotation) {
27 Set<String> prev = new HashSet<String>();
29 FileObject lf = cfg.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/glob/" + tn(annotation));
32 in = lf.openInputStream();
33 } catch(FileNotFoundException e) {
37 BufferedReader r = new BufferedReader(new InputStreamReader(in, "utf-8"));
39 while((ln = r.readLine()) != null)
45 } catch(IOException e) {
46 cfg.getMessager().printMessage(Diagnostic.Kind.ERROR, "could not read previous globlist for " + tn(annotation) + ": " + e);
47 return(Collections.emptySet());
51 private void writenew(TypeElement annotation, Collection<String> names) {
53 FileObject lf = cfg.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/glob/" + tn(annotation));
54 OutputStream out = lf.openOutputStream();
56 Writer w = new BufferedWriter(new OutputStreamWriter(out, "utf-8"));
57 for(String nm : names)
63 } catch(IOException e) {
64 cfg.getMessager().printMessage(Diagnostic.Kind.ERROR, "could not write new globlist for " + tn(annotation) + ": " + e);
68 private void process(TypeElement annotation, RoundEnvironment round, TypeMap types) {
69 Set<String> prev = getprev(annotation);
70 Set<String> carry = new HashSet<String>(prev);
71 Set<String> found = new HashSet<String>();
72 for(Element e : round.getElementsAnnotatedWith(annotation)) {
73 if(!(e instanceof TypeElement)) {
74 cfg.getMessager().printMessage(Diagnostic.Kind.ERROR, tn(annotation) + " must annotate types", e);
77 TypeElement type = (TypeElement)e;
79 if(!prev.contains(nm) && verbose)
80 cfg.getMessager().printMessage(Diagnostic.Kind.NOTE, "added " + nm, type);
84 for(Iterator<String> i = carry.iterator(); i.hasNext();) {
86 TypeElement el = types.get(nm);
90 cfg.getMessager().printMessage(Diagnostic.Kind.NOTE, "removed " + nm, el);
93 List<String> all = new ArrayList<String>();
96 Collections.sort(all);
97 writenew(annotation, all);
100 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment round) {
101 for(TypeElement a : annotations) {
102 if(a.getAnnotation(Discoverable.class) != null)
103 process(a, round, new TypeMap(round.getRootElements(), eu));
108 public SourceVersion getSupportedSourceVersion() {
109 return(SourceVersion.latest());