View Javadoc

1   package jp.liq.container.reflect;
2   
3   import java.io.IOException;
4   import java.lang.annotation.Annotation;
5   import java.net.URL;
6   import java.util.Enumeration;
7   import java.util.HashSet;
8   import java.util.Iterator;
9   import java.util.Set;
10  
11  import jp.liq.container.util.AbstractFinder;
12  import jp.liq.container.util.Matcher;
13  
14  public class ClassDiscoverer {
15      private Set<Class<?>> classes;
16  
17      public ClassDiscoverer() {
18          classes = new HashSet<Class<?>>();
19      }
20  
21      public void addClassList(String path) {
22          ClassLoader loader = Thread.currentThread().getContextClassLoader();
23          try {
24              Enumeration<URL> resources = loader.getResources(path);
25              URL u = null;
26              while(resources.hasMoreElements()) {
27                  u = resources.nextElement();
28                  for(Class<?> type : new ClassListLoader(u, loader)) {
29                      classes.add(type);
30                  }
31              }
32          } catch (IOException e) {
33              throw new ReflectException(e);
34          }
35      }
36  
37      public ClassFinder classes() {
38          return new ClassFinder();
39      }
40      
41      private class AnnotationMatcher implements Matcher<Class<?>> {
42          private final Class<? extends Annotation> annotationClass;
43          AnnotationMatcher(Class<? extends Annotation> annotationClass) {
44              this.annotationClass = annotationClass;
45          }
46  
47          public boolean matches(Class<?> candidate) {
48              return candidate.isAnnotationPresent(annotationClass);
49          }
50  
51      }
52  
53      private class SubClassMatcher implements Matcher<Class<?>> {
54          private final Class<?> baseClass;
55          SubClassMatcher(Class<?> baseClass) {
56              this.baseClass = baseClass;
57          }
58  
59          public boolean matches(Class<?> candidate) {
60              return baseClass.isAssignableFrom(candidate);
61          }
62          
63      }
64  
65      public class ClassFinder extends AbstractFinder<Class<?>, ClassFinder> {
66  
67          @Override
68          protected Iterator<Class<?>> getCandidates() {
69              return classes.iterator();
70          }
71  
72          @Override
73          protected ClassFinder getThis() {
74              return this;
75          }
76  
77          public ClassFinder withAnnotation(Class<? extends Annotation> annotationClass) {
78              addMatcher(new AnnotationMatcher(annotationClass));
79              return this;
80          }
81  
82          public ClassFinder isA(Class<?> baseClass) {
83              addMatcher(new SubClassMatcher(baseClass));
84              return this;
85          }
86      }
87  }