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.exceptions.Try;
28 import org.djutils.reflection.TestClass.InnerPublic;
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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.Execution()
356 {
357 @Override
358 public void execute() throws Throwable
359 {
360 testField(sup, "xyz", Modifier.PUBLIC);
361 }
362 });
363 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.Execution()
506 {
507 @Override
508 public void execute() throws Throwable
509 {
510 testMethod(sup, "xyz", new Class<?>[] {}, Modifier.PUBLIC);
511 }
512 });
513 Try.testFail(new Try.Execution()
514 {
515 @Override
516 public void execute() throws Throwable
517 {
518 testMethod(sup, "publicArgs", new Class<?>[] {float.class}, Modifier.PUBLIC);
519 }
520 });
521 Try.testFail(new Try.Execution()
522 {
523 @Override
524 public void execute() throws Throwable
525 {
526 testMethod(sup, "xyz", new Object[] {}, Modifier.PUBLIC);
527 }
528 });
529 Try.testFail(new Try.Execution()
530 {
531 @Override
532 public void execute() throws Throwable
533 {
534 testMethod(sup, "publicArgs", new Object[] {12L}, Modifier.PUBLIC);
535 }
536 });
537 Try.testFail(new Try.Execution()
538 {
539 @Override
540 public void execute() throws Throwable
541 {
542 testMethod(Sub.class, "xyz", new Class<?>[] {}, Modifier.PUBLIC);
543 }
544 });
545 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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 Try.testFail(new Try.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(
760 (field.getModifiers() & m) != 0,
761 "failed modifier for field " + object.getClass().getSimpleName() + "." + fieldName + " for modifier " + m);
762 mSet.add(m);
763 }
764 for (int p = 0; p < 12; p++)
765 {
766 int m = 1 << p;
767 if (!mSet.contains(m))
768 {
769 assertTrue((field.getModifiers() & m) == 0,
770 "failed modifier for field " + object.getClass().getSimpleName() + "." + fieldName + " for bit " + p);
771 }
772 }
773 }
774
775
776
777
778
779 private void removeJacoco(final List<Method> methods)
780 {
781 for (Iterator<Method> it = methods.iterator(); it.hasNext();)
782 {
783 Method method = it.next();
784 if (method.getName().contains("jacoco"))
785 {
786 it.remove();
787 }
788 }
789 }
790
791
792
793
794
795
796
797
798 protected void testMethod(final Class<?> clazz, final String methodName, final Class<?>[] params, final int... modifiers)
799 throws NoSuchMethodException
800 {
801 Method method = ClassUtil.resolveMethod(clazz, methodName, params);
802 assertNotNull(method);
803 assertEquals(methodName, method.getName());
804 Set<Integer> mSet = new HashSet<>();
805 for (int m : modifiers)
806 {
807 assertTrue((method.getModifiers() & m) != 0,
808 "failed modifier for method " + clazz.getSimpleName() + "." + methodName + " for modifier " + m);
809 mSet.add(m);
810 }
811 for (int p = 0; p < 12; p++)
812 {
813 int m = 1 << p;
814 if (!mSet.contains(m))
815 {
816 assertTrue((method.getModifiers() & m) == 0,
817 "failed modifier for method " + clazz.getSimpleName() + "." + methodName + " for bit " + p);
818 }
819 }
820 }
821
822
823
824
825
826
827
828
829 protected void testMethod(final Object object, final String methodName, final Class<?>[] params, final int... modifiers)
830 throws NoSuchMethodException
831 {
832 Method method = ClassUtil.resolveMethod(object, methodName, params);
833 assertNotNull(method);
834 assertEquals(methodName, method.getName());
835 Set<Integer> mSet = new HashSet<>();
836 for (int m : modifiers)
837 {
838 assertTrue(
839 (method.getModifiers() & m) != 0,
840 "failed modifier for method " + object.getClass().getSimpleName() + "." + methodName + " for modifier " + m);
841 mSet.add(m);
842 }
843 for (int p = 0; p < 12; p++)
844 {
845 int m = 1 << p;
846 if (!mSet.contains(m))
847 {
848 assertTrue(
849 (method.getModifiers() & m) == 0,
850 "failed modifier for method " + object.getClass().getSimpleName() + "." + methodName + " for bit " + p);
851 }
852 }
853 }
854
855
856
857
858
859
860
861
862 protected void testMethod(final Object object, final String methodName, final Object[] args, final int... modifiers)
863 throws NoSuchMethodException
864 {
865 Method method = ClassUtil.resolveMethod(object, methodName, args);
866 assertNotNull(method);
867 assertEquals(methodName, method.getName());
868 Set<Integer> mSet = new HashSet<>();
869 for (int m : modifiers)
870 {
871 assertTrue(
872 (method.getModifiers() & m) != 0,
873 "failed modifier for method " + object.getClass().getSimpleName() + "." + methodName + " for modifier " + m);
874 mSet.add(m);
875 }
876 for (int p = 0; p < 12; p++)
877 {
878 int m = 1 << p;
879 if (!mSet.contains(m))
880 {
881 assertTrue(
882 (method.getModifiers() & m) == 0,
883 "failed modifier for method " + object.getClass().getSimpleName() + "." + methodName + " for bit " + p);
884 }
885 }
886 }
887
888
889 @SuppressWarnings("unused")
890 protected static class Sup
891 {
892
893 @SuppressWarnings({"checkstyle:visibilitymodifier", "checkstyle:constantname"})
894 public static final String staticFinalString = "ABC";
895
896
897 @SuppressWarnings("checkstyle:visibilitymodifier")
898 public final String finalString = "DEF";
899
900
901 @SuppressWarnings("checkstyle:visibilitymodifier")
902 private float privateFloat = 8.0f;
903
904
905 @SuppressWarnings("checkstyle:visibilitymodifier")
906 double packageDouble = 4.0d;
907
908
909 @SuppressWarnings("checkstyle:visibilitymodifier")
910 protected long protectedLong = 2L;
911
912
913 @SuppressWarnings("checkstyle:visibilitymodifier")
914 public int publicInt = 1;
915
916
917 @SuppressWarnings("checkstyle:visibilitymodifier")
918 public int publicSubInt = 21;
919
920
921
922
923
924
925 public Sup(final String s, final int i, final double d)
926 {
927
928 }
929
930
931
932
933
934 public Sup(final String s, final int i)
935 {
936
937 }
938
939
940 private void privateVoid()
941 {
942
943 }
944
945
946 void packageVoid()
947 {
948
949 }
950
951
952 protected void protectedVoid()
953 {
954
955 }
956
957
958 public void publicVoid()
959 {
960
961 }
962
963
964
965
966 private int privateInt()
967 {
968 return 1;
969 }
970
971
972
973
974 int packageInt()
975 {
976 return 2;
977 }
978
979
980
981
982 protected int protectedInt()
983 {
984 return 3;
985 }
986
987
988
989
990 public int publicInt()
991 {
992 return 4;
993 }
994
995
996
997
998
999 private void privateArgs(final String s, final double d)
1000 {
1001
1002 }
1003
1004
1005
1006
1007
1008 void packageArgs(final String s, final double d)
1009 {
1010
1011 }
1012
1013
1014
1015
1016
1017 protected void protectedArgs(final String s, final double d)
1018 {
1019
1020 }
1021
1022
1023
1024
1025
1026 public void publicArgs(final String s, final double d)
1027 {
1028
1029 }
1030 }
1031
1032
1033 @SuppressWarnings({"hiding", "unused"})
1034 @AnnTag
1035 @AnnString("avalue")
1036 protected static class Sub extends Sup
1037 {
1038
1039 @SuppressWarnings({"checkstyle:visibilitymodifier", "checkstyle:constantname"})
1040 public static final String staticFinalString = "ABC";
1041
1042
1043 @SuppressWarnings("checkstyle:visibilitymodifier")
1044 public final String finalString = "DEF";
1045
1046
1047 @SuppressWarnings("checkstyle:visibilitymodifier")
1048 private float privateFloat = 8.0f;
1049
1050
1051 @SuppressWarnings("checkstyle:visibilitymodifier")
1052 double packageDouble = 4.0d;
1053
1054
1055 @SuppressWarnings("checkstyle:visibilitymodifier")
1056 protected long protectedLong = 2L;
1057
1058
1059 @SuppressWarnings("checkstyle:visibilitymodifier")
1060 public int publicInt = 1;
1061
1062
1063 @SuppressWarnings("checkstyle:visibilitymodifier")
1064 public int publicSuperInt = 11;
1065
1066
1067
1068
1069
1070
1071 public Sub(final String s, final int i, final double d)
1072 {
1073 super(s, i, d);
1074 }
1075
1076
1077
1078
1079
1080 public Sub(final String s, final int i)
1081 {
1082 super(s, i);
1083 }
1084
1085
1086 private void privateVoid()
1087 {
1088
1089 }
1090
1091 @Override
1092 void packageVoid()
1093 {
1094
1095 }
1096
1097 @Override
1098 protected void protectedVoid()
1099 {
1100
1101 }
1102
1103 @Override
1104 public void publicVoid()
1105 {
1106
1107 }
1108
1109
1110
1111
1112 private int privateInt()
1113 {
1114 return 1;
1115 }
1116
1117 @Override
1118 int packageInt()
1119 {
1120 return 2;
1121 }
1122
1123 @Override
1124 protected int protectedInt()
1125 {
1126 return 3;
1127 }
1128
1129 @Override
1130 public int publicInt()
1131 {
1132 return 4;
1133 }
1134
1135
1136
1137
1138
1139 private void privateArgs(final String s, final double d)
1140 {
1141
1142 }
1143
1144 @Override
1145 void packageArgs(final String s, final double d)
1146 {
1147
1148 }
1149
1150 @Override
1151 protected void protectedArgs(final String s, final double d)
1152 {
1153
1154 }
1155
1156 @Override
1157 public void publicArgs(final String s, final double d)
1158 {
1159
1160 }
1161
1162
1163
1164
1165 public void publicArgs(final String s)
1166 {
1167
1168 }
1169
1170
1171 @AnnTag
1172 public class Inner
1173 {
1174
1175
1176
1177 Inner(final long l)
1178 {
1179
1180 }
1181
1182
1183 @SuppressWarnings("checkstyle:visibilitymodifier")
1184 public long publicInnerLong = 123L;
1185
1186
1187
1188
1189 public void publicInnerMethod(final long l)
1190 {
1191
1192 }
1193 }
1194 }
1195
1196
1197 @Target(ElementType.TYPE)
1198 @Retention(RetentionPolicy.RUNTIME)
1199 public @interface AnnTag
1200 {
1201
1202 }
1203
1204
1205 @Target(ElementType.TYPE)
1206 @Retention(RetentionPolicy.RUNTIME)
1207 public @interface AnnString
1208 {
1209
1210 String value();
1211 }
1212
1213 }