/** * Fetch the content of each {@link Resource} in this {@link ResourceList} as a byte array, pass the byte array * to the given {@link ByteArrayConsumer}, then close the underlying InputStream or release the underlying * ByteBuffer by calling {@link Resource#close()}. * * @param byteArrayConsumer * The {@link ByteArrayConsumer}. * @throws IllegalArgumentException * if trying to load any of the resources results in an {@link IOException} being thrown. */ public void forEachByteArray(final ByteArrayConsumer byteArrayConsumer) { forEachByteArray(byteArrayConsumer, /* ignoreIOExceptions = */ false); }
/** * Find the subset of the {@link Resource} objects in this list for which the given filter predicate is true. * * @param filter * The {@link ResourceFilter} to apply. * @return The subset of the {@link Resource} objects in this list for which the given filter predicate is true. */ public ResourceList filter(final ResourceFilter filter) { final ResourceList resourcesFiltered = new ResourceList(); for (final Resource resource : this) { if (filter.accept(resource)) { resourcesFiltered.add(resource); } } return resourcesFiltered; }
/** * @return A new {@link ResourceList} consisting of only the resources that do not have the filename extension * ".class". */ public ResourceList nonClassFilesOnly() { return filter(new ResourceFilter() { @Override public boolean accept(final Resource resource) { return !CLASSFILE_FILTER.accept(resource); } }); }
/** @return A list of all resources (including classfiles and non-classfiles) found in whitelisted packages. */ public ResourceList getAllResources() { if (allWhitelistedResources == null || allWhitelistedResources.isEmpty()) { return new ResourceList(1); } else { return allWhitelistedResources; } }
/** * @param pattern * A pattern to match {@link Resource} paths with. * @return A list of all resources found in whitelisted packages that have a path matching the requested * pattern. */ public ResourceList getResourcesMatchingPattern(final Pattern pattern) { if (closed.get()) { throw new IllegalArgumentException("Cannot use a ScanResult after it has been closed"); } if (allWhitelistedResources == null || allWhitelistedResources.isEmpty()) { return new ResourceList(1); } else { final ResourceList filteredResources = new ResourceList(); for (final Resource classpathResource : allWhitelistedResources) { final String relativePath = classpathResource.getPath(); if (pattern.matcher(relativePath).matches()) { filteredResources.add(classpathResource); } } return filteredResources; } }
if (classpathElt.whitelistedResources != null) { if (allWhitelistedResources == null) { allWhitelistedResources = new ResourceList(); pathToWhitelistedResourceList = new HashMap<>(); allWhitelistedResources.addAll(classpathElt.whitelistedResources); for (final Resource resource : classpathElt.whitelistedResources) { final String path = resource.getPath(); ResourceList resourceList = pathToWhitelistedResourceList.get(path); if (resourceList == null) { pathToWhitelistedResourceList.put(path, resourceList = new ResourceList()); resourceList.add(resource);
/** * @return A {@link List} of {@link Entry} objects for all resources in the classpath and/or module path that * have a non-unique path (i.e. where there are at least two resources with the same path). The key of * each returned {@link Entry} is the path (obtained from {@link Resource#getPath()}), and the value is * a {@link ResourceList} of at least two unique {@link Resource} objects that have that path. */ public List<Entry<String, ResourceList>> findDuplicatePaths() { final List<Entry<String, ResourceList>> duplicatePaths = new ArrayList<>(); for (final Entry<String, ResourceList> pathAndResourceList : asMap().entrySet()) { // Find ResourceLists with two or more entries if (pathAndResourceList.getValue().size() > 1) { duplicatePaths.add(new SimpleEntry<>(pathAndResourceList.getKey(), pathAndResourceList.getValue())); } } Collections.sort(duplicatePaths, new Comparator<Entry<String, ResourceList>>() { @Override public int compare(final Entry<String, ResourceList> o1, final Entry<String, ResourceList> o2) { // Sort in lexicographic order of path return o1.getKey().compareTo(o2.getKey()); } }); return duplicatePaths; }
classpathResource.close(); allWhitelistedResources.clear(); allWhitelistedResources = null;
/** * @param leafName * A resource leaf filename. * @return A list of all resources found in whitelisted packages that have the requested leafname. */ public ResourceList getResourcesWithLeafName(final String leafName) { if (closed.get()) { throw new IllegalArgumentException("Cannot use a ScanResult after it has been closed"); } if (allWhitelistedResources == null || allWhitelistedResources.isEmpty()) { return new ResourceList(1); } else { final ResourceList filteredResources = new ResourceList(); for (final Resource classpathResource : allWhitelistedResources) { final String relativePath = classpathResource.getPath(); final int lastSlashIdx = relativePath.lastIndexOf('/'); if (relativePath.substring(lastSlashIdx + 1).equals(leafName)) { filteredResources.add(classpathResource); } } return filteredResources; } }
/** * @param resourcePath * A complete resource path, relative to the classpath entry package root. * @return A list of all resources found in whitelisted packages that have the given path, relative to the * package root of the classpath element. May match several resources, up to one per classpath element. */ public ResourceList getResourcesWithPath(final String resourcePath) { if (closed.get()) { throw new IllegalArgumentException("Cannot use a ScanResult after it has been closed"); } if (allWhitelistedResources == null || allWhitelistedResources.isEmpty()) { return new ResourceList(1); } else { final String path = FileUtils.sanitizeEntryPath(resourcePath, /* removeInitialSlash = */ true); final ResourceList resourceList = pathToWhitelistedResourceList.get(path); return (resourceList == null ? new ResourceList(1) : resourceList); } }
/** * Starts up Guice and the scanner */ private void loadScanner() { Stopwatch stopwatch = Stopwatch.createStarted(); GuiceContext.log.info("Loading Classpath Scanner - [" + GuiceContext.getThreadCount() + "] threads"); if (GuiceContext.config == null) { loadConfiguration(); } scanner = new ClassGraph(); configureScanner(scanner); try { scanResult = scanner.scan(GuiceContext.getThreadCount()); Map<String, ResourceList.ByteArrayConsumer> fileScans = quickScanFiles(); fileScans.forEach((key, value) -> scanResult.getResourcesWithLeafName(key) .forEachByteArray(value)); } catch (Exception mpe) { GuiceContext.log.log(Level.SEVERE, "Unable to run scanner", mpe); } stopwatch.stop(); GuiceContext.log.fine("Loaded Classpath Scanner - Took [" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + "] millis."); }
/** * @param extension * A filename extension, e.g. "xml" to match all resources ending in ".xml". * @return A list of all resources found in whitelisted packages that have the requested filename extension. */ public ResourceList getResourcesWithExtension(final String extension) { if (closed.get()) { throw new IllegalArgumentException("Cannot use a ScanResult after it has been closed"); } if (allWhitelistedResources == null || allWhitelistedResources.isEmpty()) { return new ResourceList(1); } else { String bareExtension = extension; while (bareExtension.startsWith(".")) { bareExtension = bareExtension.substring(1); } final ResourceList filteredResources = new ResourceList(); for (final Resource classpathResource : allWhitelistedResources) { final String relativePath = classpathResource.getPath(); final int lastSlashIdx = relativePath.lastIndexOf('/'); final int lastDotIdx = relativePath.lastIndexOf('.'); if (lastDotIdx > lastSlashIdx) { if (relativePath.substring(lastDotIdx + 1).equalsIgnoreCase(bareExtension)) { filteredResources.add(classpathResource); } } } return filteredResources; } }
/** * @return This {@link ResourceList} as a map from path (obtained from {@link Resource#getPath()}), to a * {@link ResourceList} of {@link Resource} objects that have that path. */ public Map<String, ResourceList> asMap() { final Map<String, ResourceList> pathToResourceList = new HashMap<>(); for (final Resource resource : this) { final String path = resource.getPath(); ResourceList resourceList = pathToResourceList.get(path); if (resourceList == null) { resourceList = new ResourceList(1); pathToResourceList.put(path, resourceList); } resourceList.add(resource); } return pathToResourceList; }
/** * @return A new {@link ResourceList} consisting of only the resources with the filename extension ".class". */ public ResourceList classFilesOnly() { return filter(CLASSFILE_FILTER); }
/** * Starts up Guice and the scanner */ private void loadScanner() { Stopwatch stopwatch = Stopwatch.createStarted(); GuiceContext.log.info("Loading Classpath Scanner - [" + GuiceContext.getThreadCount() + "] threads"); if (GuiceContext.config == null) { loadConfiguration(); } scanner = new ClassGraph(); configureScanner(scanner); try { scanResult = scanner.scan(GuiceContext.getThreadCount()); Map<String, ResourceList.ByteArrayConsumer> fileScans = quickScanFiles(); fileScans.forEach((key, value) -> scanResult.getResourcesWithLeafName(key) .forEachByteArray(value)); } catch (Exception mpe) { GuiceContext.log.log(Level.SEVERE, "Unable to run scanner", mpe); } stopwatch.stop(); GuiceContext.log.fine("Loaded Classpath Scanner - Took [" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + "] millis."); }
/** * @param resourcePath * A complete resource path, relative to the classpath entry package root. * @return A list of all resources found in any classpath element, <i>whether in whitelisted packages or not<i>, * that have the given path, relative to the package root of the classpath element. (Resources will not * be returned if their path is blacklisted.) May match several resources, up to one per classpath * element. */ public ResourceList getResourcesWithPathIgnoringWhitelist(final String resourcePath) { if (closed.get()) { throw new IllegalArgumentException("Cannot use a ScanResult after it has been closed"); } final String path = FileUtils.sanitizeEntryPath(resourcePath, /* removeInitialSlash = */ true); final ResourceList matchingResources = new ResourceList(); for (final ClasspathElement classpathElt : classpathOrder) { final Resource matchingResource = classpathElt.getResource(path); if (matchingResource != null) { matchingResources.add(matchingResource); } } return matchingResources; }
fileScans.forEach((key, value) -> scanResult.getResourcesWithLeafName(key) .forEachByteArray(value));