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 @SupportedSourceVersion(SourceVersion.RELEASE_5)
13 public class Collector extends AbstractProcessor {
14 private ProcessingEnvironment cfg;
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))
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);
89 cfg.getMessager().printMessage(Diagnostic.Kind.NOTE, "removed " + nm, el);
92 List<String> all = new ArrayList<String>();
95 Collections.sort(all);
96 writenew(annotation, all);
99 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment round) {
100 for(TypeElement a : annotations) {
101 if(a.getAnnotation(Discoverable.class) != null)
102 process(a, round, new TypeMap(round.getRootElements(), eu));