All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.struts.action.ActionServlet Maven / Gradle / Ivy

Go to download

Base project: http://central.maven.org/maven2/struts/struts/1.2.9/ This version of Struts doesn't throw java.io.NotSerializableException when the application server wants to persist sessions and makes renderFocusJavascript return valid xml

The newest version!
/*
 * $Id: ActionServlet.java 264684 2005-08-30 03:08:01Z niallp $ 
 *
 * Copyright 2000-2005 The Apache Software Foundation.
 * 
 * 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 org.apache.struts.action;

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.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.MissingResourceException;

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 javax.sql.DataSource;

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.collections.FastHashMap;
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.ConfigRuleSet;
import org.apache.struts.config.DataSourceConfig;
import org.apache.struts.config.FormBeanConfig;
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.apache.struts.util.ServletContextWriter;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * 

ActionServlet provides the "controller" in the * Model-View-Controller (MVC) design pattern for web applications that is * commonly known as "Model 2". This nomenclature originated with a * description in the JavaServerPages Specification, version 0.92, and has * persisted ever since (in the absence of a better name).

* *

Generally, a "Model 2" application is architected as follows:

*
    *
  • The user interface will generally be created with server pages, which * will not themselves contain any business logic. These pages represent * the "view" component of an MVC architecture.
  • *
  • Forms and hyperlinks in the user interface that require business logic * to be executed will be submitted to a request URI that is mapped to this * servlet.
  • *
  • There can be one instance of this servlet class, * which receives and processes all requests that change the state of * a user's interaction with the application. The servlet delegates the * handling of a request to a {@link RequestProcessor} object. This component * represents the "controller" component of an MVC architecture.
  • *
  • The RequestProcessor selects and invokes an {@link Action} class to perform * the requested business logic, or delegates the response to another resource.
  • *
  • The Action classes can manipulate the state of the application's * interaction with the user, typically by creating or modifying JavaBeans * that are stored as request or session attributes (depending on how long * they need to be available). Such JavaBeans represent the "model" * component of an MVC architecture.
  • *
  • Instead of producing the next page of the user interface directly, * Action classes generally return an {@link ActionForward} to indicate * which resource should handle the response. If the Action * does not return null, the RequestProcessor forwards or * redirects to the specified resource (by utilizing * RequestDispatcher.forward or Response.sendRedirect) * so as to produce the next page of the user interface.
  • *
* *

The standard version of RequestsProcessor implements the * following logic for each incoming HTTP request. You can override * some or all of this functionality by subclassing this object and * implementing your own version of the processing.

*
    *
  • Identify, from the incoming request URI, the substring that will be * used to select an action procedure.
  • *
  • Use this substring to map to the Java class name of the corresponding * action class (an implementation of the Action interface). *
  • *
  • If this is the first request for a particular Action class, * instantiate an instance of that class and cache it for future use.
  • *
  • Optionally populate the properties of an ActionForm bean * associated with this mapping.
  • *
  • Call the execute method of this Action class, passing * on a reference to the mapping that was used, the relevant form-bean * (if any), and the request and the response that were passed to the * controller by the servlet container (thereby providing access to any * specialized properties of the mapping itself as well as to the * ServletContext). *
  • *
* *

The standard version of ActionServlet is configured based * on the following servlet initialization parameters, which you will specify * in the web application deployment descriptor (/WEB-INF/web.xml) * for your application. Subclasses that specialize this servlet are free to * define additional initialization parameters.

*
    *
  • config - Comma-separated list of context-relative * path(s) to the XML resource(s) containing the configuration information * for the default module. (Multiple files support since Struts 1.1) * [/WEB-INF/struts-config.xml].
  • *
  • config/${module} - Comma-separated list of * Context-relative path(s) to the XML resource(s) * containing the configuration information for the module that * will use the specified prefix (/${module}). This can be repeated as many * times as required for multiple modules. (Since Struts 1.1)
  • *
  • configFactory - The Java class name of the * ModuleConfigFactory used to create the implementation of the * ModuleConfig interface. * [org.apache.struts.config.impl.DefaultModuleConfigFactory] *
  • *
  • convertNull - Force simulation of the Struts 1.0 behavior * when populating forms. If set to true, the numeric Java wrapper class types * (like java.lang.Integer) will default to null (rather than 0). * (Since Struts 1.1) [false]
  • *
  • rulesets - Comma-delimited list of fully qualified * classnames of additional org.apache.commons.digester.RuleSet * instances that should be added to the Digester that will * be processing struts-config.xml files. By default, only * the RuleSet for the standard configuration elements is * loaded. (Since Struts 1.1)
  • *
  • validating - Should we use a validating XML parser to * process the configuration file (strongly recommended)? [true]
  • *
* * @version $Rev: 264684 $ $Date: 2005-08-30 04:08:01 +0100 (Tue, 30 Aug 2005) $ */ public class ActionServlet extends HttpServlet { // ----------------------------------------------------- Instance Variables /** *

Comma-separated list of context-relative path(s) to our configuration * resource(s) for the default module.

*/ protected String config = "/WEB-INF/struts-config.xml"; /** *

The Digester used to produce ModuleConfig objects from a * Struts configuration file.

* * @since Struts 1.1 */ protected Digester configDigester = null; /** *

The flag to request backwards-compatible conversions for form bean * properties of the Java wrapper class types.

* * @since Struts 1.1 */ protected boolean convertNull = false; /** *

The JDBC data sources that has been configured for this module, * if any, keyed by the servlet context attribute under which they are * stored.

*/ protected FastHashMap dataSources = new FastHashMap(); /** *

The resources object for our internal resources.

*/ protected MessageResources internal = null; /** *

The Java base name of our internal resources.

* @since Struts 1.1 */ protected String internalName = "org.apache.struts.action.ActionResources"; /** *

Commons Logging instance.

* * @since Struts 1.1 */ protected static Log log = LogFactory.getLog(ActionServlet.class); /** *

The RequestProcessor instance we will use to process * all incoming requests.

* * @since Struts 1.1 */ protected RequestProcessor processor = null; /** *

The set of public identifiers, and corresponding resource names, for * the versions of the configuration file DTDs that we know about. There * MUST be an even number of Strings in this list!

*/ 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", "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN", "/org/apache/struts/resources/web-app_2_2.dtd", "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", "/org/apache/struts/resources/web-app_2_3.dtd" }; /** *

The URL pattern to which we are mapped in our web application * deployment descriptor.

*/ protected String servletMapping = null; // :FIXME: - multiples? /** *

The servlet name under which we are registered in our web application * deployment descriptor.

*/ protected String servletName = null; // ---------------------------------------------------- HttpServlet Methods /** *

Gracefully shut down this controller servlet, releasing any resources * that were allocated at initialization.

*/ public void destroy() { if (log.isDebugEnabled()) { log.debug(internal.getMessage("finalizing")); } destroyModules(); destroyInternal(); getServletContext().removeAttribute(Globals.ACTION_SERVLET_KEY); // 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 */ } PropertyUtils.clearDescriptors(); } /** *

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.

* * @exception ServletException if we cannot configure ourselves correctly */ public void init() throws ServletException { // 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(); getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this); initModuleConfigFactory(); // Initialize modules as needed ModuleConfig moduleConfig = initModuleConfig("", config); initModuleMessageResources(moduleConfig); initModuleDataSources(moduleConfig); initModulePlugIns(moduleConfig); moduleConfig.freeze(); Enumeration names = getServletConfig().getInitParameterNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); if (!name.startsWith("config/")) { continue; } String prefix = name.substring(6); moduleConfig = initModuleConfig (prefix, getServletConfig().getInitParameter(name)); initModuleMessageResources(moduleConfig); initModuleDataSources(moduleConfig); initModulePlugIns(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()); } } /** *

Saves a String[] of module prefixes in the ServletContext under * Globals.MODULE_PREFIXES_KEY. NOTE - * the "" prefix for the default module is not included in this list.

* * @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); } /** *

Process an HTTP "GET" request.

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

Process an HTTP "POST" request.

* * @param request The servlet request we are processing * @param response The servlet response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet exception occurs */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { process(request, response); } // --------------------------------------------------------- Public Methods /** *

Remember a servlet mapping from our web application deployment * descriptor, if it is for this servlet.

* * @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 (log.isDebugEnabled()) { log.debug("Process servletName=" + servletName + ", urlPattern=" + urlPattern); } if (servletName == null) { return; } if (servletName.equals(this.servletName)) { this.servletMapping = urlPattern; } } /** *

Return the MessageResources instance containing our * internal message strings.

* * @since Struts 1.1 */ public MessageResources getInternal() { return (this.internal); } // ------------------------------------------------------ Protected Methods /** *

