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

com.gitee.starblues.utils.ScanUtils Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
package com.gitee.starblues.utils;


import org.pf4j.PluginWrapper;
import org.springframework.util.ClassUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 扫描工具类
 *
 * @author starBlues
 * @version 2.2.2
 */
public class ScanUtils {

    /**
     * 扫描指定包中的类。包括子包中的类
     *
     * @param basePackage 包名
     * @param baseClass  当前操作的基础类
     * @return 类全路径(形如:xx.bb.cc)
     * @throws IOException 扫描异常
     */
    public static Set scanClassPackageName(String basePackage, Class baseClass) throws IOException {
        String osName = System.getProperty("os.name");
        if (osName.startsWith("Windows")) {
            // windows
            return scanClassPackageNameOfWindows(basePackage, baseClass);
        } else {
            // unix or linux
            return scanClassPackageNameOfOther(basePackage, baseClass);
        }
    }

    /**
     * 扫描windows环境下的类。包括子包中的类
     * @param basePackage 包名
     * @param baseClass 当前操作的基础类
     * @return 类全路径(形如:xx.bb.cc)
     * @throws IOException 扫描异常
     */
    private static Set scanClassPackageNameOfWindows(String basePackage, Class baseClass) throws IOException {
        String classpathRootPath = baseClass.getResource("/").getPath();
        final String classpath = classpathRootPath
                .replace("/","\\")
                .replaceFirst("\\\\","");
        // 把包名 packageName 转换为路径名
        basePackage = basePackage.replace(".", File.separator);
        // class 文件全路径
        String fullPath = classpath + basePackage;

        return filterPath(fullPath).map(path -> {
                    String pathString = path.toString();
                    return pathString
                            .replace(classpath, "")
                            .replace("\\",".")
                            .replace(".class","");
                }).collect(Collectors.toSet());
    }


    /**
     * 扫描linux/unix/mac环境下的类。包括子包中的类
     * @param basePackage 包名
     * @param baseClass 当前操作的基础类
     * @return 类全路径(形如:xx.bb.cc)
     * @throws IOException 扫描异常
     */
    private static Set scanClassPackageNameOfOther(String basePackage, Class baseClass) throws IOException {
        final String classpath = baseClass.getResource("/").getPath();
        // class 文件全路径
        String fullPath = classpath + ClassUtils.classPackageAsResourcePath(baseClass);

        return filterPath(fullPath).map(path -> {
                    String pathString = path.toString();
                    // 去头去尾
                    pathString = pathString
                            .replace(classpath, "")
                            .replace(".class", "");
                    // 转换为 aa.bb.cc
                    return ClassUtils.convertResourcePathToClassName(pathString);
                }).collect(Collectors.toSet());
    }

    /**
     * 过滤类
     * @param fullPath 类的全路径
     * @return Stream
     * @throws IOException IOException
     */
    private static Stream filterPath(String fullPath) throws IOException {
        return Files.walk(Paths.get(fullPath))
                .filter(Objects::nonNull)
                .filter(Files::isRegularFile)
                .filter(path -> {
                    String fileName = path.getFileName().toString();
                    if(fileName == null){
                        return false;
                    }
                    return fileName.endsWith(".class");
                });
    }


    /**
     * 扫描jar包中的类。
     *
     * @param basePackage 包名
     * @param pluginWrapper jar的PluginWrapper
     * @return 类全路径
     * @throws IOException 扫描异常
     */
    public static Set scanClassPackageName(String basePackage, PluginWrapper pluginWrapper) throws IOException {
        String pluginPath = pluginWrapper.getPluginPath().toString();
        Set classPackageNames = new HashSet<>();
        try (JarFile jarFile = new JarFile(pluginPath)) {
            Enumeration jarEntries = jarFile.entries();
            while (jarEntries.hasMoreElements()) {
                JarEntry entry = jarEntries.nextElement();
                String jarEntryName = entry.getName();
                if (jarEntryName.contains(".class") && jarEntryName.replaceAll("/", ".").startsWith(basePackage)) {
                    String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replace("/", ".");
                    classPackageNames.add(className);
                }
            }
        }
        return classPackageNames;
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy