11package cat .michal .catbase .injector ;
22
3- import java .io .BufferedReader ;
3+ import java .io .File ;
44import java .io .IOException ;
5- import java .io .InputStream ;
6- import java .io .InputStreamReader ;
5+ import java .net .JarURLConnection ;
76import java .net .URL ;
87import java .util .ArrayList ;
98import java .util .Enumeration ;
1514
1615public class ClassFinder {
1716 private final ClassLoader classLoader ;
18-
19- ClassFinder (ClassLoader classLoader ) {
17+
18+ public ClassFinder (ClassLoader classLoader ) {
2019 this .classLoader = classLoader ;
2120 }
2221
23- ClassFinder () {
22+ public ClassFinder () {
2423 this (ClassLoader .getSystemClassLoader ());
2524 }
2625
@@ -32,57 +31,53 @@ public List<Class<?>> findAllClasses(String packageName) {
3231 }
3332
3433 public List <String > findAllClassesPaths (String packageName ) {
35- URL resource = classLoader .getResource (packageName .replace ('.' , '/' ));
36- assert resource != null ;
37- if (resource .getProtocol ().startsWith ("jar" )) {
38- return enumerateJar (packageName , resource );
39- }
40-
41- InputStream stream = classLoader
42- .getResourceAsStream (packageName .replace ('.' , '/' ));
43-
44- assert stream != null ;
45- BufferedReader reader = new BufferedReader (new InputStreamReader (stream ));
34+ String path = packageName .replace ('.' , '/' );
35+ URL resource = classLoader .getResource (path );
4636 List <String > classes = new ArrayList <>();
47- reader .lines ()
48- .forEach (line -> {
49- if (line .endsWith (".class" )) {
50- classes .add (packageName + "." + line );
51- } else {
52- classes .addAll (findAllClassesPaths (packageName + "." + line ));
53- }
54- });
5537
56- return classes ;
57- }
38+ if (resource == null ) {
39+ return classes ;
40+ }
5841
59- private List <String > enumerateJar (String packageName , URL resource ) {
6042 try {
61- String [] parts = resource .toString ().split ("!/" );
62- String jarFilePath = parts [0 ].substring ("jar:file:" .length ());
63- String packagePath = packageName .replace ('.' , '/' );
64-
65- List <String > classes = new ArrayList <>();
66-
67- try (JarFile jar = new JarFile (jarFilePath )) {
68- Enumeration <JarEntry > entries = jar .entries ();
69- while (entries .hasMoreElements ()) {
70- JarEntry entry = entries .nextElement ();
71- if (entry .getName ().startsWith (packagePath + "/" ) && entry .getName ().endsWith (".class" )) {
72- classes .add (entry .getName ().replace ('/' , '.' ));
43+ if ("jar" .equals (resource .getProtocol ())) {
44+ JarURLConnection conn = (JarURLConnection ) resource .openConnection ();
45+ try (JarFile jar = conn .getJarFile ()) {
46+ Enumeration <JarEntry > entries = jar .entries ();
47+ while (entries .hasMoreElements ()) {
48+ JarEntry entry = entries .nextElement ();
49+ if (entry .getName ().startsWith (path + "/" ) && entry .getName ().endsWith (".class" )) {
50+ String className = entry .getName ().replace ('/' , '.' ).replaceAll ("\\ .class$" , "" );
51+ classes .add (className );
52+ }
7353 }
7454 }
55+ } else if ("file" .equals (resource .getProtocol ())) {
56+ File dir = new File (resource .getFile ());
57+ scanDirectory (packageName , dir , classes );
7558 }
76-
77- return classes ;
7859 } catch (IOException e ) {
79- return List .of ();
60+ e .printStackTrace ();
61+ }
62+
63+ return classes ;
64+ }
65+
66+ private void scanDirectory (String packageName , File dir , List <String > classes ) {
67+ if (!dir .exists ()) return ;
68+ for (File file : Objects .requireNonNull (dir .listFiles ())) {
69+ if (file .isDirectory ()) {
70+ scanDirectory (packageName + (packageName .isEmpty () ? "" : "." ) + file .getName (), file , classes );
71+ } else if (file .getName ().endsWith (".class" )) {
72+ String className = packageName + (packageName .isEmpty () ? "" : "." ) + file .getName ().replaceAll ("\\ .class$" , "" );
73+ classes .add (className );
74+ }
8075 }
8176 }
8277
8378 private Class <?> getClass (String className ) {
8479 try {
85- return Class .forName (className . substring ( 0 , className . lastIndexOf ( '.' )) );
80+ return Class .forName (className );
8681 } catch (ClassNotFoundException ignored ) {
8782 }
8883 return null ;
0 commit comments