Author: cziegeler
Date: Fri Apr  8 12:17:34 2005
New Revision: 160589

URL: http://svn.apache.org/viewcvs?view=rev&rev=160589
Log:
Let CoreUtil manage the Cocoon lifecycle

Added:
    cocoon/trunk/src/java/org/apache/cocoon/core/BootstrapEnvironment.java   
(with props)
Removed:
    cocoon/trunk/src/java/org/apache/cocoon/util/log/LoggingHelper.java
Modified:
    cocoon/trunk/src/java/org/apache/cocoon/core/Core.java
    cocoon/trunk/src/java/org/apache/cocoon/core/CoreUtil.java
    cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java

Added: cocoon/trunk/src/java/org/apache/cocoon/core/BootstrapEnvironment.java
URL: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/core/BootstrapEnvironment.java?view=auto&rev=160589
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/core/BootstrapEnvironment.java 
(added)
+++ cocoon/trunk/src/java/org/apache/cocoon/core/BootstrapEnvironment.java Fri 
Apr  8 12:17:34 2005
@@ -0,0 +1,97 @@
+/*
+ * 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.InputStream;
+import java.net.URL;
+
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.configuration.Settings;
+import org.apache.log.LogTarget;
+
+/**
+* The BootstrapEnvironment is the connection between the real environment
+* (servlet, cli etc.) and the Cocoon core. The core uses this object to
+* access information from the real environment and to pass several objects
+* back.
+* A BootstrapEnvironment can be used to create a new Cocoon system using
+* the [EMAIL PROTECTED] CoreUtil}.
+*
+* @version SVN $Id:$
+* @since 2.2
+*/
+public interface BootstrapEnvironment {
+
+    /** Log a message during bootstrapping. This is used to log
+     * information before the logging system is setup.
+     * @param message A message.
+     */
+    void log(String message);
+
+    /** Log a message during bootstrapping. This is used to log
+     * information before the logging system is setup.
+     * @param message A message.
+     * @param error   An error.
+     */
+    void log(String message, Throwable error);
+
+    /**
+     * Pass the root logger back to the environment. As soon as the
+     * logging system is set up, this method is called.
+     * @param rootLogger The root logger.
+     */
+    void setLogger(Logger rootLogger);
+
+    InputStream getInputStream(String path);
+    
+    void configure(Settings settings);
+    void configureLoggingContext(DefaultContext context);
+
+    void configure(DefaultContext context);
+
+    ClassLoader getInitClassLoader();
+
+    org.apache.cocoon.environment.Context getEnvironmentContext();
+    
+    /**
+     * Returns the URL to the application context.
+     */
+    String getContextURL();
+
+    /**
+     * Returns a file to the application context.
+     * @return A file pointing to the context or null if the context is not
+     *         writeable.
+     */
+    File getContextForWriting();
+
+    LogTarget getDefaultLogTarget();
+
+    /**
+     * Set the ConfigFile for the Cocoon object.
+     *
+     * @param configFileName The file location for the cocoon.xconf
+     *
+     * @throws Exception
+     */
+    URL getConfigFile(String configFileName)
+    throws Exception;
+
+    String getClassPath(Settings settings);        
+}
\ No newline at end of file

Propchange: 
cocoon/trunk/src/java/org/apache/cocoon/core/BootstrapEnvironment.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cocoon/trunk/src/java/org/apache/cocoon/core/BootstrapEnvironment.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/trunk/src/java/org/apache/cocoon/core/Core.java
URL: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/core/Core.java?view=diff&r1=160588&r2=160589
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/core/Core.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/core/Core.java Fri Apr  8 12:17:34 
2005
@@ -17,8 +17,6 @@
 package org.apache.cocoon.core;
 
 import java.io.File;
-import java.io.InputStream;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -28,12 +26,9 @@
 import org.apache.avalon.framework.context.Context;
 import org.apache.avalon.framework.context.ContextException;
 import org.apache.avalon.framework.context.Contextualizable;
-import org.apache.avalon.framework.context.DefaultContext;
-import org.apache.avalon.framework.logger.Logger;
 import org.apache.cocoon.Constants;
 import org.apache.cocoon.components.ContextHelper;
 import org.apache.cocoon.configuration.Settings;
-import org.apache.log.LogTarget;
 
 /**
  * This is the core Cocoon component.
@@ -48,6 +43,7 @@
 public class Core
     implements Contextualizable {
 
+    /** The key to lookup the component. */
     public static String ROLE = Core.class.getName();
 
     /** Application <code>Context</code> Key for the settings. Please don't
@@ -180,47 +176,6 @@
         } catch (ContextException ce) {
             throw new CascadingRuntimeException("Unable to get the settings 
object from the context.", ce);
         }
-    }
-
-    public static interface BootstrapEnvironment {
-
-        void log(String message);
-        void log(String message, Throwable error);
-        
-        InputStream getInputStream(String path);
-        
-        void configure(Settings settings);
-        void configureLoggingContext(DefaultContext context);
-
-        void configure(DefaultContext context);
-
-        ClassLoader getInitClassLoader();
-
-        org.apache.cocoon.environment.Context getEnvironmentContext();
-        
-        /**
-         * Returns the URL to the application context.
-         */
-        String getContextURL();
-
-        /**
-         * Returns a file to the application context.
-         * @return A file pointing to the context or null if the context is not
-         *         writeable.
-         */
-        File getContextForWriting();
-
-        LogTarget getDefaultLogTarget();
-
-        /**
-         * Set the ConfigFile for the Cocoon object.
-         *
-         * @param configFileName The file location for the cocoon.xconf
-         *
-         * @throws Exception
-         */
-        public URL getConfigFile(final Logger logger, final String 
configFileName)
-        throws Exception;
     }
     
 }

Modified: cocoon/trunk/src/java/org/apache/cocoon/core/CoreUtil.java
URL: 
http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/core/CoreUtil.java?view=diff&r1=160588&r2=160589
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/core/CoreUtil.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/core/CoreUtil.java Fri Apr  8 
12:17:34 2005
@@ -32,6 +32,7 @@
 import org.apache.avalon.excalibur.logger.LogKitLoggerManager;
 import org.apache.avalon.excalibur.logger.LoggerManager;
 import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.activity.Disposable;
 import org.apache.avalon.framework.configuration.Configurable;
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
@@ -43,14 +44,15 @@
 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.configuration.ConfigurationBuilder;
 import org.apache.cocoon.configuration.Settings;
