001/* 002 * Copyright 2013 Chris Pheby 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.jadira.scanner; 017 018import java.lang.annotation.Annotation; 019import java.net.URL; 020import java.util.ArrayList; 021import java.util.Collection; 022import java.util.List; 023 024import org.jadira.scanner.classpath.ClasspathResolver; 025import org.jadira.scanner.classpath.filter.JElementTypeFilter; 026import org.jadira.scanner.classpath.filter.JTypeAnnotatedWithFilter; 027import org.jadira.scanner.classpath.filter.JTypeSubTypeOfFilter; 028import org.jadira.scanner.classpath.projector.ClasspathProjector; 029import org.jadira.scanner.classpath.types.JElement; 030import org.jadira.scanner.classpath.types.JType; 031import org.jadira.scanner.core.api.Filter; 032import org.jadira.scanner.core.api.Locator; 033 034public class Scanner { 035 036 protected final transient Configuration configuration; 037 private ClasspathResolver classpathResolver; 038 039 public Scanner(final Configuration configuration) { 040 this.configuration = configuration; 041 042 List<URL> urls = new ArrayList<URL>(); 043 if (configuration.getUrls() != null) { 044 urls.addAll(configuration.getUrls()); 045 } 046 if (configuration.getLocators() != null) { 047 for (Locator<URL> next : configuration.getLocators()) { 048 urls.addAll(next.locate()); 049 } 050 } 051 if (configuration.getClassLoaders() == null) { 052 classpathResolver = new ClasspathResolver(urls); 053 } else { 054 classpathResolver = new ClasspathResolver(urls, configuration.getClassLoaders()); 055 } 056 } 057 058 public Scanner(final String prefix, final Filter<?>...s) { 059 this((Object) prefix,s); 060 } 061 062 public Scanner(final Object... params) { 063 this(ConfigurationBuilder.build(params)); 064 } 065 066 public Scanner() { 067 this(new ConfigurationBuilder()); 068 } 069 070 public <T> Class<? extends T>[] findSubTypesOf(final Class<T> type) { 071 072 @SuppressWarnings("unchecked") 073 Class<? extends T>[] result = (Class<? extends T>[]) jtypeToClass(classpathResolver.resolveAll(null, ClasspathProjector.SINGLETON, assembleFilters(new JElementTypeFilter(JType.class), new JTypeSubTypeOfFilter(type)))); 074 return result; 075 } 076 077 public Class<?>[] findTypesAnnotatedWith(final Class<? extends Annotation> annotation) { 078 079 return jtypeToClass(classpathResolver.resolveAll(null, ClasspathProjector.SINGLETON, assembleFilters(new JElementTypeFilter(JType.class), new JTypeAnnotatedWithFilter(annotation)))); 080 } 081 082 public Configuration getConfiguration() { 083 return configuration; 084 } 085 086 private static Class<?>[] jtypeToClass(Collection<? extends JElement> jclasses) { 087 088 List<JType> elements = new ArrayList<JType>(jclasses.size()); 089 for (JElement next : jclasses) { 090 if (!(next instanceof JType)) { 091 throw new IllegalStateException("Only JType can be converted to classes"); 092 } else { 093 elements.add((JType)next); 094 } 095 } 096 return jtypeToClass(elements.toArray(new JType[]{})); 097 } 098 099 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}