public Set<Class<?>> findAnnotated(Class<? extends Annotation> annotation, String... packageNames) { if (packageNames == null) { return Collections.emptySet(); } if (log.isDebugEnabled()) { log.debug("Searching for annotations of {} in packages: {}", annotation.getName(), Arrays.asList(packageNames)); } PackageScanFilter test = getCompositeFilter(new AnnotatedWithPackageScanFilter(annotation, true)); Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); for (String pkg : packageNames) { find(test, pkg, classes); } log.debug("Found: {}", classes); return classes; }
public Set<Class<?>> findAnnotated(Set<Class<? extends Annotation>> annotations, String... packageNames) { if (packageNames == null) { return Collections.emptySet(); } if (log.isDebugEnabled()) { log.debug("Searching for annotations of {} in packages: {}", annotations, Arrays.asList(packageNames)); } PackageScanFilter test = getCompositeFilter(new AnnotatedWithAnyPackageScanFilter(annotations, true)); Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); for (String pkg : packageNames) { find(test, pkg, classes); } log.debug("Found: {}", classes); return classes; }
public Set<Class<?>> findImplementations(Class<?> parent, String... packageNames) { if (packageNames == null) { return Collections.emptySet(); } if (log.isDebugEnabled()) { log.debug("Searching for implementations of {} in packages: {}", parent.getName(), Arrays.asList(packageNames)); } PackageScanFilter test = getCompositeFilter(new AssignableToPackageScanFilter(parent)); Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); for (String pkg : packageNames) { find(test, pkg, classes); } log.debug("Found: {}", classes); return classes; }
/** * Finds matches in a physical directory on a filesystem. Examines all files * within a directory - if the File object is not a directory, and ends with * <i>.class</i> the file is loaded and tested to see if it is acceptable * according to the Test. Operates recursively to find classes within a * folder structure matching the package structure. * * @param test a Test used to filter the classes that are discovered * @param parent the package name up to this directory in the package * hierarchy. E.g. if /classes is in the classpath and we wish to * examine files in /classes/org/apache then the values of * <i>parent</i> would be <i>org/apache</i> * @param location a File object representing a directory */ private void loadImplementationsInDirectory(PackageScanFilter test, String parent, File location, Set<Class<?>> classes) { File[] files = location.listFiles(); StringBuilder builder; for (File file : files) { builder = new StringBuilder(100); String name = file.getName(); if (name != null) { name = name.trim(); builder.append(parent).append("/").append(name); String packageOrClass = parent == null ? name : builder.toString(); if (file.isDirectory()) { loadImplementationsInDirectory(test, packageOrClass, file, classes); } else if (name.endsWith(".class")) { addIfMatching(test, packageOrClass, classes); } } } }
/** * Finds matching classes within a jar files that contains a folder * structure matching the package structure. If the File is not a JarFile or * does not exist a warning will be logged, but no error will be raised. * * @param test a Test used to filter the classes that are discovered * @param parent the parent package under which classes must be in order to * be considered * @param stream the inputstream of the jar file to be examined for classes * @param urlPath the url of the jar file to be examined for classes * @param classes to add found and matching classes * @param jarCache cache for JARs to speedup loading */ private void loadImplementationsInJar(PackageScanFilter test, String parent, InputStream stream, String urlPath, Set<Class<?>> classes, Map<String, List<String>> jarCache) { ObjectHelper.notNull(classes, "classes"); ObjectHelper.notNull(jarCache, "jarCache"); List<String> entries = jarCache != null ? jarCache.get(urlPath) : null; if (entries == null) { entries = doLoadJarClassEntries(stream, urlPath); if (jarCache != null) { jarCache.put(urlPath, entries); log.trace("Cached {} JAR with {} entries", urlPath, entries.size()); } } else { log.trace("Using cached {} JAR with {} entries", urlPath, entries.size()); } doLoadImplementationsInJar(test, parent, entries, classes); }
public void find(PackageScanFilter test, String packageName, Set<Class<?>> classes) { packageName = packageName.replace('.', '/'); // remember the number of classes found so far int classesSize = classes.size(); // look in osgi bundles loadImplementationsInBundle(test, packageName, classes); // if we did not find any new, then fallback to use regular non bundle class loading if (classes.size() == classesSize) { // Using the non-OSGi classloaders as a fallback // this is necessary when use JBI packaging for servicemix-camel SU // so that we get chance to use SU classloader to scan packages in the SU log.trace("Cannot find any classes in bundles, not trying regular classloaders scanning: {}", packageName); for (ClassLoader classLoader : super.getClassLoaders()) { if (!isOsgiClassloader(classLoader)) { find(test, packageName, classLoader, classes); } } } }
private Set<String> getImplementationsInBundle(PackageScanFilter test, String packageName) { Bundle[] bundles; if (bundle.getBundleContext() != null) { bundles = bundle.getBundleContext().getBundles(); } else { bundles = new Bundle[]{bundle}; } Set<String> urls = new LinkedHashSet<String>(); for (Bundle bd : bundles) { log.trace("Searching in bundle: {}", bd); try { Enumeration<URL> paths = bd.findEntries("/" + packageName, "*.class", true); while (paths != null && paths.hasMoreElements()) { URL path = paths.nextElement(); String pathString = path.getPath(); String urlString = pathString.substring(pathString.indexOf(packageName)); urls.add(urlString); log.trace("Added url: {}", urlString); } } catch (Throwable t) { log.warn("Cannot search in bundle: " + bundle + " for classes matching criteria: " + test + " due: " + t.getMessage() + ". This exception will be ignored.", t); } } return urls; }
public boolean matches(Class<?> type) { for (PackageScanFilter filter : filters) { if (!filter.matches(type)) { return false; } } return true; }
public Set<Class<?>> findByFilter(PackageScanFilter filter, String... packageNames) { if (packageNames == null) { return Collections.emptySet(); } Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); for (String pkg : packageNames) { find(filter, pkg, classes); } log.debug("Found: {}", classes); return classes; }
protected void find(PackageScanFilter test, String packageName, Set<Class<?>> classes) { packageName = packageName.replace('.', '/'); Set<ClassLoader> set = getClassLoaders(); for (ClassLoader classLoader : set) { find(test, packageName, classLoader, classes); } }
private PackageScanFilter getCompositeFilter(PackageScanFilter filter) { if (scanFilters != null) { CompositePackageScanFilter composite = new CompositePackageScanFilter(scanFilters); composite.addFilter(filter); return composite; } return filter; }
@Override protected void findRouteBuildersByPackageScan(String[] packages, PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception { // add filter to class resolver which then will filter getContext().getPackageScanClassResolver().addFilter(filter); ClassLoader classLoader = new BundleDelegatingClassLoader(bundleContext.getBundle()); PackageScanRouteBuilderFinder finder = new PackageScanRouteBuilderFinder(getContext(), packages, classLoader, getContext().getPackageScanClassResolver()); finder.appendBuilders(builders); // and remove the filter getContext().getPackageScanClassResolver().removeFilter(filter); }
@Override protected void findRouteBuildersByPackageScan(String[] packages, PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception { // add filter to class resolver which then will filter getContext().getPackageScanClassResolver().addFilter(filter); PackageScanRouteBuilderFinder finder = new PackageScanRouteBuilderFinder(getContext(), packages, getContextClassLoaderOnStart(), getContext().getPackageScanClassResolver()); finder.appendBuilders(builders); // and remove the filter getContext().getPackageScanClassResolver().removeFilter(filter); }
private void loadImplementationsInBundle(PackageScanFilter test, String packageName, Set<Class<?>> classes) { Set<String> urls = getImplementationsInBundle(test, packageName); if (urls != null) { for (String url : urls) { // substring to avoid leading slashes addIfMatching(test, url, classes); } } }
@Override protected void findRouteBuildersByPackageScan(String[] packages, PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception { // add filter to class resolver which then will filter getContext().getPackageScanClassResolver().addFilter(filter); PackageScanRouteBuilderFinder finder = new PackageScanRouteBuilderFinder(getContext(), packages, getContextClassLoaderOnStart(), getBeanPostProcessor(), getContext().getPackageScanClassResolver()); finder.appendBuilders(builders); // and remove the filter getContext().getPackageScanClassResolver().removeFilter(filter); }
public void testCompositePackageScanFilter() { PackageScanFilter one = new AnnotatedWithPackageScanFilter(org.apache.camel.spring.scan.ScannableOne.class); PackageScanFilter two = new AssignableToPackageScanFilter(ScanTargetOne.class); Set<PackageScanFilter> filters = CollectionHelper.createSetContaining(one, two); CompositePackageScanFilter filter = new CompositePackageScanFilter(filters); validateFilter(filter, ScanTargetOne.class); validateFilter(filter, ScanTargetTwo.class); filter = new CompositePackageScanFilter(); filter.addFilter(one); filter.addFilter(two); validateFilter(filter, ScanTargetOne.class); validateFilter(filter, ScanTargetTwo.class); }
protected void find(PackageScanFilter test, String packageName, ClassLoader loader, Set<Class<?>> classes) { if (LOG.isTraceEnabled()) { LOG.tracef("Searching for: %s in package: %s using classloader: %s", new Object[]{test, packageName, loader.getClass().getName()}); } Enumeration<URL> urls; try { urls = getResources(loader, packageName); if (!urls.hasMoreElements()) { LOG.trace("No URLs returned by classloader"); } } catch (IOException ioe) { ExtensionLogger.ROOT_LOGGER.cannotReadPackage(packageName, ioe); return; } while (urls.hasMoreElements()) { URL url = urls.nextElement(); LOG.tracef("URL from classloader: %s", url); if (url.toString().startsWith("vfs:")) { try { VirtualFile vfsDir = VFS.getChild(url); handleDirectory(vfsDir, null, classes, test); } catch (URISyntaxException uriEx) { ExtensionLogger.ROOT_LOGGER.failedToParseURL(url.toString(), uriEx); } } } }
private void handleDirectory(VirtualFile file, String path, Set<Class<?>> classes, PackageScanFilter test) { for (VirtualFile child : file.getChildren()) { String newPath = (path == null) ? child.getName() : (path + '/' + child.getName()); if (child.isDirectory()) { handleDirectory(child, newPath, classes, test); } else { handleFile(child, classes, test); } } }
private void handleFile(VirtualFile file, Set<Class<?>> classes, PackageScanFilter test) { if (file.getName().endsWith(".class")) { String fqn = file.getPathName(); String qn; if (fqn.indexOf("jar/") != -1) { qn = fqn.substring(fqn.indexOf("jar/") + 4); } else { qn = fqn.substring(fqn.indexOf("/") + 1); } addIfMatching(test, qn, classes); } }
@Override protected void find(PackageScanFilter filter, String packageName, ClassLoader classLoader, Set<Class<?>> classes) { LOGGER.info("Searching for: {} in package: {} using classloader: {}", new Object[] { filter, packageName, classLoader }); // Would be the case for the system classloader if (!(classLoader instanceof ModuleClassLoader)) { super.find(filter, packageName, classLoader, classes); return; } int classLoadCount = classes.size(); ModuleClassLoader moduleClassLoader = (ModuleClassLoader) classLoader; Iterator<Resource> itres = moduleClassLoader.iterateResources("/", true); while (itres.hasNext()) { Resource resource = itres.next(); String resname = resource.getName(); if (resname.startsWith(packageName) && resname.endsWith(".class")) { String className = resname.substring(0, resname.length() - 6).replace('/', '.'); try { Class<?> loadedClass = moduleClassLoader.loadClass(className); if (filter.matches(loadedClass)) { LOGGER.info("Found type in package scan: {}", loadedClass.getName()); classes.add(loadedClass); } } catch (ClassNotFoundException ex) { //ignore } } } // No classes found by previous package scan so delegate to super if(classes.size() == classLoadCount) { super.find(filter, packageName, classLoader, classes); } }
@Override public Set<Class<?>> findByFilter(PackageScanFilter filter, String... packageNames) { // noop return null; }
@Override public void addFilter(PackageScanFilter filter) { // noop }
@Override public void removeFilter(PackageScanFilter filter) { // noop }
public CompositePackageScanFilter() { filters = new LinkedHashSet<PackageScanFilter>(); }
public CompositePackageScanFilter(Set<PackageScanFilter> filters) { this.filters = new LinkedHashSet<PackageScanFilter>(filters); }
public void addFilter(PackageScanFilter filter) { filters.add(filter); }
public InvertingPackageScanFilter(PackageScanFilter filter) { this.filter = filter; }
public void addFilter(PackageScanFilter filter) { if (scanFilters == null) { scanFilters = new LinkedHashSet<PackageScanFilter>(); } scanFilters.add(filter); }
public void removeFilter(PackageScanFilter filter) { if (scanFilters != null) { scanFilters.remove(filter); } }
@Override protected void findRouteBuildersByContextScan(PackageScanFilter filter, boolean includeNonSingletons, List<RoutesBuilder> builders) throws Exception { ContextScanRouteBuilderFinder finder = new ContextScanRouteBuilderFinder(getContext(), filter, includeNonSingletons); finder.appendBuilders(builders); }
public ContextScanRouteBuilderFinder(BlueprintCamelContext camelContext, PackageScanFilter filter, boolean includeNonSingletons) { this.blueprintContainer = camelContext.getBlueprintContainer(); this.filter = filter; this.includeNonSingletons = includeNonSingletons; }
@Override protected void findRouteBuildersByContextScan(PackageScanFilter filter, boolean includeNonSingletons, List<RoutesBuilder> builders) throws Exception { ContextScanRouteBuilderFinder finder = new ContextScanRouteBuilderFinder(manager, filter, includeNonSingletons); finder.appendBuilders(builders); }
ContextScanRouteBuilderFinder(BeanManager manager, PackageScanFilter filter, boolean includeNonSingletons) { this.manager = manager; this.filter = filter; this.includeNonSingletons = includeNonSingletons; }
public AnnotationModelLoader(PackageScanClassResolver resolver, PackageScanFilter filter) { this(resolver); this.filter = filter; }
public ContextScanRouteBuilderFinder(SpringCamelContext camelContext, PackageScanFilter filter, boolean includeNonSingletons) { this.applicationContext = camelContext.getApplicationContext(); this.filter = filter; this.includeNonSingletons = includeNonSingletons; }