net.lightbody.bmp.proxy.jetty.jetty.servlet.XMLConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for net.lightbody.bmp.proxy.jetty.jetty.servlet.XMLConfiguration.java

Source

// ========================================================================
// $Id: XMLConfiguration.java,v 1.20 2005/12/05 08:56:48 gregwilkins Exp $
// Copyright 2003-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at 
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package net.lightbody.bmp.proxy.jetty.jetty.servlet;

import net.lightbody.bmp.proxy.jetty.http.Authenticator;
import net.lightbody.bmp.proxy.jetty.http.ClientCertAuthenticator;
import net.lightbody.bmp.proxy.jetty.http.SecurityConstraint;
import net.lightbody.bmp.proxy.jetty.log.LogFactory;
import net.lightbody.bmp.proxy.jetty.util.LogSupport;
import net.lightbody.bmp.proxy.jetty.util.Resource;
import net.lightbody.bmp.proxy.jetty.xml.XmlParser;
import org.apache.commons.logging.Log;

import javax.servlet.UnavailableException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Iterator;
import java.util.Map;

/* ------------------------------------------------------------------------------- */
/**
 * @version $Revision: 1.20 $
 * @author gregw
 */
public class XMLConfiguration implements WebApplicationContext.Configuration {
    private static Log log = LogFactory.getLog(XMLConfiguration.class);
    private WebApplicationContext _context;
    protected XmlParser xmlParser;

    public XMLConfiguration() {
        // Get parser
        xmlParser = webXmlParser();
    }

    public static XmlParser webXmlParser() {
        XmlParser xmlParser = new XmlParser();
        //set up cache of DTDs and schemas locally
        URL dtd22 = WebApplicationContext.class.getResource("/javax/servlet/resources/web-app_2_2.dtd");
        URL dtd23 = WebApplicationContext.class.getResource("/javax/servlet/resources/web-app_2_3.dtd");
        URL jsp20xsd = WebApplicationContext.class.getResource("/javax/servlet/resources/jsp_2_0.xsd");
        URL j2ee14xsd = WebApplicationContext.class.getResource("/javax/servlet/resources/j2ee_1_4.xsd");
        URL webapp24xsd = WebApplicationContext.class.getResource("/javax/servlet/resources/web-app_2_4.xsd");
        URL schemadtd = WebApplicationContext.class.getResource("/javax/servlet/resources/XMLSchema.dtd");
        URL xmlxsd = WebApplicationContext.class.getResource("/javax/servlet/resources/xml.xsd");
        URL webserviceclient11xsd = WebApplicationContext.class
                .getResource("/javax/servlet/resources/j2ee_web_services_client_1_1.xsd");
        URL webservice11xsd = WebApplicationContext.class
                .getResource("/javax/servlet/resources/j2ee_web_services_1_1.xsd");
        URL datatypesdtd = WebApplicationContext.class.getResource("/javax/servlet/resources/datatypes.dtd");
        xmlParser.redirectEntity("web-app_2_2.dtd", dtd22);
        xmlParser.redirectEntity("-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN", dtd22);
        xmlParser.redirectEntity("web.dtd", dtd23);
        xmlParser.redirectEntity("web-app_2_3.dtd", dtd23);
        xmlParser.redirectEntity("-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", dtd23);
        xmlParser.redirectEntity("XMLSchema.dtd", schemadtd);
        xmlParser.redirectEntity("http://www.w3.org/2001/XMLSchema.dtd", schemadtd);
        xmlParser.redirectEntity("-//W3C//DTD XMLSCHEMA 200102//EN", schemadtd);
        xmlParser.redirectEntity("jsp_2_0.xsd", jsp20xsd);
        xmlParser.redirectEntity("http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd", jsp20xsd);
        xmlParser.redirectEntity("j2ee_1_4.xsd", j2ee14xsd);
        xmlParser.redirectEntity("http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd", j2ee14xsd);
        xmlParser.redirectEntity("web-app_2_4.xsd", webapp24xsd);
        xmlParser.redirectEntity("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd", webapp24xsd);
        xmlParser.redirectEntity("xml.xsd", xmlxsd);
        xmlParser.redirectEntity("http://www.w3.org/2001/xml.xsd", xmlxsd);
        xmlParser.redirectEntity("datatypes.dtd", datatypesdtd);
        xmlParser.redirectEntity("http://www.w3.org/2001/datatypes.dtd", datatypesdtd);
        xmlParser.redirectEntity("j2ee_web_services_client_1_1.xsd", webservice11xsd);
        xmlParser.redirectEntity("http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd", webservice11xsd);
        xmlParser.redirectEntity("http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",
                webserviceclient11xsd);
        return xmlParser;
    }

