001: // ========================================================================
002: // Copyright 2003-2005 Mort Bay Consulting Pty. Ltd.
003: // ------------------------------------------------------------------------
004: // Licensed under the Apache License, Version 2.0 (the "License");
005: // you may not use this file except in compliance with the License.
006: // You may obtain a copy of the License at
007: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014: package org.mortbay.jetty.webapp;
015:
016: import java.io.File;
017: import java.io.IOException;
018: import java.net.MalformedURLException;
019: import java.net.URL;
020: import java.util.ArrayList;
021: import java.util.EventListener;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.Map;
025:
026: import javax.servlet.UnavailableException;
027:
028: import org.mortbay.jetty.Handler;
029: import org.mortbay.jetty.handler.ContextHandler;
030: import org.mortbay.jetty.security.Authenticator;
031: import org.mortbay.jetty.security.BasicAuthenticator;
032: import org.mortbay.jetty.security.ClientCertAuthenticator;
033: import org.mortbay.jetty.security.Constraint;
034: import org.mortbay.jetty.security.ConstraintMapping;
035: import org.mortbay.jetty.security.DigestAuthenticator;
036: import org.mortbay.jetty.security.FormAuthenticator;
037: import org.mortbay.jetty.security.UserRealm;
038: import org.mortbay.jetty.servlet.Dispatcher;
039: import org.mortbay.jetty.servlet.ErrorPageErrorHandler;
040: import org.mortbay.jetty.servlet.FilterHolder;
041: import org.mortbay.jetty.servlet.FilterMapping;
042: import org.mortbay.jetty.servlet.ServletHandler;
043: import org.mortbay.jetty.servlet.ServletHolder;
044: import org.mortbay.jetty.servlet.ServletMapping;
045: import org.mortbay.log.Log;
046: import org.mortbay.resource.Resource;
047: import org.mortbay.util.LazyList;
048: import org.mortbay.util.Loader;
049: import org.mortbay.xml.XmlParser;
050:
051: /* ------------------------------------------------------------------------------- */
052: /**
053: * Configure by parsing default web.xml and web.xml
054: *
055: * @author gregw
056: */
057: public class WebXmlConfiguration implements Configuration {
058: protected WebAppContext _context;
059: protected XmlParser _xmlParser;
060: protected Object _filters;
061: protected Object _filterMappings;
062: protected Object _servlets;
063: protected Object _servletMappings;
064: protected Object _welcomeFiles;
065: protected Object _constraintMappings;
066: protected Object _listeners;
067: protected Map _errorPages;
068: protected boolean _hasJSP;
069: protected String _jspServletName;
070: protected boolean _defaultWelcomeFileList;
071: protected ServletHandler _servletHandler;
072: protected int _version;
073:
074: public WebXmlConfiguration() {
075: // Get parser
076: _xmlParser = webXmlParser();
077: }
078:
079: public static XmlParser webXmlParser() {
080: XmlParser xmlParser = new XmlParser();
081: //set up cache of DTDs and schemas locally
082: URL dtd22 = WebAppContext.class
083: .getResource("/javax/servlet/resources/web-app_2_2.dtd");
084: URL dtd23 = WebAppContext.class
085: .getResource("/javax/servlet/resources/web-app_2_3.dtd");
086: URL jsp20xsd = WebAppContext.class
087: .getResource("/javax/servlet/resources/jsp_2_0.xsd");
088: URL jsp21xsd = WebAppContext.class
089: .getResource("/javax/servlet/resources/jsp_2_1.xsd");
090: URL j2ee14xsd = WebAppContext.class
091: .getResource("/javax/servlet/resources/j2ee_1_4.xsd");
092: URL webapp24xsd = WebAppContext.class
093: .getResource("/javax/servlet/resources/web-app_2_4.xsd");
094: URL webapp25xsd = WebAppContext.class
095: .getResource("/javax/servlet/resources/web-app_2_5.xsd");
096: URL schemadtd = WebAppContext.class
097: .getResource("/javax/servlet/resources/XMLSchema.dtd");
098: URL xmlxsd = WebAppContext.class
099: .getResource("/javax/servlet/resources/xml.xsd");
100: URL webservice11xsd = WebAppContext.class
101: .getResource("/javax/servlet/resources/j2ee_web_services_client_1_1.xsd");
102: URL webservice12xsd = WebAppContext.class
103: .getResource("/javax/servlet/resources/javaee_web_services_client_1_2.xsd");
104: URL datatypesdtd = WebAppContext.class
105: .getResource("/javax/servlet/resources/datatypes.dtd");
106: xmlParser.redirectEntity("web-app_2_2.dtd", dtd22);
107: xmlParser
108: .redirectEntity(
109: "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",
110: dtd22);
111: xmlParser.redirectEntity("web.dtd", dtd23);
112: xmlParser.redirectEntity("web-app_2_3.dtd", dtd23);
113: xmlParser
114: .redirectEntity(
115: "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
116: dtd23);
117: xmlParser.redirectEntity("XMLSchema.dtd", schemadtd);
118: xmlParser.redirectEntity(
119: "http://www.w3.org/2001/XMLSchema.dtd", schemadtd);
120: xmlParser.redirectEntity("-//W3C//DTD XMLSCHEMA 200102//EN",
121: schemadtd);
122: xmlParser.redirectEntity("jsp_2_0.xsd", jsp20xsd);
123: xmlParser
124: .redirectEntity(
125: "http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",
126: jsp20xsd);
127: xmlParser.redirectEntity("jsp_2_1.xsd", jsp21xsd);
128: xmlParser.redirectEntity(
129: "http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",
130: jsp21xsd);
131: xmlParser.redirectEntity("j2ee_1_4.xsd", j2ee14xsd);
132: xmlParser.redirectEntity(
133: "http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",
134: j2ee14xsd);
135: xmlParser.redirectEntity("web-app_2_4.xsd", webapp24xsd);
136: xmlParser.redirectEntity(
137: "http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",
138: webapp24xsd);
139: xmlParser.redirectEntity("web-app_2_5.xsd", webapp25xsd);
140: xmlParser.redirectEntity(
141: "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",
142: webapp25xsd);
143: xmlParser.redirectEntity("xml.xsd", xmlxsd);
144: xmlParser.redirectEntity("http://www.w3.org/2001/xml.xsd",
145: xmlxsd);
146: xmlParser.redirectEntity("datatypes.dtd", datatypesdtd);
147: xmlParser.redirectEntity(
148: "http://www.w3.org/2001/datatypes.dtd", datatypesdtd);
149: xmlParser.redirectEntity("j2ee_web_services_client_1_1.xsd",
150: webservice11xsd);
151: xmlParser
152: .redirectEntity(
153: "http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",
154: webservice11xsd);
155: xmlParser.redirectEntity("javaee_web_services_client_1_2.xsd",
156: webservice12xsd);
157: xmlParser
158: .redirectEntity(
159: "http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",
160: webservice12xsd);
161:
162: return xmlParser;
163: }
164:
165: /* ------------------------------------------------------------------------------- */
166: public void setWebAppContext(WebAppContext context) {
167: _context = context;
168: }
169:
170: /* ------------------------------------------------------------------------------- */
171: public WebAppContext getWebAppContext() {
172: return _context;
173: }
174:
175: /* ------------------------------------------------------------------------------- */
176: /** Configure ClassPath.
177: */
178: public void configureClassLoader() throws Exception {
179: }
180:
181: /* ------------------------------------------------------------------------------- */
182: public void configureDefaults() throws Exception {
183: //cannot configure if the context is already started
184: if (_context.isStarted()) {
185: if (Log.isDebugEnabled()) {
186: Log
187: .debug("Cannot configure webapp after it is started");
188: }
189: return;
190: }
191: String defaultsDescriptor = getWebAppContext()
192: .getDefaultsDescriptor();
193: if (defaultsDescriptor != null
194: && defaultsDescriptor.length() > 0) {
195: Resource dftResource = Resource
196: .newSystemResource(defaultsDescriptor);
197: if (dftResource == null)
198: dftResource = Resource.newResource(defaultsDescriptor);
199: configure(dftResource.getURL().toString());
200: _defaultWelcomeFileList = _welcomeFiles != null;
201: }
202: }
203:
204: /* ------------------------------------------------------------------------------- */
205: public void configureWebApp() throws Exception {
206: //cannot configure if the context is already started
207: if (_context.isStarted()) {
208: if (Log.isDebugEnabled())
209: Log
210: .debug("Cannot configure webapp after it is started");
211: return;
212: }
213:
214: URL webxml = findWebXml();
215: if (webxml != null)
216: configure(webxml.toString());
217:
218: String overrideDescriptor = getWebAppContext()
219: .getOverrideDescriptor();
220: if (overrideDescriptor != null
221: && overrideDescriptor.length() > 0) {
222: Resource orideResource = Resource
223: .newSystemResource(overrideDescriptor);
224: if (orideResource == null)
225: orideResource = Resource
226: .newResource(overrideDescriptor);
227: _xmlParser.setValidating(false);
228: configure(orideResource.getURL().toString());
229: }
230: }
231:
232: /* ------------------------------------------------------------------------------- */
233: protected URL findWebXml() throws IOException,
234: MalformedURLException {
235: String descriptor = getWebAppContext().getDescriptor();
236: if (descriptor != null) {
237: Resource web = Resource.newResource(descriptor);
238: if (web.exists() && !web.isDirectory())
239: return web.getURL();
240: }
241:
242: Resource web_inf = getWebAppContext().getWebInf();
243: if (web_inf != null && web_inf.isDirectory()) {
244: // do web.xml file
245: Resource web = web_inf.addPath("web.xml");
246: if (web.exists())
247: return web.getURL();
248: Log
249: .debug("No WEB-INF/web.xml in "
250: + getWebAppContext().getWar()
251: + ". Serving files and default/dynamic servlets only");
252: }
253: return null;
254: }
255:
256: /* ------------------------------------------------------------------------------- */
257: public void configure(String webXml) throws Exception {
258: XmlParser.Node config = null;
259: config = _xmlParser.parse(webXml);
260: initialize(config);
261: }
262:
263: /* ------------------------------------------------------------------------------- */
264: public void deconfigureWebApp() throws Exception {
265: // TODO preserve any configuration that pre-existed.
266:
267: _servletHandler = getWebAppContext().getServletHandler();
268:
269: _servletHandler.setFilters(null);
270: _servletHandler.setFilterMappings(null);
271: _servletHandler.setServlets(null);
272: _servletHandler.setServletMappings(null);
273:
274: getWebAppContext().setEventListeners(null);
275: getWebAppContext().setWelcomeFiles(null);
276: if (getWebAppContext().getSecurityHandler() != null)
277: getWebAppContext().getSecurityHandler()
278: .setConstraintMappings(null);
279:
280: if (getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler)
281: ((ErrorPageErrorHandler) getWebAppContext()
282: .getErrorHandler()).setErrorPages(null);
283:
284: // TODO remove classpaths from classloader
285: }
286:
287: /* ------------------------------------------------------------ */
288: protected void initialize(XmlParser.Node config)
289: throws ClassNotFoundException, UnavailableException {
290: _servletHandler = getWebAppContext().getServletHandler();
291: // Get any existing servlets and mappings.
292: _filters = LazyList.array2List(_servletHandler.getFilters());
293: _filterMappings = LazyList.array2List(_servletHandler
294: .getFilterMappings());
295: _servlets = LazyList.array2List(_servletHandler.getServlets());
296: _servletMappings = LazyList.array2List(_servletHandler
297: .getServletMappings());
298:
299: _listeners = LazyList.array2List(getWebAppContext()
300: .getEventListeners());
301: _welcomeFiles = LazyList.array2List(getWebAppContext()
302: .getWelcomeFiles());
303: _constraintMappings = LazyList.array2List(getWebAppContext()
304: .getSecurityHandler().getConstraintMappings());
305:
306: _errorPages = getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler ? ((ErrorPageErrorHandler) getWebAppContext()
307: .getErrorHandler()).getErrorPages()
308: : null;
309:
310: String version = config.getAttribute("version", "DTD");
311: if ("2.5".equals(version))
312: _version = 25;
313: else if ("2.4".equals(version))
314: _version = 24;
315: else if ("DTD".equals(version)) {
316: _version = 23;
317: String dtd = _xmlParser.getDTD();
318: if (dtd != null && dtd.indexOf("web-app_2_2") >= 0)
319: _version = 22;
320: }
321:
322: Iterator iter = config.iterator();
323: XmlParser.Node node = null;
324: while (iter.hasNext()) {
325: try {
326: Object o = iter.next();
327: if (!(o instanceof XmlParser.Node))
328: continue;
329: node = (XmlParser.Node) o;
330: String name = node.getTag();
331: initWebXmlElement(name, node);
332: } catch (ClassNotFoundException e) {
333: throw e;
334: } catch (Exception e) {
335: Log.warn("Configuration problem at " + node, e);
336: throw new UnavailableException("Configuration problem");
337: }
338: }
339:
340: _servletHandler.setFilters((FilterHolder[]) LazyList.toArray(
341: _filters, FilterHolder.class));
342: _servletHandler.setFilterMappings((FilterMapping[]) LazyList
343: .toArray(_filterMappings, FilterMapping.class));
344: _servletHandler.setServlets((ServletHolder[]) LazyList.toArray(
345: _servlets, ServletHolder.class));
346: _servletHandler.setServletMappings((ServletMapping[]) LazyList
347: .toArray(_servletMappings, ServletMapping.class));
348:
349: getWebAppContext().setEventListeners(
350: (EventListener[]) LazyList.toArray(_listeners,
351: EventListener.class));
352: getWebAppContext().setWelcomeFiles(
353: (String[]) LazyList
354: .toArray(_welcomeFiles, String.class));
355: getWebAppContext().getSecurityHandler().setConstraintMappings(
356: (ConstraintMapping[]) LazyList.toArray(
357: _constraintMappings, ConstraintMapping.class));
358:
359: if (_errorPages != null
360: && getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler)
361: ((ErrorPageErrorHandler) getWebAppContext()
362: .getErrorHandler()).setErrorPages(_errorPages);
363:
364: }
365:
366: /* ------------------------------------------------------------ */
367: /**
368: * Handle web.xml element. This method is called for each top level element within the web.xml
369: * file. It may be specialized by derived WebAppHandlers to provide additional
370: * configuration and handling.
371: *
372: * @param element The element name
373: * @param node The node containing the element.
374: */
375: protected void initWebXmlElement(String element, XmlParser.Node node)
376: throws Exception {
377: if ("display-name".equals(element))
378: initDisplayName(node);
379: else if ("description".equals(element)) {
380: } else if ("context-param".equals(element))
381: initContextParam(node);
382: else if ("servlet".equals(element))
383: initServlet(node);
384: else if ("servlet-mapping".equals(element))
385: initServletMapping(node);
386: else if ("session-config".equals(element))
387: initSessionConfig(node);
388: else if ("mime-mapping".equals(element))
389: initMimeConfig(node);
390: else if ("welcome-file-list".equals(element))
391: initWelcomeFileList(node);
392: else if ("locale-encoding-mapping-list".equals(element))
393: initLocaleEncodingList(node);
394: else if ("error-page".equals(element))
395: initErrorPage(node);
396: else if ("taglib".equals(element))
397: initTagLib(node);
398: else if ("jsp-config".equals(element))
399: initJspConfig(node);
400: else if ("resource-ref".equals(element)) {
401: if (Log.isDebugEnabled())
402: Log.debug("No implementation: " + node);
403: } else if ("security-constraint".equals(element))
404: initSecurityConstraint(node);
405: else if ("login-config".equals(element))
406: initLoginConfig(node);
407: else if ("security-role".equals(element))
408: initSecurityRole(node);
409: else if ("filter".equals(element))
410: initFilter(node);
411: else if ("filter-mapping".equals(element))
412: initFilterMapping(node);
413: else if ("listener".equals(element))
414: initListener(node);
415: else if ("distributable".equals(element))
416: initDistributable(node);
417: else {
418: if (Log.isDebugEnabled()) {
419: Log
420: .debug("Element {} not handled in {}", element,
421: this );
422: Log.debug(node.toString());
423: }
424: }
425: }
426:
427: /* ------------------------------------------------------------ */
428: protected void initDisplayName(XmlParser.Node node) {
429: getWebAppContext().setDisplayName(node.toString(false, true));
430: }
431:
432: /* ------------------------------------------------------------ */
433: protected void initContextParam(XmlParser.Node node) {
434: String name = node.getString("param-name", false, true);
435: String value = node.getString("param-value", false, true);
436: if (Log.isDebugEnabled())
437: Log.debug("ContextParam: " + name + "=" + value);
438: getWebAppContext().getInitParams().put(name, value);
439: }
440:
441: /* ------------------------------------------------------------ */
442: protected void initFilter(XmlParser.Node node) {
443: String name = node.getString("filter-name", false, true);
444: FilterHolder holder = _servletHandler.getFilter(name);
445: if (holder == null) {
446: holder = _servletHandler.newFilterHolder();
447: holder.setName(name);
448: _filters = LazyList.add(_filters, holder);
449: }
450:
451: String filter_class = node.getString("filter-class", false,
452: true);
453: if (filter_class != null)
454: holder.setClassName(filter_class);
455:
456: Iterator iter = node.iterator("init-param");
457: while (iter.hasNext()) {
458: XmlParser.Node paramNode = (XmlParser.Node) iter.next();
459: String pname = paramNode.getString("param-name", false,
460: true);
461: String pvalue = paramNode.getString("param-value", false,
462: true);
463: holder.setInitParameter(pname, pvalue);
464: }
465:
466: }
467:
468: /* ------------------------------------------------------------ */
469: protected void initFilterMapping(XmlParser.Node node) {
470: String filter_name = node.getString("filter-name", false, true);
471:
472: FilterMapping mapping = new FilterMapping();
473:
474: mapping.setFilterName(filter_name);
475:
476: ArrayList paths = new ArrayList();
477: Iterator iter = node.iterator("url-pattern");
478: while (iter.hasNext()) {
479: String p = ((XmlParser.Node) iter.next()).toString(false,
480: true);
481: p = normalizePattern(p);
482: paths.add(p);
483: }
484: mapping.setPathSpecs((String[]) paths.toArray(new String[paths
485: .size()]));
486:
487: ArrayList names = new ArrayList();
488: iter = node.iterator("servlet-name");
489: while (iter.hasNext()) {
490: String n = ((XmlParser.Node) iter.next()).toString(false,
491: true);
492: names.add(n);
493: }
494: mapping.setServletNames((String[]) names
495: .toArray(new String[names.size()]));
496:
497: int dispatcher = Handler.DEFAULT;
498: iter = node.iterator("dispatcher");
499: while (iter.hasNext()) {
500: String d = ((XmlParser.Node) iter.next()).toString(false,
501: true);
502: dispatcher |= Dispatcher.type(d);
503: }
504: mapping.setDispatches(dispatcher);
505:
506: _filterMappings = LazyList.add(_filterMappings, mapping);
507: }
508:
509: /* ------------------------------------------------------------ */
510: protected String normalizePattern(String p) {
511: if (p != null && p.length() > 0 && !p.startsWith("/")
512: && !p.startsWith("*"))
513: return "/" + p;
514: return p;
515: }
516:
517: /* ------------------------------------------------------------ */
518: protected void initServlet(XmlParser.Node node) {
519: String id = node.getAttribute("id");
520:
521: // initialize holder
522: String servlet_name = node.getString("servlet-name", false,
523: true);
524: ServletHolder holder = _servletHandler.getServlet(servlet_name);
525: if (holder == null) {
526: holder = _servletHandler.newServletHolder();
527: holder.setName(servlet_name);
528: _servlets = LazyList.add(_servlets, holder);
529: }
530:
531: // init params
532: Iterator iParamsIter = node.iterator("init-param");
533: while (iParamsIter.hasNext()) {
534: XmlParser.Node paramNode = (XmlParser.Node) iParamsIter
535: .next();
536: String pname = paramNode.getString("param-name", false,
537: true);
538: String pvalue = paramNode.getString("param-value", false,
539: true);
540: holder.setInitParameter(pname, pvalue);
541: }
542:
543: String servlet_class = node.getString("servlet-class", false,
544: true);
545:
546: // Handle JSP
547: if (id != null && id.equals("jsp")) {
548: _jspServletName = servlet_name;
549: try {
550: Loader.loadClass(this .getClass(), servlet_class);
551: _hasJSP = true;
552: } catch (ClassNotFoundException e) {
553: Log.info("NO JSP Support for {}, did not find {}",
554: _context.getContextPath(), servlet_class);
555: _hasJSP = false;
556: servlet_class = "org.mortbay.servlet.NoJspServlet";
557: }
558: if (holder.getInitParameter("scratchdir") == null) {
559: File tmp = getWebAppContext().getTempDirectory();
560: File scratch = new File(tmp, "jsp");
561: if (!scratch.exists())
562: scratch.mkdir();
563: holder.setInitParameter("scratchdir", scratch
564: .getAbsolutePath());
565:
566: if ("?".equals(holder.getInitParameter("classpath"))) {
567: String classpath = getWebAppContext()
568: .getClassPath();
569: Log.debug("classpath=" + classpath);
570: if (classpath != null)
571: holder.setInitParameter("classpath", classpath);
572: }
573: }
574: }
575: if (servlet_class != null)
576: holder.setClassName(servlet_class);
577:
578: // Handler JSP file
579: String jsp_file = node.getString("jsp-file", false, true);
580: if (jsp_file != null)
581: holder.setForcedPath(jsp_file);
582:
583: // handle startup
584: XmlParser.Node startup = node.get("load-on-startup");
585: if (startup != null) {
586: String s = startup.toString(false, true).toLowerCase();
587: if (s.startsWith("t")) {
588: Log
589: .warn("Deprecated boolean load-on-startup. Please use integer");
590: holder.setInitOrder(1);
591: } else {
592: int order = 0;
593: try {
594: if (s != null && s.trim().length() > 0)
595: order = Integer.parseInt(s);
596: } catch (Exception e) {
597: Log.warn("Cannot parse load-on-startup " + s
598: + ". Please use integer");
599: Log.ignore(e);
600: }
601: holder.setInitOrder(order);
602: }
603: }
604:
605: Iterator sRefsIter = node.iterator("security-role-ref");
606: while (sRefsIter.hasNext()) {
607: XmlParser.Node securityRef = (XmlParser.Node) sRefsIter
608: .next();
609: String roleName = securityRef.getString("role-name", false,
610: true);
611: String roleLink = securityRef.getString("role-link", false,
612: true);
613: if (roleName != null && roleName.length() > 0
614: && roleLink != null && roleLink.length() > 0) {
615: if (Log.isDebugEnabled())
616: Log.debug("link role " + roleName + " to "
617: + roleLink + " for " + this );
618: holder.setUserRoleLink(roleName, roleLink);
619: } else {
620: Log.warn("Ignored invalid security-role-ref element: "
621: + "servlet-name=" + holder.getName() + ", "
622: + securityRef);
623: }
624: }
625:
626: XmlParser.Node run_as = node.get("run-as");
627: if (run_as != null) {
628: String roleName = run_as
629: .getString("role-name", false, true);
630: if (roleName != null)
631: holder.setRunAs(roleName);
632: }
633:
634: }
635:
636: /* ------------------------------------------------------------ */
637: protected void initServletMapping(XmlParser.Node node) {
638: String servlet_name = node.getString("servlet-name", false,
639: true);
640: ServletMapping mapping = new ServletMapping();
641: mapping.setServletName(servlet_name);
642:
643: ArrayList paths = new ArrayList();
644: Iterator iter = node.iterator("url-pattern");
645: while (iter.hasNext()) {
646: String p = ((XmlParser.Node) iter.next()).toString(false,
647: true);
648: p = normalizePattern(p);
649: paths.add(p);
650: }
651: mapping.setPathSpecs((String[]) paths.toArray(new String[paths
652: .size()]));
653:
654: _servletMappings = LazyList.add(_servletMappings, mapping);
655: }
656:
657: /* ------------------------------------------------------------ */
658: protected void initListener(XmlParser.Node node) {
659: String className = node
660: .getString("listener-class", false, true);
661: Object listener = null;
662: try {
663: Class listenerClass = getWebAppContext().loadClass(
664: className);
665: listener = newListenerInstance(listenerClass);
666: if (!(listener instanceof EventListener)) {
667: Log.warn("Not an EventListener: " + listener);
668: return;
669: }
670: _listeners = LazyList.add(_listeners, listener);
671: } catch (Exception e) {
672: Log.warn("Could not instantiate listener " + className, e);
673: return;
674: }
675: }
676:
677: /* ------------------------------------------------------------ */
678: protected Object newListenerInstance(Class clazz)
679: throws InstantiationException, IllegalAccessException {
680: return clazz.newInstance();
681: }
682:
683: /* ------------------------------------------------------------ */
684: protected void initDistributable(XmlParser.Node node) {
685: // the element has no content, so its simple presence
686: // indicates that the webapp is distributable...
687: WebAppContext wac = getWebAppContext();
688: if (!wac.isDistributable())
689: wac.setDistributable(true);
690: }
691:
692: /* ------------------------------------------------------------ */
693: protected void initSessionConfig(XmlParser.Node node) {
694: XmlParser.Node tNode = node.get("session-timeout");
695: if (tNode != null) {
696: int timeout = Integer.parseInt(tNode.toString(false, true));
697: getWebAppContext().getSessionHandler().getSessionManager()
698: .setMaxInactiveInterval(timeout * 60);
699: }
700: }
701:
702: /* ------------------------------------------------------------ */
703: protected void initMimeConfig(XmlParser.Node node) {
704: String extension = node.getString("extension", false, true);
705: if (extension != null && extension.startsWith("."))
706: extension = extension.substring(1);
707: String mimeType = node.getString("mime-type", false, true);
708: getWebAppContext().getMimeTypes().addMimeMapping(extension,
709: mimeType);
710: }
711:
712: /* ------------------------------------------------------------ */
713: protected void initWelcomeFileList(XmlParser.Node node) {
714: if (_defaultWelcomeFileList)
715: _welcomeFiles = null; // erase welcome files from default web.xml
716:
717: _defaultWelcomeFileList = false;
718: Iterator iter = node.iterator("welcome-file");
719: while (iter.hasNext()) {
720: XmlParser.Node indexNode = (XmlParser.Node) iter.next();
721: String welcome = indexNode.toString(false, true);
722: _welcomeFiles = LazyList.add(_welcomeFiles, welcome);
723: }
724: }
725:
726: /* ------------------------------------------------------------ */
727: protected void initLocaleEncodingList(XmlParser.Node node) {
728: Iterator iter = node.iterator("locale-encoding-mapping");
729: while (iter.hasNext()) {
730: XmlParser.Node mapping = (XmlParser.Node) iter.next();
731: String locale = mapping.getString("locale", false, true);
732: String encoding = mapping
733: .getString("encoding", false, true);
734: getWebAppContext().addLocaleEncoding(locale, encoding);
735: }
736: }
737:
738: /* ------------------------------------------------------------ */
739: protected void initErrorPage(XmlParser.Node node) {
740: String error = node.getString("error-code", false, true);
741: if (error == null || error.length() == 0)
742: error = node.getString("exception-type", false, true);
743: String location = node.getString("location", false, true);
744:
745: if (_errorPages == null)
746: _errorPages = new HashMap();
747: _errorPages.put(error, location);
748: }
749:
750: /* ------------------------------------------------------------ */
751: protected void initTagLib(XmlParser.Node node) {
752: String uri = node.getString("taglib-uri", false, true);
753: String location = node
754: .getString("taglib-location", false, true);
755:
756: getWebAppContext().setResourceAlias(uri, location);
757: }
758:
759: /* ------------------------------------------------------------ */
760: protected void initJspConfig(XmlParser.Node node) {
761: for (int i = 0; i < node.size(); i++) {
762: Object o = node.get(i);
763: if (o instanceof XmlParser.Node
764: && "taglib".equals(((XmlParser.Node) o).getTag()))
765: initTagLib((XmlParser.Node) o);
766: }
767:
768: // Map URLs from jsp property groups to JSP servlet.
769: // this is more JSP stupidness creaping into the servlet spec
770: Iterator iter = node.iterator("jsp-property-group");
771: Object paths = null;
772: while (iter.hasNext()) {
773: XmlParser.Node group = (XmlParser.Node) iter.next();
774: Iterator iter2 = group.iterator("url-pattern");
775: while (iter2.hasNext()) {
776: String url = ((XmlParser.Node) iter2.next()).toString(
777: false, true);
778: url = normalizePattern(url);
779: paths = LazyList.add(paths, url);
780: }
781: }
782:
783: if (LazyList.size(paths) > 0) {
784: String jspName = getJSPServletName();
785: if (jspName != null) {
786: ServletMapping mapping = new ServletMapping();
787: mapping.setServletName(jspName);
788: mapping.setPathSpecs(LazyList.toStringArray(paths));
789: _servletMappings = LazyList.add(_servletMappings,
790: mapping);
791: }
792: }
793: }
794:
795: /* ------------------------------------------------------------ */
796: protected void initSecurityConstraint(XmlParser.Node node) {
797: Constraint scBase = new Constraint();
798:
799: try {
800: XmlParser.Node auths = node.get("auth-constraint");
801:
802: if (auths != null) {
803: scBase.setAuthenticate(true);
804: // auth-constraint
805: Iterator iter = auths.iterator("role-name");
806: Object roles = null;
807: while (iter.hasNext()) {
808: String role = ((XmlParser.Node) iter.next())
809: .toString(false, true);
810: roles = LazyList.add(roles, role);
811: }
812: scBase.setRoles(LazyList.toStringArray(roles));
813: }
814:
815: XmlParser.Node data = node.get("user-data-constraint");
816: if (data != null) {
817: data = data.get("transport-guarantee");
818: String guarantee = data.toString(false, true)
819: .toUpperCase();
820: if (guarantee == null || guarantee.length() == 0
821: || "NONE".equals(guarantee))
822: scBase.setDataConstraint(Constraint.DC_NONE);
823: else if ("INTEGRAL".equals(guarantee))
824: scBase.setDataConstraint(Constraint.DC_INTEGRAL);
825: else if ("CONFIDENTIAL".equals(guarantee))
826: scBase
827: .setDataConstraint(Constraint.DC_CONFIDENTIAL);
828: else {
829: Log.warn("Unknown user-data-constraint:"
830: + guarantee);
831: scBase
832: .setDataConstraint(Constraint.DC_CONFIDENTIAL);
833: }
834: }
835: Iterator iter = node.iterator("web-resource-collection");
836: while (iter.hasNext()) {
837: XmlParser.Node collection = (XmlParser.Node) iter
838: .next();
839: String name = collection.getString("web-resource-name",
840: false, true);
841: Constraint sc = (Constraint) scBase.clone();
842: sc.setName(name);
843:
844: Iterator iter2 = collection.iterator("url-pattern");
845: while (iter2.hasNext()) {
846: String url = ((XmlParser.Node) iter2.next())
847: .toString(false, true);
848: url = normalizePattern(url);
849:
850: Iterator iter3 = collection.iterator("http-method");
851: if (iter3.hasNext()) {
852: while (iter3.hasNext()) {
853: String method = ((XmlParser.Node) iter3
854: .next()).toString(false, true);
855: ConstraintMapping mapping = new ConstraintMapping();
856: mapping.setMethod(method);
857: mapping.setPathSpec(url);
858: mapping.setConstraint(sc);
859: _constraintMappings = LazyList.add(
860: _constraintMappings, mapping);
861: }
862: } else {
863: ConstraintMapping mapping = new ConstraintMapping();
864: mapping.setPathSpec(url);
865: mapping.setConstraint(sc);
866: _constraintMappings = LazyList.add(
867: _constraintMappings, mapping);
868: }
869: }
870: }
871: } catch (CloneNotSupportedException e) {
872: Log.warn(e);
873: }
874:
875: }
876:
877: /* ------------------------------------------------------------ */
878: protected void initLoginConfig(XmlParser.Node node) {
879: XmlParser.Node method = node.get("auth-method");
880: FormAuthenticator _formAuthenticator = null;
881: if (method != null) {
882: Authenticator authenticator = null;
883: String m = method.toString(false, true);
884: if (Constraint.__FORM_AUTH.equals(m))
885: authenticator = _formAuthenticator = new FormAuthenticator();
886: else if (Constraint.__BASIC_AUTH.equals(m))
887: authenticator = new BasicAuthenticator();
888: else if (Constraint.__DIGEST_AUTH.equals(m))
889: authenticator = new DigestAuthenticator();
890: else if (Constraint.__CERT_AUTH.equals(m))
891: authenticator = new ClientCertAuthenticator();
892: else if (Constraint.__CERT_AUTH2.equals(m))
893: authenticator = new ClientCertAuthenticator();
894: else
895: Log.warn("UNKNOWN AUTH METHOD: " + m);
896: getWebAppContext().getSecurityHandler().setAuthenticator(
897: authenticator);
898: }
899: XmlParser.Node name = node.get("realm-name");
900: if (name != null) {
901: String realm_name = name.toString(false, true);
902:
903: UserRealm[] realms = ContextHandler.getCurrentContext()
904: .getContextHandler().getServer().getUserRealms();
905: UserRealm realm = getWebAppContext().getSecurityHandler()
906: .getUserRealm();
907: for (int i = 0; realm == null && realms != null
908: && i < realms.length; i++) {
909: if (realms[i] != null
910: && realm_name.equals(realms[i].getName()))
911: realm = realms[i];
912: }
913:
914: if (realm == null) {
915: String msg = "Unknown realm: " + realm_name;
916: Log.warn(msg);
917: } else
918: getWebAppContext().getSecurityHandler().setUserRealm(
919: realm);
920: }
921: XmlParser.Node formConfig = node.get("form-login-config");
922: if (formConfig != null) {
923: if (_formAuthenticator == null)
924: Log.warn("FORM Authentication miss-configured");
925: else {
926: XmlParser.Node loginPage = formConfig
927: .get("form-login-page");
928: if (loginPage != null)
929: _formAuthenticator.setLoginPage(loginPage.toString(
930: false, true));
931: XmlParser.Node errorPage = formConfig
932: .get("form-error-page");
933: if (errorPage != null) {
934: String ep = errorPage.toString(false, true);
935: _formAuthenticator.setErrorPage(ep);
936: }
937: }
938: }
939: }
940:
941: /* ------------------------------------------------------------ */
942: protected void initSecurityRole(XmlParser.Node node) {
943: }
944:
945: /* ------------------------------------------------------------ */
946: protected String getJSPServletName() {
947: if (_jspServletName == null) {
948: Map.Entry entry = _context.getServletHandler()
949: .getHolderEntry("test.jsp");
950: if (entry != null) {
951: ServletHolder holder = (ServletHolder) entry.getValue();
952: _jspServletName = holder.getName();
953: }
954: }
955: return _jspServletName;
956: }
957: }
|