1 package org.apache.turbine.annotation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.lang.annotation.Annotation;
23 import java.lang.reflect.AccessibleObject;
24 import java.lang.reflect.Field;
25 import java.util.List;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.ConcurrentMap;
28
29 import org.apache.commons.configuration.Configuration;
30 import org.apache.commons.lang.StringUtils;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.turbine.Turbine;
34 import org.apache.turbine.modules.Loader;
35 import org.apache.turbine.services.ServiceManager;
36 import org.apache.turbine.services.TurbineServices;
37 import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
38 import org.apache.turbine.util.TurbineException;
39
40
41
42
43
44
45
46
47 public class AnnotationProcessor
48 {
49
50 private static Log log = LogFactory.getLog(AnnotationProcessor.class);
51
52
53 private static ConcurrentMap<String, Annotation[]> annotationCache = new ConcurrentHashMap<String, Annotation[]>();
54
55
56
57
58
59
60
61
62 public static Annotation[] getAnnotations(AccessibleObject object)
63 {
64 String key = object.getClass() + object.toString();
65 Annotation[] annotations = annotationCache.get(key);
66 if (annotations == null)
67 {
68 Annotation[] newAnnotations = object.getDeclaredAnnotations();
69 annotations = annotationCache.putIfAbsent(key, newAnnotations);
70 if (annotations == null)
71 {
72 annotations = newAnnotations;
73 }
74 }
75 return annotations;
76 }
77
78
79
80
81
82
83
84
85 public static void process(Object object) throws TurbineException
86 {
87 ServiceManager manager = null;
88 Configuration config = null;
89 AssemblerBrokerService assembler = null;
90 Class<?> clazz = object.getClass();
91
92 while (clazz != null)
93 {
94 Field[] fields = clazz.getDeclaredFields();
95
96 for (Field field : fields)
97 {
98 Annotation[] annotations = getAnnotations(field);
99
100 for (Annotation a : annotations)
101 {
102 if (a instanceof TurbineService)
103 {
104 if (manager == null)
105 {
106 manager = TurbineServices.getInstance();
107 }
108 injectTurbineService(object, manager, field, (TurbineService) a);
109 }
110 else if (a instanceof TurbineConfiguration)
111 {
112 if (config == null)
113 {
114 config = Turbine.getConfiguration();
115 }
116 injectTurbineConfiguration(object, config, field, (TurbineConfiguration) a);
117 }
118 else if (a instanceof TurbineLoader)
119 {
120 if (assembler == null)
121 {
122 assembler = (AssemblerBrokerService) TurbineServices.getInstance().
123 getService(AssemblerBrokerService.SERVICE_NAME);
124 }
125 injectTurbineLoader(object, assembler, field, (TurbineLoader) a);
126 }
127 }
128 }
129
130 clazz = clazz.getSuperclass();
131 }
132 }
133
134
135
136
137
138
139
140
141
142
143
144 private static void injectTurbineLoader(Object object, AssemblerBrokerService assembler, Field field, TurbineLoader annotation) throws TurbineException
145 {
146 Loader<?> loader = assembler.getLoader(annotation.value());
147 field.setAccessible(true);
148
149 try
150 {
151 if (log.isDebugEnabled())
152 {
153 log.debug("Injection of " + loader + " into object " + object);
154 }
155
156 field.set(object, loader);
157 }
158 catch (IllegalArgumentException e)
159 {
160 throw new TurbineException("Could not inject loader "
161 + loader + " into object " + object, e);
162 }
163 catch (IllegalAccessException e)
164 {
165 throw new TurbineException("Could not inject loader "
166 + loader + " into object " + object, e);
167 }
168 }
169
170
171
172
173
174
175
176
177
178
179
180 private static void injectTurbineConfiguration(Object object, Configuration conf, Field field, TurbineConfiguration annotation) throws TurbineException
181 {
182 Class<?> type = field.getType();
183 String key = annotation.value();
184
185 try
186 {
187 if (Configuration.class.isAssignableFrom(type))
188 {
189
190 if (StringUtils.isNotEmpty(key))
191 {
192 conf = conf.subset(key);
193 }
194
195 if (log.isDebugEnabled())
196 {
197 log.debug("Injection of " + conf + " into object " + object);
198 }
199
200 field.setAccessible(true);
201 field.set(object, conf);
202 }
203 else if (conf.containsKey(key))
204 {
205 if ( String.class.isAssignableFrom( type ) )
206 {
207 String value = conf.getString(key);
208 if (log.isDebugEnabled())
209 {
210 log.debug("Injection of " + value + " into object " + object);
211 }
212
213 field.setAccessible(true);
214 field.set(object, value);
215 }
216 else if ( Boolean.TYPE.isAssignableFrom( type ) )
217 {
218 boolean value = conf.getBoolean(key);
219 if (log.isDebugEnabled())
220 {
221 log.debug("Injection of " + value + " into object " + object);
222 }
223
224 field.setAccessible(true);
225 field.setBoolean(object, value);
226 }
227 else if ( Integer.TYPE.isAssignableFrom( type ) )
228 {
229 int value = conf.getInt(key);
230 if (log.isDebugEnabled())
231 {
232 log.debug("Injection of " + value + " into object " + object);
233 }
234
235 field.setAccessible(true);
236 field.setInt(object, value);
237 }
238 else if ( Long.TYPE.isAssignableFrom( type ) )
239 {
240 long value = conf.getLong(key);
241 if (log.isDebugEnabled())
242 {
243 log.debug("Injection of " + value + " into object " + object);
244 }
245
246 field.setAccessible(true);
247 field.setLong(object, value);
248 }
249 else if ( Short.TYPE.isAssignableFrom( type ) )
250 {
251 short value = conf.getShort(key);
252 if (log.isDebugEnabled())
253 {
254 log.debug("Injection of " + value + " into object " + object);
255 }
256
257 field.setAccessible(true);
258 field.setShort(object, value);
259 }
260 else if ( Long.TYPE.isAssignableFrom( type ) )
261 {
262 long value = conf.getLong(key);
263 if (log.isDebugEnabled())
264 {
265 log.debug("Injection of " + value + " into object " + object);
266 }
267
268 field.setAccessible(true);
269 field.setLong(object, value);
270 }
271 else if ( Float.TYPE.isAssignableFrom( type ) )
272 {
273 float value = conf.getFloat(key);
274 if (log.isDebugEnabled())
275 {
276 log.debug("Injection of " + value + " into object " + object);
277 }
278
279 field.setAccessible(true);
280 field.setFloat(object, value);
281 }
282 else if ( Double.TYPE.isAssignableFrom( type ) )
283 {
284 double value = conf.getDouble(key);
285 if (log.isDebugEnabled())
286 {
287 log.debug("Injection of " + value + " into object " + object);
288 }
289
290 field.setAccessible(true);
291 field.setDouble(object, value);
292 }
293 else if ( Byte.TYPE.isAssignableFrom( type ) )
294 {
295 byte value = conf.getByte(key);
296 if (log.isDebugEnabled())
297 {
298 log.debug("Injection of " + value + " into object " + object);
299 }
300
301 field.setAccessible(true);
302 field.setByte(object, value);
303 }
304 else if ( List.class.isAssignableFrom( type ) )
305 {
306 List<Object> values = conf.getList(key);
307 if (log.isDebugEnabled())
308 {
309 log.debug("Injection of " + values + " into object " + object);
310 }
311
312 field.setAccessible(true);
313 field.set(object, values);
314 }
315 }
316 }
317 catch (IllegalArgumentException e)
318 {
319 throw new TurbineException("Could not inject configuration "
320 + conf + " into object " + object, e);
321 }
322 catch (IllegalAccessException e)
323 {
324 throw new TurbineException("Could not inject configuration "
325 + conf + " into object " + object, e);
326 }
327 }
328
329
330
331
332
333
334
335
336
337
338
339 private static void injectTurbineService(Object object, ServiceManager manager, Field field, TurbineService annotation) throws TurbineException
340 {
341 String serviceName = null;
342
343 if (StringUtils.isNotEmpty(annotation.value()))
344 {
345 serviceName = annotation.value();
346 }
347
348 else
349 {
350 Field[] typeFields = field.getType().getFields();
351 for (Field f : typeFields)
352 {
353 if (TurbineService.SERVICE_NAME.equals(f.getName()))
354 {
355 try
356 {
357 serviceName = (String)f.get(null);
358 }
359 catch (Exception e)
360 {
361 continue;
362 }
363 break;
364 }
365 else if (TurbineService.ROLE.equals(f.getName()))
366 {
367 try
368 {
369 serviceName = (String)f.get(null);
370 }
371 catch (Exception e)
372 {
373 continue;
374 }
375 break;
376 }
377 }
378 }
379
380 if (StringUtils.isEmpty(serviceName))
381 {
382
383 serviceName = field.getType().getName();
384 }
385
386 if (log.isDebugEnabled())
387 {
388 log.debug("Looking up service for injection: " + serviceName + " for object " + object);
389 }
390
391 Object service = manager.getService(serviceName);
392 field.setAccessible(true);
393
394 try
395 {
396 if (log.isDebugEnabled())
397 {
398 log.debug("Injection of " + serviceName + " into object " + object);
399 }
400
401 field.set(object, service);
402 }
403 catch (IllegalArgumentException e)
404 {
405 throw new TurbineException("Could not inject service "
406 + serviceName + " into object " + object, e);
407 }
408 catch (IllegalAccessException e)
409 {
410 throw new TurbineException("Could not inject service "
411 + serviceName + " into object " + object, e);
412 }
413 }
414 }