    public void setWebApplicationContext(WebApplicationContext context) {
        _context = context;
    }

    public WebApplicationContext getWebApplicationContext() {
        return _context;
    }

    public WebApplicationHandler getWebApplicationHandler() {
        return _context.getWebApplicationHandler();
    }

    /* ------------------------------------------------------------------------------- */
    /** Configure ClassPath.
     * This method is called before the context ClassLoader is created.  
     * Paths and libraries should be added to the context using the setClassPath,
     * addClassPath and addClassPaths methods.  The default implementation looks
     * for WEB-INF/classes, WEB-INF/lib/*.zip and WEB-INF/lib/*.jar
     * @throws Exception
     */
    public void configureClassPath() throws Exception {
        //cannot configure if the context is already started
        if (_context.isStarted()) {
            if (log.isDebugEnabled()) {
                log.debug("Cannot configure webapp after it is started");
            }
            ;
            return;
        }

        Resource webInf = _context.getWebInf();

        // Add WEB-INF classes and lib classpaths
        if (webInf != null && webInf.isDirectory()) {
            // Look for classes directory
            Resource classes = webInf.addPath("classes/");
            if (classes.exists())
                _context.setClassPath(classes.toString());
            else
                _context.setClassPath(null);

            // Look for jars
            Resource lib = webInf.addPath("lib/");
            _context.addClassPaths(lib);
        }
    }

    /* ------------------------------------------------------------------------------- */
    public void configureDefaults() throws Exception {
        //cannot configure if the context is already started
        if (_context.isStarted()) {
            if (log.isDebugEnabled()) {
                log.debug("Cannot configure webapp after it is started");
            }
            ;
            return;
        }

        getWebApplicationContext().setWelcomeFiles(null);

        String defaultsDescriptor = getWebApplicationContext().getDefaultsDescriptor();
        if (defaultsDescriptor != null && defaultsDescriptor.length() > 0) {
            Resource dftResource = Resource.newSystemResource(defaultsDescriptor);
            if (dftResource == null)
                dftResource = Resource.newResource(defaultsDescriptor);
            XmlParser.Node defaultConfig = xmlParser.parse(dftResource.getURL());
            initialize(defaultConfig);
        }
    }

    /* ------------------------------------------------------------------------------- */
    public void configureWebApp() throws Exception {
        //cannot configure if the context is already started
        if (_context.isStarted()) {
            if (log.isDebugEnabled()) {
                log.debug("Cannot configure webapp after it is started");
            }
            ;
            return;
        }

        Resource webInf = getWebApplicationContext().getWebInf();
        // handle any WEB-INF descriptors
        if (webInf != null && webInf.isDirectory()) {
            // do web.xml file
            Resource web = webInf.addPath("web.xml");
            if (!web.exists()) {
                log.info("No WEB-INF/web.xml in " + getWebApplicationContext().getWAR()
                        + ". Serving files and default/dynamic servlets only");
            } else {
                XmlParser.Node config = null;
                config = xmlParser.parse(web.getURL());
                initialize(config);
            }
        }
    }

