You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2005/01/22 21:14:57 UTC

svn commit: r126046 - /cocoon/trunk/src/core/java/org/apache/cocoon/configuration/Settings.java /cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java /cocoon/trunk/src/java/org/apache/cocoon/servlet/SettingsHelper.java

Author: cziegeler
Date: Sat Jan 22 12:14:57 2005
New Revision: 126046

URL: http://svn.apache.org/viewcvs?view=rev&rev=126046
Log:
Finish settings evaluation
Modified:
   cocoon/trunk/src/core/java/org/apache/cocoon/configuration/Settings.java
   cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java
   cocoon/trunk/src/java/org/apache/cocoon/servlet/SettingsHelper.java

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/configuration/Settings.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/configuration/Settings.java?view=diff&rev=126046&p1=cocoon/trunk/src/core/java/org/apache/cocoon/configuration/Settings.java&r1=126045&p2=cocoon/trunk/src/core/java/org/apache/cocoon/configuration/Settings.java&r2=126046
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/configuration/Settings.java	(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/configuration/Settings.java	Sat Jan 22 12:14:57 2005
@@ -15,10 +15,16 @@
  */
 package org.apache.cocoon.configuration;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.math.NumberUtils;
+
 /**
  * This object holds the global configuration of Cocoon.
  *
@@ -41,53 +47,192 @@
     public static final boolean SAVE_UPLOADS_TO_DISK = true;
     public static final int MAX_UPLOAD_SIZE = 10000000; // 10Mb
 
-    protected boolean initClassloader = false;
-    protected String[] forceProperties;
-    protected String configuration;    
+    /** 
+     * Default value for {@link #isInitClassloader()} setting (false) 
+     */
+    public static final boolean INIT_CLASSLOADER = false;
+
+    public static final boolean SHOW_TIME = false;
+    public static final boolean HIDE_SHOW_TIME = false;
+    public static final boolean MANAGE_EXCEPTIONS = true;
+    public static final String FORM_ENCODING = "";
+
+    /**
+     * This parameter tells Cocoon to set the thread's context classloader to
+     * its own classloader. If you experience strange classloader issues,
+     * try setting this parameter to "true".
+     */
+    protected boolean initClassloader = INIT_CLASSLOADER;
+
+    /**
+     * This parameter allows to set system properties
+     */
+    protected Map forceProperties = new HashMap();
+
+    /**
+     * This parameter points to the main configuration file for Cocoon.
+     * Note that the path is specified in absolute notation but it will be
+     * resolved relative to the application context path.
+     */
+    protected String configuration;
+
+    /**
+     * This parameter indicates the configuration file of the LogKit management
+     */
     protected String loggingConfiguration;
-    protected String cocoonLogger;    
+
+    /**
+     * This parameter indicates the category id of the logger from the LogKit
+     * configuration used by the environment.
+     */
     protected String accessLogger;
+
+    /**
+     * This parameter indicates the category id of the logger from the LogKit
+     * management configuration for the Cocoon engine.
+     * This logger is used for all components described in the cocoon.xconf
+     * and sitemap.xmap file not having specified a logger with the
+     * logger="..." attribute in the component configuration file.
+     */
+    protected String cocoonLogger;
+
+    /**
+     * This parameter indicates the log level to use throughout startup of the
+     * system. As soon as the logkit.xconf the setting of the logkit.xconf
+     * configuration is used instead! Only for startup and if the logkit.xconf is
+     * not readable/available this log level is of importance.
+     */
     protected String bootstrapLogLevel;
+
+    /**
+     * This parameter switches the logging system from LogKit to Log4J for Cocoon.
+     * Log4J has to be configured already.
+     */
     protected String loggerClassName;
 
     /**
-     * Allow reloading of cocoon by specifying the <code>cocoon-reload=true</code> parameter with a request
+     * If you want to configure log4j using Cocoon, then you can define
+     * an XML configuration file here. You can use the usual log4j property
+     * substituation mechanism, e.g. ${context-root} is replaced by the
+     * context root of this web application etc.
+     * You can configure the log4j configuration even if you use LogKit
+     * for Cocoon logging. You can use this to configure third party code
+     * for example.
+     */
+    protected String log4jConfiguration;
+
+    /**
+     * Allow reinstantiating (reloading) of the cocoon instance. If this is
+     * set to "yes" or "true", a new cocoon instance can be created using
+     * the request parameter "cocoon-reload". It also enables that Cocoon is
+     * reloaded when cocoon.xconf changes. Default is no for security reasons.
      */
     protected boolean allowReload = ALLOW_RELOAD;
 
-    protected String[] loadClasses;
+    /**
+     * This parameter is used to list classes that should be loaded at
+     * initialization time of the servlet. For example, JDBC Drivers used need to
+     * be named here. Additional entries may be inserted here during build
+     * depending on your build properties.
+     */
+    protected List loadClasses = new ArrayList();
 
     /**
-     * Allow processing of upload requests (mime/multipart)
+     * Causes all files in multipart requests to be processed.
+     * Default is false for security reasons. 
      */
     protected boolean enableUploads = ENABLE_UPLOADS;
-    protected String uploadDirectory;    
+
+    /**
+     * This parameter allows to specify where Cocoon should put uploaded files.
+     * The path specified can be either absolute or relative to the context
+     * path of the servlet. On windows platform, absolute directory must start
+     * with volume: C:\Path\To\Upload\Directory.
+     */
+    protected String uploadDirectory;
+
+    /**
+     * Causes all files in multipart requests to be saved to upload-dir.
+     * Default is true for security reasons.
+     */
     protected boolean autosaveUploads = SAVE_UPLOADS_TO_DISK;
-    // accepted values are deny|allow|rename - rename is default.
+
+    /**
+     * Specify handling of name conflicts when saving uploaded files to disk.
+     * Acceptable values are deny, allow, rename (default). Files are renamed
+     * x_filename where x is an integer value incremented to make the new
+     * filename unique.
+     */
     protected String overwriteUploads;
+
+    /**
+     * Specify maximum allowed size of the upload. Defaults to 10 Mb.
+     */
     protected int maxUploadSize = MAX_UPLOAD_SIZE;
+
+    /**
+     * This parameter allows to specify where Cocoon should create its page
+     * and other objects cache. The path specified can be either absolute or
+     * relative to the context path of the servlet. On windows platform,
+     * absolute directory must start with volume: C:\Path\To\Cache\Directory.
+     */
     protected String cacheDirectory;
+
+    /**
+     * This parameter allows to specify where Cocoon should put it's
+     * working files. The path specified is either absolute or relative
+     * to the context path of the Cocoon servlet. On windows platform,
+     * absolute directory must start with volume: C:\Path\To\Work\Directory.
+     */
     protected String workDirectory;
-    protected String[] extraClasspaths;
+
+    /**
+     * This parameter allows to specify additional directories or jars
+     * which Cocoon should put into it's own classpath.
+     * Note that absolute pathes are taken as such but relative pathes 
+     * are rooted at the context root of the Cocoon servlet.
+     */
+    protected List extraClasspaths = new ArrayList();
+
+    /**
+     * This parameter allows you to select the parent service manager.
+     * The class will be instantiated via the constructor that takes a single
+     * String as a parameter. That String will be equal to the text after the '/'.
+     * 
+     * Cocoon honors the LogEnabled, Initializable and Disposable interfaces for
+     * this class, if it implements them.
+     */
     protected String parentServiceManagerClassName;
 
     /**
      * Allow adding processing time to the response
      */
-    protected boolean showTime = false;
+    protected boolean showTime = SHOW_TIME;
+
     /**
      * If true, processing time will be added as an HTML comment
      */
-    protected boolean hideShowTime = false;
+    protected boolean hideShowTime = HIDE_SHOW_TIME;
+    
     /**
      * If true or not set, this class will try to catch and handle all Cocoon exceptions.
      * If false, it will rethrow them to the servlet container.
      */
-    protected boolean manageExceptions = true;
+    protected boolean manageExceptions = MANAGE_EXCEPTIONS;
+
+    /**
+     * Set form encoding. This will be the character set used to decode request
+     * parameters. If not set the ISO-8859-1 encoding will be assumed.
+    */
     protected String formEncoding;
-    protected String log4jConfiguration;
+
+    /**
+     * If this value is specified, it will be interpreted as a log level and
+     * all logging categories will be set to this level regardless of their
+     * definition in the logging configuration.
+     */
     protected String overrideLogLevel;
-    
+
     /**
      * Create a new settings object
      */
@@ -106,9 +251,54 @@
                 String key = current.getKey().toString();
                 if ( key.startsWith("org.apache.cocoon.") ) {
                     key = key.substring("org.apache.cocoon.".length());
-                    if ( key.equals("override.loglevel") ) {
-                        this.overrideLogLevel = current.getValue().toString();
+                    final String value = current.getValue().toString();
+
+                    if ( key.equals("init.classloader") ) { 
+                        this.initClassloader = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals("configuration") ) {
+                        this.configuration = value;
+                    } else if ( key.equals("logging.configuration") ) {
+                        this.loggingConfiguration = value;
+                    } else if ( key.equals("logging.logger.access") ) {
+                        this.accessLogger = value;
+                    } else if ( key.equals("logging.logger.cocoon") ) {
+                        this.cocoonLogger = value;
+                    } else if ( key.equals("logging.bootstrap.level") ) {
+                        this.bootstrapLogLevel = value;
+                    } else if ( key.equals("logging.manager.class") ) {
+                        this.loggerClassName = value;
+                    } else if ( key.equals("logging.log4j.configuration") ) {
+                        this.log4jConfiguration = value;
+                    } else if ( key.equals("allow.reload") ) {
+                        this.allowReload = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals("uploads.enable") ) {
+                        this.enableUploads = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals("uploads.directory") ) {
+                        this.uploadDirectory = value;
+                    } else if ( key.equals("uploads.autosave") ) {
+                        this.autosaveUploads = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals("uploads.overwrite") ) {
+                        this.overwriteUploads = value;
+                    } else if ( key.equals("uploads.maxsize") ) {
+                        this.maxUploadSize = NumberUtils.stringToInt(value);
+                    } else if ( key.equals("cache.directory") ) {
+                        this.cacheDirectory = value;
+                    } else if ( key.equals("work.directory") ) {
+                        this.workDirectory = value;
+                    } else if ( key.equals("parentservicemanager") ) {
+                        this.parentServiceManagerClassName = value;
+                    } else if ( key.equals("showtime") ) {
+                        this.showTime = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals("hideshowtime") ) {
+                        this.hideShowTime = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals("manageexceptions") ) {
+                        this.manageExceptions = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals("formencoding") ) {
+                        this.formEncoding = value;
+                    } else if ( key.equals("override.loglevel") ) {
+                        this.overrideLogLevel = value;
                     }
+                    // TODO - force property, load classes, extra class path
                 }
             }
         }
