View Javadoc
1   /*
2    *  Copyright 2013 Chris Pheby
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
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 }