-import org.apache.cocoon.core.Core.BootstrapEnvironment;
 import org.apache.cocoon.core.source.SimpleSourceResolver;
 import org.apache.cocoon.matching.helpers.WildcardHelper;
 import org.apache.cocoon.util.ClassUtils;
+import org.apache.cocoon.util.StringUtils;
 import org.apache.cocoon.util.log.Log4JConfigurator;
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.TraversableSource;
@@ -61,6 +63,7 @@
 import org.apache.log4j.LogManager;
 
 /**
+ * This is an utility class to create a new Cocoon instance.
  *
  * @version SVN $Id$
  * @since 2.2
@@ -73,7 +76,7 @@
     protected final static String CORE_KEY = Core.class.getName();
 
     /** The callback to the real environment */
-    protected final Core.BootstrapEnvironment env;
+    protected final BootstrapEnvironment env;
 
     /** "legacy" support: create an avalon context */
     protected final DefaultContext appContext = new DefaultContext();
@@ -81,28 +84,29 @@
     /** The settings */
     protected final Settings settings;
 
-    /** The parent service manager TODO This will be made protected*/
-    public ServiceManager parentManager;
+    /** The parent service manager. */
+    protected ServiceManager parentManager;
 
-    /** TODO This will be made protected */
-    public Logger log;
-    /** TODO This will be made protected */
-    public LoggerManager loggerManager;
+    /** The root logger. */
+    protected Logger log;
 
-    /** TODO This will be made protected */
-    public Object cocoon;
+    /** The logger manager. */
+    protected LoggerManager loggerManager;
+
+    /** The Cocoon instance (the root processor). */
+    protected Cocoon cocoon;
     
     /**
      * The time the cocoon instance was created
      */
     protected long creationTime;
 
