/** * @return A map from a {@link ClassInfo} object for each whitelisted class to a list of the classes referenced * by that class (i.e. returns a map from dependents to dependencies). Each map value is the result of * calling {@link ClassInfo#getClassDependencies()} on the corresponding key. Note that you need to call * {@link ClassGraph#enableInterClassDependencies()} before {@link ClassGraph#scan()} for this method to * work. You should also call {@link ClassGraph#enableExternalClasses()} before * {@link ClassGraph#scan()} if you want non-whitelisted classes to appear in the result. See also * {@link #getReverseClassDependencyMap()}, which inverts the map. */ public Map<ClassInfo, ClassInfoList> getClassDependencyMap() { final Map<ClassInfo, ClassInfoList> map = new HashMap<>(); for (final ClassInfo ci : getAllClasses()) { map.put(ci, ci.getClassDependencies()); } return map; }
/** * @return A mapping from a {@link ClassInfo} object for each dependency class (whitelisted or not) to a list of * the whitelisted classes that referenced that class as a dependency (i.e. returns a map from * dependencies to dependents). Note that you need to call * {@link ClassGraph#enableInterClassDependencies()} before {@link ClassGraph#scan()} for this method to * work. You should also call {@link ClassGraph#enableExternalClasses()} before * {@link ClassGraph#scan()} if you want non-whitelisted classes to appear in the result. See also * {@link #getClassDependencyMap}. */ public Map<ClassInfo, ClassInfoList> getReverseClassDependencyMap() { final Map<ClassInfo, Set<ClassInfo>> revMapSet = new HashMap<>(); for (final ClassInfo ci : getAllClasses()) { for (final ClassInfo dep : ci.getClassDependencies()) { Set<ClassInfo> set = revMapSet.get(dep); if (set == null) { revMapSet.put(dep, set = new HashSet<ClassInfo>()); } set.add(ci); } } final Map<ClassInfo, ClassInfoList> revMapList = new HashMap<>(); for (final Entry<ClassInfo, Set<ClassInfo>> ent : revMapSet.entrySet()) { revMapList.put(ent.getKey(), new ClassInfoList(ent.getValue(), /* sortByName = */ true)); } return revMapList; }
/** * Get the subclasses of this class, sorted in order of name. Call {@link ClassInfoList#directOnly()} to get * direct subclasses. * * @return the list of subclasses of this class, or the empty list if none. */ public ClassInfoList getSubclasses() { if (getName().equals("java.lang.Object")) { // Make an exception for querying all subclasses of java.lang.Object return scanResult.getAllClasses(); } else { return new ClassInfoList( this.filterClassInfo(RelType.SUBCLASSES, /* strictWhitelist = */ !isExternalClass), /* sortByName = */ true); } }
/** * Searches for the implementations/subtypes of the given class. Only the matching classes are loaded. * * @param superType The type the implementations/subtypes of which are to be searched for * @param packages The packages to limit the search to * * @return A collection of classes discovered that implementation/extend {@code superType} */ public List<Class<?>> findImplementations(Class superType, Predicate<ClassInfo> filter, String... packages) { String[] scanPackages = Utils.emptyIfNull(packages); String cacheKey = Arrays.stream(scanPackages).sorted().collect(Collectors.joining()); ScanResult scanResults = cache.computeIfAbsent(cacheKey, k -> new ClassGraph() .whitelistPackages(packages) .enableAllInfo() .initializeLoadedClasses() .scan()); try { return scanResults.getAllClasses().stream() .filter(impl -> superType.isInterface() ? impl.implementsInterface(superType.getName()) : impl.extendsSuperclass(superType.getName())) .filter(filter == null ? info -> true : filter) .flatMap(info -> loadClass(info, superType)) .collect(Collectors.toList()); } catch (Exception e) { log.error("Failed to auto discover the subtypes of " + superType.getName() + ". Error encountered while scanning the classpath/modulepath.", e); return Collections.emptyList(); } }
public ScanResult getScanResult() { if (scanResult == null) { TypeScriptGenerator.getLogger().info("Scanning classpath"); final Date scanStart = new Date(); ClassGraph classGraph = new ClassGraph().enableAllInfo(); if (classLoader != null) { classGraph = classGraph.overrideClasspath((Object[])classLoader.getURLs()); } if (verbose) { classGraph = classGraph.verbose(); } final ScanResult result = classGraph.scan(); final int count = result.getAllClasses().size(); final Date scanEnd = new Date(); final double timeInSeconds = (scanEnd.getTime() - scanStart.getTime()) / 1000.0; TypeScriptGenerator.getLogger().info(String.format("Scanning finished in %.2f seconds. Total number of classes: %d.", timeInSeconds, count)); scanResult = result; } return scanResult; }
@Override public List<String> getClassNamesForClasspath(URL[] urls) { try (ScanResult scan = new ClassGraph() .disableNestedJarScanning() .enableClassInfo() .ignoreClassVisibility() .overrideClasspath(urls) .scan()) { return scan.getAllClasses().getNames(); } }
ClassInfoList class_list = scanResult.getAllClasses();
@Override public List<String> getClassNamesForClasspath(URL[] urls) { try (ScanResult scan = new ClassGraph() .disableNestedJarScanning() .enableClassInfo() .ignoreClassVisibility() .overrideClasspath(urls) .scan()) { return scan.getAllClasses().getNames(); } }
@Override public List<String> getClassNamesForPackage(String packageName, URL url) { try (ScanResult scan = new ClassGraph() .disableNestedJarScanning() .enableClassInfo() .ignoreClassVisibility() .overrideClasspath(url) .whitelistPackagesNonRecursive(packageName) .scan()) { return scan.getAllClasses().getNames(); } } }
@Override public List<String> getClassNamesForPackage(String packageName, URL url) { try (ScanResult scan = new ClassGraph() .disableNestedJarScanning() .enableClassInfo() .ignoreClassVisibility() .overrideClasspath(url) .whitelistPackagesNonRecursive(packageName) .scan()) { return scan.getAllClasses().getNames(); } } }