1 | package org.jsesoft.ri; |
2 | |
3 | import java.lang.annotation.Annotation; |
4 | import java.lang.reflect.Constructor; |
5 | import java.lang.reflect.Field; |
6 | import java.lang.reflect.Method; |
7 | |
8 | /** |
9 | * Provides class inspection by Java reflection. |
10 | * |
11 | * <p> |
12 | * The class <code>ReflectionInspector</code>} |
13 | * traverses the reflection tree of the inspectee and calls handler function |
14 | * for all fields, constructors, methods, and annotations found. |
15 | * </p> |
16 | * <p> |
17 | * The Reflection Inspector offers two methods of exploiting the |
18 | * information provided: |
19 | * </p> |
20 | * <ul> |
21 | * <li>subclassing the inspector</li> |
22 | * <li>attaching a strategy to the inspector</li> |
23 | * </ul> |
24 | * <p> |
25 | * The JUnit test class |
26 | * {@link org.jsesoft.ri.TestReflectionInspector |
27 | * <code>org.jsesoft.ri.TestReflectionInspector</code>} |
28 | * demonstrates both types of usage. |
29 | </p> |
30 | |
31 | * @author Dr. Klaus Wiederänders |
32 | * @version $Revision: 1.3 $ |
33 | */ |
34 | public class ReflectionInspector |
35 | extends InspectorSupport |
36 | { |
37 | private Class inspectee; |
38 | private Boolean state = null; |
39 | |
40 | /** |
41 | * Inspects the specified inspectee. |
42 | * |
43 | * @return true if inspection complete |
44 | * @throws Exception |
45 | * @see #setInspectee |
46 | */ |
47 | public boolean inspect() |
48 | throws Exception |
49 | { |
50 | preInspect(); |
51 | boolean reply = inspect( getInspectee() ); |
52 | postInspect(); |
53 | return reply; |
54 | } |
55 | |
56 | /** |
57 | * Preprocesses inspection. |
58 | * |
59 | * @throws Exception |
60 | */ |
61 | public void preInspect() |
62 | throws Exception |
63 | { |
64 | state = false; |
65 | } |
66 | |
67 | /** |
68 | * Postprocesses inspection. |
69 | * |
70 | * @throws Exception |
71 | */ |
72 | public void postInspect() |
73 | throws Exception |
74 | { |
75 | state = true; |
76 | } |
77 | |
78 | @Override |
79 | public boolean inspect( Class inspected ) |
80 | throws Exception |
81 | { |
82 | if( inspected == null ) { |
83 | return true; |
84 | } |
85 | preInspect( inspected ); |
86 | if( ! super.inspect( inspected ) ) { |
87 | inspectFields( inspected ); |
88 | inspectConstructors( inspected ); |
89 | inspectMethods( inspected ); |
90 | inspect( inspected.getSuperclass() ); |
91 | } |
92 | postInspect( inspected ); |
93 | return true; |
94 | } |
95 | |
96 | @Override |
97 | public boolean inspectConstructors( Class inspected ) |
98 | throws Exception |
99 | { |
100 | preInspectConstructors( inspected ); |
101 | if( ! super.inspectConstructors( inspected ) ) { |
102 | Constructor[] constructors = inspected.getDeclaredConstructors(); |
103 | for( Constructor constructor : constructors ) { |
104 | inspectConstructor( inspected, constructor ); |
105 | } |
106 | } |
107 | postInspectConstructors( inspected ); |
108 | return true; |
109 | } |
110 | |
111 | @Override |
112 | public boolean inspectConstructor( Class inspected, Constructor constructor ) |
113 | throws Exception |
114 | { |
115 | preInspectConstructor( inspected, constructor ); |
116 | if( ! super.inspectConstructor( inspected, constructor ) ) { |
117 | inspectParameterTypes( inspected, constructor ); |
118 | inspectAnnotations( inspected, constructor ); |
119 | } |
120 | postInspectConstructor( inspected, constructor ); |
121 | return true; |
122 | } |
123 | |
124 | @Override |
125 | public boolean inspectParameterTypes( Class inspected, Constructor constructor ) |
126 | throws Exception |
127 | { |
128 | preInspectParameterTypes( inspected, constructor ); |
129 | if( ! super.inspectParameterTypes( inspected, constructor ) ) { |
130 | Class<? > [] parameterTypes = constructor.getParameterTypes(); |
131 | for( Class<? > parameterType : parameterTypes ) { |
132 | inspectParameterType( inspected, parameterType ); |
133 | } |
134 | } |
135 | postInspectParameterTypes( inspected, constructor ); |
136 | return true; |
137 | } |
138 | |
139 | @Override |
140 | public boolean inspectAnnotations( Class inspected, Constructor constructor ) |
141 | throws Exception |
142 | { |
143 | preInspectAnnotations( inspected, constructor ); |
144 | if( ! super.inspectAnnotations( inspected, constructor ) ) { |
145 | Annotation[] annotations = constructor.getAnnotations(); |
146 | for( Annotation annotation : annotations ) { |
147 | inspectAnnotation( inspected, annotation ); |
148 | } |
149 | } |
150 | postInspectAnnotations( inspected, constructor ); |
151 | return true; |
152 | } |
153 | |
154 | @Override |
155 | public boolean inspectFields( Class inspected ) |
156 | throws Exception |
157 | { |
158 | preInspectFields( inspected ); |
159 | if( ! super.inspectFields( inspected ) ) { |
160 | Field[] fields = inspected.getDeclaredFields(); |
161 | for( Field field : fields ) { |
162 | inspectField( inspected, field ); |
163 | } |
164 | } |
165 | postInspectFields( inspected ); |
166 | return true; |
167 | } |
168 | |
169 | @Override |
170 | public boolean inspectField( Class inspected, Field field ) |
171 | throws Exception |
172 | { |
173 | preInspectField( inspected, field ); |
174 | if( ! super.inspectField( inspected, field ) ) { |
175 | inspectAnnotations( inspected, field ); |
176 | } |
177 | postInspectField( inspected, field ); |
178 | return true; |
179 | } |
180 | |
181 | @Override |
182 | public boolean inspectAnnotations( Class inspected, Field field ) |
183 | throws Exception |
184 | { |
185 | preInspectAnnotations( inspected, field ); |
186 | if( ! super.inspectAnnotations( inspected, field ) ) { |
187 | Annotation[] annotations = field.getAnnotations(); |
188 | for( Annotation annotation : annotations ) { |
189 | inspectAnnotation( inspected, annotation ); |
190 | } |
191 | } |
192 | postInspectAnnotations( inspected, field ); |
193 | return true; |
194 | } |
195 | |
196 | @Override |
197 | public boolean inspectMethods( Class inspected ) |
198 | throws Exception |
199 | { |
200 | preInspectMethods( inspected ); |
201 | if( ! super.inspectMethods( inspected ) ) { |
202 | Method[] methods = inspected.getDeclaredMethods(); |
203 | for( Method method : methods ) { |
204 | inspectMethod( inspected, method ); |
205 | } |
206 | } |
207 | postInspectMethods( inspected ); |
208 | return true; |
209 | } |
210 | |
211 | @Override |
212 | public boolean inspectMethod( Class inspected, Method method ) |
213 | throws Exception |
214 | { |
215 | preInspectMethod( inspected, method ); |
216 | if( ! super.inspectMethod( inspected, method ) ) { |
217 | inspectParameterTypes( inspected, method ); |
218 | inspectAnnotations( inspected, method ); |
219 | } |
220 | postInspectMethod( inspected, method ); |
221 | return true; |
222 | } |
223 | |
224 | @Override |
225 | public boolean inspectParameterTypes( Class inspected, Method method ) |
226 | throws Exception |
227 | { |
228 | preInspectParameterTypes( inspected, method ); |
229 | if( ! super.inspectParameterTypes( inspected, method ) ) { |
230 | Class<? > [] parameterTypes = method.getParameterTypes(); |
231 | for( Class<? > parameterType : parameterTypes ) { |
232 | inspectParameterType( inspected, parameterType ); |
233 | } |
234 | } |
235 | postInspectParameterTypes( inspected, method ); |
236 | return true; |
237 | } |
238 | |
239 | @Override |
240 | public boolean inspectAnnotations( Class inspected, Method method ) |
241 | throws Exception |
242 | { |
243 | preInspectAnnotations( inspected, method ); |
244 | if( ! super.inspectAnnotations( inspected, method ) ) { |
245 | Annotation[] annotations = method.getAnnotations(); |
246 | for( Annotation annotation : annotations ) { |
247 | inspectAnnotation( inspected, annotation ); |
248 | } |
249 | } |
250 | postInspectAnnotations( inspected, method ); |
251 | return true; |
252 | } |
253 | |
254 | @Override |
255 | public boolean inspectAnnotation( Class inspected, Annotation annotation ) |
256 | throws Exception |
257 | { |
258 | preInspectAnnotation( inspected, annotation ); |
259 | if( ! super.inspectAnnotation( inspected, annotation ) ) { |
260 | // intentionally empty |
261 | } |
262 | postInspectAnnotation( inspected, annotation ); |
263 | return true; |
264 | } |
265 | |
266 | @Override |
267 | public boolean inspectParameterType( Class inspected, Class<? > parameterType ) |
268 | throws Exception |
269 | { |
270 | preInspectParameterType( inspected, parameterType ); |
271 | if( ! super.inspectParameterType( inspected, parameterType ) ) { |
272 | // intentionally empty |
273 | } |
274 | postInspectParameterType( inspected, parameterType ); |
275 | return true; |
276 | } |
277 | |
278 | /** |
279 | * Specifies the class to be inspected. |
280 | * |
281 | * @param inspectee the Class to be inspected |
282 | * @see #getInspectee |
283 | */ |
284 | public void setInspectee( Class inspectee ) |
285 | { |
286 | this.inspectee = inspectee; |
287 | } |
288 | |
289 | /** |
290 | * Retrieves the class to be inspected. |
291 | * |
292 | * @return the inspected Class |
293 | * @see #setInspectee |
294 | */ |
295 | public Class getInspectee() |
296 | { |
297 | return inspectee; |
298 | } |
299 | |
300 | /** |
301 | * Sets the state value. |
302 | * |
303 | * @return the Boolean state |
304 | */ |
305 | public Boolean getState() |
306 | { |
307 | return state; |
308 | } |
309 | |
310 | } |