1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.annotations;
20
21 import java.lang.reflect.Field;
22 import java.lang.reflect.Method;
23 import java.lang.reflect.Modifier;
24 import java.util.Locale;
25
26 import javax.annotation.Resource;
27 import javax.naming.InitialContext;
28 import javax.naming.NameNotFoundException;
29 import javax.naming.NamingException;
30
31 import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
32 import org.eclipse.jetty.plus.annotation.Injection;
33 import org.eclipse.jetty.plus.annotation.InjectionCollection;
34 import org.eclipse.jetty.util.log.Log;
35 import org.eclipse.jetty.util.log.Logger;
36 import org.eclipse.jetty.webapp.MetaData;
37 import org.eclipse.jetty.webapp.WebAppContext;
38
39 public class ResourceAnnotationHandler extends AbstractIntrospectableAnnotationHandler
40 {
41 private static final Logger LOG = Log.getLogger(ResourceAnnotationHandler.class);
42
43 protected WebAppContext _context;
44
45
46 public ResourceAnnotationHandler (WebAppContext wac)
47 {
48 super(true);
49 _context = wac;
50 }
51
52
53
54
55
56
57
58 public void doHandle(Class<?> clazz)
59 {
60 if (Util.supportsResourceInjection(clazz))
61 {
62 handleClass(clazz);
63
64 Method[] methods = clazz.getDeclaredMethods();
65 for (int i=0; i<methods.length; i++)
66 handleMethod(clazz, methods[i]);
67 Field[] fields = clazz.getDeclaredFields();
68
69 for (int i=0; i<fields.length; i++)
70 handleField(clazz, fields[i]);
71 }
72 }
73
74 public void handleClass (Class<?> clazz)
75 {
76 Resource resource = (Resource)clazz.getAnnotation(Resource.class);
77 if (resource != null)
78 {
79 String name = resource.name();
80 String mappedName = resource.mappedName();
81
82 if (name==null || name.trim().equals(""))
83 throw new IllegalStateException ("Class level Resource annotations must contain a name (Common Annotations Spec Section 2.3)");
84
85 try
86 {
87 if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name,mappedName))
88 if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name,mappedName))
89 throw new IllegalStateException("No resource at "+(mappedName==null?name:mappedName));
90 }
91 catch (NamingException e)
92 {
93 LOG.warn(e);
94 }
95 }
96 }
97
98 public void handleField(Class<?> clazz, Field field)
99 {
100 Resource resource = (Resource)field.getAnnotation(Resource.class);
101 if (resource != null)
102 {
103
104 if (Modifier.isStatic(field.getModifiers()))
105 {
106 LOG.warn("Skipping Resource annotation on "+clazz.getName()+"."+field.getName()+": cannot be static");
107 return;
108 }
109
110
111 if (Modifier.isFinal(field.getModifiers()))
112 {
113 LOG.warn("Skipping Resource annotation on "+clazz.getName()+"."+field.getName()+": cannot be final");
114 return;
115 }
116
117
118 String name = clazz.getCanonicalName()+"/"+field.getName();
119
120
121 name = (resource.name()!=null && !resource.name().trim().equals("")? resource.name(): name);
122 String mappedName = (resource.mappedName()!=null && !resource.mappedName().trim().equals("")?resource.mappedName():null);
123
124 Class<?> type = field.getType();
125
126
127
128
129 MetaData metaData = _context.getMetaData();
130 if (metaData.getOriginDescriptor("resource-ref."+name+".injection") != null)
131 {
132
133
134 return;
135 }
136
137
138
139 InjectionCollection injections = (InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
140 if (injections == null)
141 {
142 injections = new InjectionCollection();
143 _context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
144 }
145 Injection injection = injections.getInjection(name, clazz, field);
146 if (injection == null)
147 {
148
149 try
150 {
151 boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName);
152 if (!bound)
153 bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName);
154 if (!bound)
155 bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(null, name, mappedName);
156 if (!bound)
157 {
158
159 try
160 {
161 InitialContext ic = new InitialContext();
162 String nameInEnvironment = (mappedName!=null?mappedName:name);
163 ic.lookup("java:comp/env/"+nameInEnvironment);
164 bound = true;
165 }
166 catch (NameNotFoundException e)
167 {
168 bound = false;
169 }
170 }
171
172 if (bound)
173 {
174 LOG.debug("Bound "+(mappedName==null?name:mappedName) + " as "+ name);
175
176 injection = new Injection();
177 injection.setTarget(clazz, field, type);
178 injection.setJndiName(name);
179 injection.setMappingName(mappedName);
180 injections.add(injection);
181
182
183 metaData.setOrigin("resource-ref."+name+".injection",resource,clazz);
184 }
185 else if (!Util.isEnvEntryType(type))
186 {
187
188
189
190
191 throw new IllegalStateException("No resource at "+(mappedName==null?name:mappedName));
192 }
193 }
194 catch (NamingException e)
195 {
196
197
198
199 if (!Util.isEnvEntryType(type))
200 throw new IllegalStateException(e);
201 }
202 }
203 }
204 }
205
206
207
208
209
210
211
212
213
214
215
216 public void handleMethod(Class<?> clazz, Method method)
217 {
218
219 Resource resource = (Resource)method.getAnnotation(Resource.class);
220 if (resource != null)
221 {
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240 if (Modifier.isStatic(method.getModifiers()))
241 {
242 LOG.warn("Skipping Resource annotation on "+clazz.getName()+"."+method.getName()+": cannot be static");
243 return;
244 }
245
246
247
248 if (!method.getName().startsWith("set"))
249 {
250 LOG.warn("Skipping Resource annotation on "+clazz.getName()+"."+method.getName()+": invalid java bean, does not start with 'set'");
251 return;
252 }
253
254 if (method.getParameterTypes().length != 1)
255 {
256 LOG.warn("Skipping Resource annotation on "+clazz.getName()+"."+method.getName()+": invalid java bean, not single argument to method");
257 return;
258 }
259
260 if (Void.TYPE != method.getReturnType())
261 {
262 LOG.warn("Skipping Resource annotation on "+clazz.getName()+"."+method.getName()+": invalid java bean, not void");
263 return;
264 }
265
266
267
268 String name = method.getName().substring(3);
269 name = name.substring(0,1).toLowerCase(Locale.ENGLISH)+name.substring(1);
270 name = clazz.getCanonicalName()+"/"+name;
271
272 name = (resource.name()!=null && !resource.name().trim().equals("")? resource.name(): name);
273 String mappedName = (resource.mappedName()!=null && !resource.mappedName().trim().equals("")?resource.mappedName():null);
274 Class<?> paramType = method.getParameterTypes()[0];
275
276 Class<?> resourceType = resource.type();
277
278
279
280
281 MetaData metaData = _context.getMetaData();
282 if (metaData.getOriginDescriptor("resource-ref."+name+".injection") != null)
283 {
284
285
286 return;
287 }
288
289
290 InjectionCollection injections = (InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
291 if (injections == null)
292 {
293 injections = new InjectionCollection();
294 _context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
295 }
296 Injection injection = injections.getInjection(name, clazz, method, paramType);
297 if (injection == null)
298 {
299 try
300 {
301
302
303 boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName);
304
305
306 if (!bound)
307 bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName);
308
309
310 if (!bound)
311 bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(null, name, mappedName);
312
313
314
315 if (!bound)
316 {
317 try
318 {
319 InitialContext ic = new InitialContext();
320 String nameInEnvironment = (mappedName!=null?mappedName:name);
321 ic.lookup("java:comp/env/"+nameInEnvironment);
322 bound = true;
323 }
324 catch (NameNotFoundException e)
325 {
326 bound = false;
327 }
328 }
329
330 if (bound)
331 {
332 LOG.debug("Bound "+(mappedName==null?name:mappedName) + " as "+ name);
333
334 injection = new Injection();
335 injection.setTarget(clazz, method,paramType,resourceType);
336 injection.setJndiName(name);
337 injection.setMappingName(mappedName);
338 injections.add(injection);
339
340 metaData.setOrigin("resource-ref."+name+".injection",resource,clazz);
341 }
342 else if (!Util.isEnvEntryType(paramType))
343 {
344
345
346
347
348 throw new IllegalStateException("No resource at "+(mappedName==null?name:mappedName));
349 }
350 }
351 catch (NamingException e)
352 {
353
354
355
356 if (!Util.isEnvEntryType(paramType))
357 throw new IllegalStateException(e);
358 }
359 }
360
361 }
362 }
363 }