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