package org.apache.struts.action;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.MissingResourceException;
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.Converter;
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.config.ActionConfig;
import org.apache.struts.config.ApplicationConfig;
import org.apache.struts.config.ConfigRuleSet;
import org.apache.struts.config.ControllerConfig;
import org.apache.struts.config.DataSourceConfig;
import org.apache.struts.config.FormBeanConfig;
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.config.impl.ModuleConfigImpl;
import org.apache.struts.util.GenericDataSource;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.MessageResourcesFactory;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.util.ServletContextWriter;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class ActionServlet extends HttpServlet {
  protected String config = "/WEB-INF/struts-config.xml";
  
  protected Digester configDigester = null;
  
  protected boolean convertNull = false;
  
  protected FastHashMap dataSources = new FastHashMap();
  
  protected int debug = 0;
  
  protected MessageResources internal = null;
  
  protected String internalName = "org.apache.struts.action.ActionResources";
  
  protected static Log log = LogFactory.getLog(ActionServlet.class);
  
  protected RequestProcessor processor = null;
  
  protected String[] registrations = new String[] { "-//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", "-//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" };
  
  protected String servletMapping = null;
  
  protected String servletName = null;
  
  public void destroy() {
    if (log.isDebugEnabled())
      log.debug(this.internal.getMessage("finalizing")); 
    destroyModules();
    destroyDataSources();
    destroyInternal();
    getServletContext().removeAttribute("org.apache.struts.action.ACTION_SERVLET");
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    if (classLoader == null)
      classLoader = ActionServlet.class.getClassLoader(); 
    try {
      LogFactory.release(classLoader);
    } catch (Throwable t) {}
  }
  
  public void init() throws ServletException {
    initInternal();
    initOther();
    initServlet();
    getServletContext().setAttribute("org.apache.struts.action.ACTION_SERVLET", this);
    ModuleConfig moduleConfig = initModuleConfig("", this.config);
    initModuleMessageResources(moduleConfig);
    initModuleDataSources(moduleConfig);
    initModulePlugIns(moduleConfig);
    moduleConfig.freeze();
    Enumeration names = getServletConfig().getInitParameterNames();
    while (names.hasMoreElements()) {
      String name = 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();
    } 
    destroyConfigDigester();
  }
  
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    process(request, response);
  }
  
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    process(request, response);
  }
  
  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; 
  }
  
  public DataSource findDataSource(String key) {
    if (key == null)
      return (DataSource)this.dataSources.get("org.apache.struts.action.DATA_SOURCE"); 
    return (DataSource)this.dataSources.get(key);
  }
  
  public ActionFormBean findFormBean(String name) {
    ActionFormBeans afb = (ActionFormBeans)getServletContext().getAttribute("org.apache.struts.action.FORM_BEANS");
    if (afb == null)
      return null; 
    return afb.findFormBean(name);
  }
  
  public ActionForward findForward(String name) {
    ActionForwards af = (ActionForwards)getServletContext().getAttribute("org.apache.struts.action.FORWARDS");
    if (af == null)
      return null; 
    return af.findForward(name);
  }
  
  public ActionMapping findMapping(String path) {
    ActionMappings am = (ActionMappings)getServletContext().getAttribute("org.apache.struts.action.MAPPINGS");
    if (am == null)
      return null; 
    return am.findMapping(path);
  }
  
  public int getDebug() {
    return this.debug;
  }
  
  public MessageResources getInternal() {
    return this.internal;
  }
  
  public MessageResources getResources() {
    return (MessageResources)getServletContext().getAttribute("org.apache.struts.action.MESSAGE");
  }
  
  public void log(String message, int level) {
    if (this.debug >= level)
      log(message); 
  }
  
  protected void destroyApplications() {
    destroyModules();
  }
  
  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 = keys.next();
      Object value = getServletContext().getAttribute(name);
      if (value instanceof ModuleConfig) {
        ModuleConfig config = (ModuleConfig)value;
        try {
          getRequestProcessor(config).destroy();
        } catch (ServletException e) {
          log.error(e);
        } 
        getServletContext().removeAttribute(name);
        PlugIn[] plugIns = (PlugIn[])getServletContext().getAttribute("org.apache.struts.action.PLUG_INS" + config.getPrefix());
        if (plugIns != null) {
          for (int i = 0; i < plugIns.length; i++) {
            int j = plugIns.length - i + 1;
            plugIns[j].destroy();
          } 
          getServletContext().removeAttribute("org.apache.struts.action.PLUG_INS" + config.getPrefix());
        } 
      } 
    } 
  }
  
  protected void destroyConfigDigester() {
    this.configDigester = null;
  }
  
  protected void destroyDataSources() {
    synchronized (this.dataSources) {
      Iterator keys = this.dataSources.keySet().iterator();
      while (keys.hasNext()) {
        String key = keys.next();
        getServletContext().removeAttribute(key);
        DataSource dataSource = findDataSource(key);
        if (dataSource instanceof GenericDataSource) {
          if (log.isDebugEnabled())
            log.debug(this.internal.getMessage("dataSource.destroy", key)); 
          try {
            ((GenericDataSource)dataSource).close();
          } catch (SQLException e) {
            log.error(this.internal.getMessage("destroyDataSource", key), e);
          } 
        } 
      } 
      this.dataSources.clear();
    } 
  }
  
  protected void destroyInternal() {
    this.internal = null;
  }
  
  protected ApplicationConfig getApplicationConfig(HttpServletRequest request) {
    return new ApplicationConfig((ModuleConfigImpl)getModuleConfig(request));
  }
  
  protected ModuleConfig getModuleConfig(HttpServletRequest request) {
    ModuleConfig config = (ModuleConfig)request.getAttribute("org.apache.struts.action.MODULE");
    if (config == null)
      config = (ModuleConfig)getServletContext().getAttribute("org.apache.struts.action.MODULE"); 
    return config;
  }
  
  protected synchronized RequestProcessor getRequestProcessor(ModuleConfig config) throws ServletException {
    String key = "org.apache.struts.action.REQUEST_PROCESSOR" + config.getPrefix();
    RequestProcessor processor = (RequestProcessor)getServletContext().getAttribute(key);
    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);
      getServletContext().setAttribute(key, processor);
    } 
    return processor;
  }
  
  protected ApplicationConfig initApplicationConfig(String prefix, String path) throws ServletException {
    return new ApplicationConfig((ModuleConfigImpl)initModuleConfig(prefix, path));
  }
  
  protected ModuleConfig initModuleConfig(String prefix, String paths) throws ServletException {
    if (log.isDebugEnabled())
      log.debug("Initializing module path '" + prefix + "' configuration from '" + paths + "'"); 
    ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();
    ModuleConfig config = factoryObject.createModuleConfig(prefix);
    String mapping = getServletConfig().getInitParameter("mapping");
    if (mapping != null)
      config.setActionMappingClass(mapping); 
    Digester digester = initConfigDigester();
    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; 
      parseModuleConfigFile(prefix, paths, config, digester, path);
    } 
    FormBeanConfig[] fbs = config.findFormBeanConfigs();
    for (int i = 0; i < fbs.length; i++) {
      if (fbs[i].getDynamic())
        DynaActionFormClass.createDynaActionFormClass(fbs[i]); 
    } 
    if (prefix.length() < 1) {
      defaultControllerConfig(config);
      defaultMessageResourcesConfig(config);
      defaultFormBeansConfig(config);
      defaultForwardsConfig(config);
      defaultMappingsConfig(config);
    } 
    return config;
  }
  
  private void parseModuleConfigFile(String prefix, String paths, ModuleConfig config, Digester digester, String path) throws UnavailableException {
    InputStream input = null;
    try {
      URL url = getServletContext().getResource(path);
      InputSource is = new InputSource(url.toExternalForm());
      input = getServletContext().getResourceAsStream(path);
      is.setByteStream(input);
      digester.parse(is);
      getServletContext().setAttribute("org.apache.struts.action.MODULE" + prefix, config);
    } catch (MalformedURLException e) {
      handleConfigException(paths, e);
    } catch (IOException e) {
      handleConfigException(paths, e);
    } catch (SAXException e) {
      handleConfigException(paths, e);
    } finally {
      if (input != null)
        try {
          input.close();
        } catch (IOException e) {
          throw new UnavailableException(e.getMessage());
        }  
    } 
  }
  
  private void handleConfigException(String paths, Exception e) throws UnavailableException {
    log.error(this.internal.getMessage("configParse", paths), e);
    throw new UnavailableException(this.internal.getMessage("configParse", paths));
  }
  
  protected void initApplicationDataSources(ModuleConfig config) throws ServletException {
    initModuleDataSources(config);
  }
  
  protected void initModuleDataSources(ModuleConfig config) throws ServletException {
    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]; 
    this.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());
        if (ds instanceof GenericDataSource)
          ((GenericDataSource)ds).open(); 
        ds.setLogWriter((PrintWriter)scw);
      } catch (Exception e) {
        log.error(this.internal.getMessage("dataSource.init", dscs[i].getKey()), e);
        throw new UnavailableException(this.internal.getMessage("dataSource.init", dscs[i].getKey()));
      } 
      getServletContext().setAttribute(dscs[i].getKey() + config.getPrefix(), ds);
      this.dataSources.put(dscs[i].getKey(), ds);
    } 
    this.dataSources.setFast(true);
    if ("".equals(config.getPrefix()))
      initDataSources(); 
  }
  
  protected void initApplicationPlugIns(ModuleConfig config) throws ServletException {
    initModulePlugIns(config);
  }
  
  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("org.apache.struts.action.PLUG_INS" + 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());
        try {
          PropertyUtils.setProperty(plugIns[i], "currentPlugInConfigObject", plugInConfigs[i]);
        } catch (Exception e) {}
        plugIns[i].init(this, config);
      } catch (ServletException e) {
        throw e;
      } catch (Exception e) {
        String errMsg = this.internal.getMessage("plugIn.init", plugInConfigs[i].getClassName());
        log(errMsg, e);
        throw new UnavailableException(errMsg);
      } 
    } 
  }
  
  protected void initApplicationMessageResources(ModuleConfig config) throws ServletException {
    initModuleMessageResources(config);
  }
  
  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) {
        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();
        MessageResources resources = factoryObject.createResources(mrcs[i].getParameter());
        resources.setReturnNull(mrcs[i].getNull());
        getServletContext().setAttribute(mrcs[i].getKey() + config.getPrefix(), resources);
      } 
    } 
  }
  
  protected Digester initConfigDigester() throws ServletException {
    if (this.configDigester != null)
      return this.configDigester; 
    boolean validating = true;
    String value = getServletConfig().getInitParameter("validating");
    if ("false".equalsIgnoreCase(value) || "no".equalsIgnoreCase(value) || "n".equalsIgnoreCase(value) || "0".equalsIgnoreCase(value))
      validating = false; 
    this.configDigester = new Digester();
    this.configDigester.setNamespaceAware(true);
    this.configDigester.setValidating(validating);
    this.configDigester.setUseContextClassLoader(true);
    this.configDigester.addRuleSet((RuleSet)new ConfigRuleSet());
    for (int i = 0; i < this.registrations.length; i += 2) {
      URL url = getClass().getResource(this.registrations[i + 1]);
      if (url != null)
        this.configDigester.register(this.registrations[i], url.toString()); 
    } 
    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);
      } 
    } 
    return this.configDigester;
  }
  
  protected void initDataSources() throws ServletException {}
  
  protected void initInternal() throws ServletException {
    try {
      this.internal = MessageResources.getMessageResources(this.internalName);
    } catch (MissingResourceException e) {
      log.error("Cannot load internal resources from '" + this.internalName + "'", e);
      throw new UnavailableException("Cannot load internal resources from '" + this.internalName + "'");
    } 
  }
  
  protected void initOther() throws ServletException {
    String value = null;
    value = getServletConfig().getInitParameter("config");
    if (value != null)
      this.config = value; 
    value = getServletConfig().getInitParameter("debug");
    if (value != null)
      try {
        this.debug = Integer.parseInt(value);
      } catch (NumberFormatException e) {
        this.debug = 0;
      }  
    value = getServletConfig().getInitParameter("convertNull");
    if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value) || "y".equalsIgnoreCase(value) || "1".equalsIgnoreCase(value))
      this.convertNull = true; 
    if (this.convertNull) {
      ConvertUtils.deregister();
      ConvertUtils.register((Converter)new BigDecimalConverter(null), BigDecimal.class);
      ConvertUtils.register((Converter)new BigIntegerConverter(null), BigInteger.class);
      ConvertUtils.register((Converter)new BooleanConverter(null), Boolean.class);
      ConvertUtils.register((Converter)new ByteConverter(null), Byte.class);
      ConvertUtils.register((Converter)new CharacterConverter(null), Character.class);
      ConvertUtils.register((Converter)new DoubleConverter(null), Double.class);
      ConvertUtils.register((Converter)new FloatConverter(null), Float.class);
      ConvertUtils.register((Converter)new IntegerConverter(null), Integer.class);
      ConvertUtils.register((Converter)new LongConverter(null), Long.class);
      ConvertUtils.register((Converter)new ShortConverter(null), Short.class);
    } 
  }
  
  protected void initServlet() throws ServletException {
    this.servletName = getServletConfig().getServletName();
    Digester digester = new Digester();
    digester.push(this);
    digester.setNamespaceAware(true);
    digester.setValidating(false);
    for (int i = 0; i < this.registrations.length; i += 2) {
      URL url = getClass().getResource(this.registrations[i + 1]);
      if (url != null)
        digester.register(this.registrations[i], url.toString()); 
    } 
    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);
    if (log.isDebugEnabled())
      log.debug("Scanning web.xml for controller servlet mapping"); 
    InputStream input = getServletContext().getResourceAsStream("/WEB-INF/web.xml");
    try {
      digester.parse(input);
    } catch (IOException e) {
      log.error(this.internal.getMessage("configWebXml"), e);
      throw new ServletException(e);
    } catch (SAXException e) {
      log.error(this.internal.getMessage("configWebXml"), e);
      throw new ServletException(e);
    } finally {
      if (input != null)
        try {
          input.close();
        } catch (IOException e) {
          log.error(this.internal.getMessage("configWebXml"), e);
          throw new ServletException(e);
        }  
    } 
    if (log.isDebugEnabled())
      log.debug("Mapping for servlet '" + this.servletName + "' = '" + this.servletMapping + "'"); 
    if (this.servletMapping != null)
      getServletContext().setAttribute("org.apache.struts.action.SERVLET_MAPPING", this.servletMapping); 
  }
  
  protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    RequestUtils.selectModule(request, getServletContext());
    getRequestProcessor(getModuleConfig(request)).process(request, response);
  }
  
  private void defaultControllerConfig(ModuleConfig config) {
    String value = null;
    ControllerConfig cc = config.getControllerConfig();
    value = getServletConfig().getInitParameter("bufferSize");
    if (value != null)
      cc.setBufferSize(Integer.parseInt(value)); 
    value = getServletConfig().getInitParameter("content");
    if (value != null)
      cc.setContentType(value); 
    value = getServletConfig().getInitParameter("locale");
    if (value != null)
      if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)) {
        cc.setLocale(true);
      } else {
        cc.setLocale(false);
      }  
    value = getServletConfig().getInitParameter("maxFileSize");
    if (value != null)
      cc.setMaxFileSize(value); 
    value = getServletConfig().getInitParameter("nocache");
    if (value != null)
      if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)) {
        cc.setNocache(true);
      } else {
        cc.setNocache(false);
      }  
    value = getServletConfig().getInitParameter("multipartClass");
    if (value != null)
      cc.setMultipartClass(value); 
    value = getServletConfig().getInitParameter("tempDir");
    if (value != null)
      cc.setTempDir(value); 
  }
  
  private void defaultFormBeansConfig(ModuleConfig config) {
    FormBeanConfig[] fbcs = config.findFormBeanConfigs();
    ActionFormBeans afb = new ActionFormBeans();
    afb.setFast(false);
    for (int i = 0; i < fbcs.length; i++)
      afb.addFormBean((ActionFormBean)fbcs[i]); 
    afb.setFast(true);
    getServletContext().setAttribute("org.apache.struts.action.FORM_BEANS", afb);
  }
  
  private void defaultForwardsConfig(ModuleConfig config) {
    ForwardConfig[] fcs = config.findForwardConfigs();
    ActionForwards af = new ActionForwards();
    af.setFast(false);
    for (int i = 0; i < fcs.length; i++)
      af.addForward((ActionForward)fcs[i]); 
    af.setFast(true);
    getServletContext().setAttribute("org.apache.struts.action.FORWARDS", af);
  }
  
  private void defaultMappingsConfig(ModuleConfig config) {
    ActionConfig[] acs = config.findActionConfigs();
    ActionMappings am = new ActionMappings();
    am.setServlet(this);
    am.setFast(false);
    for (int i = 0; i < acs.length; i++)
      am.addMapping((ActionMapping)acs[i]); 
    am.setFast(true);
    getServletContext().setAttribute("org.apache.struts.action.MAPPINGS", am);
  }
  
  private void defaultMessageResourcesConfig(ModuleConfig config) {
    String value = null;
    MessageResourcesConfig mrc = config.findMessageResourcesConfig("org.apache.struts.action.MESSAGE");
    if (mrc == null) {
      mrc = new MessageResourcesConfig();
      mrc.setKey("org.apache.struts.action.MESSAGE");
      config.addMessageResourcesConfig(mrc);
    } 
    value = getServletConfig().getInitParameter("application");
    if (value != null)
      mrc.setParameter(value); 
    value = getServletConfig().getInitParameter("factory");
    if (value != null)
      mrc.setFactory(value); 
    value = getServletConfig().getInitParameter("null");
    if (value != null)
      if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")) {
        mrc.setNull(true);
      } else {
        mrc.setNull(false);
      }  
  }
}
