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

com.hecloud.runtime.common.locator.ClassLocator Maven / Gradle / Ivy

package com.hecloud.runtime.common.locator;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Optional;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * Class类定位器
 *
 * @author LoveInBJ
 */
public class ClassLocator {
    private static Logger logger = LoggerFactory.getLogger(ClassLocator.class);

    /**
     * 找到指定包路径以及子路径下的所有类
     *
     * @param packageName 基础包路径
     * @param filter      路径过滤字符,目前仅支持一个
     * @return 类路径数组
     */
    public List getAllClass(String packageName, String filter) {
        List list = new ArrayList<>();
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        String path = packageName.replace(".", "/");
        try {
            Enumeration enumeration = classLoader.getResources(path);
            while (enumeration.hasMoreElements()) {
                URL url = enumeration.nextElement();
                if ("jar".equals(url.getProtocol())) {
                    String jarPath = url.getPath();
                    if (StringUtils.isNotBlank(filter) && !jarPath.contains(filter)) {
                        continue;
                    }
                    JarFile jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
                    list.addAll(findClassFromJar(jarFile, path));
                } else {
                    list.addAll(findClassFromFile(new File(url.getFile()), packageName));
                }
            }
        } catch (IOException e) {
            logger.error("get all class of package {} IOException!", packageName, e);
        }
        return list;
    }

    /**
     * 获取jar文件中指定路径的类列表
     *
     * @param jarFile jar文件
     * @param path    搜索路径
     * @return 类路径数组
     */
    public List findClassFromJar(JarFile jarFile, String path) {
        List classList = new ArrayList<>();
        String packageName = path.replace(".", "/");
        try {
            Enumeration entries = jarFile.entries();
            String entryName;
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                if (entry.isDirectory()) {
                    continue;
                }
                entryName = entry.getName();
                if (entryName.charAt(0) == '/') {
                    entryName = entryName.substring(1);
                }
                if (!entryName.startsWith(packageName) || !entryName.endsWith(".class")) {
                    continue;
                }
                String className = entryName.substring(0, entryName.length() - 6);
                Class clazz = loadClass(className.replace("/", "."));
                if (null != clazz) {
                    classList.add(clazz);
                }
            }
        } catch (Exception e) {
            logger.error("get class from jar {} error!", jarFile.getName(), e);
        } finally {
            Optional.ofNullable(jarFile).ifPresent(file -> {
                try {
                    file.close();
                } catch (IOException e) {
                    logger.error("close jar {} error!", jarFile.getName(), e);
                }
            });
        }
        return classList;
    }

    /**
     * 从指定文件下搜索类列表
     *
     * @param file        待搜索文件,可以是目录
     * @param packageName 包名称
     * @return 类路径数组
     */
    public List findClassFromFile(File file, String packageName) {
        List list = new ArrayList<>();
        if (!file.exists()) {
            return list;
        }
        File[] files = Optional.ofNullable(file.listFiles()).orElse(new File[0]);
        for (File classFile : files) {
            if (classFile.isDirectory()) {
                if (!classFile.getName().contains(".")) {
                    List arrayList = findClassFromFile(classFile, packageName + "." + classFile.getName());
                    list.addAll(arrayList);
                }
            } else if (classFile.getName().endsWith(".class")) {
                try {
                    // 保存的类文件不需要后缀.class
                    list.add(Class.forName(
                            packageName + '.' + classFile.getName().substring(0, classFile.getName().length() - 6)));
                } catch (ClassNotFoundException e) {
                    logger.error("get class of {} occur ClassNotFoundException!", file, e);
                }
            }
        }
        return list;
    }

    private Class loadClass(String fullClassName) {
        try {
            return Thread.currentThread().getContextClassLoader().loadClass(fullClassName);
        } catch (ClassNotFoundException e) {
            logger.error("load class of {} occur ClassNotFoundException!", e);
        }
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy