All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.junit.gen5.commons.util.ClasspathScanner Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015-2016 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.junit.gen5.commons.util;

import static org.junit.gen5.commons.meta.API.Usage.Internal;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;

import org.junit.gen5.commons.meta.API;

/**
 * 

DISCLAIMER

* *

These utilities are intended solely for usage within the JUnit framework * itself. Any usage by external parties is not supported. * Use at your own risk! * * @since 5.0 */ @API(Internal) class ClasspathScanner { private static final String CLASS_FILE_SUFFIX = ".class"; private final Supplier classLoaderSupplier; private final BiFunction>> loadClass; ClasspathScanner(Supplier classLoaderSupplier, BiFunction>> loadClass) { this.classLoaderSupplier = classLoaderSupplier; this.loadClass = loadClass; } boolean isPackage(String packageName) { String path = packagePath(packageName); try { Enumeration resource = classLoaderSupplier.get().getResources(path); return resource.hasMoreElements(); } catch (IOException e) { return false; } } List> scanForClassesInPackage(String basePackageName, Predicate> classFilter) { Preconditions.notBlank(basePackageName, "basePackageName must not be blank"); List dirs = allSourceDirsForPackage(basePackageName); return allClassesInSourceDirs(dirs, basePackageName, classFilter); } private List> allClassesInSourceDirs(List sourceDirs, String basePackageName, Predicate> classFilter) { List> classes = new ArrayList<>(); for (File aSourceDir : sourceDirs) { classes.addAll(findClassesInSourceDirRecursively(aSourceDir, basePackageName, classFilter)); } return classes; } List> scanForClassesInClasspathRoot(File root, Predicate> classFilter) { Preconditions.notNull(root, () -> "root must not be null"); Preconditions.condition(root.exists(), () -> "root must exist, but could not be found: " + root.getAbsolutePath()); Preconditions.condition(root.isDirectory(), "root must be a directory, but is not: " + root.getAbsolutePath()); return findClassesInSourceDirRecursively(root, "", classFilter); } private List allSourceDirsForPackage(String basePackageName) { try { ClassLoader classLoader = classLoaderSupplier.get(); String path = packagePath(basePackageName); Enumeration resources = classLoader.getResources(path); List dirs = new ArrayList<>(); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); dirs.add(new File(resource.getFile())); } return dirs; } catch (IOException e) { return Collections.emptyList(); } } private String packagePath(String basePackageName) { return basePackageName.replace('.', '/'); } private List> findClassesInSourceDirRecursively(File sourceDir, String packageName, Predicate> classFilter) { List> classesCollector = new ArrayList<>(); collectClassesRecursively(sourceDir, packageName, classesCollector, classFilter); return classesCollector; } private void collectClassesRecursively(File sourceDir, String packageName, List> classesCollector, Predicate> classFilter) { File[] files = sourceDir.listFiles(); if (files == null) { return; } for (File file : files) { if (isClassFile(file)) { Optional> classForClassFile = loadClassForClassFile(file, packageName); classForClassFile.filter(classFilter).ifPresent(clazz -> classesCollector.add(clazz)); } else if (file.isDirectory()) { collectClassesRecursively(file, appendPackageName(packageName, file.getName()), classesCollector, classFilter); } } } private String appendPackageName(String packageName, String subpackageName) { if (packageName.isEmpty()) return subpackageName; else return packageName + "." + subpackageName; } private Optional> loadClassForClassFile(File file, String packageName) { String className = packageName + '.' + file.getName().substring(0, file.getName().length() - CLASS_FILE_SUFFIX.length()); return loadClass.apply(className, classLoaderSupplier.get()); } private static boolean isClassFile(File file) { return file.isFile() && file.getName().endsWith(CLASS_FILE_SUFFIX); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy