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