Indicate support for the same source version that the compiler uses.
[jglob.git] / src / dolda / jglob / Collector.java
CommitLineData
01e70f63
FT
1package dolda.jglob;
2
3import java.util.*;
4import java.io.*;
5import javax.annotation.processing.*;
6import javax.tools.*;
7import javax.lang.model.*;
8import javax.lang.model.element.*;
9import javax.lang.model.util.*;
10
11@SupportedAnnotationTypes({"*"})
01e70f63
FT
12public class Collector extends AbstractProcessor {
13 private ProcessingEnvironment cfg;
14 private Elements eu;
2c065c6f 15 private boolean verbose = false;
01e70f63
FT
16
17 public void init(ProcessingEnvironment cfg) {
18 this.cfg = cfg;
19 eu = cfg.getElementUtils();
20 }
21
22 private String tn(TypeElement el) {
23 return(eu.getBinaryName(el).toString());
24 }
25
26 private Set<String> getprev(TypeElement annotation) {
27 Set<String> prev = new HashSet<String>();
28 try {
29 FileObject lf = cfg.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/glob/" + tn(annotation));
30 InputStream in;
31 try {
32 in = lf.openInputStream();
33 } catch(FileNotFoundException e) {
34 return(prev);
35 }
36 try {
37 BufferedReader r = new BufferedReader(new InputStreamReader(in, "utf-8"));
38 String ln;
39 while((ln = r.readLine()) != null)
40 prev.add(ln);
41 return(prev);
42 } finally {
43 in.close();
44 }
45 } catch(IOException e) {
46 cfg.getMessager().printMessage(Diagnostic.Kind.ERROR, "could not read previous globlist for " + tn(annotation) + ": " + e);
47 return(Collections.emptySet());
48 }
49 }
50
51 private void writenew(TypeElement annotation, Collection<String> names) {
52 try {
53 FileObject lf = cfg.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/glob/" + tn(annotation));
54 OutputStream out = lf.openOutputStream();
55 try {
56 Writer w = new BufferedWriter(new OutputStreamWriter(out, "utf-8"));
57 for(String nm : names)
58 w.write(nm + "\n");
59 w.flush();
60 } finally {
61 out.close();
62 }
63 } catch(IOException e) {
64 cfg.getMessager().printMessage(Diagnostic.Kind.ERROR, "could not write new globlist for " + tn(annotation) + ": " + e);
65 }
66 }
67
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);
75 continue;
76 }
77 TypeElement type = (TypeElement)e;
78 String nm = tn(type);
2c065c6f 79 if(!prev.contains(nm) && verbose)
01e70f63
FT
80 cfg.getMessager().printMessage(Diagnostic.Kind.NOTE, "added " + nm, type);
81 found.add(nm);
82 carry.remove(nm);
83 }
84 for(Iterator<String> i = carry.iterator(); i.hasNext();) {
85 String nm = i.next();
86 TypeElement el = types.get(nm);
87 if(el != null) {
88 i.remove();
2c065c6f
FT
89 if(verbose)
90 cfg.getMessager().printMessage(Diagnostic.Kind.NOTE, "removed " + nm, el);
01e70f63
FT
91 }
92 }
93 List<String> all = new ArrayList<String>();
94 all.addAll(carry);
95 all.addAll(found);
96 Collections.sort(all);
97 writenew(annotation, all);
98 }
99
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));
104 }
105 return(false);
106 }
1d78ecd1
FT
107
108 public SourceVersion getSupportedSourceVersion() {
109 return(SourceVersion.latest());
110 }
01e70f63 111}