You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by da...@apache.org on 2005/12/21 02:03:36 UTC

svn commit: r358167 - in /cocoon/trunk: legal/ src/java/org/apache/cocoon/blocks/ src/test/org/apache/cocoon/test/ src/test/org/apache/cocoon/test/blocks/ src/test/org/apache/cocoon/test/blocks/WEB-INF/ tools/lib/

Author: danielf
Date: Tue Dec 20 16:59:17 2005
New Revision: 358167

URL: http://svn.apache.org/viewcvs?rev=358167&view=rev
Log:
Refactored the BlocksManager to be a servlet and to be used at entry point, instead of being a processor and called through the CocoonServlet.
Some functionality from the CocoonServlet, muli part posts and error messages are not yet implemented as they probably should be part of the BlockManager instead.
Functional tests is performed with HttpUnit.
This is ongoing work. In the next step will be making the BlockManager a servlet as well.

Added:
    cocoon/trunk/legal/httpunit-1.6.jar.licence.txt   (with props)
    cocoon/trunk/src/java/org/apache/cocoon/blocks/CoreUtil.java   (with props)
    cocoon/trunk/src/java/org/apache/cocoon/blocks/LoggerUtil.java   (with props)
    cocoon/trunk/src/test/org/apache/cocoon/test/ServletTestCase.java   (with props)
    cocoon/trunk/src/test/org/apache/cocoon/test/blocks/WEB-INF/
    cocoon/trunk/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml   (with props)
    cocoon/trunk/tools/lib/httpunit-1.6.jar   (with props)
Modified:
    cocoon/trunk/src/java/org/apache/cocoon/blocks/BlocksManager.java
    cocoon/trunk/src/test/org/apache/cocoon/test/blocks/BlocksManagerTestCase.java

Added: cocoon/trunk/legal/httpunit-1.6.jar.licence.txt
URL: http://svn.apache.org/viewcvs/cocoon/trunk/legal/httpunit-1.6.jar.licence.txt?rev=358167&view=auto
==============================================================================
--- cocoon/trunk/legal/httpunit-1.6.jar.licence.txt (added)
+++ cocoon/trunk/legal/httpunit-1.6.jar.licence.txt Tue Dec 20 16:59:17 2005
@@ -0,0 +1,7 @@
+Copyright © 2000-2004, Russell Gold
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Propchange: cocoon/trunk/legal/httpunit-1.6.jar.licence.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: cocoon/trunk/src/java/org/apache/cocoon/blocks/BlocksManager.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/blocks/BlocksManager.java?rev=358167&r1=358166&r2=358167&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/blocks/BlocksManager.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/blocks/BlocksManager.java Tue Dec 20 16:59:17 2005
@@ -16,35 +16,34 @@
 package org.apache.cocoon.blocks;
 
 import java.io.IOException;
-import java.net.URL;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.TreeMap;
 
-import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.activity.Initializable;
-import org.apache.avalon.framework.configuration.Configurable;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
 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.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.logger.Logger;
 import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.service.Serviceable;
-import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.Constants;
 import org.apache.cocoon.Modifiable;
+import org.apache.cocoon.ProcessingException;
 import org.apache.cocoon.Processor;
 import org.apache.cocoon.components.LifecycleHelper;
 import org.apache.cocoon.components.source.SourceUtil;
 import org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper;
-import org.apache.cocoon.configuration.ConfigurationBuilder;
 import org.apache.cocoon.core.Core;
 import org.apache.cocoon.core.Settings;
-import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.http.HttpEnvironment;
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.impl.URLSource;
 import org.xml.sax.InputSource;
@@ -53,104 +52,186 @@
  * @version $Id$
  */
 public class BlocksManager
-    extends AbstractLogEnabled
+	extends
+		HttpServlet
     implements
