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