@@ -66,4 +66,173 @@ public static Class<?>[] getClasses(Map<Integer, Class<?>> primitives, Object...
6666 return parameterTypesRefined ;
6767 }
6868
69- }
69+ }package me .wavelength .betterreflection ;
70+
71+ import java .io .File ;
72+ import java .io .IOException ;
73+ import java .lang .reflect .Constructor ;
74+ import java .lang .reflect .Field ;
75+ import java .lang .reflect .Method ;
76+ import java .net .URISyntaxException ;
77+ import java .net .URL ;
78+ import java .util .ArrayList ;
79+ import java .util .Enumeration ;
80+ import java .util .List ;
81+ import java .util .Map ;
82+
83+ public class BetterReflectionUtils {
84+
85+ public static Field getField (String name , Field [] fields ) {
86+ for (Field field : fields )
87+ if (field .getName ().equals (name ))
88+ return field ;
89+
90+ return null ;
91+ }
92+
93+ public static Constructor <?> getConstructor (Class <?>[] parameterTypes , Constructor <?>[] constructors ) {
94+ for (Constructor <?> constructor : constructors ) {
95+ if (doParametersMatch (constructor .getParameterTypes (), parameterTypes ))
96+ return constructor ;
97+ }
98+
99+ return null ;
100+ }
101+
102+ public static Method getMethod (String name , Class <?>[] parameterTypes , Method [] methods ) {
103+ for (Method method : methods ) {
104+ if ((method .getName ().equals (name )) && doParametersMatch (method .getParameterTypes (), parameterTypes ))
105+ return method ;
106+
107+ }
108+
109+ return null ;
110+ }
111+
112+ public static boolean doParametersMatch (Class <?>[] parameters1 , Class <?>[] parameters2 ) {
113+ if (parameters1 .length != parameters2 .length )
114+ return false ;
115+ for (int i = 0 ; i < parameters1 .length ; i ++) {
116+ if (!(parameters1 [i ].equals (parameters2 [i ])))
117+ return false ;
118+ }
119+
120+ return true ;
121+ }
122+
123+ public static Class <?>[] getClasses (Object ... parameterTypes ) {
124+ return getClasses (null , parameterTypes );
125+ }
126+
127+ public static Class <?>[] getClasses (Map <Integer , Class <?>> primitives , Object ... parameterTypes ) {
128+ Class <?>[] parameterTypesRefined = new Class <?>[parameterTypes .length ];
129+ for (int i = 0 ; i < parameterTypes .length ; i ++) {
130+ Object parameterType = parameterTypes [i ];
131+
132+ if (parameterType instanceof ReflectionParameter )
133+ parameterType = ((ReflectionParameter ) parameterType ).getValue ();
134+
135+ if (primitives != null && primitives .containsKey (i ))
136+ parameterTypesRefined [i ] = primitives .get (i );
137+ else
138+ parameterTypesRefined [i ] = (parameterType instanceof BetterReflectionClass ? (Class <?>) ((BetterReflectionClass ) parameterType ).getClasz () : (parameterType instanceof Class <?> ? (Class <?>) parameterType : parameterType .getClass ()));
139+ }
140+
141+ return parameterTypesRefined ;
142+ }
143+
144+ /* The code below is a modified version of this answer: https://stackoverflow.com/a/520344 */
145+
146+ /**
147+ * @param packageName
148+ * @return a list of directories matching the package name.
149+ * @throws IOException
150+ * @throws URISyntaxException
151+ */
152+ public static File [] getDirectoriesFromPackageName (String packageName ) throws IOException , URISyntaxException {
153+ ClassLoader classLoader = Thread .currentThread ().getContextClassLoader ();
154+ assert classLoader != null ;
155+ String path = packageName .replace ('.' , '/' );
156+ Enumeration <URL > resources = classLoader .getResources (path );
157+ List <File > directories = new ArrayList <>();
158+ while (resources .hasMoreElements ()) {
159+ URL resource = resources .nextElement ();
160+ directories .add (new File (resource .toURI ()));
161+ }
162+
163+ return directories .toArray (new File [0 ]);
164+ }
165+
166+ /**
167+ * Scans all classes accessible from the context class loader which belong to
168+ * the given package and subpackages.
169+ *
170+ * @param packageName The base package
171+ * @return The classes
172+ * @throws ClassNotFoundException
173+ * @throws IOException
174+ * @throws URISyntaxException
175+ */
176+ public static BetterReflectionClass [] getClasses (String packageName ) throws ClassNotFoundException , IOException , URISyntaxException {
177+ File [] directories = getDirectoriesFromPackageName (packageName );
178+
179+ ArrayList <BetterReflectionClass > classes = new ArrayList <>();
180+ for (File directory : directories ) {
181+ classes .addAll (findClasses (directory , packageName ));
182+ }
183+
184+ return classes .toArray (new BetterReflectionClass [0 ]);
185+ }
186+
187+ /**
188+ * Recursive method used to find all classes in a given directory and subdirs.
189+ *
190+ * @param directory The base directory
191+ * @param packageName The package name for classes found inside the base
192+ * directory
193+ * @return The classes
194+ * @throws ClassNotFoundException
195+ */
196+ public static List <BetterReflectionClass > findClasses (File directory , String packageName ) throws ClassNotFoundException {
197+ List <BetterReflectionClass > classes = new ArrayList <>();
198+ if (!directory .exists ())
199+ return classes ;
200+
201+ File [] files = directory .listFiles ();
202+ for (File file : files ) {
203+ if (file .isDirectory ()) {
204+ assert !file .getName ().contains ("." );
205+ classes .addAll (findClasses (file , packageName + "." + file .getName ()));
206+ } else if (file .getName ().endsWith (".class" )) {
207+ classes .add (new BetterReflectionClass (Class .forName (packageName + '.' + file .getName ().substring (0 , file .getName ().length () - 6 ))));
208+ }
209+ }
210+
211+ return classes ;
212+ }
213+
214+ /**
215+ * Method to find classes which names start with a specific string
216+ *
217+ * @param directory The base directory
218+ * @param packageName The package name for classes found inside the base
219+ * directory
220+ * @return The classes
221+ * @throws ClassNotFoundException
222+ * @throws URISyntaxException
223+ * @throws IOException
224+ */
225+ public static BetterReflectionClass getClassByNameStart (String packageName , String start ) throws ClassNotFoundException , IOException , URISyntaxException {
226+ File [] directories = getDirectoriesFromPackageName (packageName );
227+
228+ for (File directory : directories ) {
229+ File [] files = directory .listFiles ();
230+ for (File file : files )
231+ if (file .getName ().startsWith (start ) && file .getName ().endsWith (".class" ))
232+ return new BetterReflectionClass (Class .forName (packageName + '.' + file .getName ().substring (0 , file .getName ().length () - 6 )));
233+ }
234+
235+ return null ;
236+ }
237+
238+ }
0 commit comments