Gracefully terminate use of any modules associated with this * application (if any).

* * @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()); } } } /** *

Gracefully release any configDigester instance that we have created.

* * @since Struts 1.1 */ protected void destroyConfigDigester() { configDigester = null; } /** *

Gracefully terminate use of the internal MessageResources.

*/ protected void destroyInternal() { internal = null; } /** *

Return the module configuration object for the currently selected * module.

* * @param request The servlet request we are processing * @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); } /** *

Look up and return the {@link RequestProcessor} responsible for the * specified module, creating a new one if necessary.

* * @param config The module configuration for which to * acquire and return a RequestProcessor. * * @exception ServletException if we cannot instantiate a RequestProcessor * instance * @since Struts 1.1 */ protected synchronized RequestProcessor getRequestProcessor(ModuleConfig config) throws ServletException { // :FIXME: Document UnavailableException? 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); } /** *

Returns the RequestProcessor for the given module or null if one does not * exist. This method will not create a RequestProcessor.

* * @param config The ModuleConfig. */ private RequestProcessor getProcessorForModule(ModuleConfig config) { String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix(); return (RequestProcessor) getServletContext().getAttribute(key); } /** *

Initialize the factory used to create the module configuration.

* @since Struts 1.2 */ protected void initModuleConfigFactory(){ String configFactory = getServletConfig().getInitParameter("configFactory"); if (configFactory != null) { ModuleConfigFactory.setFactoryClass(configFactory); } } /** *

Initialize the module configuration information for the * specified module.

* * @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) * * @exception ServletException if initialization cannot be performed * @since Struts 1.1 */ protected ModuleConfig initModuleConfig(String prefix, String paths) throws ServletException { // :FIXME: Document UnavailableException? (Doesn't actually throw anything) 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(); // Process each specified resource path while (paths.length() > 0) { digester.push(config); String path = null; int comma = paths.indexOf(','); if (comma >= 0) { path = paths.substring(0, comma).trim(); paths = paths.substring(comma + 1); } else { path = paths.trim(); paths = ""; } if (path.length() < 1) { break; } this.parseModuleConfigFile(digester, path); } getServletContext().setAttribute( Globals.MODULE_KEY + config.getPrefix(), config); // Force creation and registration of DynaActionFormClass instances // for all dynamic form beans we wil be using FormBeanConfig fbs[] = config.findFormBeanConfigs(); for (int i = 0; i < fbs.length; i++) { if (fbs[i].getDynamic()) { fbs[i].getDynaActionFormClass(); } } return config; } /** *

Parses one module config file.

* * @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 */ protected void parseModuleConfigFile(Digester digester, String path) throws UnavailableException { InputStream input = null; try { URL url = getServletContext().getResource(path); // If the config isn't in the servlet context, try the class loader // which allows the config files to be stored in a jar if (url == null) { url = getClass().getResource(path); } if (url == null) { String msg = internal.getMessage("configMissing", path); log.error(msg); throw new UnavailableException(msg); } InputSource is = new InputSource(url.toExternalForm()); input = url.openStream(); is.setByteStream(input); digester.parse(is); } catch (MalformedURLException e) { handleConfigException(path, e); } catch (IOException e) { handleConfigException(path, e); } catch (SAXException e) { handleConfigException(path, e); } finally { if (input != null) { try { input.close(); } catch (IOException e) { throw new UnavailableException(e.getMessage()); } } } } /** *

Simplifies exception handling in the parseModuleConfigFile method.

* @param path * @param e * @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); } /** *

Initialize the data sources for the specified module.

* * @param config ModuleConfig information for this module * * @exception ServletException if initialization cannot be performed * @since Struts 1.1 */ protected void initModuleDataSources(ModuleConfig config) throws ServletException { // :FIXME: Document UnavailableException? if (log.isDebugEnabled()) { log.debug("Initializing module path '" + config.getPrefix() + "' data sources"); } ServletContextWriter scw = new ServletContextWriter(getServletContext()); DataSourceConfig dscs[] = config.findDataSourceConfigs(); if (dscs == null) { dscs = new DataSourceConfig[0]; } dataSources.setFast(false); for (int i = 0; i < dscs.length; i++) { if (log.isDebugEnabled()) { log.debug("Initializing module path '" + config.getPrefix() + "' data source '" + dscs[i].getKey() + "'"); } DataSource ds = null; try { ds = (DataSource) RequestUtils.applicationInstance(dscs[i].getType()); BeanUtils.populate(ds, dscs[i].getProperties()); ds.setLogWriter(scw); } catch (Exception e) { log.error(internal.getMessage("dataSource.init", dscs[i].getKey()), e); throw new UnavailableException (internal.getMessage("dataSource.init", dscs[i].getKey())); } getServletContext().setAttribute (dscs[i].getKey() + config.getPrefix(), ds); dataSources.put(dscs[i].getKey(), ds); } dataSources.setFast(true); } /** *

Initialize the plug ins for the specified module.

* * @param config ModuleConfig information for this module * * @exception 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); } } } /** *

Initialize the application MessageResources for the specified * module.

* * @param config ModuleConfig information for this module * * @exception 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); } } /** *

Create (if needed) and return a new Digester * instance that has been initialized to process Struts module * configuration files and configure a corresponding ModuleConfig * object (which must be pushed on to the evaluation stack before parsing * begins).

* * @exception 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); } /** *

Add any custom RuleSet instances to configDigester that have * been specified in the rulesets init parameter.

* * @throws ServletException */ private void addRuleSets() throws ServletException { String rulesets = getServletConfig().getInitParameter("rulesets"); if (rulesets == null) { rulesets = ""; } rulesets = rulesets.trim(); String ruleset = null; 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); } } } /** *

Check the status of the validating initialization parameter.

* * @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; } /** *

Initialize our internal MessageResources bundle.

* * @exception ServletException if we cannot initialize these resources */ protected void initInternal() throws ServletException { // :FIXME: Document UnavailableException 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 + "'"); } } /** *

Initialize other global characteristics of the controller servlet.

* * @exception ServletException if we cannot initialize these resources */ protected void initOther() throws ServletException { String value = null; 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); } } /** *

Initialize the servlet mapping under which our controller servlet * is being accessed. This will be used in the &html:form> * tag to generate correct destination URLs for form submissions.

* * @throws ServletException if error happens while scanning web.xml */ protected void initServlet() throws ServletException { // Remember our servlet name this.servletName = getServletConfig().getServletName(); // Prepare a Digester to scan the web application deployment descriptor Digester digester = new Digester(); digester.push(this); digester.setNamespaceAware(true); digester.setValidating(false); // Register our local copy of the DTDs that we can find for (int i = 0; i < registrations.length; i += 2) { URL url = this.getClass().getResource(registrations[i+1]); if (url != null) { digester.register(registrations[i], url.toString()); } } // Configure the processing rules that we need digester.addCallMethod("web-app/servlet-mapping", "addServletMapping", 2); digester.addCallParam("web-app/servlet-mapping/servlet-name", 0); digester.addCallParam("web-app/servlet-mapping/url-pattern", 1); // Process the web application deployment descriptor if (log.isDebugEnabled()) { log.debug("Scanning web.xml for controller servlet mapping"); } InputStream input = getServletContext().getResourceAsStream("/WEB-INF/web.xml"); if (input == null) { log.error(internal.getMessage("configWebXml")); throw new ServletException(internal.getMessage("configWebXml")); } try { digester.parse(input); } catch (IOException e) { log.error(internal.getMessage("configWebXml"), e); throw new ServletException(e); } catch (SAXException e) { log.error(internal.getMessage("configWebXml"), e); throw new ServletException(e); } finally { try { input.close(); } catch (IOException e) { log.error(internal.getMessage("configWebXml"), e); throw new ServletException(e); } } // Record a servlet context attribute (if appropriate) if (log.isDebugEnabled()) { log.debug("Mapping for servlet '" + servletName + "' = '" + servletMapping + "'"); } if (servletMapping != null) { getServletContext().setAttribute(Globals.SERVLET_KEY, servletMapping); } } /** *

Perform the standard request processing for this request, and create * the corresponding response.

* * @param request The servlet request we are processing * @param response The servlet response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet exception is thrown */ protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ModuleUtils.getInstance().selectModule(request, getServletContext()); ModuleConfig config = getModuleConfig(request); RequestProcessor processor = getProcessorForModule(config); if (processor == null) { processor = getRequestProcessor(config); } processor.process(request, response); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy