5 import java.nio.file.*;
6 import javax.annotation.processing.*;
8 import javax.lang.model.*;
9 import javax.lang.model.element.*;
10 import javax.lang.model.util.*;
12 @SupportedAnnotationTypes({"*"})
13 public class Collector extends AbstractProcessor {
14 private ProcessingEnvironment cfg;
16 private boolean verbose = false;
18 public void init(ProcessingEnvironment cfg) {
20 eu = cfg.getElementUtils();
23 private String tn(TypeElement el) {
24 return(eu.getBinaryName(el).toString());
27 private Set<String> getprev(TypeElement annotation) {
28 Set<String> prev = new HashSet<String>();
30 FileObject lf = cfg.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/glob/" + tn(annotation));
33 in = lf.openInputStream();
34 } catch(FileNotFoundException | NoSuchFileException e) {
38 BufferedReader r = new BufferedReader(new InputStreamReader(in, "utf-8"));
40 while((ln = r.readLine()) != null)
46 } catch(IOException e) {
47 cfg.getMessager().printMessage(Diagnostic.Kind.ERROR, "could not read previous globlist for " + tn(annotation) + ": " + e);
48 return(Collections.emptySet());
52 private void writenew(TypeElement annotation, Collection<String> names) {
54 FileObject lf = cfg.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/glob/" + tn(annotation));
55 OutputStream out = lf.openOutputStream();
57 Writer w = new BufferedWriter(new OutputStreamWriter(out, "utf-8"));
58 for(String nm : names)
64 } catch(IOException e) {
65 cfg.getMessager().printMessage(Diagnostic.Kind.ERROR, "could not write new globlist for " + tn(annotation) + ": " + e);
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);
78 TypeElement type = (TypeElement)e;
80 if(!prev.contains(nm) && verbose)
81 cfg.getMessager().printMessage(Diagnostic.Kind.NOTE, "added " + nm, type);
85 for(Iterator<String> i = carry.iterator(); i.hasNext();) {
87 TypeElement el = types.get(nm);
91 cfg.getMessager().printMessage(Diagnostic.Kind.NOTE, "removed " + nm, el);
94 List<String> all = new ArrayList<String>();
97 Collections.sort(all);
98 writenew(annotation, all);
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));
109 public SourceVersion getSupportedSourceVersion() {
110 return(SourceVersion.latest());