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