Commit | Line | Data |
---|---|---|
01e70f63 FT |
1 | package dolda.jglob; |
2 | ||
3 | import java.util.*; | |
4 | import java.io.*; | |
5 | import javax.annotation.processing.*; | |
6 | import javax.tools.*; | |
7 | import javax.lang.model.*; | |
8 | import javax.lang.model.element.*; | |
9 | import javax.lang.model.util.*; | |
10 | ||
11 | @SupportedAnnotationTypes({"*"}) | |
01e70f63 FT |
12 | public 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 | } |