cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jheym...@apache.org
Subject svn commit: r330548 [37/132] - in /cocoon/whiteboard/maven2/cocoon-flat-layout: ./ cocoon-ajax-block/ cocoon-ajax-block/api/ cocoon-ajax-block/api/src/ cocoon-ajax-block/api/src/main/ cocoon-ajax-block/api/src/main/java/ cocoon-ajax-block/api/src/main/...
Date Thu, 03 Nov 2005 14:00:48 GMT
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,1027 @@
+/*
+ * Copyright 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.cocoon.core;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.avalon.excalibur.logger.Log4JConfLoggerManager;
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Cocoon;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.container.ComponentContext;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.container.SingleComponentServiceManager;
+import org.apache.cocoon.core.logging.CocoonLogKitLoggerManager;
+import org.apache.cocoon.core.logging.PerRequestLoggerManager;
+import org.apache.cocoon.core.logging.SettingsContext;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.cocoon.util.StringUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * This is an utility class to create a new Cocoon instance.
+ * 
+ * TODO - Remove dependencies to LogKit and Log4J
+ *
+ * @version $Id: CoreUtil.java 321157 2005-10-14 17:21:29Z cziegeler $
+ * @since 2.2
+ */
+public class CoreUtil {
+
+    /** Parameter map for the context protocol */
+    protected static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+    /** The callback to the real environment. */
+    protected final BootstrapEnvironment env;
+
+    /** "legacy" support: create an avalon context. */
+    protected final DefaultContext appContext = new ComponentContext();
+
+    /** The settings. */
+    protected MutableSettings settings;
+
+    /** The parent service manager. */
+    protected ServiceManager parentManager;
+
+    /** The root logger. */
+    protected Logger log;
+
+    /** The logger manager. */
+    protected LoggerManager loggerManager;
+
+    /** The Cocoon instance (the root processor). */
+    protected Cocoon cocoon;
+
+    /** Is this a per request logger manager */
+    protected boolean isPerRequestLoggerManager = false;
+    
+    protected ClassLoader classloader;
+
+    /**
+     * Setup a new instance.
+     * @param environment The hook back to the environment.
+     * @throws Exception
+     */
+    public CoreUtil(BootstrapEnvironment environment)
+    throws Exception {
+        this.env = environment;
+        this.init();
+        this.createClassloader();        
+    }
+
+    protected void init()
+    throws Exception {
+        // first let's set up the appContext with some values to make
+        // the simple source resolver work
+
+        // add root url
+        try {
+            appContext.put(ContextHelper.CONTEXT_ROOT_URL,
+                           new URL(this.env.getContextURL()));
+        } catch (MalformedURLException ignore) {
+            // we simply ignore this
+        }
+
+        // add environment context
+        this.appContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT,
+                            this.env.getEnvironmentContext());
+
+        // now add environment specific information
+        this.env.configure(appContext);
+
+        // create settings
+        this.settings = this.createSettings();
+
+        // first init the work-directory for the logger.
+        // this is required if we are running inside a war file!
+        final String workDirParam = this.settings.getWorkDirectory();
+        File workDir;
+        if (workDirParam != null) {
+            if (this.env.getContextForWriting() == null) {
+                // No context path : consider work-directory as absolute
+                workDir = new File(workDirParam);
+            } else {
+                // Context path exists : is work-directory absolute ?
+                File workDirParamFile = new File(workDirParam);
+                if (workDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    workDir = workDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    workDir = new File(this.env.getContextForWriting(), workDirParam);
+                }
+            }
+        } else {
+            workDir = new File("cocoon-files");
+        }
+        workDir.mkdirs();
+        this.appContext.put(Constants.CONTEXT_WORK_DIR, workDir);
+        this.settings.setWorkDirectory(workDir.getAbsolutePath());
+
+        // Init logger
+        this.initLogger();
+        this.env.setLogger(this.log);
+
+        // Output some debug info
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("Context URL: " + this.env.getContextURL());
+            this.log.debug("Writeable Context: " + this.env.getContextForWriting());
+            if (workDirParam != null) {
+                this.log.debug("Using work-directory " + workDir);
+            } else {
+                this.log.debug("Using default work-directory " + workDir);
+            }
+        }
+
+        final String uploadDirParam = this.settings.getUploadDirectory();
+        File uploadDir;
+        if (uploadDirParam != null) {
+            if (this.env.getContextForWriting() == null) {
+                uploadDir = new File(uploadDirParam);
+            } else {
+                // Context path exists : is upload-directory absolute ?
+                File uploadDirParamFile = new File(uploadDirParam);
+                if (uploadDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    uploadDir = uploadDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    uploadDir = new File(this.env.getContextForWriting(), uploadDirParam);
+                }
+            }
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Using upload-directory " + uploadDir);
+            }
+        } else {
+            uploadDir = new File(workDir, "upload-dir" + File.separator);
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Using default upload-directory " + uploadDir);
+            }
+        }
+        uploadDir.mkdirs();
+        appContext.put(Constants.CONTEXT_UPLOAD_DIR, uploadDir);
+        this.settings.setUploadDirectory(uploadDir.getAbsolutePath());
+
+        String cacheDirParam = this.settings.getCacheDirectory();
+        File cacheDir;
+        if (cacheDirParam != null) {
+            if (this.env.getContextForWriting() == null) {
+                cacheDir = new File(cacheDirParam);
+            } else {
+                // Context path exists : is cache-directory absolute ?
+                File cacheDirParamFile = new File(cacheDirParam);
+                if (cacheDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    cacheDir = cacheDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    cacheDir = new File(this.env.getContextForWriting(), cacheDirParam);
+                }
+            }
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Using cache-directory " + cacheDir);
+            }
+        } else {
+            cacheDir = new File(workDir, "cache-dir" + File.separator);
+            File parent = cacheDir.getParentFile();
+            if (parent != null) {
+                parent.mkdirs();
+            }
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("cache-directory was not set - defaulting to " + cacheDir);
+            }
+        }
+        cacheDir.mkdirs();
+        appContext.put(Constants.CONTEXT_CACHE_DIR, cacheDir);
+        this.settings.setCacheDirectory(cacheDir.getAbsolutePath());
+
+        // update configuration
+        final URL u = this.env.getConfigFile(this.settings.getConfiguration());
+        this.settings.setConfiguration(u.toExternalForm());
+        this.appContext.put(Constants.CONTEXT_CONFIG_URL, u);
+
+        // set encoding
+        this.appContext.put(Constants.CONTEXT_DEFAULT_ENCODING, settings.getFormEncoding());
+
+        // set class loader
+        this.appContext.put(Constants.CONTEXT_CLASS_LOADER, this.classloader);
+
+        // create the Core object
+        final Core core = this.createCore();
+
+        // create parent service manager
+        this.parentManager = this.getParentServiceManager(core);
+
+        // settings can't be changed anymore
+        settings.makeReadOnly();
+
+        // put the core into the context - this is for internal use only
+        // The Cocoon container fetches the Core object using the context.
+        this.appContext.put(Core.ROLE, core);
+    }
+
+    public Core getCore() {
+        try {
+            return (Core)this.parentManager.lookup(Core.ROLE);
+        } catch (ServiceException neverIgnore) {
+            // this should never happen!
+            throw new CoreFatalException("Fatal exception: no Cocoon core available.", neverIgnore);
+        }
+    }
+
+    /**
+     * Create a new core instance.
+     * This method can be overwritten in sub classes.
+     * @return A new core object.
+     */
+    protected Core createCore() {
+        final Core c = new Core(this.settings, this.appContext);
+        return c;
+    }
+
+    /**
+     * Return the settings object.
+     */
+    public Settings getSettings() {
+        return this.settings;
+    }
+
+    /**
+     * Instatiates the parent service manager, as specified in the
+     * parent-service-manager init parameter.
+     *
+     * If none is specified, the method returns <code>null</code>.
+     *
+     * @return the parent service manager, or <code>null</code>.
+     */
+    protected ServiceManager getParentServiceManager(Core core) {
+        String parentServiceManagerClass = this.settings.getParentServiceManagerClassName();
+        String parentServiceManagerInitParam = null;
+        if (parentServiceManagerClass != null) {
+            int dividerPos = parentServiceManagerClass.indexOf('/');
+            if (dividerPos != -1) {
+                parentServiceManagerInitParam = parentServiceManagerInitParam.substring(dividerPos + 1);
+                parentServiceManagerClass = parentServiceManagerClass.substring(0, dividerPos);
+            }
+        }
+
+        ServiceManager parentServiceManager = null;
+        if (parentServiceManagerClass != null) {
+            try {
+                Class pcm = ClassUtils.loadClass(parentServiceManagerClass);
+                Constructor pcmc = pcm.getConstructor(new Class[]{String.class});
+                parentServiceManager = (ServiceManager) pcmc.newInstance(new Object[]{parentServiceManagerInitParam});
+
+                ContainerUtil.enableLogging(parentServiceManager, this.log);
+                ContainerUtil.contextualize(parentServiceManager, this.appContext);
+                ContainerUtil.initialize(parentServiceManager);
+            } catch (Exception e) {
+                if (this.log.isErrorEnabled()) {
+                    this.log.error("Could not initialize parent component manager.", e);
+                }
+            }
+        }
+        return new SingleComponentServiceManager(parentServiceManager, core, Core.ROLE);
+    }
+
+    /**
+     * Get the settings for Cocoon.
+     * This method reads several property files and merges the result. If there
+     * is more than one definition for a property, the last one wins.
+     * The property files are read in the following order:
+     * 1) context://WEB-INF/properties/*.properties
+     *    Default values for the core and each block - the order in which the files are read is not guaranteed.
+     * 2) context://WEB-INF/properties/[RUNNING_MODE]/*.properties
+     *    Default values for the running mode - the order in which the files are read is not guaranteed.
+     * 3) Property providers (ToBeDocumented)
+     * 4) The environment (CLI, Servlet etc.) adds own properties (e.g. from web.xml)
+     * 5) Additional property file specified by the "org.apache.cocoon.settings" system property or
+     *    if the property is not found, the file ".cocoon/settings.properties" is tried to be read from
+     *    the user directory.
+     * 6) System properties
+     *
+     * @return A new Settings object
+     */
+    protected MutableSettings createSettings() {
+        // get the running mode
+        final String mode = System.getProperty(Settings.PROPERTY_RUNNING_MODE, Settings.DEFAULT_RUNNING_MODE);
+        this.env.log("Running in mode: " + mode);
+
+        // create an empty settings objects
+        final MutableSettings s = new MutableSettings();
+
+        // we need our own resolver
+        final SourceResolver resolver = this.createSourceResolver(new LoggerWrapper(this.env));
+
+        // now read all properties from the properties directory
+        this.readProperties("context://WEB-INF/properties", s, resolver);
+        // read all properties from the mode dependent directory
+        this.readProperties("context://WEB-INF/properties/" + mode, s, resolver);
+
+        // Next look for custom property providers
+        Iterator i = s.getPropertyProviders().iterator();
+        while ( i.hasNext() ) {
+            final String className = (String)i.next();
+            try {
+                PropertyProvider provider = (PropertyProvider)ClassUtils.newInstance(className);
+                s.fill(provider.getProperties());
+            } catch (Exception ignore) {
+                env.log("Unable to get property provider for class " + className, ignore);
+                env.log("Continuing initialization.");            
+            }
+        }
+        // fill from the environment configuration, like web.xml etc.
+        env.configure(s);
+
+        // read additional properties file
+        String additionalPropertyFile = s.getProperty(Settings.PROPERTY_USER_SETTINGS, 
+                                                      System.getProperty(Settings.PROPERTY_USER_SETTINGS));
+        // if there is no property defining the addition file, we try it in the home directory
+        if ( additionalPropertyFile == null ) {
+            additionalPropertyFile = System.getProperty("user.home") + File.separator + ".cocoon/settings.properties";
+            final File testFile = new File(additionalPropertyFile);
+            if ( !testFile.exists() ) {
+                additionalPropertyFile = null;
+            }
+        }
+        if ( additionalPropertyFile != null ) {
+            env.log("Reading user settings from '" + additionalPropertyFile + "'");
+            final Properties p = new Properties();
+            try {
+                FileInputStream fis = new FileInputStream(additionalPropertyFile);
+                p.load(fis);
+                fis.close();
+            } catch (IOException ignore) {
+                env.log("Unable to read '" + additionalPropertyFile + "'.", ignore);
+                env.log("Continuing initialization.");
+            }
+        }
+        // now overwrite with system properties
+        s.fill(System.getProperties());
+
+        return s;
+    }
+
+    /**
+     * Read all property files from the given directory and apply them to the settings.
+     */
+    protected void readProperties(String directoryName,
+                                  MutableSettings s,
+                                  SourceResolver resolver) {
+        Source directory = null;
+        try {
+            directory = resolver.resolveURI(directoryName, null, CONTEXT_PARAMETERS);
+            if (directory.exists() && directory instanceof TraversableSource) {
+                final Iterator c = ((TraversableSource) directory).getChildren().iterator();
+                while (c.hasNext()) {
+                    final Source src = (Source) c.next();
+                    if ( src.getURI().endsWith(".properties") ) {
+                        final InputStream propsIS = src.getInputStream();
+                        env.log("Reading settings from '" + src.getURI() + "'.");
+                        final Properties p = new Properties();
+                        p.load(propsIS);
+                        propsIS.close();
+                        s.fill(p);
+                    }
+                }
+            }
+        } catch (IOException ignore) {
+            env.log("Unable to read from directory 'WEB-INF/properties'.", ignore);
+            env.log("Continuing initialization.");            
+        } finally {
+            resolver.release(directory);
+        }
+    }
+
+    /**
+     * Initialize the current request.
+     * This method can be used to initialize anything required for processing
+     * the request. For example, if the logger manager is a {@link PerRequestLoggerManager}
+     * than this manager is invoked to initialize the logging context for the request.
+     * This method returns a handle that should be used to clean up everything
+     * when the request is finished by calling {@link #cleanUpRequest(Object)}.
+     */
+    public Object initializeRequest(Environment env) {
+        if ( this.isPerRequestLoggerManager ) {
+            return ((PerRequestLoggerManager)this.loggerManager).initializePerRequestLoggingContext(env);
+        }
+        return null;   
+    }
+
+    /**
+     * Cleanup everything initialized during the request processing in
+     * {@link #initializeRequest(Environment)}.
+     */
+    public void cleanUpRequest(Object handle) {
+        if ( handle != null && this.isPerRequestLoggerManager) {
+            ((PerRequestLoggerManager)this.loggerManager).cleanPerRequestLoggingContext(handle);
+        }
+    }
+
+    /**
+     * Create a simple source resolver.
+     */
+    protected SourceResolver createSourceResolver(Logger logger) {
+        // Create our own resolver
+        final SimpleSourceResolver resolver = new SimpleSourceResolver();
+        resolver.enableLogging(logger);
+        try {
+            resolver.contextualize(this.appContext);
+        } catch (ContextException ce) {
+            throw new CoreInitializationException(
+                    "Cannot setup source resolver.", ce);
+        }
+        return resolver;        
+    }
+
+    protected void initLogger() {
+        String logLevel = settings.getBootstrapLogLevel();
+        if (logLevel == null) {
+            logLevel = "INFO";
+        }
+
+        String accesslogger = settings.getEnvironmentLogger();
+        if (accesslogger == null) {
+            accesslogger = "cocoon";
+        }
+
+        // create bootstrap logger
+        final BootstrapEnvironment.LogLevel level = BootstrapEnvironment.LogLevel.getLogLevelForName(logLevel);
+        final Logger bootstrapLogger = this.env.getBootstrapLogger(level);
+
+        // Create our own resolver
+        final SourceResolver resolver = this.createSourceResolver(bootstrapLogger);
+
+        // create an own service manager for the logger manager
+        final ServiceManager loggerManagerServiceManager = new SingleComponentServiceManager(
+                 null, resolver, SourceResolver.ROLE);
+
+        // create an own context for the logger manager
+        final DefaultContext subcontext = new SettingsContext(this.appContext, this.settings);
+        subcontext.put("context-work", new File(this.settings.getWorkDirectory()));
+        if (this.env.getContextForWriting() == null) {
+            File logSCDir = new File(this.settings.getWorkDirectory(), "log");
+            logSCDir.mkdirs();
+            subcontext.put("context-root", logSCDir.toString());
+        } else {
+            subcontext.put("context-root", this.env.getContextForWriting().toString());
+        }
+        this.env.configureLoggingContext(subcontext);
+
+        String loggerManagerClass = settings.getLoggerManagerClassName();
+
+        // the log4j support requires currently that the log4j system is already
+        // configured elsewhere
+
+        final LoggerManager loggerManager = this.newLoggerManager(loggerManagerClass);
+        ContainerUtil.enableLogging(loggerManager, bootstrapLogger);
+
+        try {
+            ContainerUtil.contextualize(loggerManager, subcontext);
+            ContainerUtil.service(loggerManager, loggerManagerServiceManager);
+
+            this.loggerManager = loggerManager;
+
+            if (loggerManager instanceof Configurable) {
+                //Configure the logkit management
+                String logkitConfig = settings.getLoggingConfiguration();
+
+                if ( logkitConfig != null ) {
+                    Source source = null;
+                    try {
+                        source = resolver.resolveURI(logkitConfig);
+                        final ConfigurationBuilder builder = new ConfigurationBuilder(
+                                settings);
+                        final Configuration conf = builder.build(source.getInputStream());
+                        final DefaultConfiguration categories = (DefaultConfiguration) conf
+                                .getChild("categories");
+                        final DefaultConfiguration targets = (DefaultConfiguration) conf
+                                .getChild("targets");
+                        final DefaultConfiguration factories = (DefaultConfiguration) conf
+                                .getChild("factories");
+    
+                        // now process includes
+                        final Configuration[] children = conf
+                                .getChildren("include");
+                        for (int i = 0; i < children.length; i++) {
+                            String directoryURI = children[i].getAttribute("dir");
+                            final String pattern = children[i].getAttribute(
+                                    "pattern", null);
+                            int[] parsedPattern = null;
+                            if (pattern != null) {
+                                parsedPattern = WildcardHelper
+                                        .compilePattern(pattern);
+                            }
+                            Source directory = null;
+                            try {
+                                directory = resolver.resolveURI(directoryURI,
+                                        source.getURI(), CONTEXT_PARAMETERS);
+                                if (directory instanceof TraversableSource) {
+                                    final Iterator c = ((TraversableSource) directory)
+                                            .getChildren().iterator();
+                                    while (c.hasNext()) {
+                                        final Source s = (Source) c.next();
+                                        if (parsedPattern == null
+                                                || this.match(s.getURI(),
+                                                        parsedPattern)) {
+                                            final Configuration includeConf = builder
+                                                    .build(s.getInputStream());
+                                            // add targets and categories
+                                            categories.addAllChildren(includeConf
+                                                    .getChild("categories"));
+                                            targets.addAllChildren(includeConf
+                                                    .getChild("targets"));
+                                            factories.addAllChildren(includeConf
+                                                    .getChild("factories"));
+                                        }
+                                    }
+                                } else {
+                                    throw new ConfigurationException(
+                                            "Include.dir must point to a directory, '"
+                                                    + directory.getURI()
+                                                    + "' is not a directory.'");
+                                }
+                            } catch (IOException ioe) {
+                                throw new ConfigurationException(
+                                        "Unable to read configurations from "
+                                                + directoryURI);
+                            } finally {
+                                resolver.release(directory);
+                            }
+    
+                            // finally remove include
+                            ((DefaultConfiguration) conf).removeChild(children[i]);
+                        }
+                        // override log level?
+                        if (settings.getOverrideLogLevel() != null) {
+                            this.overrideLogLevel(conf.getChild("categories"),
+                                    settings.getOverrideLogLevel());
+                        }
+                        ContainerUtil.configure(loggerManager, conf);
+                    } finally {
+                        resolver.release(source);
+                    }
+                }
+            }
+            ContainerUtil.initialize(loggerManager);
+        } catch (Exception e) {
+            bootstrapLogger.error(
+                    "Could not set up Cocoon Logger, will use screen instead",
+                    e);
+        }
+
+        this.log = this.loggerManager.getLoggerForCategory(accesslogger);
+    }
+
+    /**
+     * Create a new logger manager.
+     * @param loggerManagerClass The class name or one of the allowed shortcuts.
+     * @return A new logger manager.
+     */
+    private LoggerManager newLoggerManager(String loggerManagerClass) {
+        if ("LogKit".equalsIgnoreCase(loggerManagerClass) || loggerManagerClass == null) {
+            loggerManagerClass = CocoonLogKitLoggerManager.class.getName();
+        } else if ("LOG4J".equalsIgnoreCase(loggerManagerClass)) {
+            loggerManagerClass = Log4JConfLoggerManager.class.getName();
+        }
+        try {
+            Class clazz = Class.forName(loggerManagerClass);
+            if ( PerRequestLoggerManager.class.isAssignableFrom(clazz) ) {
+                this.isPerRequestLoggerManager = true;
+            }
+            return (LoggerManager) clazz.newInstance();
+        } catch (Exception e) {
+            this.isPerRequestLoggerManager = true;
+            return new CocoonLogKitLoggerManager();
+        }
+    }
+
+    protected void overrideLogLevel(Configuration root, String value) {
+        Configuration[] c = root.getChildren("category");
+        for(int i=0;i<c.length;i++) {
+            ((DefaultConfiguration)c[i]).setAttribute("log-level", value);
+            this.overrideLogLevel(c[i], value);
+        }
+    }
+
+    private boolean match(String uri, int[] parsedPattern ) {
+        int pos = uri.lastIndexOf('/');
+        if ( pos != -1 ) {
+            uri = uri.substring(pos+1);
+        }
+        return WildcardHelper.match(null, uri, parsedPattern);
+    }
+
+    /**
+     * Creates the Cocoon object and handles exception handling.
+     */
+    public synchronized Cocoon createCocoon()
+    throws Exception {
+
+        this.updateEnvironment();
+        this.forceLoad();
+        this.forceProperty();
+
+        try {
+            if (this.log.isInfoEnabled()) {
+                this.log.info("Reloading from: " + this.settings.getConfiguration());
+            }
+            Cocoon c = (Cocoon)ClassUtils.newInstance("org.apache.cocoon.Cocoon");
+            ContainerUtil.enableLogging(c, getCocoonLogger());
+            c.setLoggerManager(this.loggerManager);
+            ContainerUtil.contextualize(c, this.appContext);
+
+            // create the Core object
+            final Core core = this.createCore();
+            this.parentManager = this.getParentServiceManager(core);
+            ContainerUtil.service(c, this.parentManager);
+
+            ContainerUtil.initialize(c);
+            this.settings.setCreationTime(System.currentTimeMillis());
+            this.cocoon = c;
+        } catch (Exception e) {
+            this.log.error("Exception reloading Cocoon.", e);
+            this.disposeCocoon();
+            throw e;
+        }
+        return this.cocoon;
+    }
+
+    /**
+     * Create the classloader that inlcudes all the [block]/BLOCK-INF/classes directories. 
+     * @throws Exception
+     */
+    protected void createClassloader() throws Exception {
+        // get the wiring
+        final SourceResolver resolver = this.createSourceResolver(this.log);    
+        Source wiringSource = null;
+        final Configuration wiring;
+        try {
+            wiringSource = resolver.resolveURI(Constants.WIRING);
+            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+            wiring = builder.build( wiringSource.getInputStream() );            
+        } catch(org.apache.excalibur.source.SourceNotFoundException snfe) {
+            throw new WiringNotFoundException("wiring.xml not found in the root directory of your Cocoon application.");
+        } finally {
+            resolver.release(wiringSource);
+        }
+        
+        // get all wired blocks and add their classed directory to the classloader
+        List urlList = new ArrayList();        
+        Configuration[] blocks = wiring.getChildren("block");
+        for(int i = 0; i < blocks.length; i++) {
+            String location = blocks[i].getAttribute("location");
+            if(this.log.isDebugEnabled()) {
+                this.log.debug("Found block " + blocks[i].getAttribute("id") + " at " + location);
+            }
+            Source classesDir = null;
+            try {
+               classesDir = resolver.resolveURI(location + "/" + Constants.BLOCK_META_DIR + "/classes");
+               if(classesDir.exists()) {
+                   String classesDirURI = classesDir.getURI();
+                   urlList.add(new URL(classesDirURI));
+                   if(this.log.isDebugEnabled()) {
+                       this.log.debug("added " + classesDir.getURI());
+                   }
+               }               
+            } finally {
+                resolver.release(classesDir);
+            }
+        }
+
+        // setup the classloader using the current classloader as parent
+        ClassLoader parentClassloader = Thread.currentThread().getContextClassLoader();
+        URL[] urls = (URL[]) urlList.toArray(new URL[urlList.size()]);        
+        URLClassLoader classloader = new URLClassLoader(urls, parentClassloader);
+        Thread.currentThread().setContextClassLoader(classloader);
+        this.classloader = Thread.currentThread().getContextClassLoader();
+    }
+
+    /**
+     * Gets the current cocoon object.
+     * Reload cocoon if configuration changed or we are reloading.
+     * Ensure that the correct classloader is set.
+     */
+    public Cocoon getCocoon(final String pathInfo, final String reloadParam)
+    throws Exception {
+        
+        // set the blocks classloader for this thread
+        Thread.currentThread().setContextClassLoader(this.classloader);        
+        
+        if (this.settings.isReloadingEnabled("config")) {
+            boolean reload = false;
+
+            if (this.cocoon != null) {
+                if (this.cocoon.modifiedSince(this.settings.getCreationTime())) {
+                    if (this.log.isInfoEnabled()) {
+                        this.log.info("Configuration changed reload attempt");
+                    }
+                    reload = true;
+                } else if (pathInfo == null && reloadParam != null) {
+                    if (this.log.isInfoEnabled()) {
+                        this.log.info("Forced reload attempt");
+                    }
+                    reload = true;
+                }
+            } else if (pathInfo == null && reloadParam != null) {
+                if (this.log.isInfoEnabled()) {
+                    this.log.info("Invalid configurations reload");
+                }
+                reload = true;
+            }
+
+            if (reload) {
+                this.init();
+                this.createCocoon();
+            }
+        }
+        return this.cocoon;
+    }
+
+    /**
+     * Destroy Cocoon
+     */
+    protected final void disposeCocoon() {
+        if (this.cocoon != null) {
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Disposing Cocoon");
+            }
+            ContainerUtil.dispose(this.cocoon);
+            this.cocoon = null;
+        }
+        ContainerUtil.dispose(this.parentManager);
+        this.parentManager = null;
+    }
+
+    protected Logger getCocoonLogger() {
+        final String rootlogger = this.settings.getCocoonLogger();
+        if (rootlogger != null) {
+            return this.loggerManager.getLoggerForCategory(rootlogger);
+        }
+        return this.log;
+    }
+
+    /**
+     * Handle the <code>load-class</code> parameter. This overcomes
+     * limits in many classpath issues. One of the more notorious
+     * ones is a bug in WebSphere that does not load the URL handler
+     * for the <code>classloader://</code> protocol. In order to
+     * overcome that bug, set <code>load-class</code> parameter to
+     * the <code>com.ibm.servlet.classloader.Handler</code> value.
+     *
+     * <p>If you need to load more than one class, then separate each
+     * entry with whitespace, a comma, or a semi-colon. Cocoon will
+     * strip any whitespace from the entry.</p>
+     */
+    protected void forceLoad() {
+        final Iterator i = this.settings.getLoadClasses().iterator();
+        while (i.hasNext()) {
+            final String fqcn = (String)i.next();
+            try {
+                if (this.log.isDebugEnabled()) {
+                    this.log.debug("Loading: " + fqcn);
+                }
+                ClassUtils.loadClass(fqcn).newInstance();
+            } catch (Exception e) {
+                if (this.log.isWarnEnabled()) {
+                    this.log.warn("Could not load class: " + fqcn, e);
+                }
+                // Do not throw an exception, because it is not a fatal error.
+            }
+        }
+    }
+
+    /**
+     * 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.
+     */
+    protected void forceProperty() {
+        if (this.settings.getForceProperties().size() > 0) {
+            final Iterator i = this.settings.getForceProperties().entrySet().iterator();
+            while (i.hasNext()) {
+                final Map.Entry current = (Map.Entry)i.next();
+                try {
+                    if (this.log.isDebugEnabled()) {
+                        this.log.debug("Setting: " + current.getKey() + "=" + current.getValue());
+                    }
+                    System.setProperty(current.getKey().toString(), current.getValue().toString());
+                } catch (Exception e) {
+                    if (this.log.isWarnEnabled()) {
+                        this.log.warn("Could not set property: " + current.getKey(), e);
+                    }
+                    // Do not throw an exception, because it is not a fatal error.
+                }
+            }
+        }
+    }
+
+    /**
+     * Method to update the environment before Cocoon instances are created.
+     *
+     * This is also useful if you wish to customize any of the 'protected'
+     * variables from this class before a Cocoon instance is built in a derivative
+     * of this class (eg. Cocoon Context).
+     */
+    protected void updateEnvironment() throws Exception {
+//        // concatenate the class path and the extra class path
+//        String classPath = this.env.getClassPath(this.settings);
+//        StringBuffer buffer = new StringBuffer();
+//        if ( classPath != null && classPath.length() > 0 ) {
+//            buffer.append(classPath);
+//        }
+//        classPath = this.getExtraClassPath();
+//        if ( classPath != null && classPath.length() > 0 ) {
+//            if ( buffer.length() > 0 ) {
+//                buffer.append(File.pathSeparatorChar);
+//            }
+//            buffer.append(classPath);
+//        }
+        // FIXME - for now we just set an empty string as this information is looked up
+        //         by other components
+        this.appContext.put(Constants.CONTEXT_CLASSPATH, "");
+    }
+
+    /**
+     * Dispose Cocoon when environment is destroyed
+     */
+    public void destroy() {
+        this.disposeCocoon();
+    }
+
+    /**
+     * Retreives the "extra-classpath" attribute, that needs to be
+     * added to the class path.
+     */
+    protected String getExtraClassPath() {
+        if (this.settings.getExtraClasspaths().size() > 0) {
+            StringBuffer sb = new StringBuffer();
+            final Iterator iter = this.settings.getExtraClasspaths().iterator();
+            int i = 0;
+            while (iter.hasNext()) {
+                String s = (String)iter.next();
+                if (i++ > 0) {
+                    sb.append(File.pathSeparatorChar);
+                }
+                if ((s.charAt(0) == File.separatorChar) ||
+                        (s.charAt(1) == ':')) {
+                    if (this.log.isDebugEnabled()) {
+                        this.log.debug("extraClassPath is absolute: " + s);
+                    }
+                    sb.append(s);
+
+                } else {
+                    if (s.indexOf("${") != -1) {
+                        String path = StringUtils.replaceToken(s);
+                        sb.append(path);
+                        if (this.log.isDebugEnabled()) {
+                            this.log.debug("extraClassPath is not absolute replacing using token: [" + s + "] : " + path);
+                        }
+                    } else {
+                        String path = null;
+                        if (this.env.getContextForWriting() != null) {
+                            path = this.env.getContextForWriting() + s;
+                            if (this.log.isDebugEnabled()) {
+                                this.log.debug("extraClassPath is not absolute pre-pending context path: " + path);
+                            }
+                        } else {
+                            path = this.settings.getWorkDirectory() + s;
+                            if (this.log.isDebugEnabled()) {
+                                this.log.debug("extraClassPath is not absolute pre-pending work-directory: " + path);
+                            }
+                        }
+                        sb.append(path);
+                    }
+                }
+            }
+            return sb.toString();
+        }
+        return "";
+    }
+
+    protected static final class LoggerWrapper implements Logger {
+        private final BootstrapEnvironment env;
+
+        public LoggerWrapper(BootstrapEnvironment env) {
+            this.env = env;
+        }
+
+        protected void text(String arg0, Throwable arg1) {
+            if ( arg1 != null ) {
+                this.env.log(arg0, arg1);
+            } else {
+                this.env.log(arg0);
+            }
+        }
+
+        public void debug(String arg0, Throwable arg1) {
+            // we ignore debug
+        }
+
+        public void debug(String arg0) {
+            // we ignore debug
+        }
+
+        public void error(String arg0, Throwable arg1) {
+            this.text(arg0, arg1);
+        }
+
+        public void error(String arg0) {
+            this.text(arg0, null);
+        }
+
+        public void fatalError(String arg0, Throwable arg1) {
+            this.text(arg0, arg1);
+        }
+
+        public void fatalError(String arg0) {
+            this.text(arg0, null);
+        }
+
+        public Logger getChildLogger(String arg0) {
+            return this;
+        }
+
+        public void info(String arg0, Throwable arg1) {
+            // we ignore info
+        }
+
+        public void info(String arg0) {
+            // we ignore info
+        }
+
+        public boolean isDebugEnabled() {
+            return false;
+        }
+
+        public boolean isErrorEnabled() {
+            return true;
+        }
+
+        public boolean isFatalErrorEnabled() {
+            return true;
+        }
+
+        public boolean isInfoEnabled() {
+            return false;
+        }
+
+        public boolean isWarnEnabled() {
+            return false;
+        }
+
+        public void warn(String arg0, Throwable arg1) {
+            // we ignore warn
+        }
+
+        public void warn(String arg0) {
+            // we ignore warn
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/CoreUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/DynamicSettings.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/DynamicSettings.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/DynamicSettings.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/DynamicSettings.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,178 @@
+/*
+ * Copyright 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.cocoon.core;
+
+/**
+ * The settings (configuration) for the Cocoon core are described through the {@link BaseSettings}
+ * interface and the {@link DynamicSettings} interface.
+ * Whereas the settings of the {@link BaseSettings} object can't be changed at runtime,
+ * the settings of the {@link DynamicSettings} object are mutable. Use the {@link Core} instance
+ * to update the settings.
+ *
+ * @version $Id: DynamicSettings.java 312930 2005-10-11 18:13:35Z cziegeler $
+ * @since 2.2
+ */
+public interface DynamicSettings {
+
+    /**
+     * Default value for {@link #isReloadingEnabled(String)} parameter (false).
+     */
+    boolean RELOADING_ENABLED_DEFAULT = false;
+
+    /**
+     * Default value for {@link #isEnableUploads()} parameter (false).
+     */
+    boolean ENABLE_UPLOADS = false;
+    boolean SAVE_UPLOADS_TO_DISK = true;
+    int MAX_UPLOAD_SIZE = 10000000; // 10Mb
+
+    boolean SHOW_TIME = false;
+    boolean HIDE_SHOW_TIME = false;
+
+    /**
+     * Default value for {@link #isShowVersion()} parameter (true).
+     */
+    boolean SHOW_COCOON_VERSION = true;
+
+    /**
+     * 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.
+     */
+    String KEY_RELOADING = "reloading";
+
+    /**
+     * Causes all files in multipart requests to be processed.
+     * Default is false for security reasons.
+     */
+    String KEY_UPLOADS_ENABLE = "uploads.enable";
+
+    /**
+     * Causes all files in multipart requests to be saved to upload-dir.
+     * Default is true for security reasons.
+     */
+    String KEY_UPLOADS_AUTOSAVE = "uploads.autosave";
+
+    /**
+     * 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.
+     */
+    String KEY_UPLOADS_OVERWRITE = "uploads.overwrite";
+
+    /**
+     * Specify maximum allowed size of the upload. Defaults to 10 Mb.
+     */
+    String KEY_UPLOADS_MAXSIZE = "uploads.maxsize";
+
+    /**
+     * Allow adding processing time to the response
+     */
+    String KEY_SHOWTIME = "showtime";
+
+    /**
+     * If true, processing time will be added as an HTML comment
+     */
+    String KEY_HIDE_SHOWTIME = "hideshowtime";
+
+    /**
+     * If true, the X-Cocoon-Version response header will be included.
+     */
+    String KEY_SHOW_VERSION = "show-version";
+
+    /**
+     * Delay between reload checks for the configuration
+     */
+    String KEY_RELOAD_DELAY = "reload-delay";
+
+    /**
+     * Lazy mode for component loading
+     */
+    String KEY_LAZY_MODE = "core.LazyMode";
+
+    /**
+     * @return Returns the hideShowTime.
+     * @see #KEY_HIDE_SHOWTIME
+     */
+    boolean isHideShowTime();
+
+    /**
+     * @return Returns the showCocoonVersion.
+     * @see #KEY_SHOW_VERSION
+     */
+    boolean isShowVersion();
+
+    /**
+     * This method can be used by components to query if they are
+     * configured to check for reloading.
+     * @param type The type of the component that wants to check for reload.
+     * @return Returns if reloading is enabled for this component.
+     * @see #KEY_RELOADING
+     */
+    boolean isReloadingEnabled(String type);
+
+    /**
+     * This method can be used by components to get the configured
+     * delay period inbetween checks.
+     * @param type The type of the component that wants to check for reload.
+     * @return Returns the delay inbetween checks in milliseconds.
+     * @see #KEY_RELOAD_DELAY
+     */
+    long getReloadDelay(String type);
+
+    /**
+     * @return Returns the autosaveUploads.
+     * @see #KEY_UPLOADS_AUTOSAVE
+     */
+    boolean isAutosaveUploads();
+
+    /**
+     * @return Returns the enableUploads.
+     * @see #KEY_UPLOADS_ENABLE
+     */
+    boolean isEnableUploads();
+
+    /**
+     * @return Returns the maxUploadSize.
+     * @see #KEY_UPLOADS_MAXSIZE
+     */
+    int getMaxUploadSize();
+
+    /**
+     * @return Returns the overwriteUploads.
+     * @see #KEY_UPLOADS_OVERWRITE
+     */
+    String getOverwriteUploads();
+
+    /**
+     * @return Returns the showTime.
+     * @see #KEY_SHOWTIME
+     */
+    boolean isShowTime();
+
+    /**
+     * @return Returns the lazyMode.
+     * @see #KEY_LAZY_MODE
+     */
+    boolean isLazyMode();
+
+    boolean isAllowOverwrite();
+
+    boolean isSilentlyRename();
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/DynamicSettings.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/MutableSettings.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/MutableSettings.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/MutableSettings.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/MutableSettings.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,956 @@
+/*
+ * Copyright 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.cocoon.core;
+
+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.
+ *
+ * @version $Id: MutableSettings.java 325985 2005-10-17 21:34:30Z sylvain $
+ * @since 2.2
+ */
+public class MutableSettings implements Settings {
+
+    /** Are we still mutable? */
+    protected boolean readOnly = false;
+
+    /** Prefix for properties */
+    protected static final String KEYPREFIX = "org.apache.cocoon.";
+
+    /**
+     * The list of properties used to configure Cocoon
+     */
+    protected List properties = new ArrayList();
+
+    /**
+     * 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;
+
+    /**
+     * This parameter indicates the category id of the logger from the LogKit
+     * configuration used by the environment.
+     */
+    protected String environmentLogger;
+
+    /**
+     * 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.
+     */
+    protected String loggerManagerClassName;
+
+    /**
+     * 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 reloadingEnabled = RELOADING_ENABLED_DEFAULT;
+
+    /**
+     * 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();
+
+    /**
+     * Causes all files in multipart requests to be processed.
+     * Default is false for security reasons.
+     */
+    protected boolean enableUploads = ENABLE_UPLOADS;
+
+    /**
+     * 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;
+
+    /**
+     * 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;
+
+    /**
+     * 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 = SHOW_TIME;
+
+    /**
+     * If true, processing time will be added as an HTML comment
+     */
+    protected boolean hideShowTime = HIDE_SHOW_TIME;
+
+    /**
+     * If true, the X-Cocoon-Version response header will be included.
+     */
+    protected boolean showCocoonVersion = SHOW_COCOON_VERSION;
+
+    /**
+     * 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 = 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;
+
+    /**
+     * 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;
+
+    /**
+     * Delay between reload checks for the configuration.
+     */
+    protected long configurationReloadDelay = 1000;
+
+    /**
+     * Lazy mode for component loading
+     */
+    protected boolean lazyMode = false;
+
+    /** The time the cocoon instance was created. */
+    protected long creationTime;
+
+    /** The property providers. */
+    protected List propertyProviders = new ArrayList();
+
+    /**
+     * Create a new settings object
+     */
+    public MutableSettings() {
+        // nothing to do
+    }
+
+    /**
+     * Fill from a properties object
+     */
+    public void fill(Properties props) {
+        this.checkWriteable();
+        if ( props != null ) {
+            final Iterator i = props.entrySet().iterator();
+            while ( i.hasNext() ) {
+                final Map.Entry current = (Map.Entry)i.next();
+                String key = current.getKey().toString();
+                if ( key.startsWith(KEYPREFIX) ) {
+                    key = key.substring(KEYPREFIX.length());
+                    final String value = current.getValue().toString();
+
+                    if ( key.equals(KEY_CONFIGURATION) ) {
+                        this.configuration = value;
+                    } else if ( key.equals(KEY_RELOAD_DELAY) ) {
+                        this.configurationReloadDelay = NumberUtils.toLong(value);
+                    } else if ( key.equals(KEY_LOGGING_CONFIGURATION) ) {
+                        this.loggingConfiguration = value;
+                    } else if ( key.equals(KEY_LOGGING_ENVIRONMENT_LOGGER) ) {
+                        this.environmentLogger = value;
+                    } else if ( key.equals(KEY_LOGGING_COCOON_LOGGER) ) {
+                        this.cocoonLogger = value;
+                    } else if ( key.equals(KEY_LOGGING_BOOTSTRAP_LOGLEVEL) ) {
+                        this.bootstrapLogLevel = value;
+                    } else if ( key.equals(KEY_LOGGING_MANAGER_CLASS) ) {
+                        this.loggerManagerClassName = value;
+                    } else if ( key.equals(KEY_RELOADING) ) {
+                        this.reloadingEnabled = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_UPLOADS_ENABLE) ) {
+                        this.enableUploads = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_UPLOADS_DIRECTORY) ) {
+                        this.uploadDirectory = value;
+                    } else if ( key.equals(KEY_UPLOADS_AUTOSAVE) ) {
+                        this.autosaveUploads = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_UPLOADS_OVERWRITE) ) {
+                        this.overwriteUploads = value;
+                    } else if ( key.equals(KEY_UPLOADS_MAXSIZE) ) {
+                        this.maxUploadSize = NumberUtils.toInt(value);
+                    } else if ( key.equals(KEY_CACHE_DIRECTORY) ) {
+                        this.cacheDirectory = value;
+                    } else if ( key.equals(KEY_WORK_DIRECTORY) ) {
+                        this.workDirectory = value;
+                    } else if ( key.equals(KEY_PARENT_SERVICE_MANAGER) ) {
+                        this.parentServiceManagerClassName = value;
+                    } else if ( key.equals(KEY_SHOWTIME) ) {
+                        this.showTime = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_HIDE_SHOWTIME) ) {
+                        this.hideShowTime = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_SHOW_VERSION) ) {
+                        this.showCocoonVersion = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_MANAGE_EXCEPTIONS) ) {
+                        this.manageExceptions = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_FORM_ENCODING) ) {
+                        this.formEncoding = value;
+                    } else if ( key.equals(KEY_LOGGING_OVERRIDE_LOGLEVEL) ) {
+                        this.overrideLogLevel = value;
+                    } else if ( key.equals(KEY_LAZY_MODE) ) {
+                        this.lazyMode = BooleanUtils.toBoolean(value);
+                    } else if ( key.startsWith(KEY_LOAD_CLASSES) ) {
+                        this.addToLoadClasses(value);
+                    } else if ( key.startsWith(KEY_EXTRA_CLASSPATHS) ) {
+                        this.addToExtraClasspaths(value);
+                    } else if ( key.startsWith(KEY_PROPERTY_PROVIDER) ) {
+                        this.addToPropertyProviders(value);
+                    } else if ( key.startsWith(KEY_FORCE_PROPERTIES) ) {
+                        key = key.substring(KEY_FORCE_PROPERTIES.length() + 1);
+                        this.addToForceProperties(key, value);
+                    }
+                }
+            }
+            this.properties.add(props);
+        }
+    }
+
+    /**
+     * @return Returns the hideShowTime.
+     */
+    public boolean isHideShowTime() {
+        return this.hideShowTime;
+    }
+
+    /**
+     * @return Returns the allowReload.
+     */
+    public boolean isReloadingEnabled(String type) {
+        boolean result = this.reloadingEnabled;
+        if ( type != null ) {
+            String o = this.getProperty(KEYPREFIX + KEY_RELOADING + '.' + type);
+            if ( o != null ) {
+                result = BooleanUtils.toBoolean(o);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * @return Returns the autosaveUploads.
+     */
+    public boolean isAutosaveUploads() {
+        return this.autosaveUploads;
+    }
+
+    /**
+     * @return Returns the cacheDirectory.
+     */
+    public String getCacheDirectory() {
+        return this.cacheDirectory;
+    }
+
+    /**
+     * @return Returns the cocoonLogger.
+     */
+    public String getCocoonLogger() {
+        return this.cocoonLogger;
+    }
+
+    /**
+     * @return Returns the configuration.
+     */
+    public String getConfiguration() {
+        return this.configuration;
+    }
+
+    /**
+     * @return Returns the enableUploads.
+     */
+    public boolean isEnableUploads() {
+        return this.enableUploads;
+    }
+
+    /**
+     * @return Returns the extraClasspaths.
+     */
+    public List getExtraClasspaths() {
+        return this.extraClasspaths;
+    }
+
+    /**
+     * @return Returns the forceProperties.
+     */
+    public Map getForceProperties() {
+        return this.forceProperties;
+    }
+
+    /**
+     * @return Returns the formEncoding.
+     */
+    public String getFormEncoding() {
+        return this.formEncoding;
+    }
+
+    /**
+     * @return Returns the loadClasses.
+     */
+    public List getLoadClasses() {
+        return this.loadClasses;
+    }
+
+    /**
+     * @return Returns the loggerClassName.
+     */
+    public String getLoggerManagerClassName() {
+        return this.loggerManagerClassName;
+    }
+
+    /**
+     * @return Returns the loggingConfiguration.
+     */
+    public String getLoggingConfiguration() {
+        return this.loggingConfiguration;
+    }
+
+    /**
+     * @return Returns the logLevel.
+     */
+    public String getBootstrapLogLevel() {
+        return this.bootstrapLogLevel;
+    }
+
+    /**
+     * @return Returns the manageExceptions.
+     */
+    public boolean isManageExceptions() {
+        return this.manageExceptions;
+    }
+
+    /**
+     * @return Returns the maxUploadSize.
+     */
+    public int getMaxUploadSize() {
+        return this.maxUploadSize;
+    }
+
+    /**
+     * @return Returns the overwriteUploads.
+     */
+    public String getOverwriteUploads() {
+        return this.overwriteUploads;
+    }
+
+    /**
+     * @return Returns the parentServiceManagerClassName.
+     */
+    public String getParentServiceManagerClassName() {
+        return this.parentServiceManagerClassName;
+    }
+
+    /**
+     * @return Returns the showTime.
+     */
+    public boolean isShowTime() {
+        return this.showTime;
+    }
+
+    /**
+     * @return Returns the showCocoonVersion flag.
+     */
+    public boolean isShowVersion() {
+        return this.showCocoonVersion;
+    }
+
+    /**
+     * @return Returns the uploadDirectory.
+     */
+    public String getUploadDirectory() {
+        return this.uploadDirectory;
+    }
+
+    /**
+     * @return Returns the workDirectory.
+     */
+    public String getWorkDirectory() {
+        return this.workDirectory;
+    }
+
+    /**
+     * @return Returns the accessLogger.
+     */
+    public String getEnvironmentLogger() {
+        return this.environmentLogger;
+    }
+
+    /**
+     * @return Returns the overrideLogLevel.
+     */
+    public String getOverrideLogLevel() {
+        return this.overrideLogLevel;
+    }
+
+    public boolean isAllowOverwrite() {
+        if ("deny".equalsIgnoreCase(this.overwriteUploads)) {
+            return false;
+        } else if ("allow".equalsIgnoreCase(this.overwriteUploads)) {
+            return true;
+        } else {
+            // either rename is specified or unsupported value - default to rename.
+            return false;
+        }
+    }
+
+    public boolean isSilentlyRename() {
+        if ("deny".equalsIgnoreCase(this.overwriteUploads)) {
+            return false;
+        } else if ("allow".equalsIgnoreCase(this.overwriteUploads)) {
+            return false; // ignored in this case
+        } else {
+            // either rename is specified or unsupported value - default to rename.
+            return true;
+        }
+    }
+
+    /**
+     * @return Returns the configurationReloadDelay.
+     */
+    public long getReloadDelay(String type) {
+        long value = this.configurationReloadDelay;
+        if ( type != null ) {
+            String o = this.getProperty(KEYPREFIX + KEY_RELOAD_DELAY + '.' + type);
+            if ( o != null ) {
+                value = NumberUtils.toLong(o);
+            }
+        }
+        return value;
+    }
+
+    /**
+     * @return Returns the lazyMode.
+     */
+    public boolean isLazyMode() {
+        return this.lazyMode;
+    }
+
+    public String getProperty(String name) {
+        return this.getProperty(name, null);
+    }
+
+    public String getProperty(String key, String defaultValue) {
+        if ( key == null ) {
+            return defaultValue;
+        }
+        String value = null;
+        if ( key.startsWith(KEYPREFIX) ) {
+            final String sKey = key.substring(KEYPREFIX.length());
+            if ( sKey.equals(KEY_CONFIGURATION) ) {
+                value = this.configuration;
+            } else if ( sKey.equals(KEY_RELOAD_DELAY) ) {
+                value = String.valueOf(this.configurationReloadDelay);
+            } else if ( sKey.equals(KEY_LOGGING_CONFIGURATION) ) {
+                value = this.loggingConfiguration;
+            } else if ( sKey.equals(KEY_LOGGING_ENVIRONMENT_LOGGER) ) {
+                value = this.environmentLogger;
+            } else if ( sKey.equals(KEY_LOGGING_COCOON_LOGGER) ) {
+                value = this.cocoonLogger;
+            } else if ( sKey.equals(KEY_LOGGING_BOOTSTRAP_LOGLEVEL) ) {
+                value = this.bootstrapLogLevel;
+            } else if ( sKey.equals(KEY_LOGGING_MANAGER_CLASS) ) {
+                value = this.loggerManagerClassName;
+            } else if ( sKey.equals(KEY_RELOADING) ) {
+                value = String.valueOf(this.reloadingEnabled);
+            } else if ( sKey.equals(KEY_UPLOADS_ENABLE) ) {
+                value = String.valueOf(this.enableUploads);
+            } else if ( sKey.equals(KEY_UPLOADS_DIRECTORY) ) {
+                value = this.uploadDirectory = value;
+            } else if ( sKey.equals(KEY_UPLOADS_AUTOSAVE) ) {
+                value = String.valueOf(this.autosaveUploads);
+            } else if ( sKey.equals(KEY_UPLOADS_OVERWRITE) ) {
+                value = this.overwriteUploads;
+            } else if ( sKey.equals(KEY_UPLOADS_MAXSIZE) ) {
+                value = String.valueOf(this.maxUploadSize);
+            } else if ( sKey.equals(KEY_CACHE_DIRECTORY) ) {
+                value = this.cacheDirectory;
+            } else if ( sKey.equals(KEY_WORK_DIRECTORY) ) {
+                value = this.workDirectory;
+            } else if ( sKey.equals(KEY_PARENT_SERVICE_MANAGER) ) {
+                value = this.parentServiceManagerClassName;
+            } else if ( sKey.equals(KEY_SHOWTIME) ) {
+                value = String.valueOf(this.showTime);
+            } else if ( sKey.equals(KEY_HIDE_SHOWTIME) ) {
+                value = String.valueOf(this.hideShowTime);
+            } else if ( sKey.equals(KEY_MANAGE_EXCEPTIONS) ) {
+                value = String.valueOf(this.manageExceptions);
+            } else if ( sKey.equals(KEY_FORM_ENCODING) ) {
+                value = this.formEncoding;
+            } else if ( sKey.equals(KEY_LOGGING_OVERRIDE_LOGLEVEL) ) {
+                value = this.overrideLogLevel;
+            } else if ( sKey.equals(KEY_LAZY_MODE) ) {
+                value = String.valueOf(this.lazyMode);
+            } else if ( key.equals(KEY_LOAD_CLASSES) ) {
+                value = this.toString(this.loadClasses);
+            } else if ( key.equals(KEY_EXTRA_CLASSPATHS) ) {
+                this.toString(this.extraClasspaths);
+            } else if ( key.equals(KEY_FORCE_PROPERTIES) ) {
+                this.toString(this.forceProperties);
+            } else if ( key.equals(KEY_PROPERTY_PROVIDER) ) {
+                this.toString(this.propertyProviders);
+            }
+        }
+
+        int i = 0;
+        while ( i < this.properties.size() && value == null ) {
+            final Properties p = (Properties)this.properties.get(i);
+            value = p.getProperty(key);
+            i++;
+        }
+        if ( value == null ) {
+            value = defaultValue;
+        }
+        return value;
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return "Settings:\n" +
+          "Running mode : " + this.getProperty(PROPERTY_RUNNING_MODE, DEFAULT_RUNNING_MODE) + '\n' +
+          KEY_CONFIGURATION + " : " + this.configuration + '\n' +
+          KEY_RELOAD_DELAY + " : " + this.configurationReloadDelay + '\n' +
+          KEY_RELOADING + " : " + this.reloadingEnabled + '\n' +
+          KEY_EXTRA_CLASSPATHS + " : " + this.toString(this.extraClasspaths) + '\n' +
+          KEY_LOAD_CLASSES + " : " + this.toString(this.loadClasses) + '\n' +
+          KEY_FORCE_PROPERTIES + " : " + this.toString(this.forceProperties) + '\n' +
+          KEY_LOGGING_CONFIGURATION + " : " + this.loggingConfiguration + '\n' +
+          KEY_LOGGING_ENVIRONMENT_LOGGER + " : " + this.environmentLogger + '\n' +
+          KEY_LOGGING_BOOTSTRAP_LOGLEVEL + " : " + this.bootstrapLogLevel + '\n' +
+          KEY_LOGGING_COCOON_LOGGER + " : " + this.cocoonLogger + '\n' +
+          KEY_LOGGING_MANAGER_CLASS + " : " + this.loggerManagerClassName + '\n' +
+          KEY_LOGGING_OVERRIDE_LOGLEVEL + " : " + this.overrideLogLevel + '\n' +
+          KEY_MANAGE_EXCEPTIONS + " : " + this.manageExceptions + '\n' +
+          KEY_PARENT_SERVICE_MANAGER + " : " + this.parentServiceManagerClassName + '\n' +
+          KEY_UPLOADS_DIRECTORY + " : " + this.uploadDirectory + '\n' +
+          KEY_UPLOADS_AUTOSAVE + " : " + this.autosaveUploads + '\n' +
+          KEY_UPLOADS_ENABLE + " : " + this.enableUploads + '\n' +
+          KEY_UPLOADS_MAXSIZE + " : " + this.maxUploadSize + '\n' +
+          KEY_UPLOADS_OVERWRITE + " : " + this.overwriteUploads + '\n' +
+          KEY_CACHE_DIRECTORY + " : " + this.cacheDirectory + '\n' +
+          KEY_WORK_DIRECTORY + " : " + this.workDirectory + '\n' +
+          KEY_FORM_ENCODING + " : " + this.formEncoding + '\n' +
+          KEY_SHOWTIME + " : " + this.showTime + '\n' +
+          KEY_HIDE_SHOWTIME + " : " + this.hideShowTime + '\n' +
+          KEY_SHOW_VERSION + " : " + this.showCocoonVersion + '\n' +
+          KEY_LAZY_MODE + " : " + this.lazyMode + '\n';
+    }
+
+    /**
+     * Helper method to make a string out of a list of objects.
+     */
+    protected String toString(List a) {
+        final StringBuffer buffer = new StringBuffer();
+        final Iterator i = a.iterator();
+        boolean first = true;
+        while ( i.hasNext() ) {
+            if ( first ) {
+                first = false;
+            } else {
+                buffer.append(", ");
+            }
+            buffer.append(i.next());
+        }
+        return buffer.toString();        
+    }
+
+    /**
+     * Helper method to make a string out of a map of objects.
+     */
+    protected String toString(Map a) {
+        final StringBuffer buffer = new StringBuffer("{");
+        final Iterator i = a.entrySet().iterator();
+        boolean first = true;
+        while ( i.hasNext() ) {
+            if ( first ) {
+                first = false;
+            } else {
+                buffer.append(", ");
+            }
+            final Map.Entry current = (Map.Entry)i.next();
+            buffer.append(current.getKey());
+            buffer.append("=");
+            buffer.append(current.getValue());
+        }
+        buffer.append("}");
+        return buffer.toString();        
+    }
+
+    /**
+     * @param hideShowTime The hideShowTime to set.
+     */
+    public void setHideShowTime(boolean hideShowTime) {
+        this.checkWriteable();
+        this.hideShowTime = hideShowTime;
+    }
+
+    /**
+     * @param allowReload The allowReload to set.
+     */
+    public void setReloadingEnabled(boolean allowReload) {
+        this.checkWriteable();
+        this.reloadingEnabled = allowReload;
+    }
+
+    /**
+     * @param autosaveUploads The autosaveUploads to set.
+     */
+    public void setAutosaveUploads(boolean autosaveUploads) {
+        this.checkWriteable();
+        this.autosaveUploads = autosaveUploads;
+    }
+
+    /**
+     * @param cacheDirectory The cacheDirectory to set.
+     */
+    public void setCacheDirectory(String cacheDirectory) {
+        this.checkWriteable();
+        this.cacheDirectory = cacheDirectory;
+    }
+
+    /**
+     * @param cocoonLogger The cocoonLogger to set.
+     */
+    public void setCocoonLogger(String cocoonLogger) {
+        this.checkWriteable();
+        this.cocoonLogger = cocoonLogger;
+    }
+
+    /**
+     * @param configuration The configuration to set.
+     */
+    public void setConfiguration(String configuration) {
+        this.checkWriteable();
+        this.configuration = configuration;
+    }
+
+    /**
+     * @param enableUploads The enableUploads to set.
+     */
+    public void setEnableUploads(boolean enableUploads) {
+        this.checkWriteable();
+        this.enableUploads = enableUploads;
+    }
+
+    /**
+     * @param extraClasspath The extraClasspaths to set.
+     */
+    public void addToExtraClasspaths(String extraClasspath) {
+        this.checkWriteable();
+        this.extraClasspaths.add(extraClasspath);
+    }
+
+    /**
+     * @param key The forceProperties to set.
+     * @param value The forceProperties value to set.
+     */
+    public void addToForceProperties(String key, String value) {
+        this.checkWriteable();
+        this.forceProperties.put(key, value);
+    }
+
+    /**
+     * @param formEncoding The formEncoding to set.
+     */
+    public void setFormEncoding(String formEncoding) {
+        this.checkWriteable();
+        this.formEncoding = formEncoding;
+    }
+
+    /**
+     * @param className The loadClasses to set.
+     */
+    public void addToLoadClasses(String className) {
+        this.checkWriteable();
+        this.loadClasses.add(className);
+    }
+
+    /**
+     * @param loggerClassName The loggerClassName to set.
+     */
+    public void setLoggerManagerClassName(String loggerClassName) {
+        this.checkWriteable();
+        this.loggerManagerClassName = loggerClassName;
+    }
+
+    /**
+     * @param loggingConfiguration The loggingConfiguration to set.
+     */
+    public void setLoggingConfiguration(String loggingConfiguration) {
+        this.checkWriteable();
+        this.loggingConfiguration = loggingConfiguration;
+    }
+
+    /**
+     * @param logLevel The logLevel to set.
+     */
+    public void setBootstrapLogLevel(String logLevel) {
+        this.checkWriteable();
+        this.bootstrapLogLevel = logLevel;
+    }
+
+    /**
+     * @param manageExceptions The manageExceptions to set.
+     */
+    public void setManageExceptions(boolean manageExceptions) {
+        this.checkWriteable();
+        this.manageExceptions = manageExceptions;
+    }
+
+    /**
+     * @param maxUploadSize The maxUploadSize to set.
+     */
+    public void setMaxUploadSize(int maxUploadSize) {
+        this.checkWriteable();
+        this.maxUploadSize = maxUploadSize;
+    }
+
+    /**
+     * @param overwriteUploads The overwriteUploads to set.
+     */
+    public void setOverwriteUploads(String overwriteUploads) {
+        this.checkWriteable();
+        this.overwriteUploads = overwriteUploads;
+    }
+    
+    /**
+     * @param parentServiceManagerClassName The parentServiceManagerClassName to set.
+     */
+    public void setParentServiceManagerClassName(
+            String parentServiceManagerClassName) {
+        this.checkWriteable();
+        this.parentServiceManagerClassName = parentServiceManagerClassName;
+    }
+
+    /**
+     * @param showTime The showTime to set.
+     */
+    public void setShowTime(boolean showTime) {
+        this.checkWriteable();
+        this.showTime = showTime;
+    }
+
+    /**
+     * @param showCocoonVersion The showCocoonVersion flag to set.
+     */
+    public void setShowCocoonVersion(boolean showCocoonVersion) {
+        this.checkWriteable();
+        this.showCocoonVersion = showCocoonVersion;
+    }
+
+    /**
+     * @param uploadDirectory The uploadDirectory to set.
+     */
+    public void setUploadDirectory(String uploadDirectory) {
+        this.checkWriteable();
+        this.uploadDirectory = uploadDirectory;
+    }
+
+    /**
+     * @param workDirectory The workDirectory to set.
+     */
+    public void setWorkDirectory(String workDirectory) {
+        this.checkWriteable();
+        this.workDirectory = workDirectory;
+    }
+
+    /**
+     * @param logger The logger for the environment.
+     */
+    public void setEnvironmentLogger(String logger) {
+        this.checkWriteable();
+        this.environmentLogger = logger;
+    }
+
+    /**
+     * @param overrideLogLevel The overrideLogLevel to set.
+     */
+    public void setOverrideLogLevel(String overrideLogLevel) {
+        this.checkWriteable();
+        this.overrideLogLevel = overrideLogLevel;
+    }
+
+    /**
+     * @param configurationReloadDelay The configurationReloadDelay to set.
+     */
+    public void setConfigurationReloadDelay(long configurationReloadDelay) {
+        this.checkWriteable();
+        this.configurationReloadDelay = configurationReloadDelay;
+    }
+
+    /**
+     * @param lazyMode The lazyMode to set.
+     */
+    public void setLazyMode(boolean lazyMode) {
+        this.checkWriteable();
+        this.lazyMode = lazyMode;
+    }
+
+    /**
+     * Mark this object as read-only.
+     */
+    public void makeReadOnly() {
+        this.readOnly = false;
+    }
+
+    /**
+     * check if this configuration is writeable.
+     *
+     * @throws IllegalStateException if this setting is read-only
+     */
+    protected final void checkWriteable()
+    throws IllegalStateException {
+        if( this.readOnly ) {
+            throw new IllegalStateException
+                ( "Settings is read only and can not be modified anymore." );
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.core.BaseSettings#getCreationTime()
+     */
+    public long getCreationTime() {
+        return this.creationTime;
+    }
+
+    /**
+     * Set the creation time of the current cocoon instance.
+     */
+    public void setCreationTime(long value) {
+        // Don't check read only here as this will change if Cocoon
+        // is reloaded while the settings remain the same.
+        this.creationTime = value;
+    }
+
+    /**
+     * @see org.apache.cocoon.core.BaseSettings#getPropertyProviders()
+     */
+    public List getPropertyProviders() {
+        return this.propertyProviders;
+    }
+
+    /**
+     * Add a property provider.
+     */
+    public void addToPropertyProviders(String className) {
+        this.checkWriteable();
+        this.propertyProviders.add(className);
+    }
+
+    /**
+     * @see org.apache.cocoon.core.Settings#getProperties(java.lang.String)
+     */
+    public List getProperties(String keyPrefix) {
+        final List props = new ArrayList();
+        for(int i=0; i<this.properties.size(); i++) {
+            final Properties p = (Properties)this.properties.get(i);
+            final Iterator kI = p.keySet().iterator();
+            while ( kI.hasNext() ) {
+                final String name = (String)kI.next();
+                if ( name.startsWith(keyPrefix) && !props.contains(name) ) {
+                    props.add(name);
+                }
+            }
+        }
+        return props;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/MutableSettings.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/PropertyProvider.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/PropertyProvider.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/PropertyProvider.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/PropertyProvider.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,31 @@
+/*
+ * Copyright 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.cocoon.core;
+
+import java.util.Properties;
+
+/**
+ * This is an interface for custom components delivering properties to
+ * configure Cocoon.
+ *
+ * @version $Id: PropertyProvider.java 312637 2005-10-10 13:00:42Z cziegeler $
+ * @since 2.2
+ */
+public interface PropertyProvider {
+
+    Properties getProperties();
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/PropertyProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/Settings.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/Settings.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/Settings.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/Settings.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,51 @@
+/*
+ * Copyright 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.cocoon.core;
+
+import java.util.List;
+
+/**
+ * This object holds the global configuration of Cocoon.
+ *
+ * @version $Id: Settings.java 312930 2005-10-11 18:13:35Z cziegeler $
+ * @since 2.2
+ */
+public interface Settings extends BaseSettings, DynamicSettings {
+
+    /**
+     * Get the value of a property.
+     * @param key The name of the property.
+     * @return The value of the property or null.
+     */
+    String getProperty(String key);
+
+    /**
+     * Get the value of a property.
+     * @param key The name of the property.
+     * @param defaultValue The value returned if the property is not available.
+     * @return The value of the property or if the property cannot
+     *         be found the default value.
+     */
+    String getProperty(String key, String defaultValue);
+
+    /**
+     * Return all available properties starting with the prefix.
+     * @param keyPrefix The prefix each property name must have.
+     * @return A list of property names (including the prefix) or
+     *         an empty list.
+     */
+    List getProperties(String keyPrefix);
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/core/Settings.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message