-	Blocks,
-	Configurable,
-        Contextualizable,
-        Disposable,
-        Initializable,
-        Serviceable,
-        ThreadSafe,
-        Processor,
-        Modifiable { 
+    	Blocks,
+        Modifiable
+	{ 
 
     public static String ROLE = BlocksManager.class.getName();
+    private ServletConfig servletConfig;
+    private ServletContext servletContext;
     private ServiceManager serviceManager;
     private Context context;
+    private org.apache.cocoon.environment.Context environmentContext;
+    private Settings settings;
+    private String contextURL;
+    private String containerEncoding;
 
-    private String wiringFileName = null;
+    private String wiringFileName = "/" + Constants.WIRING;
     private Source wiringFile;
     private HashMap blocks = new HashMap();
     private TreeMap mountedBlocks = new TreeMap(new InverseLexicographicalOrder());
     
-    private Core core;
     private Processor processor;
+    private Logger logger;    
 
-    public void service(ServiceManager manager) throws ServiceException {
-        this.serviceManager = manager;
-        this.core = (Core)this.serviceManager.lookup(Core.ROLE);
-    }
-
-    public void contextualize(Context context) throws ContextException {
-        this.context = context;
-    }
-
-    public void configure(Configuration config)
-    throws ConfigurationException {
-        this.wiringFileName = config.getAttribute("file");
-    }
-
-    public void initialize() throws Exception {
-        getLogger().debug("Initializing the Blocks Manager");
-        
-        // Read the wiring file
-        final Settings settings = this.core.getSettings();
-        if (this.wiringFileName == null) {
-            this.wiringFileName = settings.getConfiguration();
-        }
-        try {
-            URLSource urlSource = new URLSource();
-            urlSource.init(new URL(settings.getConfiguration()), null);
-            this.wiringFile = new DelayedRefreshSourceWrapper(urlSource, settings.getReloadDelay("config"));
-        } catch (IOException e) {
-            throw new ConfigurationException("Could not open configuration file: " + settings.getConfiguration(), e);
-        }
-
-        InputSource is = SourceUtil.getInputSource(this.wiringFile);
-
-        ConfigurationBuilder builder = new ConfigurationBuilder(settings);
-        Configuration wiring = builder.build(is);
-
-        Configuration[] blockConfs = wiring.getChildren("block");
-
-        // Create and store all blocks
-        for (int i = 0; i < blockConfs.length; i++) {
-            Configuration blockConf = blockConfs[i];
-            getLogger().debug("Creating " + blockConf.getName() +
-                              " id=" + blockConf.getAttribute("id") +
-                              " location=" + blockConf.getAttribute("location"));
-            BlockManager blockManager = new BlockManager();
-            blockManager.setBlocks(this);
-            LifecycleHelper.setupComponent(blockManager,
-                                           this.getLogger(),
-                                           this.context,
-                                           this.serviceManager,
-                                           blockConf);
-            this.blocks.put(blockConf.getAttribute("id"), blockManager);
-            String mountPath = blockConf.getChild("mount").getAttribute("path", null);
-            if (mountPath != null) {
-                this.mountedBlocks.put(mountPath, blockManager);
-                getLogger().debug("Mounted block " + blockConf.getAttribute("id") +
-                                  " at " + mountPath);
-            }
+    public void init(ServletConfig servletConfig) throws ServletException {
+    	super.init(servletConfig);
+        this.containerEncoding = servletConfig.getInitParameter("container-encoding");
+        if (this.containerEncoding == null) {
+        	this.containerEncoding = "ISO-8859-1";
         }
-        this.createProcessor();
+    	this.servletConfig = servletConfig;
+    	this.servletContext = servletConfig.getServletContext();
+    	CoreUtil coreUtil = new CoreUtil(servletConfig, Constants.WIRING);
+		Core core = coreUtil.getCore();
+		this.settings = coreUtil.getSettings();
+		this.environmentContext = core.getEnvironmentContext();
+		this.context = core.getContext();
+		this.contextURL = coreUtil.getContextURL();
+		this.serviceManager = coreUtil.getServiceManager();
+		LoggerUtil loggerUtil = new LoggerUtil(servletConfig, this.context, this.settings);
+		this.logger = loggerUtil.getCocoonLogger();
+		this.getLogger().debug("Initializing the Blocks Manager");
+		
+		InputSource is = null;
+		try {
+			this.getLogger().debug("Wiring file: " + this.servletContext.getResource(this.wiringFileName));
+			URLSource urlSource = new URLSource();
+			urlSource.init(this.servletContext.getResource(this.wiringFileName), null);
+			this.wiringFile = new DelayedRefreshSourceWrapper(urlSource, 1000);
+			is = SourceUtil.getInputSource(this.wiringFile);
+		} catch (IOException e) {
+			throw new ServletException("Could not open configuration file: " + this.wiringFileName, e);
+		} catch (ProcessingException e) {
+			throw new ServletException("Could not open configuration file: " + this.wiringFileName, e);			
+		}
+				
+		DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+		Configuration wiring = null;
+		try {
+			wiring = builder.build(is);
+		} catch (Exception e) {
+			throw new ServletException("Could not create configuration from file: " + this.wiringFileName, e);			
+		}
+		
+		Configuration[] blockConfs = wiring.getChildren("block");
+		
+		try {
+		// Create and store all blocks
+		for (int i = 0; i < blockConfs.length; i++) {
+			Configuration blockConf = blockConfs[i];
+			this.getLogger().debug("Creating " + blockConf.getName() +
+					" id=" + blockConf.getAttribute("id") +
+					" location=" + blockConf.getAttribute("location"));
+			BlockManager blockManager = new BlockManager();
+			blockManager.setBlocks(this);
+			LifecycleHelper.setupComponent(blockManager,
+					this.getLogger(),
+					this.context,
+					this.serviceManager,
+					blockConf);
+			this.blocks.put(blockConf.getAttribute("id"), blockManager);
+			String mountPath = blockConf.getChild("mount").getAttribute("path", null);
+			if (mountPath != null) {
+				this.mountedBlocks.put(mountPath, blockManager);
+				this.getLogger().debug("Mounted block " + blockConf.getAttribute("id") +
+						" at " + mountPath);
+			}
+		}
+		} catch (Exception e) {
+			throw new ServletException(e);
+		}
+		this.createProcessor();
     }
-
-    public void dispose() {
+    
+    public void destroy() {
         Iterator blocksIter = this.blocks.entrySet().iterator();
         while (blocksIter.hasNext()) {
             LifecycleHelper.dispose(blocksIter.next());
         }
         if (this.serviceManager != null) {
-            this.serviceManager.release(this.core);
-            this.core = null;
             this.serviceManager = null;            
         }
         this.blocks = null;
         this.mountedBlocks = null;
     }
+    
+    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        HttpEnvironment env;
+
+        // We got it... Process the request
+        String uri = request.getServletPath();
+        if (uri == null) {
+            uri = "";
+        }
+        String pathInfo = request.getPathInfo();
+        if (pathInfo != null) {
+            // VG: WebLogic fix: Both uri and pathInfo starts with '/'
+            // This problem exists only in WL6.1sp2, not in WL6.0sp2 or WL7.0b.
+            if (uri.length() > 0 && uri.charAt(0) == '/') {
+                uri = uri.substring(1);
+            }
+            uri += pathInfo;
+        }
+
+        if (uri.length() == 0) {
+            /* empty relative URI
+                 -> HTTP-redirect from /cocoon to /cocoon/ to avoid
+                    StringIndexOutOfBoundsException when calling
+                    "".charAt(0)
+               else process URI normally
+            */
+            String prefix = request.getRequestURI();
+            if (prefix == null) {
+                prefix = "";
+            }
+
+            response.sendRedirect(response.encodeRedirectURL(prefix + "/"));
+            return;
+        }
+
+        if (uri.charAt(0) == '/') {
+        	uri = uri.substring(1);
+        }
+
+        String formEncoding = request.getParameter("cocoon-form-encoding");
+        if (formEncoding == null) {
+            formEncoding = this.settings.getFormEncoding();
+        }
+        env = new HttpEnvironment(uri,
+                                  this.contextURL,
+                                  request,
+                                  response,
+                                  this.servletContext,
+                                  this.environmentContext,
+                                  this.containerEncoding,
+                                  formEncoding);
+        env.enableLogging(getLogger());
+		
+        try {
+	        this.processor.process(env);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new ServletException(e);
+		}
+		env.commitResponse();
+	}
+
+	public ServletConfig getServletConfig() {
+		return this.servletConfig;
+	}
+
+	public String getServletInfo() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	private Logger getLogger() {
+    	return this.logger;
+    }
 
     private void createProcessor() {
         this.processor = new BlockDispatcherProcessor(this);
@@ -199,42 +280,5 @@
         public int compare(Object o1, Object o2) {
             return ((String)o2).compareTo((String)o1);
         }
-    }
-
-    // Processor methods
-    public boolean process(Environment environment) throws Exception {
-        return this.processor.process(environment);
-    }
-
-    public InternalPipelineDescription buildPipeline(Environment environment) throws Exception {
-        return this.processor.buildPipeline(environment);
-    }
-
-    public Configuration[] getComponentConfigurations() {
-        return this.processor.getComponentConfigurations();
-    }
-
-    public Processor getRootProcessor() {
-        return this.processor.getRootProcessor();
-    }
-
-    public org.apache.cocoon.environment.SourceResolver getSourceResolver() {
-        return this.processor.getSourceResolver();
-    }
-
-    public String getContext() {
-        return this.processor.getContext();
-    }
-
-    public void setAttribute(String name, Object value) {
-        this.processor.setAttribute(name, value);
-    }
-
-    public Object getAttribute(String name) {
-        return this.processor.getAttribute(name);
-    }
-
-    public Object removeAttribute(String name) {
-        return this.processor.removeAttribute(name);
     }
 }

Added: cocoon/trunk/src/java/org/apache/cocoon/blocks/CoreUtil.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/blocks/CoreUtil.java?rev=358167&view=auto
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/blocks/CoreUtil.java (added)
+++ cocoon/trunk/src/java/org/apache/cocoon/blocks/CoreUtil.java Tue Dec 20 16:59:17 2005
@@ -0,0 +1,626 @@
+/*
+ * 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.blocks;
+
+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.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+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.Constants;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.container.ComponentContext;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.CoreFatalException;
+import org.apache.cocoon.core.CoreInitializationException;
+import org.apache.cocoon.core.MutableSettings;
+import org.apache.cocoon.core.PropertyProvider;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.core.container.SingleComponentServiceManager;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.http.HttpContext;
+import org.apache.cocoon.servlet.SettingsHelper;
+import org.apache.cocoon.util.ClassUtils;
+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$
+ * @since 2.2
+ */
+public class CoreUtil {
+
+    /** Parameter map for the context protocol */
+    private static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+    /**
+     * Application <code>Context</code> Key for the servlet configuration
+     * @since 2.1.3
+     */
+    public static final String CONTEXT_SERVLET_CONFIG = "servlet-config";
+
+    private ServletConfig config;
+	private ServletContext servletContext;
+
+    /** "legacy" support: create an avalon context. */
+    private final DefaultContext appContext = new ComponentContext();
+    
+    private Context environmentContext;
+
+    /** The settings. */
+    private MutableSettings settings;
+
+    /** The parent service manager. */
+    private ServiceManager parentManager;
+
+    /** The root logger. */
+    private Logger log;
+
+    private ClassLoader classloader;
+
+	private File contextForWriting = null;
+	private String contextURL;
+	// path to a file that is supposed to be present in the servlet context
+	// and that is used for calculating the context URI
+	private String knownFile;
+
+	public CoreUtil(ServletConfig config) throws ServletException {
+		this(config, "WEB-INF/web.xml");
+	}
+	/**
+     * Setup a new instance.
+     * @param config
+     * @throws Exception
+     */
+    public CoreUtil(ServletConfig config, String knownFile) throws ServletException {
+		this.config = config;
+		this.knownFile = knownFile;
+		this.servletContext = this.config.getServletContext();
+		this.servletContext.log("Initializing Apache Cocoon " + Constants.VERSION);
+		
+		String writeableContextPath = this.servletContext.getRealPath("/");
+		String path = writeableContextPath;
+		if (path == null) {
+		    // Try to figure out the path of the root from that of a known file
+			this.servletContext.log("Figuring out root from " + this.knownFile);
+		    try {
+		        path = this.servletContext.getResource("/" + this.knownFile).toString();
+				this.servletContext.log("Got " + path);
+		    } catch (MalformedURLException me) {
+		        throw new ServletException("Unable to get resource '" + this.knownFile + "'.", me);
+		    }
+		    path = path.substring(0, path.length() - this.knownFile.length());
+			this.servletContext.log("And servlet root " + path);
+		}
+		try {
+		    if (path.indexOf(':') > 1) {
+		        this.contextURL = path;
+		    } else {
+		        this.contextURL = new File(path).toURL().toExternalForm();
+		    }
+		} catch (MalformedURLException me) {
+		    // VG: Novell has absolute file names starting with the
+		    // volume name which is easily more then one letter.
+		    // Examples: sys:/apache/cocoon or sys:\apache\cocoon
+		    try {
+		        this.contextURL= new File(path).toURL().toExternalForm();
+		    } catch (MalformedURLException ignored) {
+		        throw new ServletException("Unable to determine servlet context URL.", me);
+		    }
+		}
+		if (writeableContextPath != null) {
+			this.contextForWriting = new File(writeableContextPath);
+		}
+    	this.environmentContext = new HttpContext(config.getServletContext());
+    	this.init();
+    }
+    
+    private void init() throws ServletException {
+        // 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.contextURL));
+        } catch (MalformedURLException ignore) {
+            // we simply ignore this
+        }
+
+        // add environment context
+        this.appContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT,
+                            this.environmentContext);
+
+        // now add environment specific information
+        this.appContext.put(CONTEXT_SERVLET_CONFIG, this.config);
+
+        // 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.contextForWriting == 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.contextForWriting, workDirParam);
+                }
+            }
+        } else {
+            workDir = new File("cocoon-files");
+        }
+        workDir.mkdirs();
+        this.appContext.put(Constants.CONTEXT_WORK_DIR, workDir);
+        this.settings.setWorkDirectory(workDir.getAbsolutePath());
+
+        // Output some debug info
+        this.servletContext.log("Context URL: " + this.contextURL);
+        this.servletContext.log("Writeable Context: " + this.contextForWriting);
+        if (workDirParam != null) {
+        	this.servletContext.log("Using work-directory " + workDir);
+        } else {
+        	this.servletContext.log("Using default work-directory " + workDir);
+        }
+
+        final String uploadDirParam = this.settings.getUploadDirectory();
+        File uploadDir;
+        if (uploadDirParam != null) {
+            if (this.contextForWriting == 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.contextForWriting, uploadDirParam);
+                }
+            }
+            this.servletContext.log("Using upload-directory " + uploadDir);
+        } else {
+            uploadDir = new File(workDir, "upload-dir" + File.separator);
+            this.servletContext.log("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.contextForWriting == 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.contextForWriting, cacheDirParam);
+                }
+            }
+            this.servletContext.log("Using cache-directory " + cacheDir);
+        } else {
+            cacheDir = new File(workDir, "cache-dir" + File.separator);
+            File parent = cacheDir.getParentFile();
+            if (parent != null) {
+                parent.mkdirs();
+            }
+            this.servletContext.log("cache-directory was not set - defaulting to " + cacheDir);
+        }
+        cacheDir.mkdirs();
+        appContext.put(Constants.CONTEXT_CACHE_DIR, cacheDir);
+        this.settings.setCacheDirectory(cacheDir.getAbsolutePath());
+		String configFileName = this.settings.getConfiguration();
+		final String usedFileName;
+		
+		if (configFileName == null) {
+			this.servletContext.log("Servlet initialization argument 'configurations' not specified, attempting to use '/WEB-INF/cocoon.xconf'");
+			usedFileName = "/WEB-INF/cocoon.xconf";
+		} else {
+			usedFileName = configFileName;
+		}
+		
+		this.servletContext.log("Using configuration file: " + usedFileName);
+		
+		URL result;
+		try {
+			// test if this is a qualified url
+			if (usedFileName.indexOf(':') == -1) {
+				result = this.config.getServletContext().getResource(usedFileName);
+			} else {
+				result = new URL(usedFileName);
+			}
+		} catch (Exception mue) {
+			String msg = "Init parameter 'configurations' is invalid : " + usedFileName;
+			this.servletContext.log(msg, mue);
+			throw new ServletException(msg, mue);
+		}
+		
+		if (result == null) {
+			File resultFile = new File(usedFileName);
+			if (resultFile.isFile()) {
+				try {
+					result = resultFile.getCanonicalFile().toURL();
+				} catch (Exception e) {
+					String msg = "Init parameter 'configurations' is invalid : " + usedFileName;
+					this.servletContext.log(msg, e);
+					throw new ServletException(msg, e);
+				}
+			}
+		}
+		
+		if (result == null) {
+			String msg = "Init parameter 'configurations' doesn't name an existing resource : " + usedFileName;
+			this.servletContext.log(msg);
+			throw new ServletException(msg);
+		}
+
+        // update configuration
+        final URL u = result;
+        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);
+
+        // FIXME - for now we just set an empty string as this information is looked up
+        //         by other components
+        this.appContext.put(Constants.CONTEXT_CLASSPATH, "");
+    }
+
+    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.
+     */
+    private Core createCore() {
+        final Core c = new Core(this.settings, this.appContext);
+        return c;
+    }
+
+    /**
+     * Return the settings object.
+     */
+    public Settings getSettings() {
+        return this.settings;
+    }
+
+    public ServiceManager getServiceManager() {
+    	return this.parentManager;
+    }
+    
+    /**
+     * The root context path for the servlet
+     * @return context URL
+     */
+    public String getContextURL() {
+    	return this.contextURL;
+    }
+    /**
+     * 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>.
+     */
+    private 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
+     */
+    private MutableSettings createSettings() {
+        // get the running mode
+        final String mode = System.getProperty(Settings.PROPERTY_RUNNING_MODE, Settings.DEFAULT_RUNNING_MODE);
+        this.config.getServletContext().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.config.getServletContext()));
+
+        // 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) {
+                this.config.getServletContext().log("Unable to get property provider for class " + className, ignore);
+                this.config.getServletContext().log("Continuing initialization.");            
+            }
+        }
+        // fill from the environment configuration, like web.xml etc.
+        // fill from the servlet parameters
+		SettingsHelper.fill(s, this.config);
+		if ( s.getWorkDirectory() == null ) {
+			final File workDir = (File)this.config.getServletContext().getAttribute("javax.servlet.context.tempdir");
+			s.setWorkDirectory(workDir.getAbsolutePath());
+		}
+		if ( s.getLoggingConfiguration() == null ) {
+			s.setLoggingConfiguration("/WEB-INF/logkit.xconf");
+		}
+
+        // 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 ) {
+            this.config.getServletContext().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) {
+                this.config.getServletContext().log("Unable to read '" + additionalPropertyFile + "'.", ignore);
+                this.config.getServletContext().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.
+     */
+    private 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();
+                        this.config.getServletContext().log("Reading settings from '" + src.getURI() + "'.");
+                        final Properties p = new Properties();
+                        p.load(propsIS);
+                        propsIS.close();
+                        s.fill(p);
+                    }
+                }
+            }
+        } catch (IOException ignore) {
+            this.config.getServletContext().log("Unable to read from directory 'WEB-INF/properties'.", ignore);
+            this.config.getServletContext().log("Continuing initialization.");            
+        } finally {
+            resolver.release(directory);
+        }
+    }
+
+    /**
+     * Create a simple source resolver.
+     */
+    private 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;        
+    }
+
+    private static final class LoggerWrapper implements Logger {
+        private final ServletContext context;
+
+        public LoggerWrapper(ServletContext context) {
+            this.context = context;
+        }
+
+        private void text(String arg0, Throwable arg1) {
+            if ( arg1 != null ) {
+                this.context.log(arg0, arg1);
+            } else {
+                this.context.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/trunk/src/java/org/apache/cocoon/blocks/CoreUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/src/java/org/apache/cocoon/blocks/CoreUtil.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/src/java/org/apache/cocoon/blocks/LoggerUtil.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/blocks/LoggerUtil.java?rev=358167&view=auto
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/blocks/LoggerUtil.java (added)
+++ cocoon/trunk/src/java/org/apache/cocoon/blocks/LoggerUtil.java Tue Dec 20 16:59:17 2005
@@ -0,0 +1,295 @@
+/*
+ * 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.blocks;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import javax.servlet.ServletConfig;
+import org.apache.avalon.excalibur.logger.Log4JConfLoggerManager;
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.excalibur.logger.ServletLogger;
+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.container.ContainerUtil;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Context;
+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.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.CoreInitializationException;
+import org.apache.cocoon.core.Settings;
+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.matching.helpers.WildcardHelper;
+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$
+ * @since 2.2
+ */
+public class LoggerUtil {
+
+    /** Parameter map for the context protocol */
+    private static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+    private ServletConfig config;
+	/** "legacy" support: create an avalon context. */
+    private Context appContext;
+    
+    /** The settings. */
+    private Settings settings;
+
+    /** The root logger. */
+    private Logger log;
+
+    /** The logger manager. */
+    private LoggerManager loggerManager;
+
+    private File contextForWriting;
+	/**
+     * Setup a new instance.
+     * @param config
+     * @throws Exception
+     */
+    public LoggerUtil(ServletConfig config, Context appContext, Settings settings) {
+    	this.config = config;
+    	this.appContext = appContext;
+    	this.settings = settings;
+    	// Init logger
+		this.initLogger();
+    }
+    
+    /**
+     * Create a simple source resolver.
+     */
+    private 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;        
+    }
+
+    private 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 = new ServletLogger(this.config, level.getLevel());
+
+        // 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.contextForWriting == null) {
+            File logSCDir = new File(this.settings.getWorkDirectory(), "log");
+            logSCDir.mkdirs();
+            subcontext.put("context-root", logSCDir.toString());
+        } else {
+            subcontext.put("context-root", this.contextForWriting.toString());
+        }
+        subcontext.put("servlet-context", this.config.getServletContext());
+
+        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) ) {
+            }
+            return (LoggerManager) clazz.newInstance();
+        } catch (Exception e) {
+            return new CocoonLogKitLoggerManager();
+        }
+    }
+
+    public 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);
+    }
+
+    public Logger getCocoonLogger() {
+        final String rootlogger = this.settings.getCocoonLogger();
+        if (rootlogger != null) {
+            return this.loggerManager.getLoggerForCategory(rootlogger);
+        }
+        return this.log;
+    }
+    
+    public LoggerManager getCocoonLoggerManager() {
+    	return this.loggerManager;
+    }
+}

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

