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