/** * Adds a jar file to be scanned * * @param jar * jar(s) to be added to the scanner * * @return this scanner */ public JarScanner addJar(URL... jar) { return addJar(Arrays.asList(jar)); }
/** * Scans the specified jars for packages and returns a list of all packages found in that jar. The scanner only * collects packages that contain class files. * * @return a collection of all package names found in the jar */ public Collection<String> scanPackages() { return scanJar(p -> Files.isDirectory(p) && containsClassFiles(p) && !isIgnored(p.toAbsolutePath())); }
/** * Excludes the specified folders from scanning. The ignore pattern checks matches packages and classes * starting with the specified string. * * @param folder * folder(s) to be ignored * * @return this scanner */ public JarScanner ignore(String... folder) { return ignore(Arrays.asList(folder)); }
/** * Scans the specified jars for packages and returns a list of all packages found in that jar. The scanner makes no * distinction between packages and folders. * * @return a collection of all classes names found in the jar */ public Collection<String> scanClasses() { return scanJar(p -> isClassFile(p) && !isIgnored(p.toAbsolutePath())); }
/** * Creates a classloader for testing purposes. The classloader loads the classes from the test jars. * * @param testJars * jar files to be loaded by this classloader. For all packages and classes contained in these jars this * classloader takes precedence over the parent classloader. * @param packages * additional packages for which this classloader should take precedence over the parent classloader */ public TestClassLoader(Collection<URL> testJars, Collection<String> packages, String... excludePackages) { super(getURLs(testJars), getParentClassLoader()); this.packages = Collections.newSetFromMap(new ConcurrentHashMap<>()); this.packages.addAll(packages); this.packages.addAll(new JarScanner().addJar(testJars).ignore(excludePackages).scanPackages()); this.blacklist = Collections.newSetFromMap(new ConcurrentHashMap<>()); this.blacklist.addAll(Arrays.asList(excludePackages)); }
/** * Checks if the specified path is on the ignore list * * @param p * the path to check * * @return true if the path should be ignored */ private boolean isIgnored(Path p) { final String path = toFQName(p); return this.ignoredFolders.stream().anyMatch(path::startsWith); }
/** * Scans the jars of the JarScanner finding all items matching the path filter * @param pathFilter * the filter to find items in the jars * @return * Collections of items of the jars matching the filter */ private Collection<String> scanJar(Predicate<Path> pathFilter) { return jars.parallelStream() .map(JarScanner::createJarUri) .flatMap(u -> scanJar(u, pathFilter).stream()) .distinct() .collect(Collectors.toList()); }
/** * Scans the jar and filters all elements * * @param u * the uri of the jar file to be scanned * @param pathPredicate * the matching predicate for collecting the entries * * @return a stream of collected strings */ private Collection<String> scanJar(URI u, Predicate<Path> pathPredicate) { try (FileSystem fs = FileSystems.newFileSystem(u, READY_ONLY_ENV)) { return Files.walk(fs.getPath("/")) .filter(pathPredicate) .map(f -> toFQName(f.toAbsolutePath())) .distinct() .collect(Collectors.toList()); } catch (IOException e) { throw new UncheckedException(e); } }