    /* ------------------------------------------------------------ */
    protected void initialize(XmlParser.Node config) throws ClassNotFoundException, UnavailableException {
        Iterator iter = config.iterator();
        XmlParser.Node node = null;
        while (iter.hasNext()) {
            try {
                Object o = iter.next();
                if (!(o instanceof XmlParser.Node))
                    continue;
                node = (XmlParser.Node) o;
                String name = node.getTag();
                initWebXmlElement(name, node);
            } catch (ClassNotFoundException e) {
                throw e;
            } catch (Exception e) {
                log.warn("Configuration problem at " + node, e);
                throw new UnavailableException("Configuration problem");
            }
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * Handle web.xml element. This method is called for each top level element within the web.xml
     * file. It may be specialized by derived WebApplicationContexts to provide additional
     * configuration and handling.
     * 
     * @param element The element name
     * @param node The node containing the element.
     */
    protected void initWebXmlElement(String element, XmlParser.Node node) throws Exception {
        if ("display-name".equals(element))
            initDisplayName(node);
        else if ("description".equals(element)) {
        } else if ("context-param".equals(element))
            initContextParam(node);
        else if ("servlet".equals(element))
            initServlet(node);
        else if ("servlet-mapping".equals(element))
            initServletMapping(node);
        else if ("session-config".equals(element))
            initSessionConfig(node);
        else if ("mime-mapping".equals(element))
            initMimeConfig(node);
        else if ("welcome-file-list".equals(element))
            initWelcomeFileList(node);
        else if ("locale-encoding-mapping-list".equals(element))
            initLocaleEncodingList(node);
        else if ("error-page".equals(element))
            initErrorPage(node);
        else if ("taglib".equals(element))
            initTagLib(node);
        else if ("jsp-config".equals(element))
            initJspConfig(node);
        else if ("resource-ref".equals(element)) {
            if (log.isDebugEnabled())
                log.debug("No implementation: " + node);
        } else if ("security-constraint".equals(element))
            initSecurityConstraint(node);
        else if ("login-config".equals(element))
            initLoginConfig(node);
        else if ("security-role".equals(element))
            initSecurityRole(node);
        else if ("filter".equals(element))
            initFilter(node);
        else if ("filter-mapping".equals(element))
            initFilterMapping(node);
        else if ("listener".equals(element))
            initListener(node);
        else if ("distributable".equals(element))
            initDistributable(node);
        else {
            if (log.isDebugEnabled()) {
                log.debug("Element " + element + " not handled in " + this);
                log.debug(node);
            }
        }
    }

    /* ------------------------------------------------------------ */
    protected void initDisplayName(XmlParser.Node node) {
        getWebApplicationContext().setDisplayName(node.toString(false, true));
    }

    /* ------------------------------------------------------------ */
    protected void initContextParam(XmlParser.Node node) {
        String name = node.getString("param-name", false, true);
        String value = node.getString("param-value", false, true);
        if (log.isDebugEnabled())
            log.debug("ContextParam: " + name + "=" + value);
        getWebApplicationContext().setInitParameter(name, value);
    }

    /* ------------------------------------------------------------ */
    protected void initFilter(XmlParser.Node node) throws ClassNotFoundException, UnavailableException {
        String name = node.getString("filter-name", false, true);
        String className = node.getString("filter-class", false, true);
        if (className == null) {
            log.warn("Missing filter-class in " + node);
            return;
        }
        if (name == null)
            name = className;
        FilterHolder holder = getWebApplicationHandler().defineFilter(name, className);
        Iterator iter = node.iterator("init-param");
        while (iter.hasNext()) {
            XmlParser.Node paramNode = (XmlParser.Node) iter.next();
            String pname = paramNode.getString("param-name", false, true);
            String pvalue = paramNode.getString("param-value", false, true);
            holder.put(pname, pvalue);
        }
    }

    /* ------------------------------------------------------------ */
    protected void initFilterMapping(XmlParser.Node node) {
        String filterName = node.getString("filter-name", false, true);
        String pathSpec = node.getString("url-pattern", false, true);
        String servletName = node.getString("servlet-name", false, true);
        int dispatcher = Dispatcher.__DEFAULT;
        Iterator iter = node.iterator("dispatcher");
        while (iter.hasNext()) {
            String d = ((XmlParser.Node) iter.next()).toString(false, true);
            dispatcher |= Dispatcher.type(d);
        }

        FilterHolder holder = (servletName != null)
                ? getWebApplicationHandler().addFilterServletMapping(servletName, filterName, dispatcher)
                : getWebApplicationHandler().addFilterPathMapping(pathSpec, filterName, dispatcher);
    }

    /* ------------------------------------------------------------ */
    protected void initServlet(XmlParser.Node node)
            throws ClassNotFoundException, UnavailableException, IOException, MalformedURLException {
        String name = node.getString("servlet-name", false, true);
        String className = node.getString("servlet-class", false, true);
        String jspFile = null;
        Holder template = null;
        if (className == null) {
            // There is no class, so look for a jsp file
            jspFile = node.getString("jsp-file", false, true);
            if (jspFile != null) {
                Map.Entry entry = getWebApplicationHandler().getHolderEntry(jspFile);
                if (entry != null) {
                    template = (Holder) entry.getValue();
                    className = template.getClassName();
                }
            }
            if (className == null) {
                log.warn("Missing servlet-class|jsp-file in " + node);
                return;
            }
        }
        if (name == null)
            name = className;
        ServletHolder holder = getWebApplicationHandler().newServletHolder(name, className, jspFile);

        // handle JSP configuration
        if (jspFile != null) {
            Enumeration e = template.getInitParameterNames();

            while (e.hasMoreElements()) {
                String p = (String) e.nextElement();
                holder.setInitParameter(p, template.getInitParameter(p));
            }
            if (holder.getInitParameter("classpath") == null)
                holder.setInitParameter("classpath", getWebApplicationContext().getFileClassPath());
        }

        // handle init params
        Iterator iParamsIter = node.iterator("init-param");
        while (iParamsIter.hasNext()) {
            XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next();
            String pname = paramNode.getString("param-name", false, true);
            String pvalue = paramNode.getString("param-value", false, true);
            holder.put(pname, pvalue);
        }
        XmlParser.Node startup = node.get("load-on-startup");
        if (startup != null) {
            String s = startup.toString(false, true).toLowerCase();
            if (s.startsWith("t")) {
                log.warn("Deprecated boolean load-on-startup.  Please use integer");
                holder.setInitOrder(1);
            } else {
                int order = 0;
                try {
                    if (s != null && s.trim().length() > 0)
                        order = Integer.parseInt(s);
                } catch (Exception e) {
                    log.warn("Cannot parse load-on-startup " + s + ". Please use integer");
                    LogSupport.ignore(log, e);
                }
                holder.setInitOrder(order);
            }
        }
        Iterator sRefsIter = node.iterator("security-role-ref");
        while (sRefsIter.hasNext()) {
            XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next();
            String roleName = securityRef.getString("role-name", false, true);
            String roleLink = securityRef.getString("role-link", false, true);
            if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0) {
                if (log.isDebugEnabled())
                    log.debug("link role " + roleName + " to " + roleLink + " for " + this);
                holder.setUserRoleLink(roleName, roleLink);
            } else {
                log.warn("Ignored invalid security-role-ref element: " + "servlet-name=" + name + ", "
                        + securityRef);
            }
        }
        XmlParser.Node run_as = node.get("run-as");
        if (run_as != null) {
            String roleName = run_as.getString("role-name", false, true);
            if (roleName != null)
                holder.setRunAs(roleName);
        }
    }

    /* ------------------------------------------------------------ */
    protected void initServletMapping(XmlParser.Node node) {
        String name = node.getString("servlet-name", false, true);
        String pathSpec = node.getString("url-pattern", false, true);
        getWebApplicationHandler().mapPathToServlet(pathSpec, name);
    }

    /* ------------------------------------------------------------ */
    protected void initListener(XmlParser.Node node) {
        String className = node.getString("listener-class", false, true);
        Object listener = null;
        try {
            Class listenerClass = getWebApplicationContext().loadClass(className);
            listener = listenerClass.newInstance();
        } catch (Exception e) {
            log.warn("Could not instantiate listener " + className, e);
            return;
        }
        if (!(listener instanceof EventListener)) {
            log.warn("Not an EventListener: " + listener);
            return;
        }
        boolean known = false;
        try {
            getWebApplicationContext().addEventListener((EventListener) listener);
            known = true;
        } catch (Exception e) {
            LogSupport.ignore(log, e);
        }
        try {
            getWebApplicationHandler().addEventListener((EventListener) listener);
            known = true;
        } catch (Exception e) {
            LogSupport.ignore(log, e);
        }
        if (!known)
            log.warn("Unknown: " + listener);
    }

    /* ------------------------------------------------------------ */
    protected void initDistributable(XmlParser.Node node) {
        // the element has no content, so its simple presence
        // indicates that the webapp is distributable...
        WebApplicationContext wac = getWebApplicationContext();
        if (!wac.isDistributable())
            wac.setDistributable(true);
    }

    /* ------------------------------------------------------------ */
    protected void initSessionConfig(XmlParser.Node node) {
        XmlParser.Node tNode = node.get("session-timeout");
        if (tNode != null) {
            int timeout = Integer.parseInt(tNode.toString(false, true));
            getWebApplicationHandler().setSessionInactiveInterval(timeout * 60);
        }
    }

    /* ------------------------------------------------------------ */
    protected void initMimeConfig(XmlParser.Node node) {
        String extension = node.getString("extension", false, true);
        if (extension != null && extension.startsWith("."))
            extension = extension.substring(1);
        String mimeType = node.getString("mime-type", false, true);
        getWebApplicationContext().setMimeMapping(extension, mimeType);
    }

    /* ------------------------------------------------------------ */
    protected void initWelcomeFileList(XmlParser.Node node) {
        Iterator iter = node.iterator("welcome-file");
        while (iter.hasNext()) {
            XmlParser.Node indexNode = (XmlParser.Node) iter.next();
            String index = indexNode.toString(false, true);
            if (log.isDebugEnabled())
                log.debug("Index: " + index);
            getWebApplicationContext().addWelcomeFile(index);
        }
    }

    /* ------------------------------------------------------------ */
    protected void initLocaleEncodingList(XmlParser.Node node) {
        Iterator iter = node.iterator("locale-encoding-mapping");
        while (iter.hasNext()) {
            XmlParser.Node mapping = (XmlParser.Node) iter.next();
            String locale = mapping.getString("locale", false, true);
            String encoding = mapping.getString("encoding", false, true);
            getWebApplicationContext().addLocaleEncoding(locale, encoding);
        }
    }

    /* ------------------------------------------------------------ */
    protected void initErrorPage(XmlParser.Node node) {
        String error = node.getString("error-code", false, true);
        if (error == null || error.length() == 0)
            error = node.getString("exception-type", false, true);
        String location = node.getString("location", false, true);
        getWebApplicationContext().setErrorPage(error, location);
    }

    /* ------------------------------------------------------------ */
    protected void initTagLib(XmlParser.Node node) {
        String uri = node.getString("taglib-uri", false, true);
        String location = node.getString("taglib-location", false, true);
        getWebApplicationContext().setResourceAlias(uri, location);
    }

    /* ------------------------------------------------------------ */
    protected void initJspConfig(XmlParser.Node node) {
        for (int i = 0; i < node.size(); i++) {
            Object o = node.get(i);
            if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node) o).getTag()))
                initTagLib((XmlParser.Node) o);
        }
    }

    /* ------------------------------------------------------------ */
    protected void initSecurityConstraint(XmlParser.Node node) {
        try {
            SecurityConstraint scBase = new SecurityConstraint();
            XmlParser.Node auths = node.get("auth-constraint");
            if (auths != null) {
                scBase.setAuthenticate(true);
                // auth-constraint
                Iterator iter = auths.iterator("role-name");
                while (iter.hasNext()) {
                    String role = ((XmlParser.Node) iter.next()).toString(false, true);
                    scBase.addRole(role);
                }
            }
            XmlParser.Node data = node.get("user-data-constraint");
            if (data != null) {
                data = data.get("transport-guarantee");
                String guarantee = data.toString(false, true).toUpperCase();
                if (guarantee == null || guarantee.length() == 0 || "NONE".equals(guarantee))
                    scBase.setDataConstraint(SecurityConstraint.DC_NONE);
                else if ("INTEGRAL".equals(guarantee))
                    scBase.setDataConstraint(SecurityConstraint.DC_INTEGRAL);
                else if ("CONFIDENTIAL".equals(guarantee))
                    scBase.setDataConstraint(SecurityConstraint.DC_CONFIDENTIAL);
                else {
                    log.warn("Unknown user-data-constraint:" + guarantee);
                    scBase.setDataConstraint(SecurityConstraint.DC_CONFIDENTIAL);
                }
            }
            Iterator iter = node.iterator("web-resource-collection");
            while (iter.hasNext()) {
                XmlParser.Node collection = (XmlParser.Node) iter.next();
                String name = collection.getString("web-resource-name", false, true);
                SecurityConstraint sc = (SecurityConstraint) scBase.clone();
                sc.setName(name);
                Iterator iter2 = collection.iterator("http-method");
                while (iter2.hasNext())
                    sc.addMethod(((XmlParser.Node) iter2.next()).toString(false, true));
                iter2 = collection.iterator("url-pattern");
                while (iter2.hasNext()) {
                    String url = ((XmlParser.Node) iter2.next()).toString(false, true);
                    getWebApplicationContext().addSecurityConstraint(url, sc);
                }
            }
        } catch (CloneNotSupportedException e) {
            log.fatal(e);
        }
    }

    /* ------------------------------------------------------------ */
    protected void initLoginConfig(XmlParser.Node node) {
        XmlParser.Node method = node.get("auth-method");
        FormAuthenticator _formAuthenticator = null;
        if (method != null) {
            Authenticator authenticator = null;
            String m = method.toString(false, true);
            if (SecurityConstraint.__FORM_AUTH.equals(m))
                authenticator = _formAuthenticator = new FormAuthenticator();
            else if (SecurityConstraint.__BASIC_AUTH.equals(m))
                authenticator = new BasicAuthenticator();
            else if (SecurityConstraint.__DIGEST_AUTH.equals(m))
                authenticator = new DigestAuthenticator();
            else if (SecurityConstraint.__CERT_AUTH.equals(m))
                authenticator = new ClientCertAuthenticator();
            else if (SecurityConstraint.__CERT_AUTH2.equals(m))
                authenticator = new ClientCertAuthenticator();
            else
                log.warn("UNKNOWN AUTH METHOD: " + m);
            getWebApplicationContext().setAuthenticator(authenticator);
        }
        XmlParser.Node name = node.get("realm-name");
        if (name != null)
            getWebApplicationContext().setRealmName(name.toString(false, true));
        XmlParser.Node formConfig = node.get("form-login-config");
        if (formConfig != null) {
            if (_formAuthenticator == null)
                log.warn("FORM Authentication miss-configured");
            else {
                XmlParser.Node loginPage = formConfig.get("form-login-page");
                if (loginPage != null)
                    _formAuthenticator.setLoginPage(loginPage.toString(false, true));
                XmlParser.Node errorPage = formConfig.get("form-error-page");
                if (errorPage != null) {
                    String ep = errorPage.toString(false, true);
                    _formAuthenticator.setErrorPage(ep);
                }
            }
        }
    }

    /* ------------------------------------------------------------ */
    protected void initSecurityRole(XmlParser.Node node) {
    }
}