1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jadira.scanner;
17
18 import java.lang.annotation.Annotation;
19 import java.net.URL;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.List;
23
24 import org.jadira.scanner.classpath.ClasspathResolver;
25 import org.jadira.scanner.classpath.filter.JElementTypeFilter;
26 import org.jadira.scanner.classpath.filter.JTypeAnnotatedWithFilter;
27 import org.jadira.scanner.classpath.filter.JTypeSubTypeOfFilter;
28 import org.jadira.scanner.classpath.projector.ClasspathProjector;
29 import org.jadira.scanner.classpath.types.JElement;
30 import org.jadira.scanner.classpath.types.JType;
31 import org.jadira.scanner.core.api.Filter;
32 import org.jadira.scanner.core.api.Locator;
33
34 public class Scanner {
35
36 protected final transient Configuration configuration;
37 private ClasspathResolver classpathResolver;
38
39 public Scanner(final Configuration configuration) {
40 this.configuration = configuration;
41
42 List<URL> urls = new ArrayList<URL>();
43 if (configuration.getUrls() != null) {
44 urls.addAll(configuration.getUrls());
45 }
46 if (configuration.getLocators() != null) {
47 for (Locator<URL> next : configuration.getLocators()) {
48 urls.addAll(next.locate());
49 }
50 }
51 if (configuration.getClassLoaders() == null) {
52 classpathResolver = new ClasspathResolver(urls);
53 } else {
54 classpathResolver = new ClasspathResolver(urls, configuration.getClassLoaders());
55 }
56 }
57
58 public Scanner(final String prefix, final Filter<?>...s) {
59 this((Object) prefix,s);
60 }
61
62 public Scanner(final Object... params) {
63 this(ConfigurationBuilder.build(params));
64 }
65
66 public Scanner() {
67 this(new ConfigurationBuilder());
68 }
69
70 public <T> Class<? extends T>[] findSubTypesOf(final Class<T> type) {
71
72 @SuppressWarnings("unchecked")
73 Class<? extends T>[] result = (Class<? extends T>[]) jtypeToClass(classpathResolver.resolveAll(null, ClasspathProjector.SINGLETON, assembleFilters(new JElementTypeFilter(JType.class), new JTypeSubTypeOfFilter(type))));
74 return result;
75 }
76
77 public Class<?>[] findTypesAnnotatedWith(final Class<? extends Annotation> annotation) {
78
79 return jtypeToClass(classpathResolver.resolveAll(null, ClasspathProjector.SINGLETON, assembleFilters(new JElementTypeFilter(JType.class), new JTypeAnnotatedWithFilter(annotation))));
80 }
81
82 public Configuration getConfiguration() {
83 return configuration;
84 }
85
86 private static Class<?>[] jtypeToClass(Collection<? extends JElement> jclasses) {
87
88 List<JType> elements = new ArrayList<JType>(jclasses.size());
89 for (JElement next : jclasses) {
90 if (!(next instanceof JType)) {
91 throw new IllegalStateException("Only JType can be converted to classes");
92 } else {
93 elements.add((JType)next);
94 }
95 }
96 return jtypeToClass(elements.toArray(new JType[]{}));
97 }
98
99 private static Class<?>[] jtypeToClass(JType... jclasses) {
100
101 Class<?>[] classes = new Class[jclasses.length];
102 for (int i=0; i<jclasses.length; i++) {
103 Class<?> actualClass = (Class<?>) jclasses[i].getActualClass();
104 classes[i] = actualClass;
105 }
106 return classes;
107 }
108
109 private Filter<?>[] assembleFilters(Filter<?>... searchFilters) {
110
111 Filter<?>[] filters = new Filter<?>[configuration.getFilters().size() + searchFilters.length];
112 for (int i = 0; i < configuration.getFilters().size(); i++) {
113 filters[i] = configuration.getFilters().get(0);
114 }
115
116 for (int i = 0; i < searchFilters.length; i++) {
117 filters[configuration.getFilters().size() + i] = searchFilters[i];
118 }
119 return filters;
120 }
121 }