Propchange: cocoon/trunk/src/java/org/apache/cocoon/blocks/LoggerUtil.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/src/test/org/apache/cocoon/test/ServletTestCase.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/test/org/apache/cocoon/test/ServletTestCase.java?rev=358167&view=auto
==============================================================================
--- cocoon/trunk/src/test/org/apache/cocoon/test/ServletTestCase.java (added)
+++ cocoon/trunk/src/test/org/apache/cocoon/test/ServletTestCase.java Tue Dec 20 16:59:17 2005
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1999-2004 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.test;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Vector;
+
+
+import junit.framework.TestCase;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.Cocoon;
+
+import com.meterware.httpunit.GetMethodWebRequest;
+import com.meterware.httpunit.WebRequest;
+import com.meterware.httpunit.WebResponse;
+import com.meterware.servletunit.InvocationContext;
+import com.meterware.servletunit.ServletRunner;
+import com.meterware.servletunit.ServletUnitClient;
+
+public class ServletTestCase extends TestCase {
+
+	private ServletRunner servletRunner;
+    protected ServletUnitClient client;
+
+    private Logger logger;
+    private URL classDirURL;
+    
+    protected String processorClassName = Cocoon.class.getName();
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        String level = System.getProperty("junit.test.loglevel", "" + ConsoleLogger.LEVEL_DEBUG);
+        this.logger = new ConsoleLogger(Integer.parseInt(level));
+
+        this.classDirURL = this.getClassDirURL();
+        URL webInf = new URL(classDirURL, "WEB-INF/web.xml");
+        File webInfFile = new File(webInf.getPath());
+        this.servletRunner = new ServletRunner(webInfFile, "");
+        this.client = this.servletRunner.newClient();
+    }
+
+    protected void tearDown() throws Exception {
+    	this.servletRunner.shutDown();
+        super.tearDown();
+    }
+
+    /** Return the logger */
+    protected Logger getLogger() {
+        return this.logger;
+    }
+    
+    /**
+     * Utility method for geting the URL to the directory that this class is in
+     */
+    protected URL getClassDirURL() throws RuntimeException {
+        String className = getClass().getName().replace( '.', '/' ) + ".class";
+        String classURL = null;
+        String classDir = null;
+        try {
+            classURL =
+                getClass().getClassLoader().getResource(className).toExternalForm();
+            getLogger().debug("classURL=" + classURL);
+            classDir = classURL.substring(0, classURL.lastIndexOf('/') + 1);
+            getLogger().debug("classDir=" + classDir);
+            return new URL(classDir);
+        } catch (SecurityException e) {
+            throw new RuntimeException("Not allowed to access classloader for " + className, e);
+        } catch (MalformedURLException e) {
+            throw new RuntimeException("Malformed URL for className=" + className +
+                                       " classURL=" + classURL + " classDir=" + classDir, e);
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't create URL for " + className, e);
+        }
+    }
+
+    /**
+     * Load a binary document.
+     *
+     * @param source Source location.
+     *
+     * @return Binary data.
+     */
+    public final byte[] loadByteArray(InputStream input) {
+
+        byte[] assertiondocument = null;
+
+        try {
+            Vector document = new Vector();
+            int i = 0;
+            int c;
+
+            while ((c = input.read())!=-1) {
+                document.add(new Byte((byte) c)); 
+                i++;
+            }
+            assertiondocument = new byte[document.size()];
+            for (i = 0; i < document.size(); i++) {
+                assertiondocument[i] = ((Byte)document.get(i)).byteValue();
+            }
+
+        } catch (Exception e) {
+            getLogger().error("Could not execute test", e);
+            fail("Could not execute test: "+e);
+        }
+
+        return assertiondocument;
+    }
+
+    /**
+     * Assert that the result of a byte comparison is identical.
+     *
+     * @param expected The expected byte array
+     * @param actual The actual byte array
+     */
+    public final void assertIdentical(byte[] expected, byte[] actual) {
+        assertEquals("Byte arrays of differing sizes, ", expected.length,
+                     actual.length);
+
+        if (expected.length>0) {
+            for (int i = 0; i<expected.length; i++) {
+                assertEquals("Byte array differs at index "+i, expected[i],
+                             actual[i]);
+            }
+        }
+
+    }
+
+    protected InputStream process(String uri) throws Exception {
+    	String dummySite = "http://www.test.org";
+    	WebRequest request = new GetMethodWebRequest(dummySite + uri);
+    	/*
+    	InvocationContext ic = this.client.newInvocation(request);
+    	ic.getServlet();
+    	ic.service();
+    	WebResponse response = ic.getServletResponse();
+    	*/
+    	WebResponse response = this.client.getResponse(request);
+    	getLogger().info("Content type: " + response.getContentType());
+    	getLogger().info("Content length: " + response.getContentLength());
+    	getLogger().info("Output: " + response.getText());
+
+        return response.getInputStream();
+    }
+
+    protected void pipeTest(String uri, String expectedSource) throws Exception {
+        byte[] expected = loadByteArray((new URL(classDirURL, expectedSource)).openStream());
+        byte[] actual = loadByteArray(process(uri));
+        assertIdentical(expected, actual);
+    }
+}

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

