1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.webapp;
20
21 import java.io.IOException;
22 import java.net.URI;
23 import java.net.URL;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.EventListener;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.Set;
34
35 import javax.servlet.Servlet;
36 import javax.servlet.ServletContextEvent;
37 import javax.servlet.ServletContextListener;
38
39 import org.eclipse.jetty.util.Loader;
40 import org.eclipse.jetty.util.log.Log;
41 import org.eclipse.jetty.util.log.Logger;
42 import org.eclipse.jetty.util.resource.Resource;
43 import org.eclipse.jetty.xml.XmlParser;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class TagLibConfiguration extends AbstractConfiguration
65 {
66 private static final Logger LOG = Log.getLogger(TagLibConfiguration.class);
67
68 public static final String TLD_RESOURCES = "org.eclipse.jetty.tlds";
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 public class TagLibListener implements ServletContextListener {
87 private List<EventListener> _tldListeners;
88 private WebAppContext _context;
89
90 public TagLibListener (WebAppContext context) {
91 _context = context;
92 }
93
94 public void contextDestroyed(ServletContextEvent sce)
95 {
96 if (_tldListeners == null)
97 return;
98
99 for (int i=_tldListeners.size()-1; i>=0; i--) {
100 EventListener l = _tldListeners.get(i);
101 if (l instanceof ServletContextListener) {
102 ((ServletContextListener)l).contextDestroyed(sce);
103 }
104 }
105 }
106
107 public void contextInitialized(ServletContextEvent sce)
108 {
109 try
110 {
111
112
113 try
114 {
115
116 ClassLoader loader = _context.getClassLoader();
117 if (loader == null || loader.getParent() == null)
118 loader = getClass().getClassLoader();
119 else
120 loader = loader.getParent();
121 Class<?> clazz = loader.loadClass("org.apache.jasper.compiler.TldLocationsCache");
122 assert clazz!=null;
123 Collection<Resource> tld_resources = (Collection<Resource>)_context.getAttribute(TLD_RESOURCES);
124
125 Map<URI, List<String>> tldMap = new HashMap<URI, List<String>>();
126
127 if (tld_resources != null)
128 {
129
130 for (Resource r:tld_resources)
131 {
132 Resource jarResource = extractJarResource(r);
133
134 if (!tldMap.containsKey(jarResource.getURI()))
135 tldMap.put(jarResource.getURI(), null);
136
137 }
138
139 sce.getServletContext().setAttribute("com.sun.appserv.tld.map", tldMap);
140 }
141 }
142 catch (ClassNotFoundException e)
143 {
144 LOG.ignore(e);
145 }
146
147
148
149 Set<Resource> tlds = findTldResources();
150 List<TldDescriptor> descriptors = parseTlds(tlds);
151 processTlds(descriptors);
152
153 if (_tldListeners == null)
154 return;
155
156
157
158
159 for (EventListener l:_tldListeners) {
160 if (l instanceof ServletContextListener) {
161 ((ServletContextListener)l).contextInitialized(sce);
162 } else {
163 _context.addEventListener(l);
164 }
165 }
166
167 }
168 catch (Exception e) {
169 LOG.warn(e);
170 }
171 }
172
173
174
175
176 private Resource extractJarResource (Resource r)
177 {
178 if (r == null)
179 return null;
180
181 try
182 {
183 String url = r.getURI().toURL().toString();
184 int idx = url.lastIndexOf("!/");
185 if (idx >= 0)
186 url = url.substring(0, idx);
187 if (url.startsWith("jar:"))
188 url = url.substring(4);
189 return Resource.newResource(url);
190 }
191 catch (IOException e)
192 {
193 LOG.warn(e);
194 return null;
195 }
196 }
197
198
199
200
201
202
203
204
205
206 private Set<Resource> findTldResources () throws IOException {
207
208 Set<Resource> tlds = new HashSet<Resource>();
209
210
211
212
213 if (_context.getResourceAliases()!=null &&
214 _context.getBaseResource()!=null &&
215 _context.getBaseResource().exists())
216 {
217 Iterator<String> iter=_context.getResourceAliases().values().iterator();
218 while(iter.hasNext())
219 {
220 String location = iter.next();
221 if (location!=null && location.toLowerCase(Locale.ENGLISH).endsWith(".tld"))
222 {
223 if (!location.startsWith("/"))
224 location="/WEB-INF/"+location;
225 Resource l=_context.getBaseResource().addPath(location);
226 tlds.add(l);
227 }
228 }
229 }
230
231
232 Resource web_inf = _context.getWebInf();
233 if (web_inf!=null)
234 {
235 String[] contents = web_inf.list();
236 for (int i=0;contents!=null && i<contents.length;i++)
237 {
238 if (contents[i]!=null && contents[i].toLowerCase(Locale.ENGLISH).endsWith(".tld"))
239 {
240 Resource l=web_inf.addPath(contents[i]);
241 tlds.add(l);
242 }
243 }
244 }
245
246
247 if (web_inf != null) {
248 Resource web_inf_tlds = _context.getWebInf().addPath("/tlds/");
249 if (web_inf_tlds.exists() && web_inf_tlds.isDirectory()) {
250 String[] contents = web_inf_tlds.list();
251 for (int i=0;contents!=null && i<contents.length;i++)
252 {
253 if (contents[i]!=null && contents[i].toLowerCase(Locale.ENGLISH).endsWith(".tld"))
254 {
255 Resource l=web_inf_tlds.addPath(contents[i]);
256 tlds.add(l);
257 }
258 }
259 }
260 }
261
262
263
264
265 @SuppressWarnings("unchecked")
266 Collection<Resource> tld_resources=(Collection<Resource>)_context.getAttribute(TLD_RESOURCES);
267 if (tld_resources!=null)
268 tlds.addAll(tld_resources);
269
270 return tlds;
271 }
272
273
274
275
276
277
278
279 private List<TldDescriptor> parseTlds (Set<Resource> tlds) {
280 List<TldDescriptor> descriptors = new ArrayList<TldDescriptor>();
281
282 Resource tld = null;
283 Iterator<Resource> iter = tlds.iterator();
284 while (iter.hasNext())
285 {
286 try
287 {
288 tld = iter.next();
289 if (LOG.isDebugEnabled()) LOG.debug("TLD="+tld);
290
291 TldDescriptor d = new TldDescriptor(tld);
292 d.parse();
293 descriptors.add(d);
294 }
295 catch(Exception e)
296 {
297 LOG.warn("Unable to parse TLD: " + tld,e);
298 }
299 }
300 return descriptors;
301 }
302
303
304
305
306
307
308
309 private void processTlds (List<TldDescriptor> descriptors) throws Exception {
310
311 TldProcessor processor = new TldProcessor();
312 for (TldDescriptor d:descriptors)
313 processor.process(_context, d);
314
315 _tldListeners = new ArrayList<EventListener>(processor.getListeners());
316 }
317 }
318
319
320
321
322
323
324
325
326
327 public static class TldDescriptor extends Descriptor
328 {
329 protected static XmlParser __parserSingleton;
330
331 public TldDescriptor(Resource xml)
332 {
333 super(xml);
334 }
335
336 @Override
337 public void ensureParser() throws ClassNotFoundException
338 {
339 if (__parserSingleton == null)
340 __parserSingleton = newParser();
341 _parser = __parserSingleton;
342 }
343
344 @Override
345 public XmlParser newParser() throws ClassNotFoundException
346 {
347
348 XmlParser parser = new XmlParser(false);
349
350 URL taglib11=null;
351 URL taglib12=null;
352 URL taglib20=null;
353 URL taglib21=null;
354
355 try
356 {
357 Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage");
358 taglib11=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd");
359 taglib12=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd");
360 taglib20=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd");
361 taglib21=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd");
362 }
363 catch(Exception e)
364 {
365 LOG.ignore(e);
366 }
367 finally
368 {
369 if(taglib11==null)
370 taglib11=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd",true);
371 if(taglib12==null)
372 taglib12=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd",true);
373 if(taglib20==null)
374 taglib20=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd",true);
375 if(taglib21==null)
376 taglib21=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd",true);
377 }
378
379
380 if(taglib11!=null)
381 {
382 redirect(parser, "web-jsptaglib_1_1.dtd",taglib11);
383 redirect(parser, "web-jsptaglibrary_1_1.dtd",taglib11);
384 }
385 if(taglib12!=null)
386 {
387 redirect(parser, "web-jsptaglib_1_2.dtd",taglib12);
388 redirect(parser, "web-jsptaglibrary_1_2.dtd",taglib12);
389 }
390 if(taglib20!=null)
391 {
392 redirect(parser, "web-jsptaglib_2_0.xsd",taglib20);
393 redirect(parser, "web-jsptaglibrary_2_0.xsd",taglib20);
394 }
395 if(taglib21!=null)
396 {
397 redirect(parser, "web-jsptaglib_2_1.xsd",taglib21);
398 redirect(parser, "web-jsptaglibrary_2_1.xsd",taglib21);
399 }
400
401 parser.setXpath("/taglib/listener/listener-class");
402 return parser;
403 }
404
405 public void parse ()
406 throws Exception
407 {
408 ensureParser();
409 try
410 {
411
412
413
414 _root = _parser.parse(_xml.getInputStream());
415 }
416 catch (Exception e)
417 {
418 _root = _parser.parse(_xml.getURL().toString());
419 }
420
421 if (_root==null)
422 {
423 LOG.warn("No TLD root in {}",_xml);
424 }
425 }
426 }
427
428
429
430
431
432
433
434 public class TldProcessor extends IterativeDescriptorProcessor
435 {
436 public static final String TAGLIB_PROCESSOR = "org.eclipse.jetty.tagLibProcessor";
437 XmlParser _parser;
438 List<XmlParser.Node> _roots = new ArrayList<XmlParser.Node>();
439 List<EventListener> _listeners;
440
441
442 public TldProcessor ()
443 throws Exception
444 {
445 _listeners = new ArrayList<EventListener>();
446 registerVisitor("listener", this.getClass().getDeclaredMethod("visitListener", __signature));
447 }
448
449
450 public void visitListener (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
451 {
452 String className=node.getString("listener-class",false,true);
453 if (LOG.isDebugEnabled())
454 LOG.debug("listener="+className);
455
456 try
457 {
458 Class<?> listenerClass = context.loadClass(className);
459 EventListener l = (EventListener)listenerClass.newInstance();
460 _listeners.add(l);
461 }
462 catch(Exception e)
463 {
464 LOG.warn("Could not instantiate listener "+className+": "+e);
465 LOG.debug(e);
466 }
467 catch(Error e)
468 {
469 LOG.warn("Could not instantiate listener "+className+": "+e);
470 LOG.debug(e);
471 }
472
473 }
474
475 @Override
476 public void end(WebAppContext context, Descriptor descriptor)
477 {
478 }
479
480 @Override
481 public void start(WebAppContext context, Descriptor descriptor)
482 {
483 }
484
485 public List<EventListener> getListeners() {
486 return _listeners;
487 }
488 }
489
490
491 @Override
492 public void preConfigure(WebAppContext context) throws Exception
493 {
494 try
495 {
496 Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage");
497 }
498 catch (Exception e)
499 {
500
501 return;
502 }
503
504 TagLibListener tagLibListener = new TagLibListener(context);
505 context.addEventListener(tagLibListener);
506 }
507
508
509 @Override
510 public void configure (WebAppContext context) throws Exception
511 {
512 }
513
514 @Override
515 public void postConfigure(WebAppContext context) throws Exception
516 {
517 }
518
519
520 @Override
521 public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception
522 {
523 }
524
525
526 @Override
527 public void deconfigure(WebAppContext context) throws Exception
528 {
529 }
530 }