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

io.github.wycst.wast.common.utils.ClassUtils Maven / Gradle / Ivy

package io.github.wycst.wast.common.utils;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

@SuppressWarnings({"unchecked", "rawtypes"})
public final class ClassUtils {

    public static void loadJars(String lib) {
        File jarLib = new File(lib);
        if (jarLib.exists() && jarLib.isDirectory()) {
            for (File file : jarLib.listFiles()) {
                if (!file.isDirectory() && file.getName().toLowerCase().endsWith(".jar")) {
                    try {
                        loadJar(file);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void loadJar(File jarFile) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, MalformedURLException {
        if (!jarFile.exists()) {
            System.out.println(jarFile.getAbsolutePath() + " is not exist ");
            return;
        }
        URLClassLoader loader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        Method _addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
        _addURL.setAccessible(true);
        _addURL.invoke(loader, jarFile.toURI().toURL());
    }

    public static void loadJar(String jarFileName) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, MalformedURLException {
        loadJar(new File(jarFileName));
    }

    public static Set> getClassesFromJar(File jarFile) {
        return getClassesFromJar(jarFile, Object.class);
    }

    public static Set> getClassesFromJar(File jarFile, Class parentClass) {
        Set> classes = new LinkedHashSet>();
        JarFile jar = null;
        try {
            loadJar(jarFile);
            jar = new JarFile(jarFile);
            Enumeration entry = jar.entries();

            JarEntry jarEntry;
            String jarEntryName, className;
            Class clazz;
            while (entry.hasMoreElements()) {
                jarEntry = entry.nextElement();
                jarEntryName = jarEntry.getName();
                if (jarEntryName.charAt(0) == '/') {
                    jarEntryName = jarEntryName.substring(1);
                }
                if (jarEntry.isDirectory() || !jarEntryName.endsWith(".class")) {
                    continue;
                }
                className = jarEntryName.substring(0, jarEntryName.length() - 6);
                clazz = loadClass(className.replace("/", "."));
                if (clazz != null && parentClass != clazz && parentClass.isAssignableFrom(clazz)) {
                    classes.add(clazz);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jar != null) {
                try {
                    jar.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return classes;
    }

    public static Set> getClassesFromJar(String jarFile) {
        return getClassesFromJar(new File(jarFile));
    }

    public static Set> getClasses(String packageName, Class parentClass) {
        return getClasses(packageName, parentClass, true);
    }

    /**
     * 获取packageName下面所有的Class
     *
     * @param packageName
     * @param parentClass
     * @param scanJar     是否扫描jar
     * @return
     */
    public static Set> getClasses(String packageName, Class parentClass, boolean scanJar) {
        Set> classes = new LinkedHashSet>();
        String pkgDirName = packageName.replace('.', '/');
        try {
            Enumeration urls = ClassUtils.class.getClassLoader().getResources(pkgDirName);
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                String protocol = url.getProtocol();
                if ("file".equals(protocol)) {
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    findClasses(packageName, filePath, classes, parentClass);
                } else if (scanJar && "jar".equals(protocol)) {
                    JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
                    findClasses(packageName, jar, classes, parentClass);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return classes;
    }

    /**
     * 获取packageName下面所有的Class
     *
     * @param packageName
     * @param parentClass
     * @param annotationType
     * @param isFilterInterface 是否接口
     * @param scanJar           是否扫描jar包
     * @return
     */
    public static Set> getClassesOfAnnotationType(String packageName, Class parentClass, Class annotationType, boolean isFilterInterface, boolean scanJar) {
        Set> classes = new LinkedHashSet>();
        String pkgDirName = packageName.replace('.', '/');
        try {
            Enumeration urls = ClassUtils.class.getClassLoader().getResources(pkgDirName);
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                String protocol = url.getProtocol();
                if ("file".equals(protocol)) {
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    findClasses(packageName, filePath, classes, parentClass, annotationType, isFilterInterface);
                } else if (scanJar && "jar".equals(protocol)) {
                    JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
                    findClasses(packageName, jar, classes, parentClass, annotationType, isFilterInterface);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return classes;
    }

    /**
     * 获取packageName下面所有的Class
     *
     * @param packageName
     * @return
     */
    public static Set> getClasses(String packageName) {
        return getClasses(packageName, Object.class);
    }

    /**
     * 获取packageName下面所有的Class
     *
     * @param packageName
     * @param scanJar
     * @return
     */
    public static Set> getClasses(String packageName, boolean scanJar) {
        return getClasses(packageName, Object.class, scanJar);
    }

    /**
     * 获取classes资源目录下面的类
     *
     * @param parentCls
     * @return
     */
    public static Set> getClassesOfClassPath(Class parentCls) {
        return getClasses("", parentCls, false);
    }

    /**
     * 获取资源路径下面的类
     *
     * @param parentCls         父类
     * @param annotationType    注解类
     * @param isFilterInterface 是否为接口
     * @param scanJar           是否扫描jar
     * @return
     */
    public static Set> getClassesOfClassPath(Class parentCls, Class annotationType, boolean isFilterInterface, boolean scanJar) {
        return getClassesOfAnnotationType("", parentCls, annotationType, isFilterInterface, scanJar);
    }

    /**
     * 扫描指定packages下面满足条件的类集合
     *
     * @param packages
     * @param annotationType
     * @param isFilterInterface
     * @return
     */
    public static Set> findClasses(String[] packages, Class parentCls, Class annotationType, boolean isFilterInterface) {
        Set> clsSet = new LinkedHashSet>();
        if (CollectionUtils.isEmpty(packages)) {
            clsSet.addAll(ClassUtils.getClassesOfClassPath(parentCls, annotationType, isFilterInterface, false));
        } else {
            for (String scanPckage : packages) {
                clsSet.addAll(ClassUtils.getClassesOfAnnotationType(scanPckage, parentCls, annotationType, isFilterInterface, true)
                );
            }
        }
        return clsSet;
    }

    private static void findClasses(String packageName, String packagePath, Set> classes, Class parentClass,
                                    Class annotationType, boolean isFilterInterface) {
        File packageDir = new File(packagePath);
        if (!packageDir.exists() || !packageDir.isDirectory()) {
            return;
        }
        final String classSuf = ".class";
        File[] files = packageDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isDirectory() || pathname.getName().endsWith(classSuf);
            }
        });

        if (files == null || files.length == 0) {
            return;
        }
        String className;
        for (File file : files) {
            if (file.isDirectory()) {
                String pckName = null;
                if (packageName.equals("")) {
                    pckName = file.getName();
                } else {
                    pckName = packageName + "." + file.getName();
                }
                findClasses(pckName, packagePath.endsWith("/") ? packagePath + file.getName() : packagePath + "/" + file.getName(), classes, parentClass, annotationType, isFilterInterface);
                continue;
            }
            className = file.getName();
            className = className.substring(0, className.length() - classSuf.length());
            Class clazz = loadClass(packageName + "." + className);
            if (clazz != null && parentClass != clazz && parentClass.isAssignableFrom(clazz)) {
//                // 是否有注解
//                if (annotationType != null && clazz.getAnnotation(annotationType) == null) {
//                    continue;
//                }
//                // 是否接口
//                if (isFilterInterface && !clazz.isFilterInterface()) {
//                    continue;
//                }
                boolean validated = validate(clazz, annotationType, isFilterInterface);
                if (validated) {
                    classes.add(clazz);
                }
            }
        }
    }

    private static void findClasses(String packageName, String packagePath, Set> classes, Class parentClass) {
        findClasses(packageName, packagePath, classes, parentClass, null, false);
    }

    private static void findClasses(String packageName, JarFile jar, Set> classes, Class parentClass,
                                    Class annotationType, boolean isFilterInterface) {
        String packageDir = packageName.replace(".", "/");
        Enumeration entries = jar.entries();
        JarEntry jarEntry;
        String jarEntryName, className;
        Class clazz;
        while (entries.hasMoreElements()) {
            jarEntry = entries.nextElement();
            jarEntryName = jarEntry.getName();
            if (jarEntryName.charAt(0) == '/') {
                jarEntryName = jarEntryName.substring(1);
            }
            String classSuf = ".class";
            if (jarEntry.isDirectory() || !jarEntryName.startsWith(packageDir) || !jarEntryName.endsWith(classSuf)) {
                continue;
            }
            className = jarEntryName.substring(0, jarEntryName.length() - classSuf.length());
            clazz = loadClass(className.replace("/", "."));
            if (clazz != null && parentClass != clazz && parentClass.isAssignableFrom(clazz)) {
//                // 是否有注解
//                if (annotationType != null && clazz.getAnnotation(annotationType) == null) {
//                    continue;
//                }
//                // 是否接口
//                if (isFilterInterface && !clazz.isFilterInterface()) {
//                    continue;
//                }
                boolean validated = validate(clazz, annotationType, isFilterInterface);
                if (validated) {
                    classes.add(clazz);
                }
            }
        }
    }

    private static boolean validate(Class clazz, Class annotationType, boolean isFilterInterface) {

        try {
            // 是否接口
            if (isFilterInterface && !clazz.isInterface()) {
                return false;
            }
            // 是否有注解
            if (annotationType != null) {
                Annotation annotation = clazz.getAnnotation(annotationType);
                if (annotation != null) {
                    return true;
                }
                Annotation[] annotations = clazz.getDeclaredAnnotations();
                if (annotations != null) {
                    for (Annotation anno : annotations) {
                        if (anno.annotationType().getAnnotation(annotationType) != null)
                            return true;
                    }
                }
                return false;
            }
            return true;
        } catch (Throwable throwable) {
        }
        return false;
    }

    private static void findClasses(String packageName, JarFile jar, Set> classes, Class parentClass) {
        findClasses(packageName, jar, classes, parentClass, null, false);
    }

    private static Class loadClass(String className) {
        try {
            return Thread.currentThread().getContextClassLoader().loadClass(className);
        } catch (Throwable e) {
//            System.err.println(e.getMessage());
        }
        return null;
    }

}
 




© 2015 - 2025 Weber Informatics LLC | Privacy Policy