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