All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jvnet.hudson.annotation_indexer.Index Maven / Gradle / Ivy

The newest version!
package 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());
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy