public Set<Class<?>> scanClasspathForAnnotation(Class<?> annotation, String... onlyFromPackages) { ClassInfoList classInfoList = scanResult.getClassesWithAnnotation(annotation.getName()); classInfoList = classInfoList .filter(ci -> Arrays.stream(onlyFromPackages) .anyMatch(p -> classMatchesPackage(ci.getName(), p))); return classInfoList.loadClasses().stream().collect(toSet()); }
public Collection<String> findFunctionsInJar(File jarFile) throws IOException { ClassGraph fastClasspathScanner = new ClassGraph().disableDirScanning() .removeTemporaryFilesAfterScan().overrideClasspath(jarFile.getAbsolutePath()); ScanResult scanResult = fastClasspathScanner.enableClassInfo().scan(); Set<String> functionClasses = new HashSet<>(); functionClasses.addAll(scanResult.getClassesImplementing(Function.class.getName()).getNames()); functionClasses.addAll(scanResult.getSubclasses(FunctionAdapter.class.getName()).getNames()); return functionClasses; } }
public ClasspathScanningPrimitiveTypeRegistry(ClassLoader classLoader) { Map<String, PrimitiveType> types = CACHE.computeIfAbsent(classLoader, cl -> { final Map<String, PrimitiveType> result = new ConcurrentHashMap<>(); final String[] whitelistPackages = StringUtils.split(System.getProperty("io.atomix.whitelistPackages"), ","); final ClassGraph classGraph = whitelistPackages != null ? new ClassGraph().enableClassInfo().whitelistPackages(whitelistPackages).addClassLoader(classLoader) : new ClassGraph().enableClassInfo().addClassLoader(classLoader); try (final ScanResult scanResult = classGraph.scan()) { scanResult.getClassesImplementing(PrimitiveType.class.getName()).forEach(classInfo -> { if (classInfo.isInterface() || classInfo.isAbstract() || Modifier.isPrivate(classInfo.getModifiers())) { return; } final PrimitiveType primitiveType = newInstance(classInfo.loadClass()); final PrimitiveType oldPrimitiveType = result.put(primitiveType.name(), primitiveType); if (oldPrimitiveType != null) { LOGGER.warn("Found multiple primitives types name={}, classes=[{}, {}]", primitiveType.name(), oldPrimitiveType.getClass().getName(), primitiveType.getClass().getName()); } }); } return Collections.unmodifiableMap(result); }); primitiveTypes.putAll(types); }
/** * Convert this list of {@link ClassInfo} objects to a list of {@code Class<?>} objects. Causes the classloader * to load the class named by each {@link ClassInfo} object, if it is not already loaded. * * @throws IllegalArgumentException * if an exception or error was thrown while trying to load any of the classes. * @return The loaded {@code Class<?>} objects corresponding to each {@link ClassInfo} object in this list. */ public List<Class<?>> loadClasses() { return loadClasses(/* ignoreExceptions = */ false); }
ClassInfoList annotationHandlers = scanResult.getClassesImplementing(REWRITE_ANNOTATION_HANDLER); if (annotationHandlers.isEmpty()) { return; List<String> annotationClassNames = annotationHandlers.stream() .map(classInfo -> classInfo.getDeclaredMethodInfo("handles")) .flatMap(Collection::stream) result.addAll(scanResult.getClassesWithAnnotation(annotationClassName).getNames()); result.addAll(scanResult.getClassesWithFieldAnnotation(annotationClassName).getNames()); result.addAll(scanResult.getClassesWithMethodAnnotation(annotationClassName).getNames());
buf.append("edge [fontname = \"Courier, Regular\"]\n"); final ClassInfoList standardClassNodes = classInfoList.getStandardClasses(); final ClassInfoList interfaceNodes = classInfoList.getInterfaces(); final ClassInfoList annotationNodes = classInfoList.getAnnotations(); allVisibleNodes.addAll(standardClassNodes.getNames()); allVisibleNodes.addAll(interfaceNodes.getNames()); allVisibleNodes.addAll(annotationNodes.getNames()); for (final ClassInfo directSuperclassNode : classNode.getSuperclasses().directOnly()) { if (directSuperclassNode != null && allVisibleNodes.contains(directSuperclassNode.getName()) && !directSuperclassNode.getName().equals("java.lang.Object")) { for (final ClassInfo implementedInterfaceNode : classNode.getInterfaces().directOnly()) { if (allVisibleNodes.contains(implementedInterfaceNode.getName())) { for (final ClassInfo superinterfaceNode : interfaceNode.getInterfaces().directOnly()) { if (allVisibleNodes.contains(superinterfaceNode.getName())) {
ClassInfoList entities = scanResult.getClassesWithAnnotation(Entity.class.getName()); entities.addAll(scanResult.getClassesWithAnnotation(Embedded.class.getName())); logger.info("Found " + entities.size() + " entities in classpath"); for (String cn : entities.getNames()) { ClassInfo ci = scanResult.getClassInfo(cn); AnnotationInfoList an = ci.getAnnotationInfo();
/** * Filter this {@link ClassInfoList} to include only annotations. * * @return The filtered list, containing only annotations. */ public ClassInfoList getAnnotations() { final Set<ClassInfo> reachableClassesFiltered = new LinkedHashSet<>(size()); final Set<ClassInfo> directlyRelatedClassesFiltered = new LinkedHashSet<>(directlyRelatedClasses.size()); for (final ClassInfo ci : this) { if (ci.isAnnotation()) { reachableClassesFiltered.add(ci); if (directlyRelatedClasses.contains(ci)) { directlyRelatedClassesFiltered.add(ci); } } } return new ClassInfoList(reachableClassesFiltered, directlyRelatedClassesFiltered, sortByName); }
.stream() .filter(once) .map(ClassInfo::getName) .stream() .filter(once) .map(ClassInfo::getName) .filter(A) .forEach(a -> result.getClassesWithAnnotation(a.getName()) .stream() .filter(once) .map(ClassInfo::getName) .filter(type -> type != Jooby.Module.class && type != Module.class && type != Service.class) .forEach(i -> result.getClassesImplementing(i.getName()) .stream() .filter(inPackage) .filter(once) .filter(S) .forEach(k -> result.getSubclasses(k.getName()) .stream() .filter(inPackage) .filter(once) .stream() .filter(inPackage) .filter(once)
@Override public void handle(ScanResult scanResult, File joinfacesBaseDir) throws IOException { ClassInfoList scis = scanResult.getClassesImplementing(SERVLET_CONTAINER_INITIALIZER) .filter(classInfo -> classInfo.hasAnnotation(HANDLES_TYPES)); for (ClassInfo sciClassInfo : scis) { List<ClassInfo> handledTypes = resolveHandledTypes(sciClassInfo); SortedSet<String> classes = findHandledClasses(scanResult, handledTypes); File resultFile = new File(joinfacesBaseDir, sciClassInfo.getName() + ".classes"); writeClassList(resultFile, classes); } }
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; }
/** * Convert this list of {@link ClassInfo} objects to a list of {@code Class<?>} objects, casting each item in * the list to the requested superclass or interface type. Causes the classloader to load the class named by * each {@link ClassInfo} object, if it is not already loaded. * * <p> * <b>Important note:</b> since {@code superclassOrInterfaceType} is a class reference for an already-loaded * class, it is critical that {@code superclassOrInterfaceType} is loaded by the same classloader as the class * referred to by this {@code ClassInfo} object, otherwise the class cast will fail. * * @param <T> * The superclass or interface. * @param superclassOrInterfaceType * The superclass or interface class reference to cast each loaded class to. * @throws IllegalArgumentException * if an exception or error was thrown while trying to load or cast any of the classes. * @return The loaded {@code Class<?>} objects corresponding to each {@link ClassInfo} object in this list. */ public <T> List<Class<T>> loadClasses(final Class<T> superclassOrInterfaceType) { return loadClasses(superclassOrInterfaceType, /* ignoreExceptions = */ false); }
/** * Filter this {@link ClassInfoList} to include only standard classes (classes that are not interfaces or * annotations). * * @return The filtered list, containing only standard classes. */ public ClassInfoList getStandardClasses() { final Set<ClassInfo> reachableClassesFiltered = new LinkedHashSet<>(size()); final Set<ClassInfo> directlyRelatedClassesFiltered = new LinkedHashSet<>(directlyRelatedClasses.size()); for (final ClassInfo ci : this) { if (ci.isStandardClass()) { reachableClassesFiltered.add(ci); if (directlyRelatedClasses.contains(ci)) { directlyRelatedClassesFiltered.add(ci); } } } return new ClassInfoList(reachableClassesFiltered, directlyRelatedClassesFiltered, sortByName); }
/** * 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(); } }
@Override protected void handleScanResult(ScanResult scanResult) { super.handleScanResult(scanResult); Map<Class<? extends Annotation>, Set<Class<?>>> annotatedClasses = new HashMap<>(); Arrays.asList( ManagedBean.class, FacesComponent.class, FacesBehavior.class, FacesConverter.class, NamedEvent.class, FacesRenderer.class, FacesBehaviorRenderer.class, FacesValidator.class ).forEach(annotationClass -> { List<Class<?>> classes = scanResult.getClassesWithAnnotation(annotationClass.getName()).loadClasses(); annotatedClasses.put(annotationClass, new HashSet<>(classes)); }); JoinFacesAnnotationProvider.setAnnotatedClasses(annotatedClasses); } }
public Set<Class<?>> scanPackagesForClassesImplementing(Class<?> implementedInterface, String... onlyFromPackages) { ClassInfoList classInfoList = scanResult.getClassesImplementing(implementedInterface.getName()) .filter(ci -> !ci.isAbstract() && !ci.isInterface() && ci.isPublic()); classInfoList = classInfoList .filter(ci -> Arrays.stream(onlyFromPackages) .anyMatch(p -> classMatchesPackage(ci.getName(), p))); return classInfoList.loadClasses().stream().collect(toSet()); }
private static List<SourceType<Type>> fromClassNamePatterns(ScanResult scanResult, List<String> classNamePatterns) { final List<String> allClassNames = new ArrayList<>(); allClassNames.addAll(scanResult.getAllStandardClasses().getNames()); allClassNames.addAll(scanResult.getAllInterfaces().getNames()); Collections.sort(allClassNames); final List<String> classNames = filterClassNames(allClassNames, classNamePatterns); TypeScriptGenerator.getLogger().info(String.format("Found %d classes matching pattern.", classNames.size())); return fromClassNames(classNames); }
/** * Filter this {@link ClassInfoList} to include only {@link Enum} classes. * * @return The filtered list, containing only enums. */ public ClassInfoList getEnums() { final Set<ClassInfo> reachableClassesFiltered = new LinkedHashSet<>(size()); final Set<ClassInfo> directlyRelatedClassesFiltered = new LinkedHashSet<>(directlyRelatedClasses.size()); for (final ClassInfo ci : this) { if (ci.isEnum()) { reachableClassesFiltered.add(ci); if (directlyRelatedClasses.contains(ci)) { directlyRelatedClassesFiltered.add(ci); } } } return new ClassInfoList(reachableClassesFiltered, directlyRelatedClassesFiltered, sortByName); }
@SuppressWarnings("unchecked") private ClasspathScanningRegistry(ClassLoader classLoader, Set<String> whitelistPackages) { final Map<Class<? extends NamedType>, Map<String, NamedType>> registrations = CACHE.computeIfAbsent(classLoader, cl -> { final ClassGraph classGraph = !whitelistPackages.isEmpty() ? new ClassGraph().enableClassInfo().whitelistPackages(whitelistPackages.toArray(new String[0])).addClassLoader(classLoader) : new ClassGraph().enableClassInfo().addClassLoader(classLoader); try (final ScanResult scanResult = classGraph.scan()) { final Map<Class<? extends NamedType>, Map<String, NamedType>> result = new ConcurrentHashMap<>(); scanResult.getClassesImplementing(NamedType.class.getName()).forEach(classInfo -> { if (classInfo.isInterface() || classInfo.isAbstract() || Modifier.isPrivate(classInfo.getModifiers())) { return; } final Class<?> type = classInfo.loadClass(); final Class<? extends NamedType> classType = getClassType(type); final NamedType instance = newInstance(type); final NamedType oldInstance = result.computeIfAbsent(classType, t -> new HashMap<>()).put(instance.name(), instance); if (oldInstance != null) { LOGGER.warn("Found multiple types with name={}, classes=[{}, {}]", instance.name(), oldInstance.getClass().getName(), instance.getClass().getName()); } }); return result; } }); this.registrations.putAll(registrations); }