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 | 0 | 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 | 0 | { |
51 | 0 | this.context = context; |
52 | 0 | } |
53 | |
|
54 | |
private static Map<Class,Field[]> getDeclaredFieldBeansMap() |
55 | |
{ |
56 | 0 | ClassLoader cl = ClassUtils.getContextClassLoader(); |
57 | |
|
58 | 0 | Map<Class,Field[]> metadata = (Map<Class,Field[]>) |
59 | |
declaredFieldBeans.get(cl); |
60 | |
|
61 | 0 | if (metadata == null) |
62 | |
{ |
63 | |
|
64 | |
|
65 | 0 | synchronized (declaredFieldBeans) |
66 | |
{ |
67 | 0 | metadata = createDeclaredFieldBeansMap(cl, metadata); |
68 | 0 | } |
69 | |
} |
70 | |
|
71 | 0 | return metadata; |
72 | |
} |
73 | |
|
74 | |
private static Map<Class,Field[]> createDeclaredFieldBeansMap( |
75 | |
ClassLoader cl, Map<Class,Field[]> metadata) |
76 | |
{ |
77 | 0 | metadata = (Map<Class,Field[]>) declaredFieldBeans.get(cl); |
78 | 0 | if (metadata == null) |
79 | |
{ |
80 | 0 | metadata = new HashMap<Class,Field[]>(); |
81 | 0 | declaredFieldBeans.put(cl, metadata); |
82 | |
} |
83 | 0 | return metadata; |
84 | |
} |
85 | |
|
86 | |
|
87 | |
|
88 | |
|
89 | |
@Override |
90 | |
protected void processAnnotations(Object instance) |
91 | |
throws IllegalAccessException, InvocationTargetException, NamingException |
92 | |
{ |
93 | |
|
94 | 0 | if (context == null) |
95 | |
{ |
96 | |
|
97 | 0 | return; |
98 | |
} |
99 | |
|
100 | 0 | checkAnnotation(instance.getClass(), instance); |
101 | |
|
102 | |
|
103 | |
|
104 | |
|
105 | |
|
106 | |
|
107 | |
|
108 | 0 | Class superclass = instance.getClass().getSuperclass(); |
109 | 0 | while (superclass != null && (!superclass.equals(Object.class))) |
110 | |
{ |
111 | 0 | checkAnnotation(superclass, instance); |
112 | 0 | superclass = superclass.getSuperclass(); |
113 | |
} |
114 | 0 | } |
115 | |
|
116 | |
Field[] getDeclaredFieldBeans(Class clazz) |
117 | |
{ |
118 | 0 | Map<Class,Field[]> declaredFieldBeansMap = getDeclaredFieldBeansMap(); |
119 | 0 | Field[] fields = declaredFieldBeansMap.get(clazz); |
120 | 0 | if (fields == null) |
121 | |
{ |
122 | 0 | fields = clazz.getDeclaredFields(); |
123 | 0 | synchronized(declaredFieldBeansMap) |
124 | |
{ |
125 | 0 | declaredFieldBeansMap.put(clazz, fields); |
126 | 0 | } |
127 | |
} |
128 | 0 | return fields; |
129 | |
} |
130 | |
|
131 | |
private void checkAnnotation(Class<?> clazz, Object instance) |
132 | |
throws NamingException, IllegalAccessException, InvocationTargetException |
133 | |
{ |
134 | |
|
135 | 0 | Field[] fields = getDeclaredFieldBeans(clazz); |
136 | 0 | for (int i = 0; i < fields.length; i++) |
137 | |
{ |
138 | 0 | Field field = fields[i]; |
139 | 0 | checkFieldAnnotation(field, instance); |
140 | |
} |
141 | |
|
142 | |
|
143 | 0 | Method[] methods = getDeclaredMethods(clazz); |
144 | 0 | for (int i = 0; i < methods.length; i++) |
145 | |
{ |
146 | 0 | Method method = methods[i]; |
147 | 0 | checkMethodAnnotation(method, instance); |
148 | |
} |
149 | 0 | } |
150 | |
|
151 | |
protected void checkMethodAnnotation(Method method, Object instance) |
152 | |
throws NamingException, IllegalAccessException, InvocationTargetException |
153 | |
{ |
154 | 0 | if (method.isAnnotationPresent(Resource.class)) |
155 | |
{ |
156 | 0 | Resource annotation = method.getAnnotation(Resource.class); |
157 | 0 | lookupMethodResource(context, instance, method, annotation.name()); |
158 | |
} |
159 | 0 | } |
160 | |
|
161 | |
protected void checkFieldAnnotation(Field field, Object instance) |
162 | |
throws NamingException, IllegalAccessException |
163 | |
{ |
164 | 0 | if (field.isAnnotationPresent(Resource.class)) |
165 | |
{ |
166 | 0 | Resource annotation = field.getAnnotation(Resource.class); |
167 | 0 | lookupFieldResource(context, instance, field, annotation.name()); |
168 | |
} |
169 | 0 | } |
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 | 0 | if ((name != null) && (name.length() > 0)) |
182 | |
{ |
183 | |
|
184 | 0 | lookedupResource = context.lookup(JAVA_COMP_ENV + name); |
185 | |
} |
186 | |
else |
187 | |
{ |
188 | |
|
189 | 0 | lookedupResource = context.lookup(JAVA_COMP_ENV + instance.getClass().getName() + "/" + field.getName()); |
190 | |
} |
191 | |
|
192 | 0 | boolean accessibility = field.isAccessible(); |
193 | 0 | field.setAccessible(true); |
194 | 0 | field.set(instance, lookedupResource); |
195 | 0 | field.setAccessible(accessibility); |
196 | 0 | } |
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 | 0 | if (!method.getName().startsWith("set") |
208 | |
|| method.getParameterTypes().length != 1 |
209 | |
|| !method.getReturnType().getName().equals("void")) |
210 | |
{ |
211 | 0 | throw new IllegalArgumentException("Invalid method resource injection annotation"); |
212 | |
} |
213 | |
|
214 | |
Object lookedupResource; |
215 | |
|
216 | 0 | if ((name != null) && (name.length() > 0)) |
217 | |
{ |
218 | |
|
219 | 0 | lookedupResource = context.lookup(JAVA_COMP_ENV + name); |
220 | |
} |
221 | |
else |
222 | |
{ |
223 | |
|
224 | 0 | lookedupResource = |
225 | |
context.lookup(JAVA_COMP_ENV + instance.getClass().getName() + "/" + getFieldName(method)); |
226 | |
} |
227 | |
|
228 | 0 | boolean accessibility = method.isAccessible(); |
229 | 0 | method.setAccessible(true); |
230 | 0 | method.invoke(instance, lookedupResource); |
231 | 0 | method.setAccessible(accessibility); |
232 | 0 | } |
233 | |
|
234 | |
|
235 | |
|
236 | |
|
237 | |
|
238 | |
|
239 | |
|
240 | |
|
241 | |
protected static String getFieldName(Method setter) |
242 | |
{ |
243 | 0 | StringBuilder name = new StringBuilder(setter.getName()); |
244 | |
|
245 | |
|
246 | 0 | name.delete(0, 3); |
247 | |
|
248 | |
|
249 | 0 | name.setCharAt(0, Character.toLowerCase(name.charAt(0))); |
250 | |
|
251 | 0 | return name.toString(); |
252 | |
} |
253 | |
|
254 | |
} |