1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.plus.webapp;
15
16
17 import java.util.EventListener;
18 import java.util.Iterator;
19
20 import javax.servlet.UnavailableException;
21
22 import org.eclipse.jetty.plus.annotation.Injection;
23 import org.eclipse.jetty.plus.annotation.InjectionCollection;
24 import org.eclipse.jetty.plus.annotation.LifeCycleCallback;
25 import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
26 import org.eclipse.jetty.plus.annotation.PostConstructCallback;
27 import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
28 import org.eclipse.jetty.plus.annotation.RunAsCollection;
29 import org.eclipse.jetty.plus.servlet.ServletHandler;
30 import org.eclipse.jetty.security.SecurityHandler;
31 import org.eclipse.jetty.servlet.ServletHolder;
32 import org.eclipse.jetty.util.TypeUtil;
33 import org.eclipse.jetty.util.log.Log;
34 import org.eclipse.jetty.webapp.Configuration;
35 import org.eclipse.jetty.webapp.WebAppContext;
36 import org.eclipse.jetty.webapp.WebXmlProcessor;
37 import org.eclipse.jetty.xml.XmlParser;
38
39
40
41
42
43
44
45
46 public abstract class AbstractConfiguration implements Configuration
47 {
48 public abstract void bindEnvEntry (WebAppContext context, String name, Object value) throws Exception;
49
50 public abstract void bindResourceRef (WebAppContext context, String name, Class type) throws Exception;
51
52 public abstract void bindResourceEnvRef (WebAppContext context, String name, Class type) throws Exception;
53
54 public abstract void bindUserTransaction (WebAppContext context) throws Exception;
55
56 public abstract void bindMessageDestinationRef (WebAppContext context, String name, Class type) throws Exception;
57
58 protected abstract void parseAnnotations (WebAppContext context) throws Exception;
59
60
61 public class PlusWebXmlProcessor
62 {
63 WebAppContext _context;
64
65 public PlusWebXmlProcessor (WebAppContext context)
66 {
67 _context = context;
68 }
69
70
71 public void process (XmlParser.Node root)
72 throws Exception
73 {
74 if (root == null)
75 return;
76
77
78 Iterator iter = root.iterator();
79 XmlParser.Node node = null;
80 while (iter.hasNext())
81 {
82 try
83 {
84 Object o = iter.next();
85 if (!(o instanceof XmlParser.Node)) continue;
86 node = (XmlParser.Node) o;
87 String name = node.getTag();
88 initWebXmlElement(name, node);
89 }
90 catch (ClassNotFoundException e)
91 {
92 throw e;
93 }
94 catch (Exception e)
95 {
96 Log.warn("Configuration problem at " + node, e);
97 throw new UnavailableException("Configuration problem");
98 }
99 }
100 }
101
102 protected void initWebXmlElement(String element,XmlParser.Node node) throws Exception
103 {
104 if ("env-entry".equals(element))
105 {
106 initEnvEntry (node);
107 }
108 else if ("resource-ref".equals(element))
109 {
110
111
112
113
114
115
116 initResourceRef(node);
117 }
118 else if ("resource-env-ref".equals(element))
119 {
120
121
122
123
124
125 initResourceEnvRef(node);
126 }
127 else if ("message-destination-ref".equals(element))
128 {
129 initMessageDestinationRef(node);
130 }
131 else if ("post-construct".equals(element))
132 {
133
134
135 initPostConstruct(node);
136 }
137 else if ("pre-destroy".equals(element))
138 {
139
140
141 initPreDestroy(node);
142 }
143 }
144
145
146
147
148
149
150
151
152 protected void initEnvEntry (XmlParser.Node node)
153 throws Exception
154 {
155 String name=node.getString("env-entry-name",false,true);
156 String type = node.getString("env-entry-type",false,true);
157 String valueStr = node.getString("env-entry-value",false,true);
158
159
160
161 if (valueStr==null || valueStr.equals(""))
162 {
163 Log.warn("No value for env-entry-name "+name);
164 return;
165 }
166
167
168
169
170
171
172
173
174 initInjection (node, name, TypeUtil.fromName(type));
175
176
177 Object value = TypeUtil.valueOf(type,valueStr);
178 bindEnvEntry(_context, name, value);
179
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 protected void initResourceRef (XmlParser.Node node)
199 throws Exception
200 {
201 String jndiName = node.getString("res-ref-name",false,true);
202 String type = node.getString("res-type", false, true);
203 String auth = node.getString("res-auth", false, true);
204 String shared = node.getString("res-sharing-scope", false, true);
205
206
207 Class typeClass = TypeUtil.fromName(type);
208 if (typeClass==null)
209 typeClass = _context.loadClass(type);
210 initInjection (node, jndiName, typeClass);
211
212 bindResourceRef(_context, jndiName, typeClass);
213 }
214
215
216
217
218
219
220
221
222
223
224
225 protected void initResourceEnvRef (XmlParser.Node node)
226 throws Exception
227 {
228 String jndiName = node.getString("resource-env-ref-name",false,true);
229 String type = node.getString("resource-env-ref-type", false, true);
230
231
232
233
234
235 Class typeClass = TypeUtil.fromName(type);
236 if (typeClass==null)
237 typeClass = _context.loadClass(type);
238 initInjection (node, jndiName, typeClass);
239
240 bindResourceEnvRef(_context, jndiName, typeClass);
241 }
242
243
244
245
246
247
248
249
250
251
252 protected void initMessageDestinationRef (XmlParser.Node node)
253 throws Exception
254 {
255 String jndiName = node.getString("message-destination-ref-name",false,true);
256 String type = node.getString("message-destination-type",false,true);
257 String usage = node.getString("message-destination-usage",false,true);
258
259 Class typeClass = TypeUtil.fromName(type);
260 if (typeClass==null)
261 typeClass = _context.loadClass(type);
262 initInjection(node, jndiName, typeClass);
263
264 bindMessageDestinationRef(_context, jndiName, typeClass);
265 }
266
267
268
269
270
271
272
273 protected void initPostConstruct(XmlParser.Node node)
274 {
275 String className = node.getString("lifecycle-callback-class", false, true);
276 String methodName = node.getString("lifecycle-callback-method", false, true);
277
278 if (className==null || className.equals(""))
279 {
280 Log.warn("No lifecycle-callback-class specified");
281 return;
282 }
283 if (methodName==null || methodName.equals(""))
284 {
285 Log.warn("No lifecycle-callback-method specified for class "+className);
286 return;
287 }
288
289 LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
290 try
291 {
292 Class clazz = _context.loadClass(className);
293 LifeCycleCallback callback = new PostConstructCallback();
294 callback.setTarget(clazz, methodName);
295 callbacks.add(callback);
296 }
297 catch (ClassNotFoundException e)
298 {
299 Log.warn("Couldn't load post-construct target class "+className);
300 }
301 }
302
303
304
305
306
307
308 protected void initPreDestroy(XmlParser.Node node)
309 {
310 String className = node.getString("lifecycle-callback-class", false, true);
311 String methodName = node.getString("lifecycle-callback-method", false, true);
312 if (className==null || className.equals(""))
313 {
314 Log.warn("No lifecycle-callback-class specified for pre-destroy");
315 return;
316 }
317 if (methodName==null || methodName.equals(""))
318 {
319 Log.warn("No lifecycle-callback-method specified for pre-destroy class "+className);
320 return;
321 }
322 LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)_context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
323 try
324 {
325 Class clazz = _context.loadClass(className);
326 LifeCycleCallback callback = new PreDestroyCallback();
327 callback.setTarget(clazz, methodName);
328 callbacks.add(callback);
329 }
330 catch (ClassNotFoundException e)
331 {
332 Log.warn("Couldn't load pre-destory target class "+className);
333 }
334 }
335
336
337
338
339
340
341
342
343
344
345 protected void initInjection (XmlParser.Node node, String jndiName, Class valueClass)
346 {
347 Iterator itor = node.iterator("injection-target");
348
349 while(itor.hasNext())
350 {
351 XmlParser.Node injectionNode = (XmlParser.Node)itor.next();
352 String targetClassName = injectionNode.getString("injection-target-class", false, true);
353 String targetName = injectionNode.getString("injection-target-name", false, true);
354 if ((targetClassName==null) || targetClassName.equals(""))
355 {
356 Log.warn("No classname found in injection-target");
357 continue;
358 }
359 if ((targetName==null) || targetName.equals(""))
360 {
361 Log.warn("No field or method name in injection-target");
362 continue;
363 }
364
365 InjectionCollection injections = (InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
366
367
368 try
369 {
370 Class clazz = _context.loadClass(targetClassName);
371 Injection injection = new Injection();
372 injection.setTargetClass(clazz);
373 injection.setJndiName(jndiName);
374 injection.setTarget(clazz, targetName, valueClass);
375 injections.add(injection);
376 }
377 catch (ClassNotFoundException e)
378 {
379 Log.warn("Couldn't load injection target class "+targetClassName);
380 }
381 }
382 }
383 }
384
385
386
387 public void preConfigure (WebAppContext context)
388 throws Exception
389 {
390
391 ServletHandler servletHandler = new ServletHandler();
392 SecurityHandler securityHandler = context.getSecurityHandler();
393 org.eclipse.jetty.servlet.ServletHandler existingHandler = context.getServletHandler();
394 servletHandler.setFilterMappings(existingHandler.getFilterMappings());
395 servletHandler.setFilters(existingHandler.getFilters());
396 servletHandler.setServlets(existingHandler.getServlets());
397 servletHandler.setServletMappings(existingHandler.getServletMappings());
398 context.setServletHandler(servletHandler);
399 securityHandler.setHandler(servletHandler);
400
401 LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
402 context.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, callbacks);
403 InjectionCollection injections = new InjectionCollection();
404 context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
405 RunAsCollection runAsCollection = new RunAsCollection();
406 context.setAttribute(RunAsCollection.RUNAS_COLLECTION, runAsCollection);
407 }
408
409 public void configure (WebAppContext context)
410 throws Exception
411 {
412 bindUserTransaction(context);
413
414 WebXmlProcessor webXmlProcessor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
415 if (webXmlProcessor == null)
416 throw new IllegalStateException ("No processor for web xml");
417
418
419
420 PlusWebXmlProcessor plusProcessor = new PlusWebXmlProcessor(context);
421 plusProcessor.process(webXmlProcessor.getWebDefault());
422 plusProcessor.process(webXmlProcessor.getWebXml());
423
424
425 for (XmlParser.Node frag: webXmlProcessor.getFragments())
426 plusProcessor.process(frag);
427
428 plusProcessor.process(webXmlProcessor.getOverrideWeb());
429
430
431
432 if (!webXmlProcessor.isMetaDataComplete())
433 {
434 if (Log.isDebugEnabled()) Log.debug("Processing annotations");
435 parseAnnotations(context);
436 }
437
438
439
440 ((ServletHandler)context.getServletHandler()).setInjections((InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION));
441 ((ServletHandler)context.getServletHandler()).setCallbacks((LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION));
442
443
444
445 injectAndCallPostConstructCallbacks(context);
446 }
447
448 public void deconfigure (WebAppContext context)
449 throws Exception
450 {
451
452 callPreDestroyCallbacks(context);
453 }
454
455
456
457 protected void injectAndCallPostConstructCallbacks(WebAppContext context)
458 throws Exception
459 {
460 InjectionCollection injections = (InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
461 RunAsCollection runAsCollection = (RunAsCollection)context.getAttribute(RunAsCollection.RUNAS_COLLECTION);
462 LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
463 SecurityHandler securityHandler = context.getSecurityHandler();
464
465
466
467 if (runAsCollection != null)
468 {
469 ServletHolder[] holders = context.getServletHandler().getServlets();
470 for (int i=0;holders!=null && i<holders.length;i++)
471 {
472 runAsCollection.setRunAs(holders[i], securityHandler);
473 }
474 }
475
476 EventListener[] listeners = context.getEventListeners();
477 for (int i=0;listeners!=null && i<listeners.length;i++)
478 {
479 if (injections != null)
480 injections.inject(listeners[i]);
481 if (callbacks != null)
482 callbacks.callPostConstructCallback(listeners[i]);
483 }
484 }
485
486
487 protected void callPreDestroyCallbacks (WebAppContext context)
488 throws Exception
489 {
490 LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
491
492 if (callbacks != null)
493 {
494 EventListener[] listeners = context.getEventListeners();
495 for (int i=0; listeners!=null && i<listeners.length;i++)
496 {
497 callbacks.callPreDestroyCallback(listeners[i]);
498 }
499 }
500 }
501
502 }