annotation-indexer-1.3/0000775000175000017500000000000011746232042015640 5ustar jamespagejamespageannotation-indexer-1.3/pom.xml0000664000175000017500000000275011701727052017162 0ustar jamespagejamespage 4.0.0 org.jenkins-ci jenkins 1.24 annotation-indexer annotation-indexer 1.3 Creates index of annotations. org.kohsuke.metainf-services metainf-services 1.1 true junit junit 3.8.1 test scm:git:git://github.com/jenkinsci/lib-${project.artifactId}.git scm:git:git@github.com:jenkinsci/lib-${project.artifactId}.git MIT License http://jenkins-ci.org/mit-license m.g.o-public http://maven.glassfish.org/content/groups/public/ annotation-indexer-1.3/src/0000775000175000017500000000000011701727052016430 5ustar jamespagejamespageannotation-indexer-1.3/src/main/0000775000175000017500000000000011701727052017354 5ustar jamespagejamespageannotation-indexer-1.3/src/main/java/0000775000175000017500000000000011701727052020275 5ustar jamespagejamespageannotation-indexer-1.3/src/main/java/org/0000775000175000017500000000000011701727052021064 5ustar jamespagejamespageannotation-indexer-1.3/src/main/java/org/jvnet/0000775000175000017500000000000011701727052022212 5ustar jamespagejamespageannotation-indexer-1.3/src/main/java/org/jvnet/hudson/0000775000175000017500000000000011701727052023512 5ustar jamespagejamespageannotation-indexer-1.3/src/main/java/org/jvnet/hudson/annotation_indexer/0000775000175000017500000000000011701727052027402 5ustar jamespagejamespageannotation-indexer-1.3/src/main/java/org/jvnet/hudson/annotation_indexer/Validator.java0000664000175000017500000000263411701727052032177 0ustar jamespagejamespage/* * The contents of this file are subject to the terms of the Common Development * and Distribution License (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at http://www.sun.com/cddl/cddl.html * or http://www.netbeans.org/cddl.txt. * * When distributing Covered Code, include this CDDL Header Notice in each file * and include the License file at http://www.netbeans.org/cddl.txt. * If applicable, add the following below the CDDL Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * The Original Software is SezPoz. The Initial Developer of the Original * Software is Sun Microsystems, Inc. Portions Copyright 2008 Sun * Microsystems, Inc. All Rights Reserved. */ package org.jvnet.hudson.annotation_indexer; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; /** * Checkes the usage of {@link Indexed} annotations at compile-time. * * @author Kohsuke Kawaguchi * @see Indexed */ public interface Validator { /** * Checks the occurrence of the {@link Indexed} annotation * and report any error. Useful for early error detection. */ void check(Element use, RoundEnvironment e, ProcessingEnvironment env); } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootannotation-indexer-1.3/src/main/java/org/jvnet/hudson/annotation_indexer/AnnotationProcessorImpl.javaannotation-indexer-1.3/src/main/java/org/jvnet/hudson/annotation_indexer/AnnotationProcessorImpl.jav0000664000175000017500000001544311701727052034747 0ustar jamespagejamespage/* * The contents of this file are subject to the terms of the Common Development * and Distribution License (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at http://www.sun.com/cddl/cddl.html * or http://www.netbeans.org/cddl.txt. * * When distributing Covered Code, include this CDDL Header Notice in each file * and include the License file at http://www.netbeans.org/cddl.txt. * If applicable, add the following below the CDDL Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * The Original Software is SezPoz. The Initial Developer of the Original * Software is Sun Microsystems, Inc. Portions Copyright 2008 Sun * Microsystems, Inc. All Rights Reserved. */ package org.jvnet.hudson.annotation_indexer; import org.kohsuke.MetaInfServices; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import static javax.lang.model.SourceVersion.RELEASE_6; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.tools.Diagnostic.Kind; import javax.tools.FileObject; import static javax.tools.StandardLocation.CLASS_OUTPUT; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; /** * Creates indices of {@link Indexed} annotations. * * @author Kohsuke Kawaguchi */ @SupportedSourceVersion(RELEASE_6) @SupportedAnnotationTypes("*") @SuppressWarnings({"Since15"}) @MetaInfServices(Processor.class) public class AnnotationProcessorImpl extends AbstractProcessor { /** * Use of an annotation. */ private final class Use { /** * FQCN of the annotation. */ final String annotationName; /** * Strings that designate FQCNs where annotations are used, either on a class or its members. */ final Set classes = new TreeSet(); /** * Keeps track of elements that has the annotation. */ final Set originatingElements = new HashSet(); private Use(String annotationName) { this.annotationName = annotationName; } void add(Element elt) { originatingElements.add(elt); TypeElement t; switch (elt.getKind()) { case CLASS: case INTERFACE: case ANNOTATION_TYPE: case ENUM: t = (TypeElement) elt; break; case METHOD: case FIELD: t = (TypeElement) elt.getEnclosingElement(); break; default: throw new AssertionError(elt.getKind()); } classes.add(getElementUtils().getBinaryName(t).toString()); } String getIndexFileName() { return "META-INF/annotations/" + annotationName; } /** * Loads existing index, if it exists. */ List loadExisting() throws IOException { List elements = new ArrayList(); try { FileObject in = processingEnv.getFiler().getResource(CLASS_OUTPUT, "", getIndexFileName()); // Read existing annotations, for incremental compilation. BufferedReader is = new BufferedReader(new InputStreamReader(in.openInputStream(),"UTF-8")); try { String line; while ((line=is.readLine())!=null) elements.add(line); } finally { is.close(); } } catch (FileNotFoundException x) { // OK, created for the first time } return elements; } void write() { try { FileObject out = processingEnv.getFiler().createResource(CLASS_OUTPUT, "", getIndexFileName(), originatingElements.toArray(new Element[originatingElements.size()])); PrintWriter w = new PrintWriter(new OutputStreamWriter(out.openOutputStream(),"UTF-8")); try { for (String el : classes) w.println(el); } finally { w.close(); } } catch (IOException x) { processingEnv.getMessager().printMessage(Kind.ERROR, x.toString()); } } } private Elements getElementUtils() { return processingEnv.getElementUtils(); } @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) return false; // map from indexable annotation names, to actual uses Map output = new HashMap(); scan(annotations, roundEnv, output); for (Use u : output.values()) u.write(); return false; } private AnnotationMirror findAnnotationOn(Element e, String name) { for (AnnotationMirror a : getElementUtils().getAllAnnotationMirrors(e)) if (getElementUtils().getBinaryName((TypeElement) a.getAnnotationType().asElement()).contentEquals(name)) return a; return null; } private void scan(Set annotations, RoundEnvironment roundEnv, Map output) { for (TypeElement ann : annotations) { AnnotationMirror indexed = findAnnotationOn(ann,Indexed.class.getName()); if (indexed == null) continue; // not indexed String annName = getElementUtils().getBinaryName(ann).toString(); Use o = output.get(annName); if (o==null) output.put(annName,o=new Use(annName)); for (Element elt : roundEnv.getElementsAnnotatedWith(ann)) { AnnotationMirror marked = findAnnotationOn(elt,annName); assert marked != null; // TODO: validator support o.add(elt); } } } } annotation-indexer-1.3/src/main/java/org/jvnet/hudson/annotation_indexer/Index.java0000664000175000017500000001073111701727052031316 0ustar jamespagejamespagepackage org.jvnet.hudson.annotation_indexer; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URL; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; /** * @author Kohsuke Kawaguchi */ public class Index { /** * Lists up all the elements annotated by the given annotation and of the given {@link AnnotatedElement} subtype. */ public static Iterable list(Class type, ClassLoader cl, final Class subType) throws IOException { final Iterable base = list(type,cl); return new Iterable() { public Iterator iterator() { return new FilterIterator(base.iterator()) { protected boolean filter(Object o) { return subType.isInstance(o); } }; } }; } /** * Lists up all the elements annotated by the given annotation. */ public static Iterable list(final Class type, final ClassLoader cl) throws IOException { if (!type.isAnnotationPresent(Indexed.class)) throw new IllegalArgumentException(type+" doesn't have @Indexed"); final Set ids = new TreeSet(); final Enumeration res = cl.getResources("META-INF/annotations/"+type.getName()); while (res.hasMoreElements()) { URL url = res.nextElement(); BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8")); String line; while ((line=r.readLine())!=null) ids.add(line); } return new Iterable() { public Iterator iterator() { return new Iterator() { /** * Next element to return. */ private AnnotatedElement next; private Iterator iditr = ids.iterator(); private List lookaheads = new LinkedList(); public boolean hasNext() { fetch(); return next!=null; } public AnnotatedElement next() { fetch(); AnnotatedElement r = next; next = null; return r; } public void remove() { throw new UnsupportedOperationException(); } private void fetch() { while (next==null) { if (!lookaheads.isEmpty()) { next = lookaheads.remove(0); return; } if (!iditr.hasNext()) return; String name = iditr.next(); try { Class c = cl.loadClass(name); if (c.isAnnotationPresent(type)) lookaheads.add(c); listAnnotatedElements(c.getDeclaredMethods()); listAnnotatedElements(c.getDeclaredFields()); } catch (ClassNotFoundException e) { LOGGER.log(Level.FINE, "Failed to load: "+name,e); } } } private void listAnnotatedElements(AnnotatedElement[] elements) { for (AnnotatedElement m : elements) { // this means we don't correctly handle if (m.isAnnotationPresent(type)) lookaheads.add(m); } } }; } }; } private static final Logger LOGGER = Logger.getLogger(Index.class.getName()); } annotation-indexer-1.3/src/main/java/org/jvnet/hudson/annotation_indexer/FilterIterator.java0000664000175000017500000000234211701727052033205 0ustar jamespagejamespagepackage org.jvnet.hudson.annotation_indexer; import java.util.Iterator; import java.util.NoSuchElementException; /** * @author Kohsuke Kawaguchi */ abstract class FilterIterator implements Iterator { private final Iterator core; private T next; private boolean fetched; protected FilterIterator(Iterator core) { this.core = core; } protected FilterIterator(Iterable core) { this(core.iterator()); } private void fetch() { while(!fetched && core.hasNext()) { T n = core.next(); if(filter(n)) { next = n; fetched = true; } } } /** * Filter out items in the original collection. * * @return * true to leave this item and return this item from this iterator. * false to hide this item. */ protected abstract boolean filter(T t); public boolean hasNext() { fetch(); return fetched; } public T next() { fetch(); if(!fetched) throw new NoSuchElementException(); fetched = false; return next; } public void remove() { core.remove(); } } annotation-indexer-1.3/src/main/java/org/jvnet/hudson/annotation_indexer/Indexed.java0000664000175000017500000000272511701727052031633 0ustar jamespagejamespage/* * The contents of this file are subject to the terms of the Common Development * and Distribution License (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at http://www.sun.com/cddl/cddl.html * or http://www.netbeans.org/cddl.txt. * * When distributing Covered Code, include this CDDL Header Notice in each file * and include the License file at http://www.netbeans.org/cddl.txt. * If applicable, add the following below the CDDL Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * The Original Software is SezPoz. The Initial Developer of the Original * Software is Sun Microsystems, Inc. Portions Copyright 2008 Sun * Microsystems, Inc. All Rights Reserved. */ package org.jvnet.hudson.annotation_indexer; import java.lang.annotation.Documented; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; /** * Marks annotations that should be indexed during compilation. * * The annotations indexed this way can be later enumerated efficiently with {@link Index}. * * @author Kohsuke Kawaguchi */ @Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE) public @interface Indexed { Class[] validators() default {}; }