1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.plus.annotation;
15
16 import java.lang.reflect.Field;
17 import java.lang.reflect.Member;
18 import java.lang.reflect.Method;
19
20 import javax.naming.InitialContext;
21 import javax.naming.NamingException;
22
23 import org.eclipse.jetty.util.IntrospectionUtil;
24 import org.eclipse.jetty.util.Loader;
25 import org.eclipse.jetty.util.TypeUtil;
26 import org.eclipse.jetty.util.log.Log;
27
28
29
30
31
32
33
34
35
36 public class Injection
37 {
38 private Class _targetClass;
39 private String _jndiName;
40 private String _mappingName;
41 private Member _target;
42 private String _className;
43 private String _fieldName;
44 private String _methodName;
45 private String _paramCanonicalName;
46 private String _annotationResourceType;
47
48
49 public Injection ()
50 {}
51
52
53
54
55
56 public Class getTargetClass()
57 {
58 return _targetClass;
59 }
60
61
62 public String getTargetClassName()
63 {
64 return _className;
65 }
66
67 public String getFieldName ()
68 {
69 return _fieldName;
70 }
71
72 public String getMethodName ()
73 {
74 return _methodName;
75 }
76
77 public String getParamCanonicalName ()
78 {
79 return _paramCanonicalName;
80 }
81
82 public boolean isField ()
83 {
84 return (_fieldName != null);
85 }
86
87 public boolean isMethod ()
88 {
89 return (_methodName != null);
90 }
91
92
93
94
95 public String getJndiName()
96 {
97 return _jndiName;
98 }
99
100
101
102 public void setJndiName(String jndiName)
103 {
104 this._jndiName = jndiName;
105 }
106
107
108
109 public String getMappingName()
110 {
111 return _mappingName;
112 }
113
114
115
116 public void setMappingName(String mappingName)
117 {
118 this._mappingName = mappingName;
119 }
120
121
122
123
124 public Member getTarget()
125 {
126 return _target;
127 }
128
129
130
131
132
133
134
135
136 public void setTarget (String className, String fieldName, String annotationResourceType)
137 {
138 _className = className;
139 _fieldName = fieldName;
140 _annotationResourceType = annotationResourceType;
141 }
142
143 public void setTarget (String className, String methodName, String paramCanonicalName, String annotationResourceType)
144 {
145 _className = className;
146 _methodName = methodName;
147 _paramCanonicalName = paramCanonicalName;
148 _annotationResourceType = annotationResourceType;
149 }
150
151
152 public void setTarget (Class clazz, String targetName, Class targetType)
153 {
154
155 String setter = "set"+targetName.substring(0,1).toUpperCase()+targetName.substring(1);
156 try
157 {
158 Log.debug("Looking for method for setter: "+setter+" with arg "+targetType);
159 _target = IntrospectionUtil.findMethod(clazz, setter, new Class[] {targetType}, true, false);
160 _targetClass = clazz;
161 _className = clazz.getCanonicalName();
162 _methodName = targetName;
163 _paramCanonicalName = targetType.getCanonicalName();
164 }
165 catch (NoSuchMethodException me)
166 {
167
168 try
169 {
170 _target = IntrospectionUtil.findField(clazz, targetName, targetType, true, false);
171 _targetClass = clazz;
172 _className = clazz.getCanonicalName();
173 _fieldName = targetName;
174 }
175 catch (NoSuchFieldException fe)
176 {
177 throw new IllegalArgumentException("No such field or method "+targetName+" on class "+_targetClass);
178 }
179 }
180 }
181
182
183
184
185
186
187
188 public void inject (Object injectable)
189 {
190 try
191 {
192 if (_target == null)
193 loadField();
194
195 if (_target == null)
196 loadMethod();
197 }
198 catch (Exception e)
199 {
200 throw new IllegalStateException (e);
201 }
202
203 if (_target != null)
204 {
205 if (_target instanceof Field)
206 injectField((Field)_target, injectable);
207 else
208 injectMethod((Method)_target, injectable);
209 }
210 else
211 throw new IllegalStateException ("No method or field to inject with "+getJndiName());
212 }
213
214
215
216
217
218
219
220 public Object lookupInjectedValue ()
221 throws NamingException
222 {
223 InitialContext context = new InitialContext();
224 return context.lookup("java:comp/env/"+getJndiName());
225 }
226
227
228
229
230
231
232
233
234 protected void injectField (Field field, Object injectable)
235 {
236 if (validateInjection())
237 {
238 try
239 {
240 boolean accessibility = field.isAccessible();
241 field.setAccessible(true);
242 field.set(injectable, lookupInjectedValue());
243 field.setAccessible(accessibility);
244 }
245 catch (Exception e)
246 {
247 Log.warn(e);
248 throw new IllegalStateException("Inject failed for field "+field.getName());
249 }
250 }
251 else
252 throw new IllegalStateException ("Invalid injection for "+_className+"."+_fieldName);
253 }
254
255
256
257
258
259
260 protected void injectMethod (Method method, Object injectable)
261 {
262 if (validateInjection())
263 {
264 try
265 {
266 boolean accessibility = method.isAccessible();
267 method.setAccessible(true);
268 method.invoke(injectable, new Object[] {lookupInjectedValue()});
269 method.setAccessible(accessibility);
270 }
271 catch (Exception e)
272 {
273 Log.warn(e);
274 throw new IllegalStateException("Inject failed for method "+method.getName());
275 }
276 }
277 else
278 throw new IllegalStateException("Invalid injection for "+_className+"."+_methodName);
279 }
280
281
282
283 protected void loadField()
284 throws ClassNotFoundException, NoSuchFieldException
285 {
286 if (_fieldName == null || _className == null)
287 return;
288
289 if (_targetClass == null)
290 _targetClass = Loader.loadClass(null, _className);
291
292 _target = _targetClass.getDeclaredField(_fieldName);
293 }
294
295
296
297
298
299
300
301
302 protected void loadMethod ()
303 throws ClassNotFoundException, NoSuchMethodException
304 {
305 if (_methodName == null || _className == null)
306 return;
307
308 if (_targetClass == null)
309 _targetClass = Loader.loadClass(null, _className);
310
311 Class arg = TypeUtil.fromName(_paramCanonicalName);
312
313 if (arg == null)
314 arg = Loader.loadClass(null, _paramCanonicalName);
315
316 _target = _targetClass.getDeclaredMethod(_methodName, new Class[] {arg});
317 }
318
319
320 private boolean validateInjection ()
321 {
322
323
324
325
326 if (_annotationResourceType != null)
327 {
328 if (_target == null)
329 return false;
330
331 try
332 {
333 Class<?> annotationType = TypeUtil.fromName(_annotationResourceType);
334 if (annotationType == null)
335 annotationType = Loader.loadClass(null, _annotationResourceType);
336
337 if (_target instanceof Field)
338 {
339 return ((Field)_target).getType().isAssignableFrom(annotationType);
340 }
341 else if (_target instanceof Method)
342 {
343 Class<?>[] args = ((Method)_target).getParameterTypes();
344 return args[0].isAssignableFrom(annotationType);
345 }
346
347 return false;
348 }
349 catch (Exception e)
350 {
351 Log.warn("Unable to verify injection for "+_className+"."+ (_fieldName==null?_methodName:_fieldName));
352 return false;
353 }
354 }
355 else
356 return true;
357 }
358 }