Propchange: cocoon/trunk/src/test/org/apache/cocoon/test/ServletTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/trunk/src/test/org/apache/cocoon/test/blocks/BlocksManagerTestCase.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/test/org/apache/cocoon/test/blocks/BlocksManagerTestCase.java?rev=358167&r1=358166&r2=358167&view=diff
==============================================================================
--- cocoon/trunk/src/test/org/apache/cocoon/test/blocks/BlocksManagerTestCase.java (original)
+++ cocoon/trunk/src/test/org/apache/cocoon/test/blocks/BlocksManagerTestCase.java Tue Dec 20 16:59:17 2005
@@ -15,24 +15,10 @@
  */
 package org.apache.cocoon.test.blocks;
 
-import org.apache.cocoon.Constants;
-import org.apache.cocoon.blocks.BlocksManager;
-import org.apache.cocoon.test.SitemapTestCase;
+import org.apache.cocoon.test.ServletTestCase;
 
-public class BlocksManagerTestCase extends SitemapTestCase {
+public class BlocksManagerTestCase extends ServletTestCase {
     
-    protected void setUp() throws Exception {
-        this.processorClassName = BlocksManager.class.getName();
-        super.setUp();
-    }
-    
-    /* (non-Javadoc)
-     * @see org.apache.cocoon.test.SitemapTestCase#getConfiguration()
-     */
-    protected String getConfiguration() {
-        return Constants.WIRING;
-    }
-
     public void testBlockSource1() throws Exception {
         pipeTest("/test1/test", "test1/test.xml");
     }

Added: cocoon/trunk/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml?rev=358167&view=auto
==============================================================================
--- cocoon/trunk/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml (added)
+++ cocoon/trunk/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml Tue Dec 20 16:59:17 2005
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-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.
+-->
+
+<!--+
+    | This is the BlocksManagerTestCase web-app configurations file
+    +-->
+
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+    "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+
+  <!-- Servlet Configuration ========================================== -->
+
+  <servlet>
+    <servlet-name>BlocksManager</servlet-name>
+    <display-name>BlocksManager</display-name>
+    <description>BlocksManager</description>
+
+    <servlet-class>org.apache.cocoon.blocks.BlocksManager</servlet-class>
+
+    <init-param>
+      <param-name>work-directory</param-name>
+      <param-value>work</param-value>
+    </init-param>
+
+    <init-param>
+      <param-name>configurations</param-name>
+      <param-value>wiring.xml</param-value>
+    </init-param>
+
+    <!--
+      Set encoding used by the container. If not set the ISO-8859-1 encoding
+      will be assumed.
+      Since the servlet specification requires that the ISO-8859-1 encoding
+      is used (by default), you should never change this value unless
+      you have a buggy servlet container.
+    -->
+    <init-param>
+      <param-name>container-encoding</param-name>
+      <param-value>ISO-8859-1</param-value>
+    </init-param>
+
+  </servlet>
+
+  <!-- URL space mappings ============================================= -->
+
+  <servlet-mapping>
+    <servlet-name>BlocksManager</servlet-name>
+    <url-pattern>/</url-pattern>
+  </servlet-mapping>
+
+</web-app>

Propchange: cocoon/trunk/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/tools/lib/httpunit-1.6.jar
URL: http://svn.apache.org/viewcvs/cocoon/trunk/tools/lib/httpunit-1.6.jar?rev=358167&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cocoon/trunk/tools/lib/httpunit-1.6.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream