Handle NoSuchFileExceptions from newer versions of javac.
[jglob.git] / src / dolda / jglob / Collector.java
CommitLineData
01e70f63
FT
1package dolda.jglob;
2
3import java.util.*;
4import java.io.*;
004c0410 5import java.nio.file.*;
01e70f63
FT
6import javax.annotation.processing.*;
7import javax.tools.*;
8import javax.lang.model.*;
9import javax.lang.model.element.*;
10import javax.lang.model.util.*;
11
12@SupportedAnnotationTypes({"*"})
01e70f63
FT
13public 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}