-    public CoreUtil(Core.BootstrapEnvironment environment) 
+    public CoreUtil(BootstrapEnvironment environment) 
     throws Exception {
         this.env = environment;
 
         // create settings
-        this.settings = createSettings(this.env);
+        this.settings = this.createSettings();
         this.appContext.put(Core.CONTEXT_SETTINGS, this.settings);
 
         if (this.settings.isInitClassloader()) {
@@ -157,7 +161,8 @@
         this.settings.setWorkDirectory(workDir.getAbsolutePath());
 
         // Init logger
-        initLogger();
+        this.initLogger();
+        this.env.setLogger(this.log);
 
         // Output some debug info
         if (this.log.isDebugEnabled()) {
@@ -233,7 +238,7 @@
         this.settings.setCacheDirectory(cacheDir.getAbsolutePath());
 
         // update settings
-        final URL u = this.env.getConfigFile(this.log, 
this.settings.getConfiguration());
+        final URL u = this.env.getConfigFile(this.settings.getConfiguration());
         this.settings.setConfiguration(u.toExternalForm());
         this.appContext.put(Constants.CONTEXT_CONFIG_URL, u);
 
@@ -305,9 +310,8 @@
     /**
      * Get the settings for Cocoon
      * @param env This provides access to various parts of the used 
environment.
-     * TODO Make a non-static, protected method out of this
      */
-    public static Settings createSettings(BootstrapEnvironment env) {
+    protected Settings createSettings() {
         // create an empty settings objects
         final Settings s = new Settings();
 
@@ -551,7 +555,8 @@
         return WildcardHelper.match(null, uri, parsedPattern);      
     }
 
-    public static final class RootServiceManager implements ServiceManager {
+    public static final class RootServiceManager 
+    implements ServiceManager, Disposable {
         
         protected final ServiceManager parent;
         protected final Core cocoon;
@@ -561,7 +566,7 @@
             this.cocoon = c;
         }
 
-        /* (non-Javadoc)
+        /**
          * @see 
org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
          */
         public boolean hasService(String key) {
@@ -574,7 +579,7 @@
             return false;
         }
 
-        /* (non-Javadoc)
+        /**
          * @see 
org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
          */
         public Object lookup(String key) throws ServiceException {
@@ -587,7 +592,7 @@
             throw new ServiceException("Cocoon", "Component for key '" + key + 
"' not found.");
         }
 
-        /* (non-Javadoc)
+        /**
          * @see 
org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
          */
         public void release(Object component) {
@@ -595,12 +600,19 @@
                 this.parent.release(component);
             }
         }
+
+        /**
+         * @see org.apache.avalon.framework.activity.Disposable#dispose()
+         */
+        public void dispose() {
+            ContainerUtil.dispose(this.parent);
+        }
     }
 
     /**
      * Creates the Cocoon object and handles exception handling.
      */
-    public synchronized void createCocoon() 
+    public synchronized Cocoon createCocoon() 
     throws Exception {
 
         /* HACK for reducing class loader problems.                            
         */
@@ -621,9 +633,9 @@
             if (this.log.isInfoEnabled()) {
                 this.log.info("Reloading from: " + 
this.settings.getConfiguration());
             }
-            Object c = ClassUtils.newInstance("org.apache.cocoon.Cocoon");
+            Cocoon c = 
(Cocoon)ClassUtils.newInstance("org.apache.cocoon.Cocoon");
             ContainerUtil.enableLogging(c, getCocoonLogger());
-            // TODO: c.setLoggerManager(this.loggerManager);
+            c.setLoggerManager(this.loggerManager);
             ContainerUtil.contextualize(c, this.appContext);
 
             // create the Core object
@@ -634,27 +646,26 @@
             ContainerUtil.initialize(c);
             this.creationTime = System.currentTimeMillis();
 
-            disposeCocoon();
             this.cocoon = c;
         } catch (Exception e) {
             this.log.error("Exception reloading", e);
             this.disposeCocoon();
             throw e;
         }
+        return this.cocoon;
     }
 
     /**
      * Gets the current cocoon object.  Reload cocoon if configuration
      * changed or we are reloading.
      */
-    public void getCocoon(final String pathInfo, final String reloadParam)
+    public Cocoon getCocoon(final String pathInfo, final String reloadParam)
     throws Exception {
         if (this.settings.isAllowReload()) {
             boolean reload = false;
 
             if (this.cocoon != null) {
-                // TODO: activate
-/*                if (this.cocoon.modifiedSince(this.creationTime)) {
+                if (this.cocoon.modifiedSince(this.creationTime)) {
                     if (this.log.isInfoEnabled()) {
                         this.log.info("Configuration changed reload attempt");
                     }
@@ -664,7 +675,7 @@
                         this.log.info("Forced reload attempt");
                     }
                     reload = true;
-                } */
+                }
             } else if (pathInfo == null && reloadParam != null) {
                 if (this.log.isInfoEnabled()) {
                     this.log.info("Invalid configurations reload");
@@ -677,6 +688,7 @@
                 this.createCocoon();
             }
         }
+        return this.cocoon;
     }
 
     /**
@@ -684,6 +696,9 @@
      */
     public final void disposeCocoon() {
         if (this.cocoon != null) {
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Disposing Cocoon");
+            }
             ContainerUtil.dispose(this.cocoon);
             this.cocoon = null;
         }
@@ -766,7 +781,10 @@
      * of this class (eg. Cocoon Context).
      */
     protected void updateEnvironment() throws Exception {
-        // can be overridden
+        StringBuffer buffer = new 
StringBuffer(this.env.getClassPath(this.settings));
+        buffer.append(File.pathSeparatorChar).append(this.getExtraClassPath());
+
+        this.appContext.put(Constants.CONTEXT_CLASSPATH, buffer.toString());
     }
 
     /**
@@ -780,13 +798,58 @@
                 // ignore this
             }
         }
+        this.disposeCocoon();
+    }
 
-        if (this.cocoon != null) {
-            if (this.log.isDebugEnabled()) {
-                this.log.debug("Servlet destroyed - disposing Cocoon");
+    /**
+     * 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);
+                    }
+                }
             }
-            this.disposeCocoon();
+            return sb.toString();
         }
+        return "";
     }
+
 
 }

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&r1=160588&r2=160589
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java 
(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/servlet/CocoonServlet.java Fri Apr  
8 12:17:34 2005
@@ -15,12 +15,33 @@
  */
 package org.apache.cocoon.servlet;
 
-import org.apache.avalon.excalibur.logger.LoggerManager;
-import org.apache.avalon.framework.container.ContainerUtil;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.SocketException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.avalon.framework.context.DefaultContext;
 import org.apache.avalon.framework.logger.Logger;
-import org.apache.avalon.framework.service.ServiceManager;
-
 import org.apache.cocoon.Cocoon;
 import org.apache.cocoon.ConnectionResetException;
 import org.apache.cocoon.Constants;
@@ -29,7 +50,7 @@
 import org.apache.cocoon.components.notification.Notifier;
 import org.apache.cocoon.components.notification.Notifying;
 import org.apache.cocoon.configuration.Settings;
-import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.BootstrapEnvironment;
 import org.apache.cocoon.core.CoreUtil;
 import org.apache.cocoon.environment.Context;
 import org.apache.cocoon.environment.Environment;
@@ -37,43 +58,13 @@
 import org.apache.cocoon.environment.http.HttpEnvironment;
 import org.apache.cocoon.servlet.multipart.MultipartHttpServletRequest;
 import org.apache.cocoon.servlet.multipart.RequestFactory;
-import org.apache.cocoon.util.ClassUtils;
 import org.apache.cocoon.util.IOUtils;
-import org.apache.cocoon.util.StringUtils;
 import org.apache.cocoon.util.log.CocoonLogFormatter;
-
-import org.apache.cocoon.util.log.LoggingHelper;
 import org.apache.commons.lang.SystemUtils;
 import org.apache.log.ContextMap;
 import org.apache.log.LogTarget;
 import org.apache.log.output.ServletOutputLogTarget;
 
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.SocketException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-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;
-import java.util.jar.Manifest;
-
 /**
  * This is the entry point for Cocoon execution as an HTTP Servlet.
  *
@@ -103,14 +94,6 @@
     static final float MINUTE = 60 * SECOND;
     static final float HOUR   = 60 * MINUTE;
 
-    private Logger log;
-    private LoggerManager loggerManager;
-
-    /**
-     * The time the cocoon instance was created
-     */
-    protected long creationTime;
-
     /**
      * The <code>Cocoon</code> instance
      */
@@ -124,7 +107,7 @@
     /**
      * Avalon application context
      */
-    protected DefaultContext appContext;
+    protected org.apache.avalon.framework.context.Context appContext;
 
     private String containerEncoding;
 
@@ -133,9 +116,6 @@
     /** The classloader that will be set as the context classloader if 
init-classloader is true */
     protected final ClassLoader classLoader = this.getClass().getClassLoader();
 
-    /** The parent ServiceManager, if any. Stored here in order to be able to 
dispose it in destroy(). */
-    private ServiceManager parentServiceManager;
-
     /**
      * This is the path to the servlet context (or the result
      * of calling getRealPath('/') on the ServletContext.
@@ -154,8 +134,11 @@
      */
     protected RequestFactory requestFactory;
 
-    /** Settings */
-    protected Settings settings;
+    /** CoreUtil */
+    protected CoreUtil coreUtil;
+
+    /** The logger */
+    protected Logger log;
 
     /**
      * Initialize this <code>CocoonServlet</code> instance.  You will
@@ -224,15 +207,12 @@
         }
 
         // initialize settings
-        Core.BootstrapEnvironment env = new ServletBootstrapEnvironment(conf, 
this.classLoader, this.servletContextPath, this.servletContextURL);
+        ServletBootstrapEnvironment env = new 
ServletBootstrapEnvironment(conf, this.classLoader, this.servletContextPath, 
this.servletContextURL);
 
         try {
-            CoreUtil util = new CoreUtil(env);
-            this.settings = util.getCore().getSettings();
-            this.appContext = (DefaultContext)util.getCore().getContext();
-            this.log = util.log;
-            this.loggerManager = util.loggerManager;
-            this.parentServiceManager = util.parentManager;
+            this.coreUtil = new CoreUtil(env);
+            this.appContext = coreUtil.getCore().getContext();
+            this.log = env.logger;
         } catch (Exception e) {
             if ( e instanceof ServletException ) {
                 throw (ServletException)e;
@@ -241,7 +221,7 @@
         }
 
         if (getLogger().isDebugEnabled()) {
-            getLogger().debug(this.settings.toString());
+            
getLogger().debug(this.coreUtil.getCore().getSettings().toString());
             getLogger().debug("getRealPath for /: " + this.servletContextPath);
             if (this.servletContextPath == null) {
                 getLogger().debug("getResource for /WEB-INF: " + debugPathOne);
@@ -250,14 +230,19 @@
         }
 
         this.containerEncoding = getInitParameter("container-encoding", 
"ISO-8859-1");
-        this.requestFactory = new RequestFactory(settings.isAutosaveUploads(),
-                                                 new 
File(settings.getUploadDirectory()),
-                                                 settings.isAllowOverwrite(),
-                                                 settings.isSilentlyRename(),
-                                                 settings.getMaxUploadSize(),
+        this.requestFactory = new 
RequestFactory(coreUtil.getCore().getSettings().isAutosaveUploads(),
+                                                 new 
File(coreUtil.getCore().getSettings().getUploadDirectory()),
+                                                 
coreUtil.getCore().getSettings().isAllowOverwrite(),
+                                                 
coreUtil.getCore().getSettings().isSilentlyRename(),
+                                                 
coreUtil.getCore().getSettings().getMaxUploadSize(),
                                                  this.containerEncoding);
 
-        createCocoon();
+        try {
+            this.exception = null;
+            this.cocoon = this.coreUtil.createCocoon();
+        } catch (Exception e) {
+            this.exception = e;
+        }
         if (this.exception == null) {
             this.servletContext.log("Apache Cocoon " + Constants.VERSION + " 
is up and ready.");
         } else {
@@ -269,318 +254,12 @@
      * Dispose Cocoon when servlet is destroyed
      */
     public void destroy() {
-        if (this.settings.isInitClassloader()) {
-            try {
-                Thread.currentThread().setContextClassLoader(this.classLoader);
-            } catch (Exception e) {
-                // ignore this
-            }
-        }
-
-        if (this.cocoon != null) {
-            if (getLogger().isDebugEnabled()) {
-                getLogger().debug("Servlet destroyed - disposing Cocoon");
-            }
-            disposeCocoon();
-        }
-
-        ContainerUtil.dispose(this.parentServiceManager);
-    }
-
-    /**
-     * This builds the important ClassPath used by this Servlet.  It
-     * does so in a Servlet Engine neutral way.  It uses the
-     * <code>ServletContext</code>'s <code>getRealPath</code> method
-     * to get the Servlet 2.2 identified classes and lib directories.
-     * It iterates in alphabetical order through every file in the
-     * lib directory and adds it to the classpath.
-     *
-     * Also, we add the files to the ClassLoader for the Cocoon system.
-     * In order to protect ourselves from skitzofrantic classloaders,
-     * we need to work with a known one.
-     *
-     * We need to get this to work properly when Cocoon is in a war.
-     *
-     * @throws ServletException
-     */
-    protected String getClassPath() throws ServletException {
-        StringBuffer buildClassPath = new StringBuffer();
-
-        File root = null;
-        if (this.servletContextPath != null) {
-            // Old method.  There *MUST* be a better method than this...
-
-            String classDir = 
this.servletContext.getRealPath("/WEB-INF/classes");
-            String libDir = this.servletContext.getRealPath("/WEB-INF/lib");
-
-            if (libDir != null) {
-                root = new File(libDir);
-            }
-
-            if (classDir != null) {
-                buildClassPath.append(classDir);
-            }
-        } else {
-            // New(ish) method for war'd deployments
-            URL classDirURL = null;
-            URL libDirURL = null;
-
-            try {
-                classDirURL = 
this.servletContext.getResource("/WEB-INF/classes");
-            } catch (MalformedURLException me) {
-                getLogger().warn("Unable to add WEB-INF/classes to the 
classpath", me);
-            }
-
-            try {
-                libDirURL = this.servletContext.getResource("/WEB-INF/lib");
-            } catch (MalformedURLException me) {
-                getLogger().warn("Unable to add WEB-INF/lib to the classpath", 
me);
-            }
-
-            if (libDirURL != null && 
libDirURL.toExternalForm().startsWith("file:")) {
-                root = new 
File(libDirURL.toExternalForm().substring("file:".length()));
-            }
-
-            if (classDirURL != null) {
-                buildClassPath.append(classDirURL.toExternalForm());
-            }
-        }
-
-        // Unable to find lib directory. Going the hard way.
-        if (root == null) {
-            root = extractLibraries();
-        }
-
-        if (root != null && root.isDirectory()) {
-            File[] libraries = root.listFiles();
-            Arrays.sort(libraries);
-            for (int i = 0; i < libraries.length; i++) {
-                String fullName = IOUtils.getFullFilename(libraries[i]);
-                buildClassPath.append(File.pathSeparatorChar).append(fullName);
-            }
-        }
-
-        buildClassPath.append(File.pathSeparatorChar)
-                      .append(SystemUtils.JAVA_CLASS_PATH);
-
-        buildClassPath.append(File.pathSeparatorChar)
-                      .append(getExtraClassPath());
-        return buildClassPath.toString();
-    }
-
-    private File extractLibraries() {
-        try {
-            URL manifestURL = 
this.servletContext.getResource("/META-INF/MANIFEST.MF");
-            if (manifestURL == null) {
-                this.getLogger().fatalError("Unable to get Manifest");
-                return null;
-            }
-
-            Manifest mf = new Manifest(manifestURL.openStream());
-            Attributes attr = mf.getMainAttributes();
-            String libValue = attr.getValue("Cocoon-Libs");
-            if (libValue == null) {
-                this.getLogger().fatalError("Unable to get 'Cocoon-Libs' 
attribute from the Manifest");
-                return null;
-            }
-
-            List libList = new ArrayList();
-            for (StringTokenizer st = new StringTokenizer(libValue, " "); 
st.hasMoreTokens();) {
-                libList.add(st.nextToken());
-            }
-
-            File root = new File(this.settings.getWorkDirectory(), "lib");
-            root.mkdirs();
-
-            File[] oldLibs = root.listFiles();
-            for (int i = 0; i < oldLibs.length; i++) {
-                String oldLib = oldLibs[i].getName();
-                if (!libList.contains(oldLib)) {
-                    this.getLogger().debug("Removing old library " + 
oldLibs[i]);
-                    oldLibs[i].delete();
-                }
-            }
-
-            this.getLogger().warn("Extracting libraries into " + root);
-            byte[] buffer = new byte[65536];
-            for (Iterator i = libList.iterator(); i.hasNext();) {
-                String libName = (String) i.next();
-
-                long lastModified = -1;
-                try {
-                    lastModified = Long.parseLong(attr.getValue("Cocoon-Lib-" 
+ libName.replace('.', '_')));
-                } catch (Exception e) {
-                    this.getLogger().debug("Failed to parse lastModified: " + 
attr.getValue("Cocoon-Lib-" + libName.replace('.', '_')));
-                }
-
-                File lib = new File(root, libName);
-                if (lib.exists() && lib.lastModified() != lastModified) {
-                    this.getLogger().debug("Removing modified library " + lib);
-                    lib.delete();
-                }
-
-                InputStream is = 
this.servletContext.getResourceAsStream("/WEB-INF/lib/" + libName);
-                if (is == null) {
-                    this.getLogger().warn("Skipping " + libName);
-                } else {
-                    this.getLogger().debug("Extracting " + libName);
-                    OutputStream os = null;
-                    try {
-                        os = new FileOutputStream(lib);
-                        int count;
-                        while ((count = is.read(buffer)) > 0) {
-                            os.write(buffer, 0, count);
-                        }
-                    } finally {
-                        if (is != null) is.close();
-                        if (os != null) os.close();
-                    }
-                }
-
-                if (lastModified != -1) {
-                    lib.setLastModified(lastModified);
-                }
-            }
-
-            return root;
-        } catch (IOException e) {
-            this.getLogger().fatalError("Exception while processing Manifest 
file", e);
-            return null;
-        }
-    }
-
-
-    /**
-     * Retreives the "extra-classpath" attribute, that needs to be
-     * added to the class path.
-     *
-     * @throws ServletException
-     */
-    protected String getExtraClassPath() throws ServletException {
-        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 (getLogger().isDebugEnabled()) {
-                        getLogger().debug("extraClassPath is absolute: " + s);
-                    }
-                    sb.append(s);
-
-                } else {
-                    if (s.indexOf("${") != -1) {
-                        String path = StringUtils.replaceToken(s);
-                        sb.append(path);
-                        if (getLogger().isDebugEnabled()) {
-                            getLogger().debug("extraClassPath is not absolute 
replacing using token: [" + s + "] : " + path);
-                        }
-                    } else {
-                        String path = null;
-                        if (this.servletContextPath != null) {
-                            path = this.servletContextPath + s;
-                            if (getLogger().isDebugEnabled()) {
-                                getLogger().debug("extraClassPath is not 
absolute pre-pending context path: " + path);
-                            }
-                        } else {
-                            path = this.settings.getWorkDirectory() + s;
-                            if (getLogger().isDebugEnabled()) {
-                                getLogger().debug("extraClassPath is not 
absolute pre-pending work-directory: " + path);
-                            }
-                        }
-                        sb.append(path);
-                    }
-                }
-            }
-            return sb.toString();
-        }
-        return "";
-    }
-
-    protected void initLogger() {
-        final CocoonLogFormatter formatter = new CocoonLogFormatter();
-        formatter.setFormat("%7.7{priority} %{time}   [%8.8{category}] " +
-                            "(%{uri}) %{thread}/%{class:short}: 
%{message}\\n%{throwable}");
-        final ServletOutputLogTarget servTarget = new 
ServletOutputLogTarget(this.servletContext, formatter);
-
-        final DefaultContext subcontext = new DefaultContext(this.appContext);
-        subcontext.put("servlet-context", this.servletContext);
-        subcontext.put("context-work", new 
File(this.settings.getWorkDirectory()));
-        if (this.servletContextPath == null) {
-            File logSCDir = new File(this.settings.getWorkDirectory(), "log");
-            logSCDir.mkdirs();
-            subcontext.put("context-root", logSCDir.toString());
-        } else {
-            subcontext.put("context-root", this.servletContextPath);
-        }
-
-        LoggingHelper lh = new LoggingHelper(this.settings, servTarget, 
subcontext);
-        this.loggerManager = lh.getLoggerManager();
-        this.log = lh.getLogger();
-    }
-
-    /**
-     * 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>
-     */
-    private void forceLoad() {
-        final Iterator i = this.settings.getLoadClasses();
-        while (i.hasNext()) {
-            final String fqcn = (String)i.next();
-            try {
-                if (getLogger().isDebugEnabled()) {
-                    getLogger().debug("Loading: " + fqcn);
-                }
-                ClassUtils.loadClass(fqcn).newInstance();
-            } catch (Exception e) {
-                if (getLogger().isWarnEnabled()) {
-                    getLogger().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.
-     */
-    private void forceProperty() {
-        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 {
-                    if (getLogger().isDebugEnabled()) {
-                        getLogger().debug("Setting: " + current.getKey() + "=" 
+ current.getValue());
-                    }
-                    systemProps.setProperty(current.getKey().toString(), 
current.getValue().toString());
-                } catch (Exception e) {
-                    if (getLogger().isWarnEnabled()) {
-                        getLogger().warn("Could not set property: " + 
current.getKey(), e);
-                    }
-                    // Do not throw an exception, because it is not a fatal 
error.
-                }
-            }
-            System.setProperties(systemProps);
+        this.servletContext.log("Destroying Cocoon Servlet.");
+        if ( this.coreUtil != null ) {
+            this.coreUtil.destroy();
+            this.coreUtil = null;
         }
+        super.destroy();
     }
 
     /**
@@ -592,7 +271,7 @@
 
         /* HACK for reducing class loader problems.                            
         */
         /* example: xalan extensions fail if someone adds xalan jars in 
tomcat3.2.1/lib */
-        if (this.settings.isInitClassloader()) {
+        if (this.coreUtil.getCore().getSettings().isInitClassloader()) {
             try {
                 Thread.currentThread().setContextClassLoader(this.classLoader);
             } catch (Exception e) {
@@ -609,7 +288,7 @@
         // get the request (wrapped if contains multipart-form data)
         HttpServletRequest request;
         try{
-            if (this.settings.isEnableUploads()) {
+            if (this.coreUtil.getCore().getSettings().isEnableUploads()) {
                 request = requestFactory.getServletRequest(req);
             } else {
                 request = req;
@@ -626,7 +305,12 @@
         }
 
         // Get the cocoon engine instance
-        getCocoon(request.getPathInfo(), 
request.getParameter(Constants.RELOAD_PARAM));
+        try {
+            this.exception = null;
+            this.cocoon = this.coreUtil.getCocoon(request.getPathInfo(), 
request.getParameter(Constants.RELOAD_PARAM));
+        } catch (Exception e) {
+            this.exception = e;
+        }
 
         // Check if cocoon was initialized
         if (this.cocoon == null) {
@@ -766,7 +450,7 @@
 
             if (contentType != null && contentType.equals("text/html")) {
                 String showTime = 
request.getParameter(Constants.SHOWTIME_PARAM);
-                boolean show = this.settings.isShowTime();
+                boolean show = 
this.coreUtil.getCore().getSettings().isShowTime();
                 if (showTime != null) {
                     show = !showTime.equalsIgnoreCase("no");
                 }
@@ -774,7 +458,7 @@
                     if ( timeString == null ) {
                         timeString = processTime(end - start);
                     }
-                    boolean hide = this.settings.isHideShowTime();
+                    boolean hide = 
this.coreUtil.getCore().getSettings().isHideShowTime();
                     if (showTime != null) {
                         hide = showTime.equalsIgnoreCase("hide");
                     }
@@ -826,7 +510,7 @@
                                    String title, String message, String 
description,
                                    Exception e)
     throws IOException {
-        if (this.settings.isManageExceptions()) {
+        if (this.coreUtil.getCore().getSettings().isManageExceptions()) {
             if (env != null) {
                 env.tryResetResponse();
             } else {
@@ -884,7 +568,7 @@
 
         String formEncoding = req.getParameter("cocoon-form-encoding");
         if (formEncoding == null) {
-            formEncoding = this.settings.getFormEncoding();
+            formEncoding = 
this.coreUtil.getCore().getSettings().getFormEncoding();
         }
         env = new HttpEnvironment(uri,
                                   this.servletContextURL,
@@ -898,102 +582,6 @@
         return env;
     }
 
-    /**
-     * 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 synchronized ServiceManager getParentServiceManager() {
-        // FIXME - move this to CoreUtil!
-/*        ContainerUtil.dispose(this.parentServiceManager);
-
-        this.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, getLogger());
-                ContainerUtil.contextualize(parentServiceManager, 
this.appContext);
-                ContainerUtil.initialize(parentServiceManager);
-            } catch (Exception e) {
-                if (getLogger().isErrorEnabled()) {
-                    getLogger().error("Could not initialize parent component 
manager.", e);
-                }
-            }
-        }*/
-        return parentServiceManager;
-    }
-
-    /**
-     * Creates the Cocoon object and handles exception handling.
-     */
-    private synchronized void createCocoon()
-    throws ServletException {
-
-        /* HACK for reducing class loader problems.                            
         */
-        /* example: xalan extensions fail if someone adds xalan jars in 
tomcat3.2.1/lib */
-        if (this.settings.isInitClassloader()) {
-            try {
-                Thread.currentThread().setContextClassLoader(this.classLoader);
-            } catch (Exception e) {
-                // ignore
-            }
-        }
-
-        updateEnvironment();
-        forceLoad();
-        forceProperty();
-
-        try {
-            this.exception = null;
-            if (getLogger().isInfoEnabled()) {
-                getLogger().info("Reloading from: " + 
this.settings.getConfiguration());
-            }
-            Cocoon c = (Cocoon) 
ClassUtils.newInstance("org.apache.cocoon.Cocoon");
-            ContainerUtil.enableLogging(c, getCocoonLogger());
-            c.setLoggerManager(getLoggerManager());
-            ContainerUtil.contextualize(c, this.appContext);
-            final ServiceManager parent = this.getParentServiceManager();
-            if (parent != null) {
-                ContainerUtil.service(c, parent);
-            }
-            ContainerUtil.initialize(c);
-            this.creationTime = System.currentTimeMillis();
-
-            disposeCocoon();
-            this.cocoon = c;
-        } catch (Exception e) {
-            getLogger().error("Exception reloading", e);
-            this.exception = e;
-            disposeCocoon();
-        }
-    }
-
-    private Logger getCocoonLogger() {
-        final String rootlogger = this.settings.getCocoonLogger();
-        if (rootlogger != null) {
-            return this.getLoggerManager().getLoggerForCategory(rootlogger);
-        }
-        return getLogger();
-    }
-
-    /**
-     * 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 ServletException {
-        this.appContext.put(Constants.CONTEXT_CLASS_LOADER, classLoader);
-        this.appContext.put(Constants.CONTEXT_CLASSPATH, getClassPath());
-    }
-
     private String processTime(long time) {
         StringBuffer out = new StringBuffer(PROCESSED_BY);
         if (time <= SECOND) {
@@ -1013,51 +601,6 @@
     }
 
     /**
-     * Gets the current cocoon object.  Reload cocoon if configuration
-     * changed or we are reloading.
-     */
-    private void getCocoon(final String pathInfo, final String reloadParam)
-    throws ServletException {
-        if (this.settings.isAllowReload()) {
-            boolean reload = false;
-
-            if (this.cocoon != null) {
-                if (this.cocoon.modifiedSince(this.creationTime)) {
-                    if (getLogger().isInfoEnabled()) {
-                        getLogger().info("Configuration changed reload 
attempt");
-                    }
-                    reload = true;
-                } else if (pathInfo == null && reloadParam != null) {
-                    if (getLogger().isInfoEnabled()) {
-                        getLogger().info("Forced reload attempt");
-                    }
-                    reload = true;
-                }
-            } else if (pathInfo == null && reloadParam != null) {
-                if (getLogger().isInfoEnabled()) {
-                    getLogger().info("Invalid configurations reload");
-                }
-                reload = true;
-            }
-
-            if (reload) {
-                initLogger();
-                createCocoon();
-            }
-        }
-    }
-
-    /**
-     * Destroy Cocoon
-     */
-    private final void disposeCocoon() {
-        if (this.cocoon != null) {
-            ContainerUtil.dispose(this.cocoon);
-            this.cocoon = null;
-        }
-    }
-
-    /**
      * Get an initialisation parameter. The value is trimmed, and null is 
returned if the trimmed value
      * is empty.
      */
@@ -1089,17 +632,14 @@
         return this.log;
     }
 
-    protected LoggerManager getLoggerManager() {
-        return this.loggerManager;
-    }
-
     protected static final class ServletBootstrapEnvironment
-    implements Core.BootstrapEnvironment {
+    implements BootstrapEnvironment {
 
         private final ServletConfig config;
         private final ClassLoader   classLoader;
         private final File          writeableContextPath;
         private final String        contextPath;
+        public Logger logger;
 
         public ServletBootstrapEnvironment(ServletConfig config, 
                                            ClassLoader   cl, 
@@ -1116,28 +656,35 @@
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#log(java.lang.String)
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#log(java.lang.String)
          */
         public void log(String message) {
             this.config.getServletContext().log(message);
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#log(java.lang.String, 
java.lang.Throwable)
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#log(java.lang.String, 
java.lang.Throwable)
          */
         public void log(String message, Throwable error) {
             this.config.getServletContext().log(message, error);
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#getInputStream(java.lang.String)
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#setLogger(org.apache.avalon.framework.logger.Logger)
+         */
+        public void setLogger(Logger rootLogger) {
+            this.logger = rootLogger;
+        }
+
+        /**
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#getInputStream(java.lang.String)
          */
         public InputStream getInputStream(String path) {
             return this.config.getServletContext().getResourceAsStream(path);
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#configure(org.apache.cocoon.configuration.Settings)
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#configure(org.apache.cocoon.configuration.Settings)
          */
         public void configure(Settings settings) {
             // fill from the servlet parameters
@@ -1149,21 +696,21 @@
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#getInitClassLoader()
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#getInitClassLoader()
          */
         public ClassLoader getInitClassLoader() {
             return this.classLoader;
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#getEnvironmentContext()
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#getEnvironmentContext()
          */
         public Context getEnvironmentContext() {
             return new HttpContext(this.config.getServletContext());
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#getContextURL()
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getContextURL()
          */
         public String getContextURL() {
             return this.contextPath;
@@ -1171,13 +718,14 @@
 
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#getContextForWriting()
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#getContextForWriting()
          */
         public File getContextForWriting() {
             return this.writeableContextPath;
         }
+
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#getDefaultLogTarget()
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#getDefaultLogTarget()
          */
         public LogTarget getDefaultLogTarget() {
             final CocoonLogFormatter formatter = new CocoonLogFormatter();
@@ -1188,41 +736,37 @@
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#configureLoggingContext(org.apache.avalon.framework.context.DefaultContext)
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#configureLoggingContext(org.apache.avalon.framework.context.DefaultContext)
          */
         public void configureLoggingContext(DefaultContext context) {
             context.put("servlet-context", this.config.getServletContext());
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#configure(org.apache.avalon.framework.context.DefaultContext)
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#configure(org.apache.avalon.framework.context.DefaultContext)
          */
         public void configure(DefaultContext context) {
             context.put(CONTEXT_SERVLET_CONFIG, this.config);
-            // TODO - move the following into CoreUtil
-            context.put(Constants.CONTEXT_CLASS_LOADER, classLoader);
-            // TODO:
-            //context.put(Constants.CONTEXT_CLASSPATH, getClassPath());
         }
 
         /**
-         * @see 
org.apache.cocoon.core.Core.BootstrapEnvironment#getConfigFile(org.apache.avalon.framework.logger.Logger,
 java.lang.String)
+         * @see 
org.apache.cocoon.core.BootstrapEnvironment#getConfigFile(java.lang.String)
          */
-        public URL getConfigFile(final Logger logger, final String 
configFileName)
+        public URL getConfigFile(final String configFileName)
         throws Exception {
             final String usedFileName;
 
             if (configFileName == null) {
-                if (logger.isWarnEnabled()) {
-                    logger.warn("Servlet initialization argument 
'configurations' not specified, attempting to use '/WEB-INF/cocoon.xconf'");
+                if (this.logger.isWarnEnabled()) {
+                    this.logger.warn("Servlet initialization argument 
'configurations' not specified, attempting to use '/WEB-INF/cocoon.xconf'");
                 }
                 usedFileName = "/WEB-INF/cocoon.xconf";
             } else {
                 usedFileName = configFileName;
             }
 
-            if (logger.isDebugEnabled()) {
-                logger.debug("Using configuration file: " + usedFileName);
+            if (this.logger.isDebugEnabled()) {
+                this.logger.debug("Using configuration file: " + usedFileName);
             }
 
             URL result;
@@ -1235,7 +779,7 @@
                 }
             } catch (Exception mue) {
                 String msg = "Init parameter 'configurations' is invalid : " + 
usedFileName;
-                logger.error(msg, mue);
+                this.logger.error(msg, mue);
                 throw new ServletException(msg, mue);
             }
 
@@ -1246,7 +790,7 @@
                         result = resultFile.getCanonicalFile().toURL();
                     } catch (Exception e) {
                         String msg = "Init parameter 'configurations' is 
invalid : " + usedFileName;
-                        logger.error(msg, e);
+                        this.logger.error(msg, e);
                         throw new ServletException(msg, e);
                     }
                 }
@@ -1254,10 +798,170 @@
 
             if (result == null) {
                 String msg = "Init parameter 'configuration' doesn't name an 
existing resource : " + usedFileName;
-                logger.error(msg);
+                this.logger.error(msg);
                 throw new ServletException(msg);
             }
             return result;
+        }
+
+        /**
+         * This builds the important ClassPath used by this Servlet.  It
+         * does so in a Servlet Engine neutral way.  It uses the
+         * <code>ServletContext</code>'s <code>getRealPath</code> method
+         * to get the Servlet 2.2 identified classes and lib directories.
+         * It iterates in alphabetical order through every file in the
+         * lib directory and adds it to the classpath.
+         *
+         * Also, we add the files to the ClassLoader for the Cocoon system.
+         * In order to protect ourselves from skitzofrantic classloaders,
+         * we need to work with a known one.
+         *
+         * We need to get this to work properly when Cocoon is in a war.
+         *
+         * @throws ServletException
+         */
+        public String getClassPath(Settings settings) {
+            StringBuffer buildClassPath = new StringBuffer();
+
+            File root = null;
+            if (this.getContextForWriting() != null) {
+                // Old method.  There *MUST* be a better method than this...
+
+                String classDir = 
this.config.getServletContext().getRealPath("/WEB-INF/classes");
+                String libDir = 
this.config.getServletContext().getRealPath("/WEB-INF/lib");
+
+                if (libDir != null) {
+                    root = new File(libDir);
+                }
+
+                if (classDir != null) {
+                    buildClassPath.append(classDir);
+                }
+            } else {
+                // New(ish) method for war'd deployments
+                URL classDirURL = null;
+                URL libDirURL = null;
+
+                try {
+                    classDirURL = 
this.config.getServletContext().getResource("/WEB-INF/classes");
+                } catch (MalformedURLException me) {
+                    this.logger.warn("Unable to add WEB-INF/classes to the 
classpath", me);
+                }
+
+                try {
+                    libDirURL = 
this.config.getServletContext().getResource("/WEB-INF/lib");
+                } catch (MalformedURLException me) {
+                    this.logger.warn("Unable to add WEB-INF/lib to the 
classpath", me);
+                }
+
+                if (libDirURL != null && 
libDirURL.toExternalForm().startsWith("file:")) {
+                    root = new 
File(libDirURL.toExternalForm().substring("file:".length()));
+                }
+
+                if (classDirURL != null) {
+                    buildClassPath.append(classDirURL.toExternalForm());
+                }
+            }
+
+            // Unable to find lib directory. Going the hard way.
+            if (root == null) {
+                root = this.extractLibraries(settings);
+            }
+
+            if (root != null && root.isDirectory()) {
+                File[] libraries = root.listFiles();
+                Arrays.sort(libraries);
+                for (int i = 0; i < libraries.length; i++) {
+                    String fullName = IOUtils.getFullFilename(libraries[i]);
+                    
buildClassPath.append(File.pathSeparatorChar).append(fullName);
+                }
+            }
+
+            buildClassPath.append(File.pathSeparatorChar)
+                          .append(SystemUtils.JAVA_CLASS_PATH);
+
+            return buildClassPath.toString();
+        }
+
+        private File extractLibraries(Settings settings) {
+            try {
+                URL manifestURL = 
this.config.getServletContext().getResource("/META-INF/MANIFEST.MF");
+                if (manifestURL == null) {
+                    this.logger.fatalError("Unable to get Manifest");
+                    return null;
+                }
+
+                Manifest mf = new Manifest(manifestURL.openStream());
+                Attributes attr = mf.getMainAttributes();
+                String libValue = attr.getValue("Cocoon-Libs");
+                if (libValue == null) {
+                    this.logger.fatalError("Unable to get 'Cocoon-Libs' 
attribute from the Manifest");
+                    return null;
+                }
+
+                List libList = new ArrayList();
+                for (StringTokenizer st = new StringTokenizer(libValue, " "); 
st.hasMoreTokens();) {
+                    libList.add(st.nextToken());
+                }
+
+                File root = new File(settings.getWorkDirectory(), "lib");
+                root.mkdirs();
+
+                File[] oldLibs = root.listFiles();
+                for (int i = 0; i < oldLibs.length; i++) {
+                    String oldLib = oldLibs[i].getName();
+                    if (!libList.contains(oldLib)) {
+                        this.logger.debug("Removing old library " + 
oldLibs[i]);
+                        oldLibs[i].delete();
+                    }
+                }
+
+                this.logger.warn("Extracting libraries into " + root);
+                byte[] buffer = new byte[65536];
+                for (Iterator i = libList.iterator(); i.hasNext();) {
+                    String libName = (String) i.next();
+
+                    long lastModified = -1;
+                    try {
+                        lastModified = 
Long.parseLong(attr.getValue("Cocoon-Lib-" + libName.replace('.', '_')));
+                    } catch (Exception e) {
+                        this.logger.debug("Failed to parse lastModified: " + 
attr.getValue("Cocoon-Lib-" + libName.replace('.', '_')));
+                    }
+
+                    File lib = new File(root, libName);
+                    if (lib.exists() && lib.lastModified() != lastModified) {
+                        this.logger.debug("Removing modified library " + lib);
+                        lib.delete();
+                    }
+
+                    InputStream is = 
this.config.getServletContext().getResourceAsStream("/WEB-INF/lib/" + libName);
+                    if (is == null) {
+                        this.logger.warn("Skipping " + libName);
+                    } else {
+                        this.logger.debug("Extracting " + libName);
+                        OutputStream os = null;
+                        try {
+                            os = new FileOutputStream(lib);
+                            int count;
+                            while ((count = is.read(buffer)) > 0) {
+                                os.write(buffer, 0, count);
+                            }
+                        } finally {
+                            if (is != null) is.close();
+                            if (os != null) os.close();
+                        }
+                    }
+
+                    if (lastModified != -1) {
+                        lib.setLastModified(lastModified);
+                    }
+                }
+
+                return root;
+            } catch (IOException e) {
+                this.logger.fatalError("Exception while processing Manifest 
file", e);
+                return null;
+            }
         }
 
     }


Reply via email to