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

com.datastax.util.io.ClassScanner Maven / Gradle / Ivy

package com.datastax.util.io;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ClassScanner {
    private Map> classes = new HashMap<>();
    private List classList=new ArrayList<>();

    private FilenameFilter javaClassFilter;                                    // 类文件过滤器,只扫描一级类
    private final String CLASS_FILE_SUFFIX = ".class";                       // Java字节码文件后缀
    private String packPrefix;                                         // 包路径根路劲

    public ClassScanner() {
        javaClassFilter = (dir, name) -> {
            // 排除内部内
            return !name.contains("$");
        };
    }

    /**
     * @param basePath    包所在的根路径
     * @param packagePath 目标包路径
     * @return Integer 被扫描到的类的数量
     * @throws ClassNotFoundException
     * @Title: scan
     * @Description 扫描指定包(本地)
     */
    public Integer scan(String basePath, String packagePath, boolean recursive) throws ClassNotFoundException {
        packPrefix = basePath;

        String packTmp = packagePath.replace('.', '/');
        File dir = new File(basePath, packTmp);

        // 不是文件夹
        if (dir.isDirectory()) {
            scanDir(dir,recursive);
        }

        return classList.size();
    }

    /**
     * @param packagePath 包路径
     * @param recursive   是否扫描子包
     * @return Integer 类数量
     * @Title: scan
     * @Description 扫描指定包, Jar或本地
     */
    public Integer scan(String packagePath, boolean recursive) {
        Enumeration dir;
        String filePackPath = packagePath.replace('.', '/');
        try {
            // 得到指定路径中所有的资源文件
            dir = Thread.currentThread().getContextClassLoader().getResources(filePackPath);
            packPrefix = Thread.currentThread().getContextClassLoader().getResource("").getPath();
            if (System.getProperty("file.separator").equals("\\")) {
                packPrefix = packPrefix.substring(1);
            }

            // 遍历资源文件
            while (dir.hasMoreElements()) {
                URL url = dir.nextElement();
                String protocol = url.getProtocol();

                if ("file".equals(protocol)) {
                    File file = new File(url.getPath().substring(1));
                    scanDir(file,recursive);
                } else if ("jar".equals(protocol)) {
                    scanJar(url, recursive);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return classList.size();
    }

    /**
     * @param url       jar-url路径
     * @param recursive 是否递归遍历子包
     * @throws IOException
     * @throws ClassNotFoundException
     * @Title: scanJar
     * @Description 扫描Jar包下所有class
     */
    public void scanJar(URL url, boolean recursive) throws IOException, ClassNotFoundException {
        JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
        JarFile jarFile = jarURLConnection.getJarFile();

        // 遍历Jar包
        Enumeration entries = jarFile.entries();
        while (entries.hasMoreElements()) {
            JarEntry jarEntry = (JarEntry) entries.nextElement();
            String fileName = jarEntry.getName();

            if (jarEntry.isDirectory()) {
                if (recursive) {
                }
                continue;
            }

            // .class
            if (fileName.endsWith(CLASS_FILE_SUFFIX)) {
                String className = fileName.substring(0, fileName.indexOf('.')).replace('/', '.');
                //classes.put(className, Class.forName(className));
                classList.add(className);
            }

        }
    }

    /**
     * @param dir Java包文件夹
     * @throws ClassNotFoundException
     * @Title: scanDir
     * @Description 执行扫描
     */
    private void scanDir(File dir, boolean recursive) {
        File[] fs = dir.listFiles(javaClassFilter);
        for (int i = 0; fs != null && i < fs.length; i++) {
            File f = fs[i];
            String path = f.getAbsolutePath();

            // 跳过其他文件
            if (path.endsWith(CLASS_FILE_SUFFIX)) {
                String className = getPackageByPath(f, packPrefix); // 获取包名
                //classes.put(className, Class.forName(className));
                classList.add(className);
            }

            if(recursive){
                scanDir(f,recursive);
            }
        }
    }

    /**
     * @return Map<String,Class<?>> K:类全名, V:Class字节码
     * @Title: getClasses
     * @Description 获取包中所有类
     */
    private Map> getClasses() {
        return classes;
    }

    public List getClassList(){
        return classList;
    }

    public List getClassByType(String jarFile,String type,boolean childOnly)
            throws IOException, ClassNotFoundException {
        if(jarFile.contains("file:")){
            jarFile=jarFile.replace("file:","");
        }
        jarFile = "jar:file:" + jarFile + "!/";
        scanJar(new URL(jarFile),true);
        List clzList=getClassList();
        List classList=new ArrayList<>();
        for(String clz : clzList){
            if(childOnly && clz.equals(type)){
                continue;
            }

            try {
                if(Class.forName(type).isInstance(Class.forName(clz).newInstance())){
                    classList.add(clz);
                }
            } catch (InstantiationException e) {
                //e.printStackTrace();
            } catch (IllegalAccessException e) {
                //e.printStackTrace();
            }
        }
        return classList;
    }

    /**
     * @Title: getMethodName
     * @Description: 获取对象类型属性的get方法名
     * @param propertyName
     *            属性名
     * @return String "get"开头且参数(propertyName)值首字母大写的字符串
     */
    public static String convertToReflectGetMethod(String propertyName) {
        return "get" + toFirstUpChar(propertyName);
    }

    /**
     * @Title: convertToReflectSetMethod
     * @Description: 获取对象类型属性的set方法名
     * @param propertyName
     *            属性名
     * @return String "set"开头且参数(propertyName)值首字母大写的字符串
     */
    public static String convertToReflectSetMethod(String propertyName) {
        return "set" + toFirstUpChar(propertyName);
    }

    /**
     * @Title: toFirstUpChar
     * @Description: 将字符串的首字母大写
     * @param target
     *            目标字符串
     * @return String 首字母大写的字符串
     */
    public static String toFirstUpChar(String target) {
        StringBuilder sb = new StringBuilder(target);
        sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
        return sb.toString();
    }

    /**
     * @Title: getFileSuffixName
     * @Description: 获取文件名后缀
     * @param fileName
     *            文件名
     * @return String 文件名后缀。如:jpg
     */
    public static String getFileSuffixName(String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    }

    /**
     *
     * @Title: checkStringIsNotEmpty
     * @Description:验证字符串是否不为空
     * @param stringValue
     *            传入要验证的字符串
     * @return boolean true:不为 空 或 不为null; false:值为 空 或 为null
     */
    public static boolean isNotEmpty(String stringValue) {
        if (null == stringValue || "".equals(stringValue.trim())) {
            return false;
        }
        return true;
    }

    /**
     * @Title: getPackageByPath
     * @Description 通过指定文件获取类全名
     * @param classFile 类文件
     * @return String 类全名
     */
    public static String getPackageByPath(File classFile, String exclude){
        if(classFile == null || classFile.isDirectory()){
            return null;
        }

        String path = classFile.getAbsolutePath().replace('\\', '/');

        path = path.substring(path.indexOf(exclude) + exclude.length()).replace('/', '.');
        if(path.startsWith(".")){
            path = path.substring(1);
        }
        if(path.endsWith(".")){
            path = path.substring(0, path.length() - 1);
        }

        return path.substring(0, path.lastIndexOf('.'));
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy