liurunyu
2023-11-20 5078baaa0a532eadf9487e8852451265c2f65d34
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.dy.common.util;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Logger;
 
@SuppressWarnings("unused")
public class ClassScan {
 
    private static final Logger logger = Logger.getLogger(ClassScan.class.getName());
 
    
    /**
     * 在指定的URL路径中搜索Class
     *
     * @param uris 要搜索的java文件URI,不能用URL类型,因为URL路径中有中文将失败
     * @param rootPackage 要搜索的java文件的包路径
     */
    public List<String> searchClassFromUrl(URI[] uris, String rootPackage){
        List<String> classNames = new ArrayList<>() ;
        for (URI uri : uris) {
            try {
                File file = new File(uri.getPath());
                if (!file.exists()){
                    throw new FileNotFoundException();
                }
                this.doSearchClass(file, rootPackage ,classNames);
            } catch (Exception ex) {
                logger.throwing(ClassScan.class.getName(), "searchClassFromUrl", ex);
            }
        }
        return classNames ;
    }
    
    /**
     * 在指定的jar文件中搜索Class
     * @param file 要搜索的jar文件
     */
    public List<String> searchClassFromArchive(JarFile file) {
        List<String> classNames = new ArrayList<>() ;
        for (Enumeration<JarEntry> enumeration = file.entries(); enumeration.hasMoreElements();) {
            JarEntry entry = enumeration.nextElement();
            if (entry.getName().endsWith(".class")) {
                classNames.add(file.getName()) ;
            }
        }
        return classNames ;
    }
 
    /**
     * 搜索指定文件夹下层级里的class
     * @param dir 文件夹
     * @param rootPackage 根包
     * @param classNames 类名称集合
     */
    private void doSearchClass(File dir, String rootPackage, List<String> classNames) {
        String path ;
        if (dir.isDirectory()) {
            File[] fs = dir.listFiles() ;
            if(fs != null && fs.length > 0){
                for (File f : fs){
                    //只搜当前文件夹中文件
                    this.doSearchClass(f, rootPackage, classNames);
                }
            }
            return;
        }
        if (dir.getName().endsWith(".class")) {
            path = dir.getAbsolutePath() ;
            path = path.replace('/', '.') ;
            path = path.replace('\\', '.') ;
            path = path.substring(path.indexOf(rootPackage)) ;
            classNames.add(path) ;
        } else if (dir.getName().endsWith(".zip") || dir.getName().endsWith(".jar")) {
            try {
                this.searchClassFromArchive(new JarFile(dir));
            } catch (IOException ex) {
                logger.throwing(ClassScan.class.getName(), "doSearchClass", ex);
            }
        }
    }
 
}