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