1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.mortbay.jetty.webapp;
15
16 import java.io.File;
17 import java.io.IOException;
18 import java.net.MalformedURLException;
19 import java.net.URL;
20 import java.util.ArrayList;
21 import java.util.EventListener;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.jar.JarEntry;
26 import java.util.regex.Pattern;
27
28 import javax.servlet.Servlet;
29 import javax.servlet.UnavailableException;
30
31 import org.mortbay.jetty.Handler;
32 import org.mortbay.jetty.handler.ContextHandler;
33 import org.mortbay.jetty.security.Authenticator;
34 import org.mortbay.jetty.security.BasicAuthenticator;
35 import org.mortbay.jetty.security.Constraint;
36 import org.mortbay.jetty.security.ConstraintMapping;
37 import org.mortbay.jetty.security.DigestAuthenticator;
38 import org.mortbay.jetty.security.FormAuthenticator;
39 import org.mortbay.jetty.security.UserRealm;
40 import org.mortbay.jetty.servlet.Dispatcher;
41 import org.mortbay.jetty.servlet.ErrorPageErrorHandler;
42 import org.mortbay.jetty.servlet.FilterHolder;
43 import org.mortbay.jetty.servlet.FilterMapping;
44 import org.mortbay.jetty.servlet.ServletHandler;
45 import org.mortbay.jetty.servlet.ServletHolder;
46 import org.mortbay.jetty.servlet.ServletMapping;
47 import org.mortbay.log.Log;
48 import org.mortbay.resource.Resource;
49 import org.mortbay.util.LazyList;
50 import org.mortbay.util.Loader;
51 import org.mortbay.xml.XmlParser;
52
53
54
55
56
57
58 public class WebXmlConfiguration implements Configuration
59 {
60 protected WebAppContext _context;
61 protected XmlParser _xmlParser;
62 protected Object _filters;
63 protected Object _filterMappings;
64 protected Object _servlets;
65 protected Object _servletMappings;
66 protected Object _welcomeFiles;
67 protected Object _constraintMappings;
68 protected Object _listeners;
69 protected Map _errorPages;
70 protected boolean _hasJSP;
71 protected String _jspServletName;
72 protected String _jspServletClass;
73 protected boolean _defaultWelcomeFileList;
74 protected ServletHandler _servletHandler;
75 protected int _version;
76 protected boolean _metaDataComplete = false;
77 private URL _webxml;
78
79 public WebXmlConfiguration() throws ClassNotFoundException
80 {
81
82 _xmlParser=webXmlParser();
83 }
84
85 public static XmlParser webXmlParser() throws ClassNotFoundException
86 {
87 XmlParser xmlParser=new XmlParser();
88
89 URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd",true);
90 URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd",true);
91 URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd",true);
92 URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd",true);
93 URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd",true);
94 URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd",true);
95 URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd",true);
96 URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd",true);
97 URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd",true);
98 URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd",true);
99 URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd",true);
100
101
102 URL jsp20xsd=null;
103 URL jsp21xsd=null;
104
105 try
106 {
107 Class jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage");
108 jsp20xsd=jsp_page.getResource("/javax/servlet/resources/jsp_2_0.xsd");
109 jsp21xsd=jsp_page.getResource("/javax/servlet/resources/jsp_2_1.xsd");
110 }
111 catch(Exception e)
112 {
113 Log.ignore(e);
114 }
115 finally
116 {
117 if (jsp20xsd==null)
118 jsp20xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/jsp_2_0.xsd",true);
119 if (jsp21xsd==null)
120 jsp21xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/jsp_2_1.xsd",true);
121 }
122
123 redirect(xmlParser,"web-app_2_2.dtd",dtd22);
124 redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22);
125 redirect(xmlParser,"web.dtd",dtd23);
126 redirect(xmlParser,"web-app_2_3.dtd",dtd23);
127 redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23);
128 redirect(xmlParser,"XMLSchema.dtd",schemadtd);
129 redirect(xmlParser,"http://www.w3.org/2001/XMLSchema.dtd",schemadtd);
130 redirect(xmlParser,"-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd);
131 redirect(xmlParser,"jsp_2_0.xsd",jsp20xsd);
132 redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd);
133 redirect(xmlParser,"jsp_2_1.xsd",jsp21xsd);
134 redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd);
135 redirect(xmlParser,"j2ee_1_4.xsd",j2ee14xsd);
136 redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
137 redirect(xmlParser,"web-app_2_4.xsd",webapp24xsd);
138 redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd);
139 redirect(xmlParser,"web-app_2_5.xsd",webapp25xsd);
140 redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd);
141 redirect(xmlParser,"web-app_3_0.xsd",webapp30xsd);
142 redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd",webapp30xsd);
143 redirect(xmlParser,"xml.xsd",xmlxsd);
144 redirect(xmlParser,"http://www.w3.org/2001/xml.xsd",xmlxsd);
145 redirect(xmlParser,"datatypes.dtd",datatypesdtd);
146 redirect(xmlParser,"http://www.w3.org/2001/datatypes.dtd",datatypesdtd);
147 redirect(xmlParser,"j2ee_web_services_client_1_1.xsd",webservice11xsd);
148 redirect(xmlParser,"http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd);
149 redirect(xmlParser,"javaee_web_services_client_1_2.xsd",webservice12xsd);
150 redirect(xmlParser,"http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd);
151
152 return xmlParser;
153 }
154
155
156 private static void redirect(XmlParser parser,String resource, URL source)
157 {
158 if (source!=null)
159 parser.redirectEntity(resource,source);
160 }
161
162
163 public void setWebAppContext (WebAppContext context)
164 {
165 _context = context;
166 }
167
168
169 public WebAppContext getWebAppContext()
170 {
171 return _context;
172 }
173
174
175
176
177 public void configureClassLoader()
178 throws Exception
179 {
180 }
181
182
183
184
185
186
187
188 public void configureDefaults() throws Exception
189 {
190
191 if (_context.isStarted())
192 {
193 if (Log.isDebugEnabled()){Log.debug("Cannot configure webapp after it is started");}
194 return;
195 }
196 String defaultsDescriptor=getWebAppContext().getDefaultsDescriptor();
197 if(defaultsDescriptor!=null&&defaultsDescriptor.length()>0)
198 {
199 Resource dftResource=Resource.newSystemResource(defaultsDescriptor);
200 if(dftResource==null)
201 dftResource=_context.newResource(defaultsDescriptor);
202
203
204 XmlParser.Node config=null;
205 config=_xmlParser.parse(dftResource.getURL().toString());
206 initialize(config);
207 _defaultWelcomeFileList=_welcomeFiles!=null;
208 }
209 }
210
211
212
213
214
215
216 public void configureWebApp() throws Exception
217 {
218
219 if (_context.isStarted())
220 {
221 if (Log.isDebugEnabled())
222 Log.debug("Cannot configure webapp after it is started");
223 return;
224 }
225
226 _webxml=findWebXml();
227 if (_webxml!=null)
228 configure(_webxml.toString());
229
230 String overrideDescriptor=getWebAppContext().getOverrideDescriptor();
231 if(overrideDescriptor!=null&&overrideDescriptor.length()>0)
232 {
233 Resource orideResource=Resource.newSystemResource(overrideDescriptor);
234 if(orideResource==null)
235 orideResource=_context.newResource(overrideDescriptor);
236 _xmlParser.setValidating(false);
237 configure(orideResource.getURL().toString());
238 }
239
240
241 configureWebFragments();
242 }
243
244
245
246
247
248
249
250 public void configureWebFragments () throws Exception
251 {
252 Log.debug("metadata-complete "+_metaDataComplete);
253
254
255 if (_metaDataComplete)
256 return;
257
258
259
260
261 String tmp = (String)_context.getInitParameter("org.mortbay.jetty.webapp.WebXmlFragmentPattern");
262 Pattern webFragPattern = (tmp==null?null:Pattern.compile(tmp));
263
264 JarScanner fragScanner = new JarScanner ()
265 {
266 public void processEntry(URL jarUrl, JarEntry entry)
267 {
268 try
269 {
270 String name = entry.getName();
271 if (name.toLowerCase().equals("meta-inf/web.xml"))
272 {
273 Resource webXmlFrag = _context.newResource("jar:"+jarUrl+"!/"+name);
274 Log.debug("web.xml fragment found {}", webXmlFrag);
275
276
277
278
279
280
281
282 XmlParser.Node config=null;
283 config=_xmlParser.parse(webXmlFrag.toString());
284 initialize(config);
285 }
286 }
287 catch (Exception e)
288 {
289 Log.warn("Problem processing jar entry "+entry, e);
290 }
291 }
292 };
293 fragScanner.setWebAppContext(_context);
294 fragScanner.scan (webFragPattern, Thread.currentThread().getContextClassLoader(), true, false);
295 }
296
297
298 protected URL findWebXml() throws IOException, MalformedURLException
299 {
300 String descriptor=getWebAppContext().getDescriptor();
301 if (descriptor!=null)
302 {
303 Resource web= _context.newResource(descriptor);
304 if (web.exists()&& !web.isDirectory())
305 return web.getURL();
306 }
307
308 Resource web_inf=getWebAppContext().getWebInf();
309 if(web_inf!=null && web_inf.isDirectory())
310 {
311
312 Resource web=web_inf.addPath("web.xml");
313 if(web.exists())
314 return web.getURL();
315 Log.debug("No WEB-INF/web.xml in "+getWebAppContext().getWar()
316 +". Serving files and default/dynamic servlets only");
317 }
318 return null;
319 }
320
321
322 public void configure(String webXml) throws Exception
323 {
324 XmlParser.Node config=null;
325 config=_xmlParser.parse(webXml);
326 initializeVersion(config);
327 initialize(config);
328 }
329
330
331 public void deconfigureWebApp() throws Exception
332 {
333
334
335 _servletHandler = getWebAppContext().getServletHandler();
336
337 _servletHandler.setFilters(null);
338 _servletHandler.setFilterMappings(null);
339 _servletHandler.setServlets(null);
340 _servletHandler.setServletMappings(null);
341
342 getWebAppContext().setEventListeners(null);
343 getWebAppContext().setWelcomeFiles(null);
344 if (getWebAppContext().getSecurityHandler() != null)
345 getWebAppContext().getSecurityHandler().setConstraintMappings(null);
346
347 if (getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler)
348 ((ErrorPageErrorHandler)getWebAppContext().getErrorHandler()).setErrorPages(null);
349
350
351 }
352
353
354 protected void initializeVersion (XmlParser.Node config)
355 {
356 String version=config.getAttribute("version","DTD");
357 if ("2.5".equals(version))
358 _version=25;
359 else if ("2.4".equals(version))
360 _version=24;
361 else if ("3.0".equals(version))
362 _version=30;
363 else if ("DTD".equals(version))
364 {
365 _version=23;
366 String dtd=_xmlParser.getDTD();
367 if (dtd!=null && dtd.indexOf("web-app_2_2")>=0)
368 _version=22;
369 }
370
371 if (_version < 25)
372 _metaDataComplete = true;
373 else
374 _metaDataComplete = Boolean.valueOf((String)config.getAttribute("metadata-complete", "false")).booleanValue();
375
376 Log.debug("Calculated metadatacomplete = "+_metaDataComplete+" with version="+version);
377
378 _context.setAttribute("metadata-complete", String.valueOf(_metaDataComplete));
379 }
380
381
382
383 protected void initialize(XmlParser.Node config) throws ClassNotFoundException,UnavailableException
384 {
385 _servletHandler = getWebAppContext().getServletHandler();
386
387 _filters=LazyList.array2List(_servletHandler.getFilters());
388 _filterMappings=LazyList.array2List(_servletHandler.getFilterMappings());
389 _servlets=LazyList.array2List(_servletHandler.getServlets());
390 _servletMappings=LazyList.array2List(_servletHandler.getServletMappings());
391
392 _listeners = LazyList.array2List(getWebAppContext().getEventListeners());
393 _welcomeFiles = LazyList.array2List(getWebAppContext().getWelcomeFiles());
394 _constraintMappings = LazyList.array2List(getWebAppContext().getSecurityHandler().getConstraintMappings());
395
396 _errorPages = getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler ?
397 ((ErrorPageErrorHandler)getWebAppContext().getErrorHandler()).getErrorPages():null;
398
399
400
401 Iterator iter=config.iterator();
402 XmlParser.Node node=null;
403 while(iter.hasNext())
404 {
405 try
406 {
407 Object o=iter.next();
408 if(!(o instanceof XmlParser.Node))
409 continue;
410 node=(XmlParser.Node)o;
411 String name=node.getTag();
412 initWebXmlElement(name,node);
413 }
414 catch(ClassNotFoundException e)
415 {
416 throw e;
417 }
418 catch(Exception e)
419 {
420 Log.warn("Configuration problem at "+node,e);
421 throw new UnavailableException("Configuration problem");
422 }
423 }
424
425 _servletHandler.setFilters((FilterHolder[])LazyList.toArray(_filters,FilterHolder.class));
426 _servletHandler.setFilterMappings((FilterMapping[])LazyList.toArray(_filterMappings,FilterMapping.class));
427 _servletHandler.setServlets((ServletHolder[])LazyList.toArray(_servlets,ServletHolder.class));
428 _servletHandler.setServletMappings((ServletMapping[])LazyList.toArray(_servletMappings,ServletMapping.class));
429
430 getWebAppContext().setEventListeners((EventListener[])LazyList.toArray(_listeners,EventListener.class));
431 getWebAppContext().setWelcomeFiles((String[])LazyList.toArray(_welcomeFiles,String.class));
432 getWebAppContext().getSecurityHandler().setConstraintMappings((ConstraintMapping[])LazyList.toArray(_constraintMappings, ConstraintMapping.class));
433
434 if (_errorPages!=null && getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler)
435 ((ErrorPageErrorHandler)getWebAppContext().getErrorHandler()).setErrorPages(_errorPages);
436
437 }
438
439
440
441
442
443
444
445
446
447
448 protected void initWebXmlElement(String element,XmlParser.Node node) throws Exception
449 {
450 if("display-name".equals(element))
451 initDisplayName(node);
452 else if("description".equals(element))
453 {}
454 else if("context-param".equals(element))
455 initContextParam(node);
456 else if("servlet".equals(element))
457 initServlet(node);
458 else if("servlet-mapping".equals(element))
459 initServletMapping(node);
460 else if("session-config".equals(element))
461 initSessionConfig(node);
462 else if("mime-mapping".equals(element))
463 initMimeConfig(node);
464 else if("welcome-file-list".equals(element))
465 initWelcomeFileList(node);
466 else if("locale-encoding-mapping-list".equals(element))
467 initLocaleEncodingList(node);
468 else if("error-page".equals(element))
469 initErrorPage(node);
470 else if("taglib".equals(element))
471 initTagLib(node);
472 else if("jsp-config".equals(element))
473 initJspConfig(node);
474 else if("resource-ref".equals(element))
475 {
476 if(Log.isDebugEnabled())
477 Log.debug("No implementation: "+node);
478 }
479 else if("security-constraint".equals(element))
480 initSecurityConstraint(node);
481 else if("login-config".equals(element))
482 initLoginConfig(node);
483 else if("security-role".equals(element))
484 initSecurityRole(node);
485 else if("filter".equals(element))
486 initFilter(node);
487 else if("filter-mapping".equals(element))
488 initFilterMapping(node);
489 else if("listener".equals(element))
490 initListener(node);
491 else if("distributable".equals(element))
492 initDistributable(node);
493 else if("web-fragment".equals(element))
494 {}
495 else
496 {
497 if(Log.isDebugEnabled())
498 {
499 Log.debug("Element {} not handled in {}",element,this);
500 Log.debug(node.toString());
501 }
502 }
503 }
504
505
506 protected void initDisplayName(XmlParser.Node node)
507 {
508 getWebAppContext().setDisplayName(node.toString(false,true));
509 }
510
511
512 protected void initContextParam(XmlParser.Node node)
513 {
514 String name=node.getString("param-name",false,true);
515 String value=node.getString("param-value",false,true);
516 if(Log.isDebugEnabled())
517 Log.debug("ContextParam: "+name+"="+value);
518 getWebAppContext().getInitParams().put(name, value);
519 }
520
521
522 protected void initFilter(XmlParser.Node node)
523 {
524 String name=node.getString("filter-name",false,true);
525 FilterHolder holder= _servletHandler.getFilter(name);
526 if (holder==null)
527 {
528 holder=_servletHandler.newFilterHolder();
529 holder.setName(name);
530 _filters=LazyList.add(_filters,holder);
531 }
532
533 String filter_class=node.getString("filter-class",false,true);
534 if (filter_class!=null)
535 holder.setClassName(filter_class);
536
537 Iterator iter=node.iterator("init-param");
538 while(iter.hasNext())
539 {
540 XmlParser.Node paramNode=(XmlParser.Node)iter.next();
541 String pname=paramNode.getString("param-name",false,true);
542 String pvalue=paramNode.getString("param-value",false,true);
543 holder.setInitParameter(pname, pvalue);
544 }
545
546 }
547
548
549 protected void initFilterMapping(XmlParser.Node node)
550 {
551 String filter_name=node.getString("filter-name",false,true);
552
553
554
555 FilterMapping mapping = new FilterMapping();
556
557 mapping.setFilterName(filter_name);
558
559 ArrayList paths = new ArrayList();
560 Iterator iter=node.iterator("url-pattern");
561 while(iter.hasNext())
562 {
563 String p=((XmlParser.Node)iter.next()).toString(false,true);
564 p=normalizePattern(p);
565 paths.add(p);
566 }
567 mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()]));
568
569
570 ArrayList names = new ArrayList();
571 iter=node.iterator("servlet-name");
572 while(iter.hasNext())
573 {
574 String n=((XmlParser.Node)iter.next()).toString(false,true);
575 names.add(n);
576 }
577 mapping.setServletNames((String[])names.toArray(new String[names.size()]));
578
579
580 int dispatcher=Handler.DEFAULT;
581 iter=node.iterator("dispatcher");
582 while(iter.hasNext())
583 {
584 String d=((XmlParser.Node)iter.next()).toString(false,true);
585 dispatcher|=Dispatcher.type(d);
586 }
587 mapping.setDispatches(dispatcher);
588
589 iter=node.iterator("life-cycle");
590 while(iter.hasNext())
591 {
592 String l=((XmlParser.Node)iter.next()).toString(false,true);
593 if ("initial".equalsIgnoreCase(l))
594 mapping.setInitialLifeCycle(true);
595 if ("redispatch".equalsIgnoreCase(l))
596 mapping.setRedispatchLifeCycle(true);
597 }
598 mapping.setDispatches(dispatcher);
599
600 _filterMappings=LazyList.add(_filterMappings,mapping);
601 }
602
603
604 protected String normalizePattern(String p)
605 {
606 if (p!=null && p.length()>0 && !p.startsWith("/") && !p.startsWith("*"))
607 return "/"+p;
608 return p;
609 }
610
611
612 protected void initServlet(XmlParser.Node node)
613 {
614 String id=node.getAttribute("id");
615
616
617 String servlet_name=node.getString("servlet-name",false,true);
618 ServletHolder holder = _servletHandler.getServlet(servlet_name);
619 if (holder==null)
620 {
621 holder=_servletHandler.newServletHolder();
622 holder.setName(servlet_name);
623 _servlets=LazyList.add(_servlets,holder);
624 }
625
626
627 Iterator iParamsIter=node.iterator("init-param");
628 while(iParamsIter.hasNext())
629 {
630 XmlParser.Node paramNode=(XmlParser.Node)iParamsIter.next();
631 String pname=paramNode.getString("param-name",false,true);
632 String pvalue=paramNode.getString("param-value",false,true);
633 holder.setInitParameter(pname,pvalue);
634 }
635
636 String servlet_class=node.getString("servlet-class",false,true);
637
638
639 if (id!=null && id.equals("jsp"))
640 {
641 _jspServletName=servlet_name;
642 _jspServletClass=servlet_class;
643 try
644 {
645 Loader.loadClass(this.getClass(), servlet_class);
646 _hasJSP=true;
647 }
648 catch(ClassNotFoundException e)
649 {
650 Log.info("NO JSP Support for {}, did not find {}",_context.getContextPath(),servlet_class);
651 _hasJSP=false;
652 _jspServletClass=servlet_class="org.mortbay.jetty.servlet.NoJspServlet";
653 }
654 if (holder.getInitParameter("scratchdir")==null)
655 {
656 File tmp=getWebAppContext().getTempDirectory();
657 File scratch=new File(tmp,"jsp");
658 if (!scratch.exists())
659 scratch.mkdir();
660 holder.setInitParameter("scratchdir",scratch.getAbsolutePath());
661
662 if ("?".equals(holder.getInitParameter("classpath")))
663 {
664 String classpath=getWebAppContext().getClassPath();
665 Log.debug("classpath="+classpath);
666 if (classpath!=null)
667 holder.setInitParameter("classpath",classpath);
668 }
669 }
670 }
671 if (servlet_class!=null)
672 holder.setClassName(servlet_class);
673
674
675
676 String jsp_file=node.getString("jsp-file",false,true);
677 if (jsp_file!=null)
678 {
679 holder.setForcedPath(jsp_file);
680 holder.setClassName(_jspServletClass);
681 }
682
683
684 XmlParser.Node startup=node.get("load-on-startup");
685 if(startup!=null)
686 {
687 String s=startup.toString(false,true).toLowerCase();
688 if(s.startsWith("t"))
689 {
690 Log.warn("Deprecated boolean load-on-startup. Please use integer");
691 holder.setInitOrder(1);
692 }
693 else
694 {
695 int order=0;
696 try
697 {
698 if(s!=null&&s.trim().length()>0)
699 order=Integer.parseInt(s);
700 }
701 catch(Exception e)
702 {
703 Log.warn("Cannot parse load-on-startup "+s+". Please use integer");
704 Log.ignore(e);
705 }
706 holder.setInitOrder(order);
707 }
708 }
709
710 Iterator sRefsIter=node.iterator("security-role-ref");
711 while(sRefsIter.hasNext())
712 {
713 XmlParser.Node securityRef=(XmlParser.Node)sRefsIter.next();
714 String roleName=securityRef.getString("role-name",false,true);
715 String roleLink=securityRef.getString("role-link",false,true);
716 if(roleName!=null&&roleName.length()>0&&roleLink!=null&&roleLink.length()>0)
717 {
718 if(Log.isDebugEnabled())
719 Log.debug("link role "+roleName+" to "+roleLink+" for "+this);
720 holder.setUserRoleLink(roleName,roleLink);
721 }
722 else
723 {
724 Log.warn("Ignored invalid security-role-ref element: "+"servlet-name="+holder.getName()+", "+securityRef);
725 }
726 }
727
728 XmlParser.Node run_as=node.get("run-as");
729 if(run_as!=null)
730 {
731 String roleName=run_as.getString("role-name",false,true);
732 if(roleName!=null)
733 holder.setRunAs(roleName);
734 }
735
736 }
737
738
739 protected void initServletMapping(XmlParser.Node node)
740 {
741 String servlet_name = node.getString("servlet-name",false,true);
742 ServletMapping mapping = new ServletMapping();
743 mapping.setServletName(servlet_name);
744
745 ArrayList paths = new ArrayList();
746 Iterator iter=node.iterator("url-pattern");
747 while(iter.hasNext())
748 {
749 String p=((XmlParser.Node)iter.next()).toString(false,true);
750 p=normalizePattern(p);
751 paths.add(p);
752 }
753 mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()]));
754
755 _servletMappings=LazyList.add(_servletMappings,mapping);
756 }
757
758
759 protected void initListener(XmlParser.Node node)
760 {
761 String className=node.getString("listener-class",false,true);
762 Object listener=null;
763 try
764 {
765 Class listenerClass=getWebAppContext().loadClass(className);
766 listener=newListenerInstance(listenerClass);
767 if(!(listener instanceof EventListener))
768 {
769 Log.warn("Not an EventListener: "+listener);
770 return;
771 }
772 _listeners=LazyList.add(_listeners, listener);
773 }
774 catch(Exception e)
775 {
776 Log.warn("Could not instantiate listener "+className,e);
777 return;
778 }
779 }
780
781
782 protected Object newListenerInstance(Class clazz)
783 throws InstantiationException, IllegalAccessException
784 {
785 return clazz.newInstance();
786 }
787
788
789 protected void initDistributable(XmlParser.Node node)
790 {
791
792
793 WebAppContext wac=getWebAppContext();
794 if (!wac.isDistributable())
795 wac.setDistributable(true);
796 }
797
798
799 protected void initSessionConfig(XmlParser.Node node)
800 {
801 XmlParser.Node tNode=node.get("session-timeout");
802 if(tNode!=null)
803 {
804 int timeout=Integer.parseInt(tNode.toString(false,true));
805 getWebAppContext().getSessionHandler().getSessionManager().setMaxInactiveInterval(timeout*60);
806 }
807 }
808
809
810 protected void initMimeConfig(XmlParser.Node node)
811 {
812 String extension=node.getString("extension",false,true);
813 if(extension!=null&&extension.startsWith("."))
814 extension=extension.substring(1);
815 String mimeType=node.getString("mime-type",false,true);
816 getWebAppContext().getMimeTypes().addMimeMapping(extension, mimeType);
817 }
818
819
820 protected void initWelcomeFileList(XmlParser.Node node)
821 {
822 if (_defaultWelcomeFileList)
823 _welcomeFiles=null;
824
825 _defaultWelcomeFileList=false;
826 Iterator iter=node.iterator("welcome-file");
827 while(iter.hasNext())
828 {
829 XmlParser.Node indexNode=(XmlParser.Node)iter.next();
830 String welcome=indexNode.toString(false,true);
831 _welcomeFiles=LazyList.add(_welcomeFiles,welcome);
832 }
833 }
834
835
836 protected void initLocaleEncodingList(XmlParser.Node node)
837 {
838 Iterator iter=node.iterator("locale-encoding-mapping");
839 while(iter.hasNext())
840 {
841 XmlParser.Node mapping=(XmlParser.Node)iter.next();
842 String locale=mapping.getString("locale",false,true);
843 String encoding=mapping.getString("encoding",false,true);
844 getWebAppContext().addLocaleEncoding(locale,encoding);
845 }
846 }
847
848
849 protected void initErrorPage(XmlParser.Node node)
850 {
851 String error=node.getString("error-code",false,true);
852 if(error==null||error.length()==0)
853 error=node.getString("exception-type",false,true);
854 String location=node.getString("location",false,true);
855
856 if (_errorPages==null)
857 _errorPages=new HashMap();
858 _errorPages.put(error,location);
859 }
860
861
862 protected void initTagLib(XmlParser.Node node)
863 {
864 String uri=node.getString("taglib-uri",false,true);
865 String location=node.getString("taglib-location",false,true);
866
867 getWebAppContext().setResourceAlias(uri,location);
868 }
869
870
871 protected void initJspConfig(XmlParser.Node node)
872 {
873 for (int i=0;i<node.size();i++)
874 {
875 Object o=node.get(i);
876 if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node)o).getTag()))
877 initTagLib((XmlParser.Node)o);
878 }
879
880
881
882 Iterator iter=node.iterator("jsp-property-group");
883 Object paths=null;
884 while(iter.hasNext())
885 {
886 XmlParser.Node group=(XmlParser.Node)iter.next();
887 Iterator iter2 = group.iterator("url-pattern");
888 while (iter2.hasNext())
889 {
890 String url = ((XmlParser.Node) iter2.next()).toString(false, true);
891 url=normalizePattern(url);
892 paths=LazyList.add(paths,url);
893 }
894 }
895
896 if (LazyList.size(paths)>0)
897 {
898 String jspName=getJSPServletName();
899 if (jspName!=null)
900 {
901 ServletMapping mapping = new ServletMapping();
902 mapping.setServletName(jspName);
903 mapping.setPathSpecs(LazyList.toStringArray(paths));
904 _servletMappings=LazyList.add(_servletMappings,mapping);
905 }
906 }
907 }
908
909
910 protected void initSecurityConstraint(XmlParser.Node node)
911 {
912 Constraint scBase = new Constraint();
913
914 try
915 {
916 XmlParser.Node auths = node.get("auth-constraint");
917
918 if (auths != null)
919 {
920 scBase.setAuthenticate(true);
921
922 Iterator iter = auths.iterator("role-name");
923 Object roles=null;
924 while (iter.hasNext())
925 {
926 String role = ((XmlParser.Node) iter.next()).toString(false, true);
927 roles=LazyList.add(roles,role);
928 }
929 scBase.setRoles(LazyList.toStringArray(roles));
930 }
931
932 XmlParser.Node data = node.get("user-data-constraint");
933 if (data != null)
934 {
935 data = data.get("transport-guarantee");
936 String guarantee = data.toString(false, true).toUpperCase();
937 if (guarantee == null || guarantee.length() == 0 || "NONE".equals(guarantee))
938 scBase.setDataConstraint(Constraint.DC_NONE);
939 else if ("INTEGRAL".equals(guarantee))
940 scBase.setDataConstraint(Constraint.DC_INTEGRAL);
941 else if ("CONFIDENTIAL".equals(guarantee))
942 scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
943 else
944 {
945 Log.warn("Unknown user-data-constraint:" + guarantee);
946 scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
947 }
948 }
949 Iterator iter = node.iterator("web-resource-collection");
950 while (iter.hasNext())
951 {
952 XmlParser.Node collection = (XmlParser.Node) iter.next();
953 String name = collection.getString("web-resource-name", false, true);
954 Constraint sc = (Constraint) scBase.clone();
955 sc.setName(name);
956
957
958 Iterator iter2 = collection.iterator("url-pattern");
959 while (iter2.hasNext())
960 {
961 String url = ((XmlParser.Node) iter2.next()).toString(false, true);
962 url=normalizePattern(url);
963
964 Iterator iter3 = collection.iterator("http-method");
965 if (iter3.hasNext())
966 {
967 while (iter3.hasNext())
968 {
969 String method=((XmlParser.Node) iter3.next()).toString(false, true);
970 ConstraintMapping mapping = new ConstraintMapping();
971 mapping.setMethod(method);
972 mapping.setPathSpec(url);
973 mapping.setConstraint(sc);
974 _constraintMappings=LazyList.add(_constraintMappings,mapping);
975 }
976 }
977 else
978 {
979 ConstraintMapping mapping = new ConstraintMapping();
980 mapping.setPathSpec(url);
981 mapping.setConstraint(sc);
982 _constraintMappings=LazyList.add(_constraintMappings,mapping);
983 }
984 }
985 }
986 }
987 catch (CloneNotSupportedException e)
988 {
989 Log.warn(e);
990 }
991
992 }
993
994
995 protected void initLoginConfig(XmlParser.Node node) throws Exception
996 {
997 XmlParser.Node method=node.get("auth-method");
998 FormAuthenticator _formAuthenticator=null;
999 if(method!=null)
1000 {
1001 Authenticator authenticator=null;
1002 String m=method.toString(false,true);
1003 if(Constraint.__FORM_AUTH.equals(m))
1004 authenticator=_formAuthenticator=new FormAuthenticator();
1005 else if(Constraint.__BASIC_AUTH.equals(m))
1006 authenticator=new BasicAuthenticator();
1007 else if(Constraint.__DIGEST_AUTH.equals(m))
1008 authenticator=new DigestAuthenticator();
1009 else if(Constraint.__CERT_AUTH.equals(m) ||
1010 Constraint.__CERT_AUTH2.equals(m))
1011 authenticator=(Authenticator)Loader.loadClass(WebXmlConfiguration.class,"org.mortbay.jetty.security.ClientCertAuthenticator").newInstance();
1012 else
1013 Log.warn("UNKNOWN AUTH METHOD: "+m);
1014 getWebAppContext().getSecurityHandler().setAuthenticator(authenticator);
1015 }
1016 XmlParser.Node name=node.get("realm-name");
1017
1018 UserRealm[] realms=ContextHandler.getCurrentContext().getContextHandler().getServer().getUserRealms();
1019
1020 String realm_name=name==null?"default":name.toString(false,true);
1021
1022 UserRealm realm=getWebAppContext().getSecurityHandler().getUserRealm();
1023 for (int i=0;realm==null && realms!=null && i<realms.length; i++)
1024 {
1025 if (realms[i]!=null && realm_name.equals(realms[i].getName()))
1026 realm=realms[i];
1027 }
1028
1029 if (realm==null)
1030 {
1031 String msg = "Unknown realm: "+realm_name;
1032 Log.warn(msg);
1033 }
1034 else
1035 getWebAppContext().getSecurityHandler().setUserRealm(realm);
1036
1037
1038 XmlParser.Node formConfig=node.get("form-login-config");
1039 if(formConfig!=null)
1040 {
1041 if(_formAuthenticator==null)
1042 Log.warn("FORM Authentication miss-configured");
1043 else
1044 {
1045 XmlParser.Node loginPage=formConfig.get("form-login-page");
1046 if(loginPage!=null)
1047 _formAuthenticator.setLoginPage(loginPage.toString(false,true));
1048 XmlParser.Node errorPage=formConfig.get("form-error-page");
1049 if(errorPage!=null)
1050 {
1051 String ep=errorPage.toString(false,true);
1052 _formAuthenticator.setErrorPage(ep);
1053 }
1054 }
1055 }
1056 }
1057
1058
1059 protected void initSecurityRole(XmlParser.Node node)
1060 {}
1061
1062
1063
1064
1065
1066 protected String getJSPServletName()
1067 {
1068 if (_jspServletName==null)
1069 {
1070 Map.Entry entry= _context.getServletHandler().getHolderEntry("test.jsp");
1071 if (entry!=null)
1072 {
1073 ServletHolder holder=(ServletHolder)entry.getValue();
1074 _jspServletName=holder.getName();
1075 }
1076 }
1077 return _jspServletName;
1078 }
1079 }