1 package org.djutils.reflection;
2
3 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4 import static org.junit.jupiter.api.Assertions.assertEquals;
5 import static org.junit.jupiter.api.Assertions.assertFalse;
6 import static org.junit.jupiter.api.Assertions.assertNotEquals;
7 import static org.junit.jupiter.api.Assertions.assertNotNull;
8 import static org.junit.jupiter.api.Assertions.assertNull;
9 import static org.junit.jupiter.api.Assertions.assertTrue;
10 import static org.junit.jupiter.api.Assertions.fail;
11
12 import java.lang.annotation.Annotation;
13 import java.lang.annotation.ElementType;
14 import java.lang.annotation.Retention;
15 import java.lang.annotation.RetentionPolicy;
16 import java.lang.annotation.Target;
17 import java.lang.reflect.Constructor;
18 import java.lang.reflect.Field;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Modifier;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Set;
26
27 import org.djutils.reflection.TestClass.InnerPublic;
28 import org.djutils.test.UnitTest;
29 import org.junit.jupiter.api.Test;
30
31
32
33
34
35
36
37
38
39
40
41
42 public class ClassUtilTest
43 {
44
45 @Test
46 public void testClassUtilClass()
47 {
48 assertEquals(0, ClassUtil.getClass(null).length);
49 assertEquals(String.class, ClassUtil.getClass(new Object[] {"Peter"})[0]);
50
51 assertArrayEquals(new Class<?>[] {String.class, Double.class, Integer.class, Integer.class},
52 ClassUtil.getClass(new Object[] {"X", 1.0d, 5, Integer.valueOf(5)}));
53 assertArrayEquals(new Class<?>[] {String.class, Double.class, null, Integer.class},
54 ClassUtil.getClass(new Object[] {"X", 1.0d, null, 5}));
55 }
56
57
58
59
60 @Test
61 public void testToDescriptor()
62 {
63 assertEquals("I", FieldSignature.toDescriptor(int.class));
64 assertEquals("D", FieldSignature.toDescriptor(double.class));
65 assertEquals("Z", FieldSignature.toDescriptor(boolean.class));
66 assertEquals("C", FieldSignature.toDescriptor(char.class));
67 assertEquals("B", FieldSignature.toDescriptor(byte.class));
68 assertEquals("F", FieldSignature.toDescriptor(float.class));
69 assertEquals("J", FieldSignature.toDescriptor(long.class));
70 assertEquals("S", FieldSignature.toDescriptor(short.class));
71 assertEquals("[I", FieldSignature.toDescriptor(int[].class));
72
73 assertEquals("Ljava/lang/Integer;", FieldSignature.toDescriptor(Integer.class));
74 }
75
76
77
78
79
80 @Test
81 public void testToClass() throws ClassNotFoundException
82 {
83 assertEquals(int.class, FieldSignature.toClass("int"));
84 assertEquals(int.class, FieldSignature.toClass("I"));
85 assertEquals(double.class, FieldSignature.toClass("double"));
86 assertEquals(double.class, FieldSignature.toClass("D"));
87 assertEquals(boolean.class, FieldSignature.toClass("boolean"));
88 assertEquals(boolean.class, FieldSignature.toClass("Z"));
89 assertEquals(char.class, FieldSignature.toClass("C"));
90 assertEquals(char.class, FieldSignature.toClass("char"));
91 assertEquals(byte.class, FieldSignature.toClass("B"));
92 assertEquals(byte.class, FieldSignature.toClass("byte"));
93 assertEquals(float.class, FieldSignature.toClass("F"));
94 assertEquals(float.class, FieldSignature.toClass("float"));
95 assertEquals(long.class, FieldSignature.toClass("J"));
96 assertEquals(long.class, FieldSignature.toClass("long"));
97 assertEquals(short.class, FieldSignature.toClass("S"));
98 assertEquals(short.class, FieldSignature.toClass("short"));
99 assertEquals(int[].class, FieldSignature.toClass("[I"));
100 assertEquals(int[].class, FieldSignature.toClass("[I"));
101 assertEquals(Integer.class, FieldSignature.toClass("Ljava/lang/Integer;"));
102 assertEquals(void.class, FieldSignature.toClass("void"));
103 assertEquals(void.class, FieldSignature.toClass("V"));
104 try
105 {
106 assertNull(FieldSignature.toClass("XXX"));
107 fail("name of non existant class should have thrown a ClassNotFoundException");
108 }
109 catch (ClassNotFoundException cnfe)
110 {
111
112 }
113 }
114
115
116
117
118
119 @Test
120 public void testFieldSignature() throws ClassNotFoundException
121 {
122 FieldSignature fs = new FieldSignature("[J");
123 assertEquals("[J", fs.toString());
124 assertEquals("[J", fs.getStringValue());
125 assertEquals(long[].class, fs.getClassValue());
126 FieldSignature fs2 = new FieldSignature(double[].class);
127 assertEquals("[D", fs2.toString());
128 assertEquals("[D", fs2.getStringValue());
129 assertEquals(double[].class, fs2.getClassValue());
130 }
131
132
133
134
135
136
137
138 @Test
139 public void testMethodSignature() throws NoSuchMethodException, SecurityException, ClassNotFoundException
140 {
141 MethodSignature ms = new MethodSignature(String.class.getConstructor(String.class));
142 assertEquals(String.class, ms.getReturnType());
143 Class<?>[] parameterTypes = ms.getParameterTypes();
144 assertEquals(1, parameterTypes.length);
145 assertEquals(String.class, parameterTypes[0]);
146 assertEquals("Ljava/lang/String;", ms.getParameterDescriptor());
147 ms = new MethodSignature(String.class.getConstructor());
148 assertEquals(String.class, ms.getReturnType());
149 parameterTypes = ms.getParameterTypes();
150 assertEquals(0, parameterTypes.length);
151 ms = new MethodSignature("(I)[D");
152 assertEquals(double[].class, ms.getReturnType());
153 parameterTypes = ms.getParameterTypes();
154 assertEquals(1, parameterTypes.length);
155 assertEquals(int.class, parameterTypes[0]);
156 ms = new MethodSignature(String.class.getMethod("length"));
157 parameterTypes = ms.getParameterTypes();
158 assertEquals(0, parameterTypes.length);
159 Class<?> returnType = ms.getReturnType();
160 assertEquals(int.class, returnType);
161 Method[] methods = String.class.getMethods();
162
163 Method substring = null;
164 for (Method m : methods)
165 {
166 if (m.getName().equals("substring") && m.getParameterCount() == 2)
167 {
168 substring = m;
169 }
170 }
171 if (null == substring)
172 {
173 System.err.println("Could not find substring(int from, int to) method");
174 }
175 else
176 {
177 ms = new MethodSignature(substring);
178 parameterTypes = ms.getParameterTypes();
179 assertEquals(2, parameterTypes.length);
180 assertEquals(int.class, parameterTypes[0]);
181 assertEquals(int.class, parameterTypes[1]);
182 returnType = ms.getReturnType();
183 assertEquals(String.class, returnType);
184 assertEquals("II", ms.getParameterDescriptor());
185 assertEquals("Ljava/lang/String;", ms.getReturnDescriptor());
186 assertEquals("(II)Ljava/lang/String;", ms.toString());
187 }
188 ms = new MethodSignature(String.class.getMethod("getBytes"));
189 returnType = ms.getReturnType();
190 assertEquals(byte[].class, returnType);
191 ms = new MethodSignature(String.class.getConstructor(byte[].class));
192 parameterTypes = ms.getParameterTypes();
193 assertEquals(1, parameterTypes.length);
194 assertEquals(byte[].class, parameterTypes[0]);
195 assertEquals("[B", ms.getParameterDescriptor());
196 }
197
198
199
200
201
202
203
204
205
206 @Test
207 public void testClassUtilConstructors() throws NoSuchMethodException, InstantiationException, IllegalAccessException,
208 IllegalArgumentException, InvocationTargetException
209 {
210 Constructor<TestClass> c1 = ClassUtil.resolveConstructor(TestClass.class, new Class<?>[] {});
211 TestClass o1 = c1.newInstance();
212 assertEquals("<init>", o1.getState());
213
214 Constructor<TestClass> c2 = ClassUtil.resolveConstructor(TestClass.class, new Class<?>[] {String.class});
215 TestClass o2 = c2.newInstance("c2");
216 assertEquals("c2", o2.getState());
217
218 Constructor<InnerPublic> c3 = ClassUtil.resolveConstructor(InnerPublic.class, new Class<?>[] {});
219 InnerPublic o3 = c3.newInstance();
220 assertEquals("<initInnerPublic>", o3.getInnerState());
221
222 Constructor<InnerPublic> c4 = ClassUtil.resolveConstructor(InnerPublic.class, new Class<?>[] {String.class});
223 InnerPublic o4 = c4.newInstance("inner");
224 assertEquals("inner", o4.getInnerState());
225
226
227 Constructor<InnerPublic> c4a = ClassUtil.resolveConstructor(InnerPublic.class, new Class<?>[] {String.class});
228 InnerPublic o4a = c4a.newInstance("inner2");
229 assertEquals("inner2", o4a.getInnerState());
230
231
232 try
233 {
234 ClassUtil.resolveConstructor(TestClass.class, new Class<?>[] {Integer.class});
235 fail("Constructor TestClass(int) does not exist and resolving should throw an exception");
236 }
237 catch (NoSuchMethodException e)
238 {
239
240 }
241
242
243 ClassUtil.resolveConstructor(TestClass.class, new Class<?>[] {boolean.class});
244 ClassUtil.resolveConstructor(TestClass.class, ClassUtilTest.class, new Class<?>[] {String.class});
245 try
246 {
247 ClassUtil.resolveConstructor(TestClass.class, ClassUtilTest.class, new Class<?>[] {boolean.class});
248 fail("Constructor TestClass(boolean) is private and resolving should throw an exception");
249 }
250 catch (IllegalAccessException e)
251 {
252
253 }
254
255 assertEquals(3, ClassUtil.getAllConstructors(TestClass.class).length);
256 }
257
258
259
260
261
262
263
264
265
266 @Test
267 public void testClassUtilConstructor() throws NoSuchMethodException, InstantiationException, IllegalAccessException,
268 IllegalArgumentException, InvocationTargetException
269 {
270 Constructor<Sup>[] cArr = ClassUtil.getAllConstructors(Sup.class);
271 assertEquals(2, cArr.length);
272
273 cArr = ClassUtil.getAllConstructors(Sup.class);
274 assertEquals(2, cArr.length);
275 Constructor<Sup> c1 = ClassUtil.resolveConstructor(Sup.class, new Class<?>[] {String.class, int.class});
276 assertNotNull(c1);
277
278 Constructor<Sup> c1a = ClassUtil.resolveConstructor(Sup.class, new Class<?>[] {String.class, int.class});
279 assertEquals(c1, c1a);
280 Constructor<Sup> c2 = ClassUtil.resolveConstructor(Sup.class, new Object[] {"abc", 1, 2.0d});
281 assertNotNull(c2);
282
283 Constructor<Sup> c2a = ClassUtil.resolveConstructor(Sup.class, new Object[] {"abc", 1, 2.0d});
284 assertEquals(c2, c2a);
285 Constructor<Sub> c2b = ClassUtil.resolveConstructor(Sub.class, new Object[] {"abc", 1, 2.0d});
286 assertNotEquals(c2a, c2b);
287 assertTrue(ClassUtil.isMoreSpecific(c2b, c2a));
288
289 assertFalse(ClassUtil.isMoreSpecific(c2a, c1));
290 assertFalse(ClassUtil.isMoreSpecific(c1, c2a));
291 assertFalse(ClassUtil.isMoreSpecific(c1, c2b));
292
293 UnitTest.testFail(new UnitTest.Execution()
294 {
295 @Override
296 public void execute() throws Throwable
297 {
298 Constructor<Sup> cx = ClassUtil.resolveConstructor(Sup.class, new Class<?>[] {String.class, float.class});
299 fail("illegal retrieval of constructor " + cx.toString());
300 }
301 });
302 UnitTest.testFail(new UnitTest.Execution()
303 {
304 @Override
305 public void execute() throws Throwable
306 {
307 Constructor<Sup> cx = ClassUtil.resolveConstructor(Sup.class, new Object[] {1.2f});
308 fail("illegal retrieval of constructor " + cx.toString());
309 }
310 });
311
312 Sub sup = new Sub("a", 1);
313 Constructor<Sub.Inner> csi2 = ClassUtil.resolveConstructor(Sub.Inner.class, new Object[] {sup, 123L});
314 assertNotNull(csi2);
315 }
316
317
318
319
320
321 @Test
322 public void testClassUtilField() throws NoSuchFieldException
323 {
324 Set<Field> fSet = ClassUtil.getAllFields(Sup.class);
325 removeJacoco(fSet);
326 assertEquals(7, fSet.size());
327
328 testField(Sup.class, "staticFinalString", Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC);
329 testField(Sup.class, "finalString", Modifier.FINAL, Modifier.PUBLIC);
330 testField(Sup.class, "publicInt", Modifier.PUBLIC);
331 testField(Sup.class, "protectedLong", Modifier.PROTECTED);
332 testField(Sup.class, "packageDouble");
333 testField(Sup.class, "privateFloat", Modifier.PRIVATE);
334 testField(Sup.class, "publicSubInt", Modifier.PUBLIC);
335
336 testField(Sub.class, "staticFinalString", Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC);
337 testField(Sub.class, "finalString", Modifier.FINAL, Modifier.PUBLIC);
338 testField(Sub.class, "publicInt", Modifier.PUBLIC);
339 testField(Sub.class, "protectedLong", Modifier.PROTECTED);
340 testField(Sub.class, "packageDouble");
341 testField(Sub.class, "privateFloat", Modifier.PRIVATE);
342 testField(Sub.class, "publicSuperInt", Modifier.PUBLIC);
343 testField(Sub.class, "publicSubInt", Modifier.PUBLIC);
344
345 Sub sup = new Sub("a", 1);
346 testField(sup, "staticFinalString", Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC);
347 testField(sup, "finalString", Modifier.FINAL, Modifier.PUBLIC);
348 testField(sup, "publicInt", Modifier.PUBLIC);
349 testField(sup, "protectedLong", Modifier.PROTECTED);
350 testField(sup, "packageDouble");
351 testField(sup, "privateFloat", Modifier.PRIVATE);
352 testField(sup, "publicSuperInt", Modifier.PUBLIC);
353 testField(sup, "publicSubInt", Modifier.PUBLIC);
354
355 UnitTest.testFail(new UnitTest.Execution()
356 {
357 @Override
358 public void execute() throws Throwable
359 {
360 testField(sup, "xyz", Modifier.PUBLIC);
361 }
362 });
363 UnitTest.testFail(new UnitTest.Execution()
364 {
365 @Override
366 public void execute() throws Throwable
367 {
368 testField(Sub.class, "xyz", Modifier.PUBLIC);
369 }
370 });
371 Field f1 = ClassUtil.resolveField(Sub.class, this.getClass(), "publicInt");
372 assertNotNull(f1);
373 UnitTest.testFail(new UnitTest.Execution()
374 {
375 @Override
376 public void execute() throws Throwable
377 {
378 Field f2 = ClassUtil.resolveField(Sub.class, this.getClass(), "privateFloat");
379 fail("should not be able to resolve private field " + f2);
380 }
381 });
382
383 Sub.Inner supInn = new Sub("a", 1).new Inner(12L);
384 testField(supInn, "publicInnerLong", Modifier.PUBLIC);
385 testField(supInn, "staticFinalString", Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC);
386 testField(supInn, "finalString", Modifier.FINAL, Modifier.PUBLIC);
387 testField(supInn, "publicInt", Modifier.PUBLIC);
388 testField(supInn, "protectedLong", Modifier.PROTECTED);
389 testField(supInn, "packageDouble");
390 testField(supInn, "privateFloat", Modifier.PRIVATE);
391 testField(supInn, "publicSuperInt", Modifier.PUBLIC);
392 testField(supInn, "publicSubInt", Modifier.PUBLIC);
393
394 UnitTest.testFail(new UnitTest.Execution()
395 {
396 @Override
397 public void execute() throws Throwable
398 {
399 Field f3 = ClassUtil.resolveField((Class<?>) null, "publicSubInt");
400 fail("should not be able to resolve field from null object" + f3);
401 }
402 });
403 UnitTest.testFail(new UnitTest.Execution()
404 {
405 @Override
406 public void execute() throws Throwable
407 {
408 Field f3 = ClassUtil.resolveField(Sub.class, null);
409 fail("should not be able to resolve field from null object" + f3);
410 }
411 });
412 UnitTest.testFail(new UnitTest.Execution()
413 {
414 @Override
415 public void execute() throws Throwable
416 {
417 Field f3 = ClassUtil.resolveField((Object) null, "publicSubInt");
418 fail("should not be able to resolve field from null object" + f3);
419 }
420 });
421 UnitTest.testFail(new UnitTest.Execution()
422 {
423 @Override
424 public void execute() throws Throwable
425 {
426 Field f3 = ClassUtil.resolveField(supInn, null);
427 fail("should not be able to resolve field from null object" + f3);
428 }
429 });
430 }
431
432
433
434
435
436 @SuppressWarnings("checkstyle:methodlength")
437 @Test
438 public void testClassUtilMethod() throws NoSuchMethodException
439 {
440 List<Method> mList0 = ClassUtil.getAllMethods(Object.class);
441 removeJacoco(mList0);
442 List<Method> mList1 = ClassUtil.getAllMethods(Sup.class);
443 removeJacoco(mList1);
444
445 assertEquals(mList0.size() + 12, mList1.size());
446 List<Method> mList2 = ClassUtil.getAllMethods(Sup.class, "privateVoid");
447 assertEquals(1, mList2.size());
448
449 testMethod(Sup.class, "publicVoid", new Class<?>[] {}, Modifier.PUBLIC);
450 testMethod(Sup.class, "publicInt", new Class<?>[] {}, Modifier.PUBLIC);
451 testMethod(Sup.class, "publicArgs", new Class<?>[] {String.class, double.class}, Modifier.PUBLIC);
452 testMethod(Sup.class, "protectedVoid", new Class<?>[] {}, Modifier.PROTECTED);
453 testMethod(Sup.class, "protectedInt", new Class<?>[] {}, Modifier.PROTECTED);
454 testMethod(Sup.class, "protectedArgs", new Class<?>[] {String.class, double.class}, Modifier.PROTECTED);
455 testMethod(Sup.class, "packageVoid", new Class<?>[] {});
456 testMethod(Sup.class, "packageInt", new Class<?>[] {});
457 testMethod(Sup.class, "packageArgs", new Class<?>[] {String.class, double.class});
458 testMethod(Sup.class, "privateVoid", new Class<?>[] {}, Modifier.PRIVATE);
459 testMethod(Sup.class, "privateInt", new Class<?>[] {}, Modifier.PRIVATE);
460 testMethod(Sup.class, "privateArgs", new Class<?>[] {String.class, double.class}, Modifier.PRIVATE);
461
462 testMethod(Sub.class, "publicVoid", new Class<?>[] {}, Modifier.PUBLIC);
463 testMethod(Sub.class, "publicInt", new Class<?>[] {}, Modifier.PUBLIC);
464 testMethod(Sub.class, "publicArgs", new Class<?>[] {String.class, double.class}, Modifier.PUBLIC);
465 testMethod(Sub.class, "publicArgs", new Class<?>[] {String.class}, Modifier.PUBLIC);
466 testMethod(Sub.class, "protectedVoid", new Class<?>[] {}, Modifier.PROTECTED);
467 testMethod(Sub.class, "protectedInt", new Class<?>[] {}, Modifier.PROTECTED);
468 testMethod(Sub.class, "protectedArgs", new Class<?>[] {String.class, double.class}, Modifier.PROTECTED);
469 testMethod(Sub.class, "packageVoid", new Class<?>[] {});
470 testMethod(Sub.class, "packageInt", new Class<?>[] {});
471 testMethod(Sub.class, "packageArgs", new Class<?>[] {String.class, double.class});
472 testMethod(Sub.class, "privateVoid", new Class<?>[] {}, Modifier.PRIVATE);
473 testMethod(Sub.class, "privateInt", new Class<?>[] {}, Modifier.PRIVATE);
474 testMethod(Sub.class, "privateArgs", new Class<?>[] {String.class, double.class}, Modifier.PRIVATE);
475
476 Sub sup = new Sub("a", 1);
477 testMethod(sup, "publicVoid", new Class<?>[] {}, Modifier.PUBLIC);
478 testMethod(sup, "publicInt", new Class<?>[] {}, Modifier.PUBLIC);
479 testMethod(sup, "publicArgs", new Class<?>[] {String.class, double.class}, Modifier.PUBLIC);
480 testMethod(sup, "publicArgs", new Class<?>[] {String.class}, Modifier.PUBLIC);
481 testMethod(sup, "protectedVoid", new Class<?>[] {}, Modifier.PROTECTED);
482 testMethod(sup, "protectedInt", new Class<?>[] {}, Modifier.PROTECTED);
483 testMethod(sup, "protectedArgs", new Class<?>[] {String.class, double.class}, Modifier.PROTECTED);
484 testMethod(sup, "packageVoid", new Class<?>[] {});
485 testMethod(sup, "packageInt", new Class<?>[] {});
486 testMethod(sup, "packageArgs", new Class<?>[] {String.class, double.class});
487 testMethod(sup, "privateVoid", new Class<?>[] {}, Modifier.PRIVATE);
488 testMethod(sup, "privateInt", new Class<?>[] {}, Modifier.PRIVATE);
489 testMethod(sup, "privateArgs", new Class<?>[] {String.class, double.class}, Modifier.PRIVATE);
490
491 testMethod(sup, "publicVoid", new Object[] {}, Modifier.PUBLIC);
492 testMethod(sup, "publicInt", new Object[] {}, Modifier.PUBLIC);
493 testMethod(sup, "publicArgs", new Object[] {"abc", 12.0d}, Modifier.PUBLIC);
494 testMethod(sup, "publicArgs", new Object[] {"def"}, Modifier.PUBLIC);
495 testMethod(sup, "protectedVoid", new Object[] {}, Modifier.PROTECTED);
496 testMethod(sup, "protectedInt", new Object[] {}, Modifier.PROTECTED);
497 testMethod(sup, "protectedArgs", new Object[] {"ghi", 13.0d}, Modifier.PROTECTED);
498 testMethod(sup, "packageVoid", new Object[] {});
499 testMethod(sup, "packageInt", new Object[] {});
500 testMethod(sup, "packageArgs", new Object[] {"jkl", 14.0d});
501 testMethod(sup, "privateVoid", new Object[] {}, Modifier.PRIVATE);
502 testMethod(sup, "privateInt", new Object[] {}, Modifier.PRIVATE);
503 testMethod(sup, "privateArgs", new Object[] {"mno", 15.0d}, Modifier.PRIVATE);
504
505 UnitTest.testFail(new UnitTest.Execution()
506 {
507 @Override
508 public void execute() throws Throwable
509 {
510 testMethod(sup, "xyz", new Class<?>[] {}, Modifier.PUBLIC);
511 }
512 });
513 UnitTest.testFail(new UnitTest.Execution()
514 {
515 @Override
516 public void execute() throws Throwable
517 {
518 testMethod(sup, "publicArgs", new Class<?>[] {float.class}, Modifier.PUBLIC);
519 }
520 });
521 UnitTest.testFail(new UnitTest.Execution()
522 {
523 @Override
524 public void execute() throws Throwable
525 {
526 testMethod(sup, "xyz", new Object[] {}, Modifier.PUBLIC);
527 }
528 });
529 UnitTest.testFail(new UnitTest.Execution()
530 {
531 @Override
532 public void execute() throws Throwable
533 {
534 testMethod(sup, "publicArgs", new Object[] {12L}, Modifier.PUBLIC);
535 }
536 });
537 UnitTest.testFail(new UnitTest.Execution()
538 {
539 @Override
540 public void execute() throws Throwable
541 {
542 testMethod(Sub.class, "xyz", new Class<?>[] {}, Modifier.PUBLIC);
543 }
544 });
545 UnitTest.testFail(new UnitTest.Execution()
546 {
547 @Override
548 public void execute() throws Throwable
549 {
550 testMethod(Sub.class, "publicArgs", new Class<?>[] {float.class}, Modifier.PUBLIC);
551 }
552 });
553
554 Method m1 = ClassUtil.resolveMethod(Sub.class, this.getClass(), "publicArgs", new Class<?>[] {String.class});
555 assertNotNull(m1);
556 UnitTest.testFail(new UnitTest.Execution()
557 {
558 @Override
559 public void execute() throws Throwable
560 {
561 Method m2 = ClassUtil.resolveMethod(Sub.class, this.getClass(), "privateArgs", new Class<?>[] {});
562 fail("should not be able to resolve private field " + m2);
563 }
564 });
565
566 Sub.Inner supInn = new Sub("a", 1).new Inner(12L);
567 testMethod(supInn, "publicInnerMethod", new Class<?>[] {long.class}, Modifier.PUBLIC);
568 testMethod(supInn, "publicVoid", new Class<?>[] {}, Modifier.PUBLIC);
569 testMethod(supInn, "publicInt", new Class<?>[] {}, Modifier.PUBLIC);
570 testMethod(supInn, "publicArgs", new Class<?>[] {String.class, double.class}, Modifier.PUBLIC);
571 testMethod(supInn, "publicArgs", new Class<?>[] {String.class}, Modifier.PUBLIC);
572 testMethod(supInn, "protectedVoid", new Class<?>[] {}, Modifier.PROTECTED);
573 testMethod(supInn, "protectedInt", new Class<?>[] {}, Modifier.PROTECTED);
574 testMethod(supInn, "protectedArgs", new Class<?>[] {String.class, double.class}, Modifier.PROTECTED);
575 testMethod(supInn, "packageVoid", new Class<?>[] {});
576 testMethod(supInn, "packageInt", new Class<?>[] {});
577 testMethod(supInn, "packageArgs", new Class<?>[] {String.class, double.class});
578 testMethod(supInn, "privateVoid", new Class<?>[] {}, Modifier.PRIVATE);
579 testMethod(supInn, "privateInt", new Class<?>[] {}, Modifier.PRIVATE);
580 testMethod(supInn, "privateArgs", new Class<?>[] {String.class, double.class}, Modifier.PRIVATE);
581
582 testMethod(supInn, "publicInnerMethod", new Object[] {12L}, Modifier.PUBLIC);
583 testMethod(supInn, "publicVoid", new Object[] {}, Modifier.PUBLIC);
584 testMethod(supInn, "publicInt", new Object[] {}, Modifier.PUBLIC);
585 testMethod(supInn, "publicArgs", new Object[] {"abc", 12.0d}, Modifier.PUBLIC);
586 testMethod(supInn, "publicArgs", new Object[] {"def"}, Modifier.PUBLIC);
587 testMethod(supInn, "protectedVoid", new Object[] {}, Modifier.PROTECTED);
588 testMethod(supInn, "protectedInt", new Object[] {}, Modifier.PROTECTED);
589 testMethod(supInn, "protectedArgs", new Object[] {"ghi", 13.0d}, Modifier.PROTECTED);
590 testMethod(supInn, "packageVoid", new Object[] {});
591 testMethod(supInn, "packageInt", new Object[] {});
592 testMethod(supInn, "packageArgs", new Object[] {"jkl", 14.0d});
593 testMethod(supInn, "privateVoid", new Object[] {}, Modifier.PRIVATE);
594 testMethod(supInn, "privateInt", new Object[] {}, Modifier.PRIVATE);
595 testMethod(supInn, "privateArgs", new Object[] {"mno", 15.0d}, Modifier.PRIVATE);
596
597 UnitTest.testFail(new UnitTest.Execution()
598 {
599 @Override
600 public void execute() throws Throwable
601 {
602 Method m3 = ClassUtil.resolveMethod((Class<?>) null, "publicInt", new Class<?>[] {});
603 fail("should not be able to resolve field from null object" + m3);
604 }
605 });
606 UnitTest.testFail(new UnitTest.Execution()
607 {
608 @Override
609 public void execute() throws Throwable
610 {
611 Method m3 = ClassUtil.resolveMethod(Sub.class, null, new Class<?>[] {});
612 fail("should not be able to resolve field from null object" + m3);
613 }
614 });
615 UnitTest.testFail(new UnitTest.Execution()
616 {
617 @Override
618 public void execute() throws Throwable
619 {
620 Method m3 = ClassUtil.resolveMethod((Object) null, "publicInt", new Class<?>[] {});
621 fail("should not be able to resolve field from null object" + m3);
622 }
623 });
624 UnitTest.testFail(new UnitTest.Execution()
625 {
626 @Override
627 public void execute() throws Throwable
628 {
629 Method m3 = ClassUtil.resolveMethod(supInn, null, new Class<?>[] {});
630 fail("should not be able to resolve field from null object" + m3);
631 }
632 });
633 UnitTest.testFail(new UnitTest.Execution()
634 {
635 @Override
636 public void execute() throws Throwable
637 {
638 Method m3 = ClassUtil.resolveMethod((Object) null, "publicInt", new Object[] {});
639 fail("should not be able to resolve field from null object" + m3);
640 }
641 });
642 UnitTest.testFail(new UnitTest.Execution()
643 {
644 @Override
645 public void execute() throws Throwable
646 {
647 Method m3 = ClassUtil.resolveMethod(supInn, null, new Object[] {});
648 fail("should not be able to resolve field from null object" + m3);
649 }
650 });
651 }
652
653
654
655
656 @Test
657 public void testClassUtilAnnotation()
658 {
659 Set<Annotation> aSet0 = ClassUtil.getAllAnnotations(Sub.class);
660 assertEquals(2, aSet0.size());
661
662 Annotation a1 = ClassUtil.resolveAnnotation(Sub.class, AnnTag.class);
663 assertNotNull(a1);
664 UnitTest.testFail(new UnitTest.Execution()
665 {
666 @Override
667 public void execute() throws Throwable
668 {
669 Annotation a3 = ClassUtil.resolveAnnotation(Sup.class, AnnTag.class);
670 fail("should not be able to resolve non-existing annotation " + a3);
671 }
672 });
673 UnitTest.testFail(new UnitTest.Execution()
674 {
675 @Override
676 public void execute() throws Throwable
677 {
678 Annotation a3 = ClassUtil.resolveAnnotation(null, AnnTag.class);
679 fail("should not be able to resolve non-existing annotation " + a3);
680 }
681 });
682 UnitTest.testFail(new UnitTest.Execution()
683 {
684 @Override
685 public void execute() throws Throwable
686 {
687 Annotation a3 = ClassUtil.resolveAnnotation(Sub.class, null);
688 fail("should not be able to resolve non-existing annotation " + a3);
689 }
690 });
691
692 Annotation a4 = ClassUtil.resolveAnnotation(Sub.Inner.class, AnnTag.class);
693 assertNotNull(a4);
694
695 AnnString a5 = (AnnString) ClassUtil.resolveAnnotation(Sub.class, AnnString.class);
696 assertNotNull(a5);
697 assertEquals("avalue", a5.value());
698 }
699
700
701
702
703
704 private void removeJacoco(final Set<Field> fields)
705 {
706 for (Iterator<Field> it = fields.iterator(); it.hasNext();)
707 {
708 Field field = it.next();
709 if (field.getName().contains("jacoco"))
710 {
711 it.remove();
712 }
713 }
714 }
715
716
717
718
719
720
721
722 protected void testField(final Class<?> clazz, final String fieldName, final int... modifiers) throws NoSuchFieldException
723 {
724 Field field = ClassUtil.resolveField(clazz, fieldName);
725 assertNotNull(field);
726 assertEquals(fieldName, field.getName());
727 Set<Integer> mSet = new HashSet<>();
728 for (int m : modifiers)
729 {
730 assertTrue((field.getModifiers() & m) != 0,
731 "failed modifier for field " + clazz.getSimpleName() + "." + fieldName + " for modifier " + m);
732 mSet.add(m);
733 }
734 for (int p = 0; p < 12; p++)
735 {
736 int m = 1 << p;
737 if (!mSet.contains(m))
738 {
739 assertTrue((field.getModifiers() & m) == 0,
740 "failed modifier for field " + clazz.getSimpleName() + "." + fieldName + " for bit " + p);
741 }
742 }
743 }
744
745
746
747
748
749
750
751 protected void testField(final Object object, final String fieldName, final int... modifiers) throws NoSuchFieldException
752 {
753 Field field = ClassUtil.resolveField(object, fieldName);
754 assertNotNull(field);
755 assertEquals(fieldName, field.getName());
756 Set<Integer> mSet = new HashSet<>();
757 for (int m : modifiers)
758 {
759 assertTrue((field.getModifiers() & m) != 0,
760 "failed modifier for field " + object.getClass().getSimpleName() + "." + fieldName + " for modifier " + m);
761 mSet.add(m);
762 }
763 for (int p = 0; p < 12; p++)
764 {
765 int m = 1 << p;
766 if (!mSet.contains(m))
767 {
768 assertTrue((field.getModifiers() & m) == 0,
769 "failed modifier for field " + object.getClass().getSimpleName() + "." + fieldName + " for bit " + p);
770 }
771 }
772 }
773
774
775
776
777
778 private void removeJacoco(final List<Method> methods)
779 {
780 for (Iterator<Method> it = methods.iterator(); it.hasNext();)
781 {
782 Method method = it.next();
783 if (method.getName().contains("jacoco"))
784 {
785 it.remove();
786 }
787 }
788 }
789
790
791
792
793
794
795
796
797 protected void testMethod(final Class<?> clazz, final String methodName, final Class<?>[] params, final int... modifiers)
798 throws NoSuchMethodException
799 {
800 Method method = ClassUtil.resolveMethod(clazz, methodName, params);
801 assertNotNull(method);
802 assertEquals(methodName, method.getName());
803 Set<Integer> mSet = new HashSet<>();
804 for (int m : modifiers)
805 {
806 assertTrue((method.getModifiers() & m) != 0,
807 "failed modifier for method " + clazz.getSimpleName() + "." + methodName + " for modifier " + m);
808 mSet.add(m);
809 }
810 for (int p = 0; p < 12; p++)
811 {
812 int m = 1 << p;
813 if (!mSet.contains(m))
814 {
815 assertTrue((method.getModifiers() & m) == 0,
816 "failed modifier for method " + clazz.getSimpleName() + "." + methodName + " for bit " + p);
817 }
818 }
819 }
820
821
822
823
824
825
826
827
828 protected void testMethod(final Object object, final String methodName, final Class<?>[] params, final int... modifiers)
829 throws NoSuchMethodException
830 {
831 Method method = ClassUtil.resolveMethod(object, methodName, params);
832 assertNotNull(method);
833 assertEquals(methodName, method.getName());
834 Set<Integer> mSet = new HashSet<>();
835 for (int m : modifiers)
836 {
837 assertTrue((method.getModifiers() & m) != 0, "failed modifier for method " + object.getClass().getSimpleName() + "."
838 + methodName + " for modifier " + m);
839 mSet.add(m);
840 }
841 for (int p = 0; p < 12; p++)
842 {
843 int m = 1 << p;
844 if (!mSet.contains(m))
845 {
846 assertTrue((method.getModifiers() & m) == 0,
847 "failed modifier for method " + object.getClass().getSimpleName() + "." + methodName + " for bit " + p);
848 }
849 }
850 }
851
852
853
854
855
856
857
858
859 protected void testMethod(final Object object, final String methodName, final Object[] args, final int... modifiers)
860 throws NoSuchMethodException
861 {
862 Method method = ClassUtil.resolveMethod(object, methodName, args);
863 assertNotNull(method);
864 assertEquals(methodName, method.getName());
865 Set<Integer> mSet = new HashSet<>();
866 for (int m : modifiers)
867 {
868 assertTrue((method.getModifiers() & m) != 0, "failed modifier for method " + object.getClass().getSimpleName() + "."
869 + methodName + " for modifier " + m);
870 mSet.add(m);
871 }
872 for (int p = 0; p < 12; p++)
873 {
874 int m = 1 << p;
875 if (!mSet.contains(m))
876 {
877 assertTrue((method.getModifiers() & m) == 0,
878 "failed modifier for method " + object.getClass().getSimpleName() + "." + methodName + " for bit " + p);
879 }
880 }
881 }
882
883
884 @SuppressWarnings("unused")
885 protected static class Sup
886 {
887
888 @SuppressWarnings({"checkstyle:visibilitymodifier", "checkstyle:constantname"})
889 public static final String staticFinalString = "ABC";
890
891
892 @SuppressWarnings("checkstyle:visibilitymodifier")
893 public final String finalString = "DEF";
894
895
896 @SuppressWarnings("checkstyle:visibilitymodifier")
897 private float privateFloat = 8.0f;
898
899
900 @SuppressWarnings("checkstyle:visibilitymodifier")
901 double packageDouble = 4.0d;
902
903
904 @SuppressWarnings("checkstyle:visibilitymodifier")
905 protected long protectedLong = 2L;
906
907
908 @SuppressWarnings("checkstyle:visibilitymodifier")
909 public int publicInt = 1;
910
911
912 @SuppressWarnings("checkstyle:visibilitymodifier")
913 public int publicSubInt = 21;
914
915
916
917
918
919
920 public Sup(final String s, final int i, final double d)
921 {
922
923 }
924
925
926
927
928
929 public Sup(final String s, final int i)
930 {
931
932 }
933
934
935 private void privateVoid()
936 {
937
938 }
939
940
941 void packageVoid()
942 {
943
944 }
945
946
947 protected void protectedVoid()
948 {
949
950 }
951
952
953 public void publicVoid()
954 {
955
956 }
957
958
959
960
961 private int privateInt()
962 {
963 return 1;
964 }
965
966
967
968
969 int packageInt()
970 {
971 return 2;
972 }
973
974
975
976
977 protected int protectedInt()
978 {
979 return 3;
980 }
981
982
983
984
985 public int publicInt()
986 {
987 return 4;
988 }
989
990
991
992
993
994 private void privateArgs(final String s, final double d)
995 {
996
997 }
998
999
1000
1001
1002
1003 void packageArgs(final String s, final double d)
1004 {
1005
1006 }
1007
1008
1009
1010
1011
1012 protected void protectedArgs(final String s, final double d)
1013 {
1014
1015 }
1016
1017
1018
1019
1020
1021 public void publicArgs(final String s, final double d)
1022 {
1023
1024 }
1025 }
1026
1027
1028 @SuppressWarnings({"hiding", "unused"})
1029 @AnnTag
1030 @AnnString("avalue")
1031 protected static class Sub extends Sup
1032 {
1033
1034 @SuppressWarnings({"checkstyle:visibilitymodifier", "checkstyle:constantname"})
1035 public static final String staticFinalString = "ABC";
1036
1037
1038 @SuppressWarnings("checkstyle:visibilitymodifier")
1039 public final String finalString = "DEF";
1040
1041
1042 @SuppressWarnings("checkstyle:visibilitymodifier")
1043 private float privateFloat = 8.0f;
1044
1045
1046 @SuppressWarnings("checkstyle:visibilitymodifier")
1047 double packageDouble = 4.0d;
1048
1049
1050 @SuppressWarnings("checkstyle:visibilitymodifier")
1051 protected long protectedLong = 2L;
1052
1053
1054 @SuppressWarnings("checkstyle:visibilitymodifier")
1055 public int publicInt = 1;
1056
1057
1058 @SuppressWarnings("checkstyle:visibilitymodifier")
1059 public int publicSuperInt = 11;
1060
1061
1062
1063
1064
1065
1066 public Sub(final String s, final int i, final double d)
1067 {
1068 super(s, i, d);
1069 }
1070
1071
1072
1073
1074
1075 public Sub(final String s, final int i)
1076 {
1077 super(s, i);
1078 }
1079
1080
1081 private void privateVoid()
1082 {
1083
1084 }
1085
1086 @Override
1087 void packageVoid()
1088 {
1089
1090 }
1091
1092 @Override
1093 protected void protectedVoid()
1094 {
1095
1096 }
1097
1098 @Override
1099 public void publicVoid()
1100 {
1101
1102 }
1103
1104
1105
1106
1107 private int privateInt()
1108 {
1109 return 1;
1110 }
1111
1112 @Override
1113 int packageInt()
1114 {
1115 return 2;
1116 }
1117
1118 @Override
1119 protected int protectedInt()
1120 {
1121 return 3;
1122 }
1123
1124 @Override
1125 public int publicInt()
1126 {
1127 return 4;
1128 }
1129
1130
1131
1132
1133
1134 private void privateArgs(final String s, final double d)
1135 {
1136
1137 }
1138
1139 @Override
1140 void packageArgs(final String s, final double d)
1141 {
1142
1143 }
1144
1145 @Override
1146 protected void protectedArgs(final String s, final double d)
1147 {
1148
1149 }
1150
1151 @Override
1152 public void publicArgs(final String s, final double d)
1153 {
1154
1155 }
1156
1157
1158
1159
1160 public void publicArgs(final String s)
1161 {
1162
1163 }
1164
1165
1166 @AnnTag
1167 public class Inner
1168 {
1169
1170
1171
1172 Inner(final long l)
1173 {
1174
1175 }
1176
1177
1178 @SuppressWarnings("checkstyle:visibilitymodifier")
1179 public long publicInnerLong = 123L;
1180
1181
1182
1183
1184 public void publicInnerMethod(final long l)
1185 {
1186
1187 }
1188 }
1189 }
1190
1191
1192 @Target(ElementType.TYPE)
1193 @Retention(RetentionPolicy.RUNTIME)
1194 public @interface AnnTag
1195 {
1196
1197 }
1198
1199
1200 @Target(ElementType.TYPE)
1201 @Retention(RetentionPolicy.RUNTIME)
1202 public @interface AnnString
1203 {
1204
1205 String value();
1206 }
1207
1208 }