KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > celtix > common > injection > ResourceInjector


1 package org.objectweb.celtix.common.injection;
2
3
4 import java.lang.annotation.Annotation JavaDoc;
5 import java.lang.reflect.Field JavaDoc;
6 import java.lang.reflect.InvocationTargetException JavaDoc;
7 import java.lang.reflect.Method JavaDoc;
8 import java.util.Collection JavaDoc;
9 import java.util.LinkedList JavaDoc;
10 import java.util.List JavaDoc;
11 import java.util.logging.Level JavaDoc;
12 import java.util.logging.Logger JavaDoc;
13 import javax.annotation.PostConstruct;
14 import javax.annotation.Resource;
15 import javax.annotation.Resources;
16 import org.objectweb.celtix.common.annotation.AnnotationProcessor;
17 import org.objectweb.celtix.common.annotation.AnnotationVisitor;
18 import org.objectweb.celtix.common.logging.LogUtils;
19 import org.objectweb.celtix.resource.ResourceManager;
20
21
22 /**
23  * injects references specified using @Resource annotation
24  *
25  */

26 public class ResourceInjector implements AnnotationVisitor {
27
28     private static final Logger JavaDoc LOG = LogUtils.getL7dLogger(ResourceInjector.class);
29
30     private final ResourceManager resourceManager;
31     private Object JavaDoc target;
32
33     public ResourceInjector(ResourceManager resMgr) {
34         resourceManager = resMgr;
35     }
36
37     public void inject(Object JavaDoc o) {
38
39         AnnotationProcessor processor = new AnnotationProcessor(o);
40         processor.accept(this);
41
42         invokePostConstruct();
43     }
44
45
46
47     // Implementation of org.objectweb.celtix.common.annotation.AnnotationVisitor
48

49     public final void visitClass(final Class JavaDoc<?> clz, final Annotation JavaDoc annotation) {
50         
51         assert annotation instanceof Resource || annotation instanceof Resources : annotation;
52
53         if (annotation instanceof Resource) {
54             injectResourceClassLevel(clz, (Resource)annotation);
55         } else if (annotation instanceof Resources) {
56             Resources resources = (Resources)annotation;
57             for (Resource resource : resources.value()) {
58                 injectResourceClassLevel(clz, resource);
59             }
60         }
61
62     }
63
64     private void injectResourceClassLevel(Class JavaDoc<?> clz, Resource res) {
65         if (res.name() == null || "".equals(res.name())) {
66             LOG.log(Level.INFO, "RESOURCE_NAME_NOT_SPECIFIED", target.getClass().getName());
67             return;
68         }
69
70         Object JavaDoc resource = null;
71         // first find a setter that matches this resource
72
Method JavaDoc setter = findSetterForResource(res);
73         if (setter != null) {
74             Class JavaDoc<?> type = getResourceType(res, setter);
75             resource = resourceManager.resolveResource(res.name(), type);
76             if (resource == null) {
77                 LOG.log(Level.INFO, "RESOURCE_RESOLVE_FAILED");
78                 return;
79             }
80
81             invokeSetter(setter, resource);
82             return;
83         }
84         
85         Field JavaDoc field = findFieldForResource(res);
86         if (field != null) {
87             Class JavaDoc<?> type = getResourceType(res, field);
88             resource = resourceManager.resolveResource(res.name(), type);
89             if (resource == null) {
90                 LOG.log(Level.INFO, "RESOURCE_RESOLVE_FAILED");
91                 return;
92             }
93             injectField(field, resource);
94             return;
95         }
96         LOG.log(Level.SEVERE, "NO_SETTER_OR_FIELD_FOR_RESOURCE", getTarget().getClass().getName());
97     }
98
99     public final List JavaDoc<Class JavaDoc<? extends Annotation JavaDoc>> getTargetAnnotations() {
100         List JavaDoc<Class JavaDoc<? extends Annotation JavaDoc>> al = new LinkedList JavaDoc<Class JavaDoc<? extends Annotation JavaDoc>>();
101         al.add(Resource.class);
102         al.add(Resources.class);
103         return al;
104     }
105
106     public final void visitField(final Field JavaDoc field, final Annotation JavaDoc annotation) {
107
108         assert annotation instanceof Resource : annotation;
109         
110         Resource res = (Resource)annotation;
111
112         String JavaDoc name = getFieldNameForResource(res, field);
113         Class JavaDoc<?> type = getResourceType(res, field);
114         
115         Object JavaDoc resource = resourceManager.resolveResource(name, type);
116         if (resource != null) {
117             injectField(field, resource);
118         } else {
119             LOG.log(Level.INFO, "RESOURCE_RESOLVE_FAILED", name);
120         }
121     }
122
123     public final void visitMethod(final Method JavaDoc method, final Annotation JavaDoc annotation) {
124         
125         assert annotation instanceof Resource : annotation;
126
127         Resource res = (Resource)annotation;
128         
129         String JavaDoc resourceName = getResourceName(res, method);
130         Class JavaDoc<?> clz = getResourceType(res, method);
131
132         Object JavaDoc resource = resourceManager.resolveResource(resourceName, clz);
133         if (resource != null) {
134             invokeSetter(method, resource);
135         } else {
136             LOG.log(Level.INFO, "RESOURCE_RESOLVE_FAILED", new Object JavaDoc[] {resourceName, clz});
137         }
138     }
139
140
141     public final void setTarget(final Object JavaDoc object) {
142         target = object;
143     }
144
145     public final Object JavaDoc getTarget() {
146         return target;
147     }
148
149     private Field JavaDoc findFieldForResource(Resource res) {
150         assert target != null;
151         assert res.name() != null;
152
153         for (Field JavaDoc field : target.getClass().getFields()) {
154             if (field.getName().equals(res.name())) {
155                 return field;
156             }
157         }
158
159         for (Field JavaDoc field : target.getClass().getDeclaredFields()) {
160             if (field.getName().equals(res.name())) {
161                 return field;
162             }
163         }
164         return null;
165     }
166
167
168     private Method JavaDoc findSetterForResource(Resource res) {
169         assert target != null;
170
171         String JavaDoc setterName = resourceNameToSetter(res.name());
172         Method JavaDoc setterMethod = null;
173
174         for (Method JavaDoc method : getTarget().getClass().getMethods()) {
175             if (setterName.equals(method.getName())) {
176                 setterMethod = method;
177                 break;
178             }
179         }
180         
181         if (setterMethod != null && setterMethod.getParameterTypes().length != 1) {
182             LOG.log(Level.WARNING, "SETTER_INJECTION_WITH_INCORRECT_TYPE", setterMethod);
183         }
184         return setterMethod;
185     }
186
187     
188     private String JavaDoc resourceNameToSetter(String JavaDoc resName) {
189
190         return "set" + Character.toUpperCase(resName.charAt(0)) + resName.substring(1);
191     }
192     
193
194     private void invokeSetter(Method JavaDoc method, Object JavaDoc resource) {
195         try {
196             method.invoke(getTarget(), resource);
197         } catch (IllegalAccessException JavaDoc e) {
198             LOG.log(Level.SEVERE, "INJECTION_SETTER_NOT_VISIBLE", method);
199         } catch (InvocationTargetException JavaDoc e) {
200             LogUtils.log(LOG, Level.SEVERE, "INJECTION_SETTER_RAISED_EXCEPTION", e, method);
201         }
202     }
203
204
205     private String JavaDoc getResourceName(Resource res, Method JavaDoc method) {
206         assert method != null;
207         assert res != null;
208         assert method.getName().startsWith("set") : method;
209
210         if (res.name() == null || "".equals(res.name())) {
211             String JavaDoc name = method.getName();
212             name = name.substring(3);
213             name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
214             return name;
215         }
216         return res.name();
217     }
218
219
220
221     private void injectField(Field JavaDoc field, Object JavaDoc resource) {
222         assert field != null;
223         assert resource != null;
224
225         boolean accessible = field.isAccessible();
226         try {
227             if (field.getType().isAssignableFrom(resource.getClass())) {
228                 field.setAccessible(true);
229                 field.set(getTarget(), resource);
230             }
231         } catch (IllegalAccessException JavaDoc e) {
232             e.printStackTrace();
233             LOG.severe("FAILED_TO_INJECT_FIELD");
234         } finally {
235             field.setAccessible(accessible);
236         }
237     }
238
239
240     private void invokePostConstruct() {
241         
242         boolean accessible = false;
243         for (Method JavaDoc method : getPostConstructMethods()) {
244             PostConstruct pc = method.getAnnotation(PostConstruct.class);
245             if (pc != null) {
246                 try {
247                     method.setAccessible(true);
248                     method.invoke(target);
249                 } catch (IllegalAccessException JavaDoc e) {
250                     LOG.log(Level.WARNING, "INJECTION_COMPLETE_NOT_VISIBLE", method);
251                 } catch (InvocationTargetException JavaDoc e) {
252                     LOG.log(Level.WARNING, "INJECTION_COMPLETE_THREW_EXCEPTION", e);
253                 } finally {
254                     method.setAccessible(accessible);
255                 }
256             }
257         }
258     }
259
260     private Collection JavaDoc<Method JavaDoc> getPostConstructMethods() {
261
262         Collection JavaDoc<Method JavaDoc> methods = new LinkedList JavaDoc<Method JavaDoc>();
263         addPostConstructMethods(getTarget().getClass().getMethods(), methods);
264         addPostConstructMethods(getTarget().getClass().getDeclaredMethods(), methods);
265         return methods;
266     }
267
268     private void addPostConstructMethods(Method JavaDoc[] methods, Collection JavaDoc<Method JavaDoc> postConstructMethods) {
269         for (Method JavaDoc method : methods) {
270             if (method.getAnnotation(PostConstruct.class) != null
271                 && !postConstructMethods.contains(method)) {
272                 postConstructMethods.add(method);
273             }
274         }
275     }
276      
277         
278     /**
279      * making this protected to keep pmd happy
280      */

281     protected Class JavaDoc<?> getResourceType(Resource res, Field JavaDoc field) {
282         assert res != null;
283         Class JavaDoc type = res.type();
284         if (res.type() == null || Object JavaDoc.class == res.type()) {
285             type = field.getType();
286         }
287         return type;
288     }
289
290
291     private Class JavaDoc<?> getResourceType(Resource res, Method JavaDoc method) {
292         return res.type() != null && !Object JavaDoc.class.equals(res.type())
293             ? res.type()
294             : method.getParameterTypes()[0];
295     }
296
297
298     private String JavaDoc getFieldNameForResource(Resource res, Field JavaDoc field) {
299         assert res != null;
300         if (res.name() == null || "".equals(res.name())) {
301             return field.getName();
302         }
303         return res.name();
304     }
305
306 }
307
Popular Tags