@@ -201,27 +391,30 @@
     /**
      * @return Returns the extraClasspaths.
      */
-    public String[] getExtraClasspaths() {
+    public List getExtraClasspaths() {
         return this.extraClasspaths;
     }
     /**
      * @param extraClasspaths The extraClasspaths to set.
      */
-    public void setExtraClasspaths(String[] extraClasspaths) {
-        this.extraClasspaths = extraClasspaths;
+    public void addToExtraClasspaths(String extraClasspath) {
+        this.extraClasspaths.add(extraClasspath);
     }
+    
     /**
      * @return Returns the forceProperties.
      */
-    public String[] getForceProperties() {
+    public Map getForceProperties() {
         return this.forceProperties;
     }
+    
     /**
      * @param forceProperties The forceProperties to set.
      */
-    public void setForceProperties(String[] forceProperties) {
-        this.forceProperties = forceProperties;
+    public void addToForceProperties(String key, String value) {
+        this.forceProperties.put(key, value);
     }
+    
     /**
      * @return Returns the formEncoding.
      */
@@ -246,18 +439,21 @@
     public void setInitClassloader(boolean initClassloader) {
         this.initClassloader = initClassloader;
     }
+
     /**
      * @return Returns the loadClasses.
      */
-    public String[] getLoadClasses() {
-        return this.loadClasses;
+    public Iterator getLoadClasses() {
+        return this.loadClasses.iterator();
     }
+
     /**
      * @param loadClasses The loadClasses to set.
      */
-    public void setLoadClasses(String[] loadClasses) {
-        this.loadClasses = loadClasses;
+    public void addToLoadClasses(String className) {
+        this.loadClasses.add(className);
     }
+
     /**
      * @return Returns the loggerClassName.
      */

Modified: cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java?view=diff&rev=126046&p1=cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java&r1=126045&p2=cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java&r2=126046
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java	(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java	Sat Jan 22 12:14:57 2005
@@ -30,6 +30,7 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.jar.Attributes;
@@ -139,9 +140,6 @@
     /** The parent ServiceManager, if any. Stored here in order to be able to dispose it in destroy(). */
     private ServiceManager parentServiceManager;
 
-    protected String forceLoadParameter;
-    protected String forceSystemProperty;
-
     /**
      * This is the path to the servlet context (or the result
      * of calling getRealPath('/') on the ServletContext.
@@ -325,8 +323,6 @@
                 this.getLogger().debug("Path for Root: " + debugPathTwo);
             }
         }
-        this.forceLoadParameter = getInitParameter("load-class", null);
-        this.forceSystemProperty = getInitParameter("force-property", null);
 
         // Output some debug info
         if (getLogger().isDebugEnabled()) {
@@ -393,14 +389,9 @@
         this.appContext.put(Constants.CONTEXT_CACHE_DIR, this.cacheDir);
 
         this.appContext.put(Constants.CONTEXT_CONFIG_URL,
-                            getConfigFile(conf.getInitParameter("configurations")));
-        if (conf.getInitParameter("configurations") == null) {
-            if (getLogger().isDebugEnabled()) {
-                getLogger().debug("configurations was not set - defaulting to... ?");
-            }
-        }
+                            this.getConfigFile(this.settings.getConfiguration()));
 
-        parentServiceManagerClass = getInitParameter("parent-service-manager", null);
+        parentServiceManagerClass = this.settings.getParentServiceManagerClassName();
         if (parentServiceManagerClass != null) {
             int dividerPos = parentServiceManagerClass.indexOf('/');
             if (dividerPos != -1) {
@@ -642,13 +633,12 @@
      * @throws ServletException
      */
     protected String getExtraClassPath() throws ServletException {
-        String extraClassPath = this.getInitParameter("extra-classpath");
-        if (extraClassPath != null) {
+        if (this.settings.getExtraClasspaths().size() > 0) {
             StringBuffer sb = new StringBuffer();
-            StringTokenizer st = new StringTokenizer(extraClassPath, SystemUtils.PATH_SEPARATOR, false);
+            final Iterator iter = this.settings.getExtraClasspaths().iterator();
             int i = 0;
-            while (st.hasMoreTokens()) {
-                String s = st.nextToken();
+            while (iter.hasNext()) {
+                String s = (String)iter.next();
                 if (i++ > 0) {
                     sb.append(File.pathSeparatorChar);
                 }
@@ -778,29 +768,21 @@
      * bug in WebSphere that does not load the URL handler for the
      * "classloader://" protocol.  In order to overcome that bug,
      * set "force-load" to "com.ibm.servlet.classloader.Handler".
-     *
-     * If you need to force more than one class to load, then
-     * separate each entry with whitespace, a comma, or a semi-colon.
-     * Cocoon will strip any whitespace from the entry.
      */
     private void forceLoad() {
-        if (this.forceLoadParameter != null) {
-            StringTokenizer fqcnTokenizer = new StringTokenizer(forceLoadParameter, " \t\r\n\f;,", false);
-
-            while (fqcnTokenizer.hasMoreTokens()) {
-                final String fqcn = fqcnTokenizer.nextToken().trim();
-
-                try {
-                    if (getLogger().isDebugEnabled()) {
-                        getLogger().debug("Trying to load class: " + fqcn);
-                    }
-                    ClassUtils.loadClass(fqcn).newInstance();
-                } catch (Exception e) {
-                    if (getLogger().isWarnEnabled()) {
-                        getLogger().warn("Could not force-load class: " + fqcn, e);
-                    }
-                    // Do not throw an exception, because it is not a fatal error.
+        final Iterator i = this.settings.getLoadClasses();
+        while ( i.hasNext() ) {
+            final String fqcn = (String)i.next();
+            try {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Trying to load class: " + fqcn);
                 }
+                ClassUtils.loadClass(fqcn).newInstance();
+            } catch (Exception e) {
+                if (getLogger().isWarnEnabled()) {
+                    getLogger().warn("Could not force-load class: " + fqcn, e);
+                }
+                // Do not throw an exception, because it is not a fatal error.
             }
         }
     }
@@ -813,28 +795,19 @@
      * Cocoon will strip any whitespace from the entry.
      */
     private void forceProperty() {
-        if (this.forceSystemProperty != null) {
-            StringTokenizer tokenizer = new StringTokenizer(forceSystemProperty, " \t\r\n\f;,", false);
-
-            java.util.Properties systemProps = System.getProperties();
-            while (tokenizer.hasMoreTokens()) {
-                final String property = tokenizer.nextToken().trim();
-                if (property.indexOf('=') == -1) {
-                    continue;
-                }
+        if ( this.settings.getForceProperties().size() > 0 ) {
+            Properties systemProps = System.getProperties();
+            final Iterator i = this.settings.getForceProperties().entrySet().iterator(); 
+            while (i.hasNext()) {
+                final Map.Entry current = (Map.Entry)i.next();
                 try {
-                    String key = property.substring(0, property.indexOf('='));
-                    String value = property.substring(property.indexOf('=') + 1);
-                    if (value.indexOf("${") != -1) {
-                        value = StringUtils.replaceToken(value);
-                    }
                     if (getLogger().isDebugEnabled()) {
-                        getLogger().debug("setting " + key + "=" + value);
+                        getLogger().debug("setting " + current.getKey() + "=" + current.getValue());
                     }
-                    systemProps.setProperty(key, value);
+                    systemProps.setProperty(current.getKey().toString(), current.getValue().toString());
                 } catch (Exception e) {
                     if (getLogger().isWarnEnabled()) {
-                        getLogger().warn("Could not set property: " + property, e);
+                        getLogger().warn("Could not set property: " + current.getKey(), e);
                     }
                     // Do not throw an exception, because it is not a fatal error.
                 }

Modified: cocoon/trunk/src/java/org/apache/cocoon/servlet/SettingsHelper.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/servlet/SettingsHelper.java?view=diff&rev=126046&p1=cocoon/trunk/src/java/org/apache/cocoon/servlet/SettingsHelper.java&r1=126045&p2=cocoon/trunk/src/java/org/apache/cocoon/servlet/SettingsHelper.java&r2=126046
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/SettingsHelper.java	(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/SettingsHelper.java	Sat Jan 22 12:14:57 2005
@@ -20,7 +20,9 @@
 import javax.servlet.ServletConfig;
 
 import org.apache.cocoon.configuration.Settings;
+import org.apache.cocoon.util.StringUtils;
 import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.SystemUtils;
 
 /**
  * This helper class initializes the {@link Settings} object from the servlet
@@ -35,34 +37,87 @@
     }
     
     public static void fill(Settings s, ServletConfig config) {
-        // logging
-        s.setCocoonLogger(config.getInitParameter("cocoon-logger"));
-        s.setAccessLogger(config.getInitParameter("servlet-logger"));
-        s.setBootstrapLogLevel(config.getInitParameter("log-level"));
-        s.setLoggerClassName(config.getInitParameter("logger-class"));
-        String value = config.getInitParameter("logkit-config");
+        String value;
+
+        s.setInitClassloader(getInitParameterAsBoolean(config, "init-classloader", s.isInitClassloader()));
+
+        handleForceProperty(getInitParameter(config, "force-property"), s);
+
+        value = getInitParameter(config, "configurations");
+        if ( value != null ) {
+            s.setConfiguration(value);
+        } else if ( s.getConfiguration() == null ) {
+            s.setConfiguration("/WEB-INF/cocoon.xconf");
+        }
+
+        value = getInitParameter(config, "logkit-config");
         if ( value != null ) {
             s.setLoggingConfiguration("context:/" + value);
         }
-        value = config.getInitParameter("log4j-config");
+
+        value = getInitParameter(config, "servlet-logger");
+        if ( value != null ) {
+            s.setAccessLogger(value);
+        }
+
+        value = getInitParameter(config, "cocoon-logger");
+        if ( value != null ) {
+            s.setCocoonLogger(value);
+        }
+
+        value = getInitParameter(config, "log-level");
+        if ( value != null ) {
+            s.setBootstrapLogLevel(value);
+        }
+
+        value = getInitParameter(config, "logger-class");
+        if ( value != null ) {
+            s.setLoggerClassName(value);
+        }
+
+        value = getInitParameter(config, "log4j-config");
         if ( value != null ) {
             s.setLog4jConfiguration("context:/" + value);
         }
+
+        s.setAllowReload(getInitParameterAsBoolean(config, "allow-reload", s.isAllowReload()));
+
+        handleLoadClass(getInitParameter(config, "load-class"), s);
+
+        s.setEnableUploads(getInitParameterAsBoolean(config, "enable-uploads", s.isEnableUploads()));
+
+        value = getInitParameter(config, "upload-directory");
+        if ( value != null ) {
+            s.setUploadDirectory(value);
+        }
+
+        s.setAutosaveUploads(getInitParameterAsBoolean(config, "autosave-uploads", s.isAutosaveUploads()));
+
+        value = getInitParameter(config, "overwrite-uploads");
+        if ( value != null ) {
+            s.setOverwriteUploads(config.getInitParameter(value));
+        }
+
+        s.setMaxUploadSize(getInitParameterAsInteger(config, "upload-max-size", s.getMaxUploadSize()));
         
-        s.setInitClassloader(getInitParameterAsBoolean(config, "init-classloader", false));
-        s.setForceProperties(getInitParameterAsArray(config, "force-property"));
-        s.setConfiguration(config.getInitParameter("configurations"));
-        s.setAllowReload(getInitParameterAsBoolean(config, "allow-reload", Settings.ALLOW_RELOAD));
-        s.setLoadClasses(getInitParameterAsArray(config, "load-class"));
-        s.setEnableUploads(getInitParameterAsBoolean(config, "enable-uploads", Settings.ENABLE_UPLOADS));
-        s.setUploadDirectory(config.getInitParameter("upload-directory"));
-        s.setAutosaveUploads(getInitParameterAsBoolean(config, "autosave-uploads", Settings.SAVE_UPLOADS_TO_DISK));
-        s.setOverwriteUploads(config.getInitParameter("overwrite-uploads"));
-        s.setMaxUploadSize(getInitParameterAsInteger(config, "upload-max-size", Settings.MAX_UPLOAD_SIZE));
-        s.setCacheDirectory(config.getInitParameter("cache-directory"));
-        s.setWorkDirectory(config.getInitParameter("work-directory"));
-        s.setParentServiceManagerClassName(config.getInitParameter("parent-service-manager"));
-        value = config.getInitParameter("show-time");
+        value = getInitParameter(config, "cache-directory");
+        if ( value != null ) {
+            s.setCacheDirectory(value);
+        }
+
+        value = getInitParameter(config, "work-directory");
+        if ( value != null ) {
+            s.setWorkDirectory(value);
+        }
+
+        handleExtraClassPath(config.getInitParameter("extra-classpath"), s);
+
+        value = getInitParameter(config, "parent-service-manager");
+        if ( value != null ) {
+            s.setParentServiceManagerClassName(value);
+        }
+
+        value = getInitParameter(config, "show-time");
         if ( value != null && value.equalsIgnoreCase("hide") ) {
             s.setShowTime(true);
             s.setHideShowTime(true);
@@ -70,15 +125,18 @@
             s.setShowTime(getInitParameterAsBoolean(config, "show-time", false));
             s.setHideShowTime(false);
         }
-        s.setManageExceptions(getInitParameterAsBoolean(config, "manage-exceptions", true));
-        s.setFormEncoding(config.getInitParameter("form-encoding"));
-        
-        // TODO extra classpath
+
+        s.setManageExceptions(getInitParameterAsBoolean(config, "manage-exceptions", s.isManageExceptions()));
+
+        value = getInitParameter(config, "form-encoding");
+        if ( value != null ) {
+            s.setFormEncoding(value);
+        }
     }
     
     /** Convenience method to access boolean servlet parameters */
     protected static boolean getInitParameterAsBoolean(ServletConfig config, String name, boolean defaultValue) {
-        String value = config.getInitParameter(name);
+        String value = getInitParameter(config, name);
         if (value == null) {
             return defaultValue;
         }
@@ -87,32 +145,85 @@
     }
 
     protected static int getInitParameterAsInteger(ServletConfig config, String name, int defaultValue) {
-        String value = config.getInitParameter(name);
+        String value = getInitParameter(config, name);
         if (value == null) {
             return defaultValue;
         }
         return Integer.parseInt(value);
     }
     
-    protected static String[] getInitParameterAsArray(ServletConfig config, String name) {
-        final String param = config.getInitParameter(name);
+    private static void handleLoadClass(String param, Settings s) {
         if ( param == null ) {
-            return null;
+            return;
         }
         StringTokenizer tokenizer = new StringTokenizer(param, " \t\r\n\f;,", false);
         String[] array = null;    
         while (tokenizer.hasMoreTokens()) {
             final String value = tokenizer.nextToken().trim();
-            if ( array == null ) {
-                array = new String[1];
-            } else {
-                String[] ca = new String[array.length+1];
-                System.arraycopy(array, 0, ca, 0, array.length);
-                array = ca;
+            s.addToLoadClasses(value);
+        }
+    }
+
+    /**
+     * Handle the "force-property" parameter.
+     *
+     * If you need to force more than one property to load, then
+     * separate each entry with whitespace, a comma, or a semi-colon.
+     * Cocoon will strip any whitespace from the entry.
+     */
+    private static void handleForceProperty(String forceSystemProperty, Settings s) {
+        if (forceSystemProperty != null) {
+            StringTokenizer tokenizer = new StringTokenizer(forceSystemProperty, " \t\r\n\f;,", false);
+
+            while (tokenizer.hasMoreTokens()) {
+                final String property = tokenizer.nextToken().trim();
+                if (property.indexOf('=') == -1) {
+                    continue;
+                }
+                try {
+                    String key = property.substring(0, property.indexOf('='));
+                    String value = property.substring(property.indexOf('=') + 1);
+                    if (value.indexOf("${") != -1) {
+                        value = StringUtils.replaceToken(value);
+                    }
+                    s.addToForceProperties(key, value);
+                } catch (Exception e) {
+                    // Do not throw an exception, because it is not a fatal error.
+                }
+            }
+        }
+    }
+
+    /**
+     * Retreives the "extra-classpath" attribute, that needs to be
+     * added to the class path.
+     */
+    private static void handleExtraClassPath(String extraClassPath, Settings settings) {
+        if (extraClassPath != null) {
+            StringBuffer sb = new StringBuffer();
+            StringTokenizer st = new StringTokenizer(extraClassPath, SystemUtils.PATH_SEPARATOR, false);
+            int i = 0;
+            while (st.hasMoreTokens()) {
+                String s = st.nextToken();
+                settings.addToExtraClasspaths(s);
             }
-            array[array.length-1] = value;
         }
-        return array;
+    }
+
+    /**
+     * Get an initialisation parameter. The value is trimmed, and null is returned if the trimmed value
+     * is empty.
+     */
+    private static String getInitParameter(ServletConfig config, String name) {
+        String result = config.getInitParameter(name);
+        if (result != null) {
+            result = result.trim();
+            if (result.length() == 0) {
+                result = null;
+            }
+        }
+
+        return result;
     }
     
 }