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
192 public void handleMethod(String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation,
193 List<Value> values)
194 {
195 try
196 {
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 if ((access & org.objectweb.asm.Opcodes.ACC_STATIC) > 0)
217 {
218 Log.warn("Skipping Resource annotation on "+className+"."+methodName+": cannot be static");
219 return;
220 }
221
222
223
224 if (!methodName.startsWith("set"))
225 {
226 Log.warn("Skipping Resource annotation on "+className+"."+methodName+": invalid java bean, does not start with 'set'");
227 return;
228 }
229 org.objectweb.asm.Type[] args = org.objectweb.asm.Type.getArgumentTypes(desc);
230 if (args == null || args.length != 1)
231 {
232 Log.warn("Skipping Resource annotation on "+className+"."+methodName+": invalid java bean, not single argument to method");
233 return;
234 }
235 org.objectweb.asm.Type retVal = org.objectweb.asm.Type.getReturnType(desc);
236 if (!org.objectweb.asm.Type.VOID_TYPE.equals(retVal))
237 {
238 Log.warn("Skipping Resource annotation on "+className+"."+methodName+": invalid java bean, not void");
239 return;
240 }
241
242
243
244 String name = methodName.substring(3);
245 name = name.substring(0,1).toLowerCase()+name.substring(1);
246 name = className+"/"+name;
247 String mappedName = null;
248 org.objectweb.asm.Type resourceType = null;
249 if (values != null)
250 {
251 for (Value v : values)
252 {
253
254 if ("name".equals(v.getName()))
255 name = (String)(v.getValue());
256
257 else if ("mappedName".equals(v.getName()) && !"".equals((String)(v.getValue())))
258 mappedName = (String)(v.getValue());
259 else if ("type".equals(v.getName()))
260 {
261 resourceType = (org.objectweb.asm.Type)(v.getValue());
262 }
263
264 }
265 }
266
267
268 Injection webXmlInjection = _injections.getInjection(name, className, methodName, Util.asCanonicalName(args[0]));
269 if (webXmlInjection == null)
270 {
271 try
272 {
273
274
275 boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac, name, mappedName);
276
277
278 if (!bound)
279 bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac.getServer(), name, mappedName);
280
281
282 if (!bound)
283 bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(null, name, mappedName);
284
285
286
287 if (!bound)
288 {
289 try
290 {
291 InitialContext ic = new InitialContext();
292 String nameInEnvironment = (mappedName!=null?mappedName:name);
293 ic.lookup("java:comp/env/"+nameInEnvironment);
294 bound = true;
295 }
296 catch (NameNotFoundException e)
297 {
298 bound = false;
299 }
300 }
301
302 if (bound)
303 {
304 Log.debug("Bound "+(mappedName==null?name:mappedName) + " as "+ name);
305
306 Injection injection = new Injection();
307 injection.setTarget(className, methodName, Util.asCanonicalName(args[0]), Util.asCanonicalName(resourceType));
308 injection.setJndiName(name);
309 injection.setMappingName(mappedName);
310 _injections.add(injection);
311 }
312 else if (!Util.isEnvEntryType(args[0].getDescriptor()))
313 {
314
315
316
317
318 throw new IllegalStateException("No resource at "+(mappedName==null?name:mappedName));
319 }
320 }
321 catch (NamingException e)
322 {
323
324
325
326 if (!Util.isEnvEntryType(args[0].getDescriptor()))
327 throw new IllegalStateException(e);
328 }
329 }
330 }
331 catch (Exception e)
332 {
333 Log.warn(e);
334 }
335 }
336 }