`

Struts1.3.10深入源代码之核心类ActionServlet类

阅读更多
org.apache.struts.action.ActionServlet类是Struts框架的核心控制器组件,所有的用户请求都由ActionServlet类来处理,然后再由ActionServlet把请求转发给其他组件。Struts框架只允许在一个应用中配置一个ActionServlet类,在应用的生命周期中,仅创建ActionServlet类的一个实例,这个ActionServlet实例可以同时相应多个用户的请求。
Struts框架的初始化过程:Servlet容器在启动时,或者用户首次请求ActionServlet时加载ActionServlet类。Servlet类在ActionServlet类被加载后立即执行它的init()方法,这可以保证当ActionServlet处理用户请求时已经被初始化。

下面是init()方法:
public void init() throws ServletException {
        final String configPrefix = "config/";
        final int configPrefixLength = configPrefix.length() - 1;

        // Wraps the entire initialization in a try/catch to better handle
        // unexpected exceptions and errors to provide better feedback
        // to the developer
        try {
            initInternal();
            initOther();
            initServlet();
            initChain();

            getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
            initModuleConfigFactory();

            // Initialize modules as needed
            ModuleConfig moduleConfig = initModuleConfig("", config);

            initModuleMessageResources(moduleConfig);
            initModulePlugIns(moduleConfig);
            initModuleFormBeans(moduleConfig);
            initModuleForwards(moduleConfig);
            initModuleExceptionConfigs(moduleConfig);
            initModuleActions(moduleConfig);
            moduleConfig.freeze();

            Enumeration names = getServletConfig().getInitParameterNames();

            while (names.hasMoreElements()) {
                String name = (String) names.nextElement();

                if (!name.startsWith(configPrefix)) {
                    continue;
                }

                String prefix = name.substring(configPrefixLength);

                moduleConfig =
                    initModuleConfig(prefix,
                        getServletConfig().getInitParameter(name));
                initModuleMessageResources(moduleConfig);
                initModulePlugIns(moduleConfig);
                initModuleFormBeans(moduleConfig);
                initModuleForwards(moduleConfig);
                initModuleExceptionConfigs(moduleConfig);
                initModuleActions(moduleConfig);
                moduleConfig.freeze();
            }

            this.initModulePrefixes(this.getServletContext());

            this.destroyConfigDigester();
        } catch (UnavailableException ex) {
            throw ex;
        } catch (Throwable t) {
            // The follow error message is not retrieved from internal message
            // resources as they may not have been able to have been
            // initialized
            log.error("Unable to initialize Struts ActionServlet due to an "
                + "unexpected exception or error thrown, so marking the "
                + "servlet as unavailable.  Most likely, this is due to an "
                + "incorrect or missing library dependency.", t);
            throw new UnavailableException(t.getMessage());
        }
    }


在init()初始化方法中主要有下面几步构成
(1)调用initInternal()方法,初始化Struts框架内在的消息资源,如与系统日志相关的通知、警告和错误消息。
(2)调用initOther()方法,从web.xml文件中加载ActionServlet的初始化参数,如congig参数。
(3)调用initServlet()方法,从web.xml文件中加载ActionServlet的URL映射信息。此外还会注册web.xml和Struts配置文件所使用的DTD文件,这些DTD文件用来验证web.xml和Struts配置文件的语法。
(4)调用initModuleConfig()方法,加载并解析默认子应用模块的Struts配置文件,创建ModuleConfig对象,把它存储在ServletContext中。
(5)调用initModuleMessageResources()方法,加载并初始化默认子应用模块的消息资源;创建MessageResources对象,把它存储在ServletContext中。
(6)调用initModuleDataSources(),加载并初始化默认子应用模块的数据源。
(7)调用initModulePlugins()方法,加载并初始化默认子应用模块的所有插件。
(8)当默认子模块被成功地初始化后,如果还包括其他子应用模块,将重复流程(4)~(7),分别对其他子应用模块进行初始化。


下面是ActionSerlet类的完整源代码
package org.apache.struts.action;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.BigIntegerConverter;
import org.apache.commons.beanutils.converters.BooleanConverter;
import org.apache.commons.beanutils.converters.ByteConverter;
import org.apache.commons.beanutils.converters.CharacterConverter;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.commons.beanutils.converters.ShortConverter;
import org.apache.commons.chain.CatalogFactory;
import org.apache.commons.chain.config.ConfigParser;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.config.ActionConfig;
import org.apache.struts.config.ConfigRuleSet;
import org.apache.struts.config.ExceptionConfig;
import org.apache.struts.config.FormBeanConfig;
import org.apache.struts.config.FormPropertyConfig;
import org.apache.struts.config.ForwardConfig;
import org.apache.struts.config.MessageResourcesConfig;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.config.ModuleConfigFactory;
import org.apache.struts.config.PlugInConfig;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.MessageResourcesFactory;
import org.apache.struts.util.ModuleUtils;
import org.apache.struts.util.RequestUtils;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.InputStream;

import java.math.BigDecimal;
import java.math.BigInteger;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.MissingResourceException;

public class ActionServlet extends HttpServlet {
    /**
     * <p>Commons Logging instance.</p>
     *
     * @since Struts 1.1
     */
    protected static Log log = LogFactory.getLog(ActionServlet.class);

    // ----------------------------------------------------- Instance Variables

    /**
     * <p>Comma-separated list of context-relative path(s) to our
     * configuration resource(s) for the default module.</p>
     */
    protected String config = "/WEB-INF/struts-config.xml";

    /**
     * <p>Comma-separated list of context or classloader-relative path(s) that
     * contain the configuration for the default commons-chain
     * catalog(s).</p>
     */
    protected String chainConfig = "org/apache/struts/chain/chain-config.xml";

    /**
     * <p>The Digester used to produce ModuleConfig objects from a Struts
     * configuration file.</p>
     *
     * @since Struts 1.1
     */
    protected Digester configDigester = null;

    /**
     * <p>The flag to request backwards-compatible conversions for form bean
     * properties of the Java wrapper class types.</p>
     *
     * @since Struts 1.1
     */
    protected boolean convertNull = false;

    /**
     * <p>The resources object for our internal resources.</p>
     */
    protected MessageResources internal = null;

    /**
     * <p>The Java base name of our internal resources.</p>
     *
     * @since Struts 1.1
     */
    protected String internalName = "org.apache.struts.action.ActionResources";

    /**
     * <p>The set of public identifiers, and corresponding resource names, for
     * the versions of the configuration file DTDs that we know about.  There
     * <strong>MUST</strong> be an even number of Strings in this list!</p>
     */
    protected String[] registrations =
        {
            "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",
            "/org/apache/struts/resources/struts-config_1_0.dtd",
            "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN",
            "/org/apache/struts/resources/struts-config_1_1.dtd",
            "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN",
            "/org/apache/struts/resources/struts-config_1_2.dtd",
            "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN",
            "/org/apache/struts/resources/struts-config_1_3.dtd",
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
            "/org/apache/struts/resources/web-app_2_3.dtd"
        };

    /**
     * <p>The URL pattern to which we are mapped in our web application
     * deployment descriptor.</p>
     */
    protected String servletMapping = null; // :FIXME: - multiples?

    /**
     * <p>The servlet name under which we are registered in our web
     * application deployment descriptor.</p>
     */
    protected String servletName = null;

    // ---------------------------------------------------- HttpServlet Methods

    /**
     * <p>Gracefully shut down this controller servlet, releasing any
     * resources that were allocated at initialization.</p>
     */
    public void destroy() {
        if (log.isDebugEnabled()) {
            log.debug(internal.getMessage("finalizing"));
        }

        destroyModules();
        destroyInternal();
        getServletContext().removeAttribute(Globals.ACTION_SERVLET_KEY);

        CatalogFactory.clear();
        PropertyUtils.clearDescriptors();

        // Release our LogFactory and Log instances (if any)
        ClassLoader classLoader =
            Thread.currentThread().getContextClassLoader();

        if (classLoader == null) {
            classLoader = ActionServlet.class.getClassLoader();
        }

        try {
            LogFactory.release(classLoader);
        } catch (Throwable t) {
            ; // Servlet container doesn't have the latest version

            // of commons-logging-api.jar installed
            // :FIXME: Why is this dependent on the container's version of
            // commons-logging? Shouldn't this depend on the version packaged
            // with Struts?

            /*
              Reason: LogFactory.release(classLoader); was added as
              an attempt to investigate the OutOfMemory error reported on
              Bugzilla #14042. It was committed for version 1.136 by craigmcc
            */
        }
    }

    /**
     * <p>Initialize this servlet.  Most of the processing has been factored
     * into support methods so that you can override particular functionality
     * at a fairly granular level.</p>
     *
     * @throws ServletException if we cannot configure ourselves correctly
     */
    public void init() throws ServletException {
        final String configPrefix = "config/";
        final int configPrefixLength = configPrefix.length() - 1;

        // Wraps the entire initialization in a try/catch to better handle
        // unexpected exceptions and errors to provide better feedback
        // to the developer
        try {
            initInternal();
            initOther();
            initServlet();
            initChain();

            getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
            initModuleConfigFactory();

            // Initialize modules as needed
            ModuleConfig moduleConfig = initModuleConfig("", config);

            initModuleMessageResources(moduleConfig);
            initModulePlugIns(moduleConfig);
            initModuleFormBeans(moduleConfig);
            initModuleForwards(moduleConfig);
            initModuleExceptionConfigs(moduleConfig);
            initModuleActions(moduleConfig);
            moduleConfig.freeze();

            Enumeration names = getServletConfig().getInitParameterNames();

            while (names.hasMoreElements()) {
                String name = (String) names.nextElement();

                if (!name.startsWith(configPrefix)) {
                    continue;
                }

                String prefix = name.substring(configPrefixLength);

                moduleConfig =
                    initModuleConfig(prefix,
                        getServletConfig().getInitParameter(name));
                initModuleMessageResources(moduleConfig);
                initModulePlugIns(moduleConfig);
                initModuleFormBeans(moduleConfig);
                initModuleForwards(moduleConfig);
                initModuleExceptionConfigs(moduleConfig);
                initModuleActions(moduleConfig);
                moduleConfig.freeze();
            }

            this.initModulePrefixes(this.getServletContext());

            this.destroyConfigDigester();
        } catch (UnavailableException ex) {
            throw ex;
        } catch (Throwable t) {
            // The follow error message is not retrieved from internal message
            // resources as they may not have been able to have been
            // initialized
            log.error("Unable to initialize Struts ActionServlet due to an "
                + "unexpected exception or error thrown, so marking the "
                + "servlet as unavailable.  Most likely, this is due to an "
                + "incorrect or missing library dependency.", t);
            throw new UnavailableException(t.getMessage());
        }
    }

    /**
     * <p>Saves a String[] of module prefixes in the ServletContext under
     * Globals.MODULE_PREFIXES_KEY.  <strong>NOTE</strong> - the "" prefix for
     * the default module is not included in this list.</p>
     *
     * @param context The servlet context.
     * @since Struts 1.2
     */
    protected void initModulePrefixes(ServletContext context) {
        ArrayList prefixList = new ArrayList();

        Enumeration names = context.getAttributeNames();

        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();

            if (!name.startsWith(Globals.MODULE_KEY)) {
                continue;
            }

            String prefix = name.substring(Globals.MODULE_KEY.length());

            if (prefix.length() > 0) {
                prefixList.add(prefix);
            }
        }

        String[] prefixes =
            (String[]) prefixList.toArray(new String[prefixList.size()]);

        context.setAttribute(Globals.MODULE_PREFIXES_KEY, prefixes);
    }

    /**
     * <p>Process an HTTP "GET" request.</p>
     *
     * @param request  The servlet request we are processing
     * @param response The servlet response we are creating
     * @throws IOException      if an input/output error occurs
     * @throws ServletException if a servlet exception occurs
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
        process(request, response);
    }

    /**
     * <p>Process an HTTP "POST" request.</p>
     *
     * @param request  The servlet request we are processing
     * @param response The servlet response we are creating
     * @throws IOException      if an input/output error occurs
     * @throws ServletException if a servlet exception occurs
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
        process(request, response);
    }

    // --------------------------------------------------------- Public Methods

    /**
     * <p>Remember a servlet mapping from our web application deployment
     * descriptor, if it is for this servlet.</p>
     *
     * @param servletName The name of the servlet being mapped
     * @param urlPattern  The URL pattern to which this servlet is mapped
     */
    public void addServletMapping(String servletName, String urlPattern) {
        if (servletName == null) {
            return;
        }

        if (servletName.equals(this.servletName)) {
            if (log.isDebugEnabled()) {
                log.debug("Process servletName=" + servletName
                    + ", urlPattern=" + urlPattern);
            }

            this.servletMapping = urlPattern;
        }
    }

    /**
     * <p>Return the <code>MessageResources</code> instance containing our
     * internal message strings.</p>
     *
     * @return the <code>MessageResources</code> instance containing our
     *         internal message strings.
     * @since Struts 1.1
     */
    public MessageResources getInternal() {
        return (this.internal);
    }

    // ------------------------------------------------------ Protected Methods

    /**
     * <p>Gracefully terminate use of any modules associated with this
     * application (if any).</p>
     *
     * @since Struts 1.1
     */
    protected void destroyModules() {
        ArrayList values = new ArrayList();
        Enumeration names = getServletContext().getAttributeNames();

        while (names.hasMoreElements()) {
            values.add(names.nextElement());
        }

        Iterator keys = values.iterator();

        while (keys.hasNext()) {
            String name = (String) keys.next();
            Object value = getServletContext().getAttribute(name);

            if (!(value instanceof ModuleConfig)) {
                continue;
            }

            ModuleConfig config = (ModuleConfig) value;

            if (this.getProcessorForModule(config) != null) {
                this.getProcessorForModule(config).destroy();
            }

            getServletContext().removeAttribute(name);

            PlugIn[] plugIns =
                (PlugIn[]) getServletContext().getAttribute(Globals.PLUG_INS_KEY
                    + config.getPrefix());

            if (plugIns != null) {
                for (int i = 0; i < plugIns.length; i++) {
                    int j = plugIns.length - (i + 1);

                    plugIns[j].destroy();
                }

                getServletContext().removeAttribute(Globals.PLUG_INS_KEY
                    + config.getPrefix());
            }
        }
    }

    /**
     * <p>Gracefully release any configDigester instance that we have created.
     * </p>
     *
     * @since Struts 1.1
     */
    protected void destroyConfigDigester() {
        configDigester = null;
    }

    /**
     * <p>Gracefully terminate use of the internal MessageResources.</p>
     */
    protected void destroyInternal() {
        internal = null;
    }

    /**
     * <p>Return the module configuration object for the currently selected
     * module.</p>
     *
     * @param request The servlet request we are processing
     * @return The module configuration object for the currently selected
     *         module.
     * @since Struts 1.1
     */
    protected ModuleConfig getModuleConfig(HttpServletRequest request) {
        ModuleConfig config =
            (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);

        if (config == null) {
            config =
                (ModuleConfig) getServletContext().getAttribute(Globals.MODULE_KEY);
        }

        return (config);
    }

    /**
     * <p>Look up and return the {@link RequestProcessor} responsible for the
     * specified module, creating a new one if necessary.</p>
     *
     * @param config The module configuration for which to acquire and return
     *               a RequestProcessor.
     * @return The {@link RequestProcessor} responsible for the specified
     *         module,
     * @throws ServletException If we cannot instantiate a RequestProcessor
     *                          instance a {@link UnavailableException} is
     *                          thrown, meaning your application is not loaded
     *                          and will not be available.
     * @since Struts 1.1
     */
    protected synchronized RequestProcessor getRequestProcessor(
        ModuleConfig config) throws ServletException {
        RequestProcessor processor = this.getProcessorForModule(config);

        if (processor == null) {
            try {
                processor =
                    (RequestProcessor) RequestUtils.applicationInstance(config.getControllerConfig()
                                                                              .getProcessorClass());
            } catch (Exception e) {
                throw new UnavailableException(
                    "Cannot initialize RequestProcessor of class "
                    + config.getControllerConfig().getProcessorClass() + ": "
                    + e);
            }

            processor.init(this, config);

            String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();

            getServletContext().setAttribute(key, processor);
        }

        return (processor);
    }

    /**
     * <p>Returns the RequestProcessor for the given module or null if one
     * does not exist.  This method will not create a RequestProcessor.</p>
     *
     * @param config The ModuleConfig.
     * @return The <code>RequestProcessor</code> for the given module, or
     *         <code>null</code> if one does not exist.
     */
    private RequestProcessor getProcessorForModule(ModuleConfig config) {
        String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();

        return (RequestProcessor) getServletContext().getAttribute(key);
    }

    /**
     * <p>Initialize the factory used to create the module configuration.</p>
     *
     * @since Struts 1.2
     */
    protected void initModuleConfigFactory() {
        String configFactory =
            getServletConfig().getInitParameter("configFactory");

        if (configFactory != null) {
            ModuleConfigFactory.setFactoryClass(configFactory);
        }
    }

    /**
     * <p>Initialize the module configuration information for the specified
     * module.</p>
     *
     * @param prefix Module prefix for this module
     * @param paths  Comma-separated list of context-relative resource path(s)
     *               for this modules's configuration resource(s)
     * @return The new module configuration instance.
     * @throws ServletException if initialization cannot be performed
     * @since Struts 1.1
     */
    protected ModuleConfig initModuleConfig(String prefix, String paths)
        throws ServletException {
        if (log.isDebugEnabled()) {
            log.debug("Initializing module path '" + prefix
                + "' configuration from '" + paths + "'");
        }

        // Parse the configuration for this module
        ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();
        ModuleConfig config = factoryObject.createModuleConfig(prefix);

        // Configure the Digester instance we will use
        Digester digester = initConfigDigester();

        List urls = splitAndResolvePaths(paths);
        URL url;

        for (Iterator i = urls.iterator(); i.hasNext();) {
            url = (URL) i.next();
            digester.push(config);
            this.parseModuleConfigFile(digester, url);
        }

        getServletContext().setAttribute(Globals.MODULE_KEY
            + config.getPrefix(), config);

        return config;
    }

    /**
     * <p>Parses one module config file.</p>
     *
     * @param digester Digester instance that does the parsing
     * @param path     The path to the config file to parse.
     * @throws UnavailableException if file cannot be read or parsed
     * @since Struts 1.2
     * @deprecated use parseModuleConfigFile(Digester digester, URL url)
     *             instead
     */
    protected void parseModuleConfigFile(Digester digester, String path)
        throws UnavailableException {
        try {
            List paths = splitAndResolvePaths(path);

            if (paths.size() > 0) {
                // Get first path as was the old behavior
                URL url = (URL) paths.get(0);

                parseModuleConfigFile(digester, url);
            } else {
                throw new UnavailableException("Cannot locate path " + path);
            }
        } catch (UnavailableException ex) {
            throw ex;
        } catch (ServletException ex) {
            handleConfigException(path, ex);
        }
    }

    /**
     * <p>Parses one module config file.</p>
     *
     * @param digester Digester instance that does the parsing
     * @param url      The url to the config file to parse.
     * @throws UnavailableException if file cannot be read or parsed
     * @since Struts 1.3
     */
    protected void parseModuleConfigFile(Digester digester, URL url)
        throws UnavailableException {

        try {
            digester.parse(url);
        } catch (IOException e) {
            handleConfigException(url.toString(), e);
        } catch (SAXException e) {
            handleConfigException(url.toString(), e);
        }
    }

    /**
     * <p>Simplifies exception handling in the parseModuleConfigFile
     * method.<p>
     *
     * @param path The path to which the exception relates.
     * @param e    The exception to be wrapped and thrown.
     * @throws UnavailableException as a wrapper around Exception
     */
    private void handleConfigException(String path, Exception e)
        throws UnavailableException {
        String msg = internal.getMessage("configParse", path);

        log.error(msg, e);
        throw new UnavailableException(msg);
    }

    /**
     * <p>Handle errors related to creating an instance of the specified
     * class.</p>
     *
     * @param className The className that could not be instantiated.
     * @param e         The exception that was caught.
     * @throws ServletException to communicate the error.
     */
    private void handleCreationException(String className, Exception e)
        throws ServletException {
        String errorMessage =
            internal.getMessage("configExtends.creation", className);

        log.error(errorMessage, e);
        throw new UnavailableException(errorMessage);
    }

    /**
     * <p>General handling for exceptions caught while inheriting config
     * information.</p>
     *
     * @param configType The type of configuration object of configName.
     * @param configName The name of the config that could not be extended.
     * @param e          The exception that was caught.
     * @throws ServletException to communicate the error.
     */
    private void handleGeneralExtensionException(String configType,
        String configName, Exception e)
        throws ServletException {
        String errorMessage =
            internal.getMessage("configExtends", configType, configName);

        log.error(errorMessage, e);
        throw new UnavailableException(errorMessage);
    }

    /**
     * <p>Handle errors caused by required fields that were not
     * specified.</p>
     *
     * @param field      The name of the required field that was not found.
     * @param configType The type of configuration object of configName.
     * @param configName The name of the config that's missing the required
     *                   value.
     * @throws ServletException to communicate the error.
     */
    private void handleValueRequiredException(String field, String configType,
        String configName) throws ServletException {
        String errorMessage =
            internal.getMessage("configFieldRequired", field, configType,
                configName);

        log.error(errorMessage);
        throw new UnavailableException(errorMessage);
    }

    /**
     * <p>Initialize the plug ins for the specified module.</p>
     *
     * @param config ModuleConfig information for this module
     * @throws ServletException if initialization cannot be performed
     * @since Struts 1.1
     */
    protected void initModulePlugIns(ModuleConfig config)
        throws ServletException {
        if (log.isDebugEnabled()) {
            log.debug("Initializing module path '" + config.getPrefix()
                + "' plug ins");
        }

        PlugInConfig[] plugInConfigs = config.findPlugInConfigs();
        PlugIn[] plugIns = new PlugIn[plugInConfigs.length];

        getServletContext().setAttribute(Globals.PLUG_INS_KEY
            + config.getPrefix(), plugIns);

        for (int i = 0; i < plugIns.length; i++) {
            try {
                plugIns[i] =
                    (PlugIn) RequestUtils.applicationInstance(plugInConfigs[i]
                        .getClassName());
                BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties());

                // Pass the current plugIn config object to the PlugIn.
                // The property is set only if the plugin declares it.
                // This plugin config object is needed by Tiles
                try {
                    PropertyUtils.setProperty(plugIns[i],
                        "currentPlugInConfigObject", plugInConfigs[i]);
                } catch (Exception e) {
                    ;

                    // FIXME Whenever we fail silently, we must document a valid
                    // reason for doing so.  Why should we fail silently if a
                    // property can't be set on the plugin?

                    /**
                     * Between version 1.138-1.140 cedric made these changes.
                     * The exceptions are caught to deal with containers
                     * applying strict security. This was in response to bug
                     * #15736
                     *
                     * Recommend that we make the currentPlugInConfigObject part
                     * of the PlugIn Interface if we can, Rob
                     */
                }

                plugIns[i].init(this, config);
            } catch (ServletException e) {
                throw e;
            } catch (Exception e) {
                String errMsg =
                    internal.getMessage("plugIn.init",
                        plugInConfigs[i].getClassName());

                log(errMsg, e);
                throw new UnavailableException(errMsg);
            }
        }
    }

    /**
     * <p>Initialize the form beans for the specified module.</p>
     *
     * @param config ModuleConfig information for this module
     * @throws ServletException if initialization cannot be performed
     * @since Struts 1.3
     */
    protected void initModuleFormBeans(ModuleConfig config)
        throws ServletException {
        if (log.isDebugEnabled()) {
            log.debug("Initializing module path '" + config.getPrefix()
                + "' form beans");
        }

        // Process form bean extensions.
        FormBeanConfig[] formBeans = config.findFormBeanConfigs();

        for (int i = 0; i < formBeans.length; i++) {
            FormBeanConfig beanConfig = formBeans[i];

            processFormBeanExtension(beanConfig, config);
        }

        for (int i = 0; i < formBeans.length; i++) {
            FormBeanConfig formBean = formBeans[i];

            // Verify that required fields are all present for the form config
            if (formBean.getType() == null) {
                handleValueRequiredException("type", formBean.getName(),
                    "form bean");
            }

            // ... and the property configs
            FormPropertyConfig[] fpcs = formBean.findFormPropertyConfigs();

            for (int j = 0; j < fpcs.length; j++) {
                FormPropertyConfig property = fpcs[j];

                if (property.getType() == null) {
                    handleValueRequiredException("type", property.getName(),
                        "form property");
                }
            }

            // Force creation and registration of DynaActionFormClass instances
            // for all dynamic form beans
            if (formBean.getDynamic()) {
                formBean.getDynaActionFormClass();
            }
        }
    }

    /**
     * <p>Extend the form bean's configuration as necessary.</p>
     *
     * @param beanConfig   the configuration to process.
     * @param moduleConfig the module configuration for this module.
     * @throws ServletException if initialization cannot be performed.
     */
    protected void processFormBeanExtension(FormBeanConfig beanConfig,
        ModuleConfig moduleConfig)
        throws ServletException {
        try {
            if (!beanConfig.isExtensionProcessed()) {
                if (log.isDebugEnabled()) {
                    log.debug("Processing extensions for '"
                        + beanConfig.getName() + "'");
                }

                beanConfig =
                    processFormBeanConfigClass(beanConfig, moduleConfig);

                beanConfig.processExtends(moduleConfig);
            }
        } catch (ServletException e) {
            throw e;
        } catch (Exception e) {
            handleGeneralExtensionException("FormBeanConfig",
                beanConfig.getName(), e);
        }
    }

    /**
     * <p>Checks if the current beanConfig is using the correct class based on
     * the class of its ancestor form bean config.</p>
     *
     * @param beanConfig   The form bean to check.
     * @param moduleConfig The config for the current module.
     * @return The form bean config using the correct class as determined by
     *         the config's ancestor and its own overridden value.
     * @throws UnavailableException if an instance of the form bean config
     *                              class cannot be created.
     * @throws ServletException     on class creation error
     */
    protected FormBeanConfig processFormBeanConfigClass(
        FormBeanConfig beanConfig, ModuleConfig moduleConfig)
        throws ServletException {
        String ancestor = beanConfig.getExtends();

        if (ancestor == null) {
            // Nothing to do, then
            return beanConfig;
        }

        // Make sure that this bean is of the right class
        FormBeanConfig baseConfig = moduleConfig.findFormBeanConfig(ancestor);

        if (baseConfig == null) {
            throw new UnavailableException("Unable to find " + "form bean '"
                + ancestor + "' to extend.");
        }

        // Was our bean's class overridden already?
        if (beanConfig.getClass().equals(FormBeanConfig.class)) {
            // Ensure that our bean is using the correct class
            if (!baseConfig.getClass().equals(beanConfig.getClass())) {
                // Replace the bean with an instance of the correct class
                FormBeanConfig newBeanConfig = null;
                String baseConfigClassName = baseConfig.getClass().getName();

                try {
                    newBeanConfig =
                        (FormBeanConfig) RequestUtils.applicationInstance(baseConfigClassName);

                    // copy the values
                    BeanUtils.copyProperties(newBeanConfig, beanConfig);

                    FormPropertyConfig[] fpc =
                        beanConfig.findFormPropertyConfigs();

                    for (int i = 0; i < fpc.length; i++) {
                        newBeanConfig.addFormPropertyConfig(fpc[i]);
                    }
                } catch (Exception e) {
                    handleCreationException(baseConfigClassName, e);
                }

                // replace beanConfig with newBeanConfig
                moduleConfig.removeFormBeanConfig(beanConfig);
                moduleConfig.addFormBeanConfig(newBeanConfig);
                beanConfig = newBeanConfig;
            }
        }

        return beanConfig;
    }

    /**
     * <p>Initialize the forwards for the specified module.</p>
     *
     * @param config ModuleConfig information for this module
     * @throws ServletException if initialization cannot be performed
     */
    protected void initModuleForwards(ModuleConfig config)
        throws ServletException {
        if (log.isDebugEnabled()) {
            log.debug("Initializing module path '" + config.getPrefix()
                + "' forwards");
        }

        // Process forwards extensions.
        ForwardConfig[] forwards = config.findForwardConfigs();

        for (int i = 0; i < forwards.length; i++) {
            ForwardConfig forward = forwards[i];

            processForwardExtension(forward, config, null);
        }

        for (int i = 0; i < forwards.length; i++) {
            ForwardConfig forward = forwards[i];

            // Verify that required fields are all present for the forward
            if (forward.getPath() == null) {
                handleValueRequiredException("path", forward.getName(),
                    "global forward");
            }
        }
    }

    /**
     * <p>Extend the forward's configuration as necessary.  If actionConfig is
     * provided, then this method will process the forwardConfig as part
     * of that actionConfig.  If actionConfig is null, the forwardConfig
     * will be processed as a global forward.</p>
     *
     * @param forwardConfig the configuration to process.
     * @param moduleConfig  the module configuration for this module.
     * @param actionConfig  If applicable, the config for the current action.
     * @throws ServletException if initialization cannot be performed.
     */
    protected void processForwardExtension(ForwardConfig forwardConfig,
        ModuleConfig moduleConfig, ActionConfig actionConfig)
        throws ServletException {
        try {
            if (!forwardConfig.isExtensionProcessed()) {
                if (log.isDebugEnabled()) {
                    log.debug("Processing extensions for '"
                        + forwardConfig.getName() + "'");
                }

                forwardConfig =
                    processForwardConfigClass(forwardConfig, moduleConfig,
                        actionConfig);

                forwardConfig.processExtends(moduleConfig, actionConfig);
            }
        } catch (ServletException e) {
            throw e;
        } catch (Exception e) {
            handleGeneralExtensionException("Forward", forwardConfig.getName(),
                e);
        }
    }

    /**
     * <p>Checks if the current forwardConfig is using the correct class based
     * on the class of its configuration ancestor.  If actionConfig is
     * provided, then this method will process the forwardConfig as part
     * of that actionConfig.  If actionConfig is null, the forwardConfig
     * will be processed as a global forward.</p>
     *
     * @param forwardConfig The forward to check.
     * @param moduleConfig  The config for the current module.
     * @param actionConfig  If applicable, the config for the current action.
     * @return The forward config using the correct class as determined by the
     *         config's ancestor and its own overridden value.
     * @throws UnavailableException if an instance of the forward config class
     *                              cannot be created.
     * @throws ServletException     on class creation error
     */
    protected ForwardConfig processForwardConfigClass(
        ForwardConfig forwardConfig, ModuleConfig moduleConfig,
        ActionConfig actionConfig)
        throws ServletException {
        String ancestor = forwardConfig.getExtends();

        if (ancestor == null) {
            // Nothing to do, then
            return forwardConfig;
        }

        // Make sure that this config is of the right class
        ForwardConfig baseConfig = null;
        if (actionConfig != null) {
            // Look for this in the actionConfig
            baseConfig = actionConfig.findForwardConfig(ancestor);
        }

        if (baseConfig == null) {
            // Either this is a forwardConfig that inherits a global config,
            //  or actionConfig is null
            baseConfig = moduleConfig.findForwardConfig(ancestor);
        }

        if (baseConfig == null) {
            throw new UnavailableException("Unable to find " + "forward '"
                + ancestor + "' to extend.");
        }

        // Was our forwards's class overridden already?
        if (forwardConfig.getClass().equals(ActionForward.class)) {
            // Ensure that our forward is using the correct class
            if (!baseConfig.getClass().equals(forwardConfig.getClass())) {
                // Replace the config with an instance of the correct class
                ForwardConfig newForwardConfig = null;
                String baseConfigClassName = baseConfig.getClass().getName();

                try {
                    newForwardConfig =
                        (ForwardConfig) RequestUtils.applicationInstance(
                                baseConfigClassName);

                    // copy the values
                    BeanUtils.copyProperties(newForwardConfig, forwardConfig);
                } catch (Exception e) {
                    handleCreationException(baseConfigClassName, e);
                }

                // replace forwardConfig with newForwardConfig
                if (actionConfig != null) {
                    actionConfig.removeForwardConfig(forwardConfig);
                    actionConfig.addForwardConfig(newForwardConfig);
                } else {
                    // this is a global forward
                    moduleConfig.removeForwardConfig(forwardConfig);
                    moduleConfig.addForwardConfig(newForwardConfig);
                }
                forwardConfig = newForwardConfig;
            }
        }

        return forwardConfig;
    }

    /**
     * <p>Initialize the exception handlers for the specified module.</p>
     *
     * @param config ModuleConfig information for this module
     * @throws ServletException if initialization cannot be performed
     * @since Struts 1.3
     */
    protected void initModuleExceptionConfigs(ModuleConfig config)
        throws ServletException {
        if (log.isDebugEnabled()) {
            log.debug("Initializing module path '" + config.getPrefix()
                + "' forwards");
        }

        // Process exception config extensions.
        ExceptionConfig[] exceptions = config.findExceptionConfigs();

        for (int i = 0; i < exceptions.length; i++) {
            ExceptionConfig exception = exceptions[i];

            processExceptionExtension(exception, config, null);
        }

        for (int i = 0; i < exceptions.length; i++) {
            ExceptionConfig exception = exceptions[i];

            // Verify that required fields are all present for the config
            if (exception.getKey() == null) {
                handleValueRequiredException("key", exception.getType(),
                    "global exception config");
            }
        }
    }

    /**
     * <p>Extend the exception's configuration as necessary. If actionConfig is
     * provided, then this method will process the exceptionConfig as part
     * of that actionConfig.  If actionConfig is null, the exceptionConfig
     * will be processed as a global forward.</p>
     *
     * @param exceptionConfig the configuration to process.
     * @param moduleConfig    the module configuration for this module.
     * @param actionConfig  If applicable, the config for the current action.
     * @throws ServletException if initialization cannot be performed.
     */
    protected void processExceptionExtension(ExceptionConfig exceptionConfig,
        ModuleConfig moduleConfig, ActionConfig actionConfig)
        throws ServletException {
        try {
            if (!exceptionConfig.isExtensionProcessed()) {
                if (log.isDebugEnabled()) {
                    log.debug("Processing extensions for '"
                        + exceptionConfig.getType() + "'");
                }

                exceptionConfig =
                    processExceptionConfigClass(exceptionConfig, moduleConfig,
                        actionConfig);

                exceptionConfig.processExtends(moduleConfig, actionConfig);
            }
        } catch (ServletException e) {
            throw e;
        } catch (Exception e) {
            handleGeneralExtensionException("Exception",
                exceptionConfig.getType(), e);
        }
    }

    /**
     * <p>Checks if the current exceptionConfig is using the correct class
     * based on the class of its configuration ancestor. If actionConfig is
     * provided, then this method will process the exceptionConfig as part
     * of that actionConfig.  If actionConfig is null, the exceptionConfig
     * will be processed as a global forward.</p>
     *
     * @param exceptionConfig The config to check.
     * @param moduleConfig    The config for the current module.
     * @param actionConfig  If applicable, the config for the current action.
     * @return The exception config using the correct class as determined by
     *         the config's ancestor and its own overridden value.
     * @throws ServletException if an instance of the exception config class
     *                          cannot be created.
     */
    protected ExceptionConfig processExceptionConfigClass(
        ExceptionConfig exceptionConfig, ModuleConfig moduleConfig,
        ActionConfig actionConfig)
        throws ServletException {
        String ancestor = exceptionConfig.getExtends();

        if (ancestor == null) {
            // Nothing to do, then
            return exceptionConfig;
        }

        // Make sure that this config is of the right class
        ExceptionConfig baseConfig = null;
        if (actionConfig != null) {
            baseConfig = actionConfig.findExceptionConfig(ancestor);
        }

        if (baseConfig == null) {
            // This means either there's no actionConfig anyway, or the
            // ancestor is not defined within the action.
            baseConfig = moduleConfig.findExceptionConfig(ancestor);
        }

        if (baseConfig == null) {
            throw new UnavailableException("Unable to find "
                + "exception config '" + ancestor + "' to extend.");
        }

        // Was our config's class overridden already?
        if (exceptionConfig.getClass().equals(ExceptionConfig.class)) {
            // Ensure that our config is using the correct class
            if (!baseConfig.getClass().equals(exceptionConfig.getClass())) {
                // Replace the config with an instance of the correct class
                ExceptionConfig newExceptionConfig = null;
                String baseConfigClassName = baseConfig.getClass().getName();

                try {
                    newExceptionConfig =
                        (ExceptionConfig) RequestUtils.applicationInstance(
                            baseConfigClassName);

                    // copy the values
                    BeanUtils.copyProperties(newExceptionConfig,
                        exceptionConfig);
                } catch (Exception e) {
                    handleCreationException(baseConfigClassName, e);
                }

                // replace exceptionConfig with newExceptionConfig
                if (actionConfig != null) {
                    actionConfig.removeExceptionConfig(exceptionConfig);
                    actionConfig.addExceptionConfig(newExceptionConfig);
                } else {
                    moduleConfig.removeExceptionConfig(exceptionConfig);
                    moduleConfig.addExceptionConfig(newExceptionConfig);
                }
                exceptionConfig = newExceptionConfig;
            }
        }

        return exceptionConfig;
    }

    /**
     * <p>Initialize the action configs for the specified module.</p>
     *
     * @param config ModuleConfig information for this module
     * @throws ServletException if initialization cannot be performed
     * @since Struts 1.3
     */
    protected void initModuleActions(ModuleConfig config)
        throws ServletException {
        if (log.isDebugEnabled()) {
            log.debug("Initializing module path '" + config.getPrefix()
                + "' action configs");
        }

        // Process ActionConfig extensions.
        ActionConfig[] actionConfigs = config.findActionConfigs();

        for (int i = 0; i < actionConfigs.length; i++) {
            ActionConfig actionConfig = actionConfigs[i];

            processActionConfigExtension(actionConfig, config);
        }

        for (int i = 0; i < actionConfigs.length; i++) {
            ActionConfig actionConfig = actionConfigs[i];

            // Verify that required fields are all present for the forward
            // configs
            ForwardConfig[] forwards = actionConfig.findForwardConfigs();

            for (int j = 0; j < forwards.length; j++) {
                ForwardConfig forward = forwards[j];

                if (forward.getPath() == null) {
                    handleValueRequiredException("path", forward.getName(),
                        "action forward");
                }
            }

            // ... and the exception configs
            ExceptionConfig[] exceptions = actionConfig.findExceptionConfigs();

            for (int j = 0; j < exceptions.length; j++) {
                ExceptionConfig exception = exceptions[j];

                if (exception.getKey() == null) {
                    handleValueRequiredException("key", exception.getType(),
                        "action exception config");
                }
            }
        }
    }

    /**
     * <p>Extend the action's configuration as necessary.</p>
     *
     * @param actionConfig the configuration to process.
     * @param moduleConfig the module configuration for this module.
     * @throws ServletException if initialization cannot be performed.
     */
    protected void processActionConfigExtension(ActionConfig actionConfig,
        ModuleConfig moduleConfig)
        throws ServletException {
        try {
            if (!actionConfig.isExtensionProcessed()) {
                if (log.isDebugEnabled()) {
                    log.debug("Processing extensions for '"
                        + actionConfig.getPath() + "'");
                }

                actionConfig =
                    processActionConfigClass(actionConfig, moduleConfig);

                actionConfig.processExtends(moduleConfig);
            }

            // Process forwards extensions.
            ForwardConfig[] forwards = actionConfig.findForwardConfigs();
            for (int i = 0; i < forwards.length; i++) {
                ForwardConfig forward = forwards[i];
                processForwardExtension(forward, moduleConfig, actionConfig);
            }

            // Process exception extensions.
            ExceptionConfig[] exceptions = actionConfig.findExceptionConfigs();
            for (int i = 0; i < exceptions.length; i++) {
                ExceptionConfig exception = exceptions[i];
                processExceptionExtension(exception, moduleConfig,
                    actionConfig);
            }
        } catch (ServletException e) {
            throw e;
        } catch (Exception e) {
            handleGeneralExtensionException("Action", actionConfig.getPath(), e);
        }
    }

    /**
     * <p>Checks if the current actionConfig is using the correct class based
     * on the class of its ancestor ActionConfig.</p>
     *
     * @param actionConfig The action config to check.
     * @param moduleConfig The config for the current module.
     * @return The config object using the correct class as determined by the
     *         config's ancestor and its own overridden value.
     * @throws ServletException if an instance of the action config class
     *                          cannot be created.
     */
    protected ActionConfig processActionConfigClass(ActionConfig actionConfig,
        ModuleConfig moduleConfig)
        throws ServletException {
        String ancestor = actionConfig.getExtends();

        if (ancestor == null) {
            // Nothing to do, then
            return actionConfig;
        }

        // Make sure that this config is of the right class
        ActionConfig baseConfig = moduleConfig.findActionConfig(ancestor);

        if (baseConfig == null) {
            throw new UnavailableException("Unable to find "
                + "action config for '" + ancestor + "' to extend.");
        }

        // Was our actionConfig's class overridden already?
        if (actionConfig.getClass().equals(ActionMapping.class)) {
            // Ensure that our config is using the correct class
            if (!baseConfig.getClass().equals(actionConfig.getClass())) {
                // Replace the config with an instance of the correct class
                ActionConfig newActionConfig = null;
                String baseConfigClassName = baseConfig.getClass().getName();

                try {
                    newActionConfig =
                        (ActionConfig) RequestUtils.applicationInstance(baseConfigClassName);

                    // copy the values
                    BeanUtils.copyProperties(newActionConfig, actionConfig);

                    // copy the forward and exception configs, too
                    ForwardConfig[] forwards =
                        actionConfig.findForwardConfigs();

                    for (int i = 0; i < forwards.length; i++) {
                        newActionConfig.addForwardConfig(forwards[i]);
                    }

                    ExceptionConfig[] exceptions =
                        actionConfig.findExceptionConfigs();

                    for (int i = 0; i < exceptions.length; i++) {
                        newActionConfig.addExceptionConfig(exceptions[i]);
                    }
                } catch (Exception e) {
                    handleCreationException(baseConfigClassName, e);
                }

                // replace actionConfig with newActionConfig
                moduleConfig.removeActionConfig(actionConfig);
                moduleConfig.addActionConfig(newActionConfig);
                actionConfig = newActionConfig;
            }
        }

        return actionConfig;
    }

    /**
     * <p>Initialize the application <code>MessageResources</code> for the
     * specified module.</p>
     *
     * @param config ModuleConfig information for this module
     * @throws ServletException if initialization cannot be performed
     * @since Struts 1.1
     */
    protected void initModuleMessageResources(ModuleConfig config)
        throws ServletException {
        MessageResourcesConfig[] mrcs = config.findMessageResourcesConfigs();

        for (int i = 0; i < mrcs.length; i++) {
            if ((mrcs[i].getFactory() == null)
                || (mrcs[i].getParameter() == null)) {
                continue;
            }

            if (log.isDebugEnabled()) {
                log.debug("Initializing module path '" + config.getPrefix()
                    + "' message resources from '" + mrcs[i].getParameter()
                    + "'");
            }

            String factory = mrcs[i].getFactory();

            MessageResourcesFactory.setFactoryClass(factory);

            MessageResourcesFactory factoryObject =
                MessageResourcesFactory.createFactory();

            factoryObject.setConfig(mrcs[i]);

            MessageResources resources =
                factoryObject.createResources(mrcs[i].getParameter());

            resources.setReturnNull(mrcs[i].getNull());
            resources.setEscape(mrcs[i].isEscape());
            getServletContext().setAttribute(mrcs[i].getKey()
                + config.getPrefix(), resources);
        }
    }

    /**
     * <p>Create (if needed) and return a new <code>Digester</code> instance
     * that has been initialized to process Struts module configuration files
     * and configure a corresponding <code>ModuleConfig</code> object (which
     * must be pushed on to the evaluation stack before parsing begins).</p>
     *
     * @return A new configured <code>Digester</code> instance.
     * @throws ServletException if a Digester cannot be configured
     * @since Struts 1.1
     */
    protected Digester initConfigDigester()
        throws ServletException {
        // :FIXME: Where can ServletException be thrown?
        // Do we have an existing instance?
        if (configDigester != null) {
            return (configDigester);
        }

        // Create a new Digester instance with standard capabilities
        configDigester = new Digester();
        configDigester.setNamespaceAware(true);
        configDigester.setValidating(this.isValidating());
        configDigester.setUseContextClassLoader(true);
        configDigester.addRuleSet(new ConfigRuleSet());

        for (int i = 0; i < registrations.length; i += 2) {
            URL url = this.getClass().getResource(registrations[i + 1]);

            if (url != null) {
                configDigester.register(registrations[i], url.toString());
            }
        }

        this.addRuleSets();

        // Return the completely configured Digester instance
        return (configDigester);
    }

    /**
     * <p>Add any custom RuleSet instances to configDigester that have been
     * specified in the <code>rulesets</code> init parameter.</p>
     *
     * @throws ServletException if an error occurs
     */
    private void addRuleSets()
        throws ServletException {
        String rulesets = getServletConfig().getInitParameter("rulesets");

        if (rulesets == null) {
            rulesets = "";
        }

        rulesets = rulesets.trim();

        String ruleset;

        while (rulesets.length() > 0) {
            int comma = rulesets.indexOf(",");

            if (comma < 0) {
                ruleset = rulesets.trim();
                rulesets = "";
            } else {
                ruleset = rulesets.substring(0, comma).trim();
                rulesets = rulesets.substring(comma + 1).trim();
            }

            if (log.isDebugEnabled()) {
                log.debug("Configuring custom Digester Ruleset of type "
                    + ruleset);
            }

            try {
                RuleSet instance =
                    (RuleSet) RequestUtils.applicationInstance(ruleset);

                this.configDigester.addRuleSet(instance);
            } catch (Exception e) {
                log.error("Exception configuring custom Digester RuleSet", e);
                throw new ServletException(e);
            }
        }
    }

    /**
     * <p>Check the status of the <code>validating</code> initialization
     * parameter.</p>
     *
     * @return true if the module Digester should validate.
     */
    private boolean isValidating() {
        boolean validating = true;
        String value = getServletConfig().getInitParameter("validating");

        if ("false".equalsIgnoreCase(value) || "no".equalsIgnoreCase(value)
            || "n".equalsIgnoreCase(value) || "0".equalsIgnoreCase(value)) {
            validating = false;
        }

        return validating;
    }

    /**
     * <p>Initialize our internal MessageResources bundle.</p>
     *
     * @throws ServletException     if we cannot initialize these resources
     * @throws UnavailableException if we cannot load  resources
     */
    protected void initInternal()
        throws ServletException {
        try {
            internal = MessageResources.getMessageResources(internalName);
        } catch (MissingResourceException e) {
            log.error("Cannot load internal resources from '" + internalName
                + "'", e);
            throw new UnavailableException(
                "Cannot load internal resources from '" + internalName + "'");
        }
    }

    /**
     * <p>Parse the configuration documents specified by the
     * <code>chainConfig</code> init-param to configure the default {@link
     * org.apache.commons.chain.Catalog} that is registered in the {@link
     * CatalogFactory} instance for this application.</p>
     *
     * @throws ServletException if an error occurs.
     */
    protected void initChain()
        throws ServletException {
        // Parse the configuration file specified by path or resource
        try {
            String value;

            value = getServletConfig().getInitParameter("chainConfig");

            if (value != null) {
                chainConfig = value;
            }

            ConfigParser parser = new ConfigParser();
            List urls = splitAndResolvePaths(chainConfig);
            URL resource;

            for (Iterator i = urls.iterator(); i.hasNext();) {
                resource = (URL) i.next();
                log.info("Loading chain catalog from " + resource);
                parser.parse(resource);
            }
        } catch (Exception e) {
            log.error("Exception loading resources", e);
            throw new ServletException(e);
        }
    }

    /**
     * <p>Initialize other global characteristics of the controller
     * servlet.</p>
     *
     * @throws ServletException if we cannot initialize these resources
     */
    protected void initOther()
        throws ServletException {
        String value;

        value = getServletConfig().getInitParameter("config");

        if (value != null) {
            config = value;
        }

        // Backwards compatibility for form beans of Java wrapper classes
        // Set to true for strict Struts 1.0 compatibility
        value = getServletConfig().getInitParameter("convertNull");

        if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)
            || "on".equalsIgnoreCase(value) || "y".equalsIgnoreCase(value)
            || "1".equalsIgnoreCase(value)) {
            convertNull = true;
        }

        if (convertNull) {
            ConvertUtils.deregister();
            ConvertUtils.register(new BigDecimalConverter(null),
                BigDecimal.class);
            ConvertUtils.register(new BigIntegerConverter(null),
                BigInteger.class);
            ConvertUtils.register(new BooleanConverter(null), Boolean.class);
            ConvertUtils.register(new ByteConverter(null), Byte.class);
            ConvertUtils.register(new CharacterConverter(null), Character.class);
            ConvertUtils.register(new DoubleConverter(null), Double.class);
            ConvertUtils.register(new FloatConverter(null), Float.class);
            ConvertUtils.register(new IntegerConverter(null), Integer.class);
            ConvertUtils.register(new LongConverter(null), Long.class);
            ConvertUtils.register(new ShortConverter(null), Short.class);
        }
    }

    /**
     * <p>Initialize the servlet mapping under whi

  


  
分享到:
评论

相关推荐

    struts1.3.10源代码

    深入研究Struts 1.3.10源代码,可以帮助我们掌握Web应用开发的基本架构,理解MVC模式在实践中的应用,以及学习如何通过配置和编程控制请求流程。同时,通过分析源码,还可以学习到如何处理HTTP请求,验证用户输入,...

    struts 1.3.10.chm api 中文版

    4. **控制器Servlet**:Struts使用一个名为`ActionServlet`的Servlet作为控制器,它负责解析HTTP请求,调用Action,处理结果并转发到视图。 5. **ActionMapping**:ActionMapping对象描述了请求与Action之间的映射...

    struts-1.3.10

    在`src`目录下,可以找到Struts框架的源代码,包括Action类、Form Bean、Tiles、国际化等组件的实现。通过阅读源码,开发者能更深入地了解如何定制和扩展框架,以满足特定需求。 实例部分是学习和掌握Struts框架的...

    Struts 1.3.10+Spring3.0.5+Mybatis3.1.1框架整合全部jar包

    它的核心组件包括ActionServlet、Action、ActionForm和ActionForward等。ActionServlet作为入口点,处理HTTP请求,并根据配置的ActionMapping将请求转发到相应的Action。ActionForm用于在控制器和视图之间传递数据,...

    Struts-1.3.10-src.zip

    这里的"Struts-1.3.10-src.zip"是一个包含Struts 1.3.10版本的源代码压缩包,用于开发者深入理解Struts的工作原理和自定义功能。以下将详细介绍Struts 1.3.10中的关键知识点: 1. **MVC设计模式**:MVC是一种软件...

    struts1.3.0

    - **ActionServlet**:作为Struts框架的核心控制器,负责接收HTTP请求,解析请求参数,并调用相应的Action来处理业务逻辑。 - **ActionForm**:用于封装用户请求的数据,从HTTP请求中提取数据并存储在Form Bean中...

    struts1框架源代码

    下面我们将深入探讨Struts1的源代码,了解其核心组件和工作原理。 1. **ActionServlet**:这是Struts1的核心控制器,它是Servlet的子类。ActionServlet负责拦截所有的HTTP请求,并根据配置文件(struts-config.xml...

    struts-1.3.10文档

    前者定义Action类、Form Bean、数据源以及结果映射,后者则对Struts进行部署描述。 3. **Action类**:每个用户请求都会映射到一个特定的Action类,该类负责处理请求并调用业务逻辑。Action类通常会返回一个Forward...

    struts-1.3.8-all&1.3.10

    6. **开发包内容**:"struts-1.3.8"和"struts-1.3.10-lib"这两个文件可能分别代表了Struts框架的源代码和库文件。库文件夹通常包含运行Struts应用所需的各种JAR文件,如Struts核心库、第三方依赖库(如Commons ...

    Struts1.3源代码

    Struts1.3源代码的分析可以帮助我们深入理解其内部工作机制,这对于开发者来说具有重要的学习价值。 在Struts1.3版本中,主要包含以下几个核心组件: 1. **ActionServlet**:这是Struts的核心控制器,负责处理HTTP...

    struts1.3.jar

    6. **DispatcherServlet**:Struts 1.3使用一个名为ActionServlet的DispatcherServlet,它是整个框架的入口点,负责接收请求,根据配置信息调度Action,然后返回响应。 7. **Plug-in机制**:Struts 1.3支持插件扩展...

    web学习笔记.pdf

    - src:包含Struts1.3.10的全部源代码。 要在Java Web项目中使用Struts2,需要将Struts2核心库(如Struts-core-2.x.jar、xwork-2.x.jar、ognl-2.x.jar、freemarker-2.x.jar、commons-logging-1.0.4.jar)放入`WEB-...

    struts1.3源码

    1. **ActionServlet**:这是Struts框架的核心控制器,它是Servlet的子类,负责处理HTTP请求,根据配置文件分发请求到相应的Action。 2. **ActionMapping**:这个类是用来映射请求到特定Action的,它包含了Action的...

    struts 1.3.0 all-in-one

    例如,ActionServlet作为控制器负责处理HTTP请求,Form Beans用于在视图和模型之间传递数据,而Action类则实现了业务逻辑。此外,Struts还提供了Tiles框架,用于构建可重用的页面布局。 在Struts 1.3.0中,引入了...

Global site tag (gtag.js) - Google Analytics