1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.config.annotation;
20
21 import javax.naming.NamingException;
22 import javax.naming.Context;
23 import javax.annotation.Resource;
24 import java.lang.reflect.Method;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Field;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.WeakHashMap;
30 import org.apache.myfaces.shared.util.ClassUtils;
31
32
33 public class ResourceAnnotationLifecycleProvider extends NoInjectionAnnotationLifecycleProvider
34 {
35
36
37
38
39
40
41
42
43 private volatile static WeakHashMap<ClassLoader, Map<Class,Field[]> > declaredFieldBeans =
44 new WeakHashMap<ClassLoader, Map<Class, Field[]>>();
45
46 protected Context context;
47 private static final String JAVA_COMP_ENV = "java:comp/env/";
48
49 public ResourceAnnotationLifecycleProvider(Context context)
50 {
51 this.context = context;
52 }
53
54 private static Map<Class,Field[]> getDeclaredFieldBeansMap()
55 {
56 ClassLoader cl = ClassUtils.getContextClassLoader();
57
58 Map<Class,Field[]> metadata = (Map<Class,Field[]>)
59 declaredFieldBeans.get(cl);
60
61 if (metadata == null)
62 {
63
64
65 synchronized (declaredFieldBeans)
66 {
67 metadata = createDeclaredFieldBeansMap(cl, metadata);
68 }
69 }
70
71 return metadata;
72 }
73
74 private static Map<Class,Field[]> createDeclaredFieldBeansMap(
75 ClassLoader cl, Map<Class,Field[]> metadata)
76 {
77 metadata = (Map<Class,Field[]>) declaredFieldBeans.get(cl);
78 if (metadata == null)
79 {
80 metadata = new HashMap<Class,Field[]>();
81 declaredFieldBeans.put(cl, metadata);
82 }
83 return metadata;
84 }
85
86
87
88
89 @Override
90 protected void processAnnotations(Object instance)
91 throws IllegalAccessException, InvocationTargetException, NamingException
92 {
93
94 if (context == null)
95 {
96
97 return;
98 }
99
100 checkAnnotation(instance.getClass(), instance);
101
102
103
104
105
106
107
108 Class superclass = instance.getClass().getSuperclass();
109 while (superclass != null && (!superclass.equals(Object.class)))
110 {
111 checkAnnotation(superclass, instance);
112 superclass = superclass.getSuperclass();
113 }
114 }
115
116 Field[] getDeclaredFieldBeans(Class clazz)
117 {
118 Map<Class,Field[]> declaredFieldBeansMap = getDeclaredFieldBeansMap();
119 Field[] fields = declaredFieldBeansMap.get(clazz);
120 if (fields == null)
121 {
122 fields = clazz.getDeclaredFields();
123 synchronized(declaredFieldBeansMap)
124 {
125 declaredFieldBeansMap.put(clazz, fields);
126 }
127 }
128 return fields;
129 }
130
131 private void checkAnnotation(Class<?> clazz, Object instance)
132 throws NamingException, IllegalAccessException, InvocationTargetException
133 {
134
135 Field[] fields = getDeclaredFieldBeans(clazz);
136 for (int i = 0; i < fields.length; i++)
137 {
138 Field field = fields[i];
139 checkFieldAnnotation(field, instance);
140 }
141
142
143 Method[] methods = getDeclaredMethods(clazz);
144 for (int i = 0; i < methods.length; i++)
145 {
146 Method method = methods[i];
147 checkMethodAnnotation(method, instance);
148 }
149 }
150
151 protected void checkMethodAnnotation(Method method, Object instance)
152 throws NamingException, IllegalAccessException, InvocationTargetException
153 {
154 if (method.isAnnotationPresent(Resource.class))
155 {
156 Resource annotation = method.getAnnotation(Resource.class);
157 lookupMethodResource(context, instance, method, annotation.name());
158 }
159 }
160
161 protected void checkFieldAnnotation(Field field, Object instance)
162 throws NamingException, IllegalAccessException
163 {
164 if (field.isAnnotationPresent(Resource.class))
165 {
166 Resource annotation = field.getAnnotation(Resource.class);
167 lookupFieldResource(context, instance, field, annotation.name());
168 }
169 }
170
171
172
173
174 protected static void lookupFieldResource(javax.naming.Context context,
175 Object instance, Field field, String name)
176 throws NamingException, IllegalAccessException
177 {
178
179 Object lookedupResource;
180
181 if ((name != null) && (name.length() > 0))
182 {
183
184 lookedupResource = context.lookup(JAVA_COMP_ENV + name);
185 }
186 else
187 {
188
189 lookedupResource = context.lookup(JAVA_COMP_ENV + instance.getClass().getName() + "/" + field.getName());
190 }
191
192 boolean accessibility = field.isAccessible();
193 field.setAccessible(true);
194 field.set(instance, lookedupResource);
195 field.setAccessible(accessibility);
196 }
197
198
199
200
201
202 protected static void lookupMethodResource(javax.naming.Context context,
203 Object instance, Method method, String name)
204 throws NamingException, IllegalAccessException, InvocationTargetException
205 {
206
207 if (!method.getName().startsWith("set")
208 || method.getParameterTypes().length != 1
209 || !method.getReturnType().getName().equals("void"))
210 {
211 throw new IllegalArgumentException("Invalid method resource injection annotation");
212 }
213
214 Object lookedupResource;
215
216 if ((name != null) && (name.length() > 0))
217 {
218
219 lookedupResource = context.lookup(JAVA_COMP_ENV + name);
220 }
221 else
222 {
223
224 lookedupResource =
225 context.lookup(JAVA_COMP_ENV + instance.getClass().getName() + "/" + getFieldName(method));
226 }
227
228 boolean accessibility = method.isAccessible();
229 method.setAccessible(true);
230 method.invoke(instance, lookedupResource);
231 method.setAccessible(accessibility);
232 }
233
234
235
236
237
238
239
240
241 protected static String getFieldName(Method setter)
242 {
243 StringBuilder name = new StringBuilder(setter.getName());
244
245
246 name.delete(0, 3);
247
248
249 name.setCharAt(0, Character.toLowerCase(name.charAt(0)));
250
251 return name.toString();
252 }
253
254 }