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
350 protected void initInjection (XmlParser.Node node, String jndiName, Class valueClass)
351 {
352 Iterator itor = node.iterator("injection-target");
353
354 while(itor.hasNext())
355 {
356 XmlParser.Node injectionNode = (XmlParser.Node)itor.next();
357 String targetClassName = injectionNode.getString("injection-target-class", false, true);
358 String targetName = injectionNode.getString("injection-target-name", false, true);
359 if ((targetClassName==null) || targetClassName.equals(""))
360 {
361 Log.warn("No classname found in injection-target");
362 continue;
363 }
364 if ((targetName==null) || targetName.equals(""))
365 {
366 Log.warn("No field or method name in injection-target");
367 continue;
368 }
369
370 InjectionCollection injections = (InjectionCollection)_context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
371
372
373 try
374 {
375 Class clazz = _context.loadClass(targetClassName);
376 Injection injection = new Injection();
377 injection.setJndiName(jndiName);
378 injection.setTarget(clazz, targetName, valueClass);
379 injections.add(injection);
380 }
381 catch (ClassNotFoundException e)
382 {
383 Log.warn("Couldn't load injection target class "+targetClassName);
384 }
385 }
386 }
387 }
388
389
390
391 public void preConfigure (WebAppContext context)
392 throws Exception
393 {
394
395 ServletHandler servletHandler = new ServletHandler();
396 SecurityHandler securityHandler = context.getSecurityHandler();
397 org.eclipse.jetty.servlet.ServletHandler existingHandler = context.getServletHandler();
398 servletHandler.setFilters(existingHandler.getFilters());
399 servletHandler.setFilterMappings(existingHandler.getFilterMappings());
400 servletHandler.setServlets(existingHandler.getServlets());
401 servletHandler.setServletMappings(existingHandler.getServletMappings());
402 context.setServletHandler(servletHandler);
403 securityHandler.setHandler(servletHandler);
404
405 LifeCycleCallbackCollection callbacks = new LifeCycleCallbackCollection();
406 context.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, callbacks);
407 InjectionCollection injections = new InjectionCollection();
408 context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
409 RunAsCollection runAsCollection = new RunAsCollection();
410 context.setAttribute(RunAsCollection.RUNAS_COLLECTION, runAsCollection);
411 }
412
413 public void postConfigure(WebAppContext context) throws Exception
414 {
415 context.setAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION, null);
416 context.setAttribute(InjectionCollection.INJECTION_COLLECTION, null);
417 context.setAttribute(RunAsCollection.RUNAS_COLLECTION, null);
418 }
419
420 public void configure (WebAppContext context)
421 throws Exception
422 {
423 bindUserTransaction(context);
424
425 WebXmlProcessor webXmlProcessor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.WEB_PROCESSOR);
426 if (webXmlProcessor == null)
427 throw new IllegalStateException ("No processor for web xml");
428
429
430
431 PlusWebXmlProcessor plusProcessor = new PlusWebXmlProcessor(context);
432 plusProcessor.process(webXmlProcessor.getWebDefault());
433 plusProcessor.process(webXmlProcessor.getWebXml());
434
435
436 for (Descriptor frag: webXmlProcessor.getFragments())
437 {
438 plusProcessor.process(frag);
439 }
440
441
442 plusProcessor.process(webXmlProcessor.getOverrideWeb());
443
444
445
446
447 ((ServletHandler)context.getServletHandler()).setInjections((InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION));
448 ((ServletHandler)context.getServletHandler()).setCallbacks((LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION));
449
450
451
452 injectAndCallPostConstructCallbacks(context);
453 }
454
455 public void deconfigure (WebAppContext context)
456 throws Exception
457 {
458
459 callPreDestroyCallbacks(context);
460 }
461
462
463
464 protected void injectAndCallPostConstructCallbacks(WebAppContext context)
465 throws Exception
466 {
467 InjectionCollection injections = (InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
468 RunAsCollection runAsCollection = (RunAsCollection)context.getAttribute(RunAsCollection.RUNAS_COLLECTION);
469 LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
470 SecurityHandler securityHandler = context.getSecurityHandler();
471
472
473
474 if (runAsCollection != null)
475 {
476 ServletHolder[] holders = context.getServletHandler().getServlets();
477 for (int i=0;holders!=null && i<holders.length;i++)
478 {
479 runAsCollection.setRunAs(holders[i], securityHandler);
480 }
481 }
482
483 EventListener[] listeners = context.getEventListeners();
484 for (int i=0;listeners!=null && i<listeners.length;i++)
485 {
486 if (injections != null)
487 injections.inject(listeners[i]);
488 if (callbacks != null)
489 callbacks.callPostConstructCallback(listeners[i]);
490 }
491 }
492
493
494 protected void callPreDestroyCallbacks (WebAppContext context)
495 throws Exception
496 {
497 LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)context.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
498
499 if (callbacks != null)
500 {
501 EventListener[] listeners = context.getEventListeners();
502 for (int i=0; listeners!=null && i<listeners.length;i++)
503 {
504 callbacks.callPreDestroyCallback(listeners[i]);
505 }
506 }
507 }
508
509 }