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