1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package cz.cuni.amis.utils;
19
20 import java.lang.reflect.Field;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Modifier;
23 import org.apache.commons.beanutils.PropertyUtils;
24
25
26
27
28
29 public class ReflectionUtils {
30
31 public ReflectionUtils() {
32 throw new RuntimeException("Cannot instantiate static class");
33 }
34
35 public static interface ProcessAnnotatedMethodCallback<T extends java.lang.annotation.Annotation> {
36 void processMethod(Method m, T annotation);
37 }
38
39 public static interface ProcessAnnotatedFieldCallback<T extends java.lang.annotation.Annotation, E extends Throwable> {
40 void processField(Field f,Object fieldValue, T annotation) throws E;
41 }
42
43 public static interface ProcessFieldCallback<E extends Throwable> {
44 void processField(Field f) throws E;
45 }
46
47 public static <E extends Throwable> void processEachDeclaredNonStaticField(Object targetObject, ProcessFieldCallback<E> callBack) throws E{
48 processEachDeclaredNonStaticField(targetObject,Object.class, callBack);
49 }
50
51 public static <E extends Throwable> void processEachDeclaredNonStaticField(Object targetObject, Class rootClass,ProcessFieldCallback<E> callBack) throws E{
52 if(!rootClass.isAssignableFrom(targetObject.getClass())){
53 throw new IllegalArgumentException("TargetObject must be instance of rootClass");
54 }
55 Class inspectedClass = targetObject.getClass();
56 while(inspectedClass != null && rootClass.isAssignableFrom(inspectedClass)){
57 for(Field f : inspectedClass.getDeclaredFields()){
58 if(Modifier.isStatic(f.getModifiers())){
59 continue;
60 }
61 callBack.processField(f);
62 }
63 inspectedClass = inspectedClass.getSuperclass();
64 }
65
66 }
67
68 public static <E extends Throwable> void processEachDeclaredFieldOfClass(Class targetClass, ProcessFieldCallback<E> callBack) throws E{
69 processEachDeclaredFieldOfClass(targetClass,Object.class, callBack);
70 }
71
72 public static <E extends Throwable> void processEachDeclaredFieldOfClass(Class targetClass, Class rootClass,ProcessFieldCallback<E> callBack) throws E{
73 if(!rootClass.isAssignableFrom(targetClass)){
74 throw new IllegalArgumentException("TargetClass must be descendant of rootClass");
75 }
76 Class inspectedClass = targetClass;
77 while(inspectedClass != null && rootClass.isAssignableFrom(inspectedClass)){
78 for(Field f : inspectedClass.getDeclaredFields()){
79 callBack.processField(f);
80 }
81 inspectedClass = inspectedClass.getSuperclass();
82 }
83
84 }
85
86
87 public static <T extends java.lang.annotation.Annotation, E extends Throwable> void processEachAnnotatedDeclaredField(final Object targetObject, final Class<T> annotationClass, final ProcessAnnotatedFieldCallback<T, E> callBack) throws E{
88 processEachAnnotatedDeclaredField(targetObject, Object.class, annotationClass, callBack);
89 }
90
91 public static <T extends java.lang.annotation.Annotation, E extends Throwable> void processEachAnnotatedDeclaredField(final Object targetObject, final Class rootClass, final Class<T> annotationClass, final ProcessAnnotatedFieldCallback<T, E> callBack) throws E{
92
93 processEachDeclaredNonStaticField(targetObject, rootClass, new ProcessFieldCallback<E>() {
94
95 @Override
96 public void processField(Field f) throws E {
97 if(f.isAnnotationPresent(annotationClass)){
98 Object fieldValue;
99 try {
100 fieldValue = PropertyUtils.getProperty(targetObject, f.getName());
101 } catch (Exception ex) {
102 throw new IllegalStateException("Could not read property value for annotated property '" + f.getName() + "' in class" + f.getDeclaringClass().getName() + "\nThe property should have public getter.", ex);
103 }
104 callBack.processField(f, fieldValue, f.getAnnotation(annotationClass));
105 }
106 }
107 });
108
109
110 }
111
112
113 public static <T extends java.lang.annotation.Annotation> void processEachAnnotatedDeclaredMethod(final Object targetObject, final Class<T> annotationClass, final ProcessAnnotatedMethodCallback<T> callBack){
114 processEachAnnotatedDeclaredMethod(targetObject, Object.class, annotationClass, callBack);
115 }
116
117 public static <T extends java.lang.annotation.Annotation> void processEachAnnotatedDeclaredMethod(final Object targetObject, final Class rootClass, final Class<T> annotationClass, final ProcessAnnotatedMethodCallback<T> callBack){
118
119 if(!rootClass.isAssignableFrom(targetObject.getClass())){
120 throw new IllegalArgumentException("TargetObject must be instance of rootClass");
121 }
122 Class inspectedClass = targetObject.getClass();
123 while(inspectedClass != null && rootClass.isAssignableFrom(inspectedClass)){
124 for(Method f : inspectedClass.getDeclaredMethods()){
125 if(f.isAnnotationPresent(annotationClass)){
126 callBack.processMethod(f,f.getAnnotation(annotationClass));
127 }
128 }
129 inspectedClass = inspectedClass.getSuperclass();
130 }
131
132 }
133
134 }