Author: pier Date: Tue Nov 2 18:03:53 2004 New Revision: 56453 Added: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/AbstractPlugin.java cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/LoggingPlugin.java cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/Utilities.java cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/AbstractLogger.java cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ConsoleLogger.java cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/Logger.java cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ServletLogger.java Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Deployer.java cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Factory.java cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Instance.java cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Extension.java cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Library.java cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/Plugin.java cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/KernelLoader.java cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/Main.java cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ServletLoader.java cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/StartupKernel.java Log: Kernel logging implemented working as a plugin and using Log4J + Commons Logging: logging is provided to blocks using those two APIs and transparently re-processed by the kernel
Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Deployer.java ============================================================================== --- cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Deployer.java (original) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Deployer.java Tue Nov 2 18:03:53 2004 @@ -20,12 +20,16 @@ import java.util.Map; import java.util.Set; +import org.apache.cocoon.kernel.Kernel; import org.apache.cocoon.kernel.KernelException; import org.apache.cocoon.kernel.configuration.Configuration; import org.apache.cocoon.kernel.description.Block; import org.apache.cocoon.kernel.description.Descriptor; +import org.apache.cocoon.kernel.description.Extension; import org.apache.cocoon.kernel.description.Library; +import org.apache.cocoon.kernel.plugins.Plugin; import org.apache.cocoon.kernel.startup.KernelLoader; +import org.apache.cocoon.kernel.startup.Logger; import org.apache.cocoon.kernel.startup.StartupKernel; /** @@ -45,14 +49,16 @@ private KernelLoader loader = null; /** <p>The [EMAIL PROTECTED] Library} of all [EMAIL PROTECTED] Block}s and [EMAIL PROTECTED] Interface}s.</p> */ private Library library = null; - /** <p>The [EMAIL PROTECTED] Runtime} of all available [EMAIL PROTECTED] Instance}s.</p> */ - //private Runtime runtime = null; - /** <p>A [EMAIL PROTECTED] Map} of all initialized singleton components.</p> */ - private Map singletons = new HashMap(); /** <p>A [EMAIL PROTECTED] Set} containing all components being initialized.</p> */ private Set initializing = new HashSet(); + /** <p>A [EMAIL PROTECTED] Map} of all initialized plugins.</p> */ + private Map plugins = new HashMap(); /** <p>A simple [EMAIL PROTECTED] Map} holding all instances and configurations.</p> */ private Map wrappers = new HashMap(); + /** <p>A [EMAIL PROTECTED] Map} of all initialized singleton components.</p> */ + private Map singletons = new HashMap(); + /** <p>The [EMAIL PROTECTED] Logger} used internally.</p> */ + private Logger logger = new Logger(); /** * <p>Create a new [EMAIL PROTECTED] Deployer} instance.</p> @@ -83,34 +89,80 @@ * @param instances A [EMAIL PROTECTED] Configuration} containing block instances. */ public void initialize(Configuration descriptors, Configuration instances) { + this.logger.log("Initializing kernel instance"); + try { /* Retrieve all descriptors and put them in the library */ Factory.configure(this.library, descriptors); - /* Make sure that our loader adds _all_ the libraries we need */ - Iterator extensions = library.iterator(Descriptor.EXTENSION); - while (extensions.hasNext()) { - Descriptor descriptor = ((Descriptor) extensions.next()); - this.loader.addURL(this, descriptor.getLibraries()); - } - + /* Make sure that our loader adds the interface libraries */ Iterator interfaces = library.iterator(Descriptor.INTERFACE); while (interfaces.hasNext()) { Descriptor descriptor = ((Descriptor) interfaces.next()); this.loader.addURL(this, descriptor.getLibraries()); } + + /* Add, load and instantiate plugins */ + Iterator extensions = library.iterator(Descriptor.EXTENSION); + while (extensions.hasNext()) { + Extension descriptor = (Extension) extensions.next(); + String element = descriptor.getPluginConfigurationElement(); + String name = descriptor.getPlugin(); + this.loader.addURL(this, descriptor.getLibraries()); + java.net.URL libs[] = descriptor.getLibraries(); + this.getLogger().debug("Adding a total of " + libs.length + " for " + descriptor); + for (int x = 0; x < libs.length; x ++) { + this.getLogger().debug("Adding library at " + libs[x]); + } + + /* Now for the initialization */ + try { + /* + * Instantiate the plugin in the classloader loading this class, + * as the plug-in might be bundled with the kernel JAR itself + */ + Class clazz = this.getClass().getClassLoader().loadClass(name); + Plugin plugin = (Plugin) clazz.newInstance(); + + /* Create a proxy for ourselves implementing StartupKernel */ + Wiring wiring = new Wiring(this); + StartupKernel kernel = (StartupKernel) Proxy.newProxyInstance( + this.loader, new Class[] { StartupKernel.class }, wiring); + + /* Configure the plugin with its configuration */ + plugin.configure(kernel, instances.child(element)); + plugin.initialize(); + this.plugins.put(element, plugin); + + } catch (Throwable throwable) { + throw new KernelException("Unable to load and initialize plugin " + + "class \"" + descriptor.getPlugin() + "\" declared " + + "by extension \"" + descriptor + "\"", throwable); + } + } + /* Do some logging */ + this.logger.log("Configured descriptors:"); + Iterator iterator = this.library.iterator(); + while (iterator.hasNext()) { + Descriptor descriptor = (Descriptor) iterator.next(); + this.logger.log(" - [" + Descriptor.NAMES[descriptor.getType()] + + "] " + descriptor.toString()); + } + /* Configure all instances and be done with it */ Factory.configure(this, instances); /* Initialize all singletons */ - Iterator iterator = this.iterator(); - System.err.println("INSTANCES:"); - while (iterator.hasNext()) { + this.logger.log("Initializing singleton instances:"); + Iterator wrappers = this.wrappers.keySet().iterator(); + while (wrappers.hasNext()) { /* Retrieve the instance and configuration */ - String name = (String) iterator.next(); - System.err.println(" " + name); - this.singletons.put(name, this.instantiate(name)); + String name = (String) wrappers.next(); + this.logger.log(" - [" + name + "] " + this.getBlock(name)); + if (this.getBlock(name).isSingletonComponent()) { + this.singletons.put(name, this.instantiate(name)); + } } } catch (DeployerException exception) { @@ -122,18 +174,31 @@ * <p>Destroy this deployer and all block instances.</p> */ public void destroy() { + this.logger.log("Destroying deployer instance"); + + this.logger.log("Destroying singleton instances:"); Iterator iterator = this.singletons.keySet().iterator(); while (iterator.hasNext()) { String current = (String) iterator.next(); + this.logger.log(" - [" + current + "] " + this.getBlock(current)); Object component = this.singletons.get(current); Instance instance = this.getInstance(current); Method destructor = instance.getComponentDestroyerMethod(); try { if (destructor != null) destructor.invoke(component, NULL); } catch (Throwable t) { - // TODO: log this with the block logger! - System.err.println("Exception destroying singleton: " + current); - t.printStackTrace(System.err); + this.logger.error("Exception destroying singleton: " + current, t); + } + } + + Iterator plugins = this.plugins.keySet().iterator(); + while (plugins.hasNext()) { + String current = (String) plugins.next(); + Plugin plugin = (Plugin) this.plugins.get(current); + try { + plugin.destroy(); + } catch (Throwable t) { + this.logger.error("Exception destroying plugin: " + current, t); } } } @@ -172,6 +237,20 @@ } } + /** + * <p>Set the [EMAIL PROTECTED] Logger} used by the kernel internals.</p> + */ + public void setLogger(Logger logger) { + if (logger != null) this.logger = logger; + } + + /** + * <p>Retrieve [EMAIL PROTECTED] Logger} used by the kernel internals.</p> + */ + public Logger getLogger() { + return this.logger; + } + /* =========================================================================== */ /* PROTECTED METHODS */ /* =========================================================================== */ @@ -179,18 +258,18 @@ /** * <p>Push a new [EMAIL PROTECTED] Block} [EMAIL PROTECTED] Instance} into this [EMAIL PROTECTED] Runtime}.</p> */ - protected void add(String name, Instance instance, Configuration configuration) { + protected void putInstance(String name, Instance inst, Configuration conf) { if (name == null) throw new NullPointerException("Null name"); - if (instance == null) throw new NullPointerException("Null instance"); - if (configuration == null) throw new NullPointerException("Null config"); - this.wrappers.put(name, new Wrapper(instance, configuration)); - } + if (inst == null) throw new NullPointerException("Null instance"); + if (conf == null) throw new NullPointerException("Null config"); + this.wrappers.put(name, new Wrapper(inst, conf)); - /** - * <p>Return an [EMAIL PROTECTED] Iterator} over all [EMAIL PROTECTED] Instance} names configured.</p> - */ - protected Iterator iterator() { - return(this.wrappers.keySet().iterator()); + Iterator iterator = this.plugins.keySet().iterator(); + while (iterator.hasNext()) { + String plugin = (String) iterator.next(); + Configuration curr = conf.child(plugin); + ((Plugin)this.plugins.get(plugin)).notify(inst, curr); + } } /** Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Factory.java ============================================================================== --- cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Factory.java (original) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Factory.java Tue Nov 2 18:03:53 2004 @@ -108,8 +108,8 @@ throw new DeployerException("Unable to instantiate non-block \"" + block + " declared at " + current.location()); } - Instance instance = new Instance(runtime, (Block) descriptor); - runtime.add(name, instance, current); + Instance instance = new Instance(runtime, (Block) descriptor, name); + runtime.putInstance(name, instance, current); } catch (DeployerException e) { throw e; } catch (Throwable t) { Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Instance.java ============================================================================== --- cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Instance.java (original) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/deployment/Instance.java Tue Nov 2 18:03:53 2004 @@ -46,16 +46,19 @@ private Block block = null; /** <p>A set of all known [EMAIL PROTECTED] URL}s to avoid duplications.</p> */ private Set urls = new HashSet(); + /** <p>The name of this instance.</p> */ + private String name = null; /** * <p>Create a new [EMAIL PROTECTED] Instance} instance.</p> */ - public Instance(Deployer deployer, Block block) + public Instance(Deployer deployer, Block block, String name) throws DeployerException { super(block.getLibraries(), deployer.getLoader()); URL libraries[] = block.getLibraries(); for (int k = 0; k < libraries.length; k ++) urls.add(libraries[k]); this.block = block; + this.name = name; /* Process all interfaces, all extended blocks and all modules */ Dependencies dependencies = new Dependencies(); @@ -105,6 +108,13 @@ /* Remember where we're coming from */ this.block = block; + } + + /** + * <p>Return the name associated with this [EMAIL PROTECTED] Instance}.</p> + */ + public String getName() { + return(this.name); } /** Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Extension.java ============================================================================== --- cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Extension.java (original) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Extension.java Tue Nov 2 18:03:53 2004 @@ -27,10 +27,8 @@ /** <p>The name of the provided Java plugin.</p> */ private String clazz = null; - /** <p>The name (if any) of the initializer method.</p> */ - private String initializer = null; - /** <p>The name (if any) of the destroyer method.</p> */ - private String destroyer = null; + /** <p>The name of the configuration element in the instances file.</p> */ + private String element = null; /** * <p>Create a new [EMAIL PROTECTED] Extension} instance.</p> @@ -56,8 +54,7 @@ } /* Process initializer, destroyer, and singleton */ - this.initializer = plugin.getStringAttribute("initialize", null); - this.destroyer = plugin.getStringAttribute("destroy", null); + this.element = plugin.getStringAttribute("configuration-element", null); } /** @@ -68,23 +65,17 @@ } /** - * <p>Return the name of the metod to call at initialization.</p> + * <p>Return the name of the element to be looked up in the configuration file + * containing the configuration of this plugin.</p> */ - public String getPluginInitializer() { - return(this.initializer); - } - - /** - * <p>Return the name of the metod to call at destruction.</p> - */ - public String getPluginDestroyer() { - return(this.initializer); + public String getPluginConfigurationElement() { + return(this.element); } /** * <p>Return the type of this descriptor.</p> */ public int getType() { - return Descriptor.BLOCK; + return Descriptor.EXTENSION; } } Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Library.java ============================================================================== --- cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Library.java (original) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Library.java Tue Nov 2 18:03:53 2004 @@ -128,6 +128,7 @@ } catch (Throwable throwable) { throw new IllegalArgumentException("Invalid type " + type); } + this.type = type; this.iterator = iterator; } Added: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/AbstractPlugin.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/AbstractPlugin.java Tue Nov 2 18:03:53 2004 @@ -0,0 +1,138 @@ +/* =============================================================================== * + * Copyright (C) 1999-2004, The Apache Software Foundation. All rights reserved. * + * * + * 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.kernel.plugins; + +import org.apache.cocoon.kernel.configuration.Configuration; +import org.apache.cocoon.kernel.deployment.Instance; +import org.apache.cocoon.kernel.startup.Logger; +import org.apache.cocoon.kernel.startup.StartupKernel; + +/** + * <p>TODO.</p> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> + * @author Copyright © 2000-2004 <a href="http://www.apache.org/">The Apache + * Software Foundation</a>. All rights reserved. + */ +public class AbstractPlugin extends Logger implements Plugin { + + /** <p>The configured [EMAIL PROTECTED] StartupKernel} instance.</p> */ + private StartupKernel kernel = null; + /** <p>The global plugin [EMAIL PROTECTED] Configuration} member.</p> */ + private Configuration config = null; + + /** + * <p>Create a new [EMAIL PROTECTED] AbstractPlugin} instance.</p> + */ + public AbstractPlugin() { + super(); + } + + /** + * <p>Configure this plugin from a specified [EMAIL PROTECTED] Configuration}.</p> + * + * <p>This method is <b>final</b>. Implement the [EMAIL PROTECTED] #configure()} method + * and access the [EMAIL PROTECTED] StartupKernel} and [EMAIL PROTECTED] Configuration} calling + * the [EMAIL PROTECTED] #getKernel()} and [EMAIL PROTECTED] #getConfiguration()} methods.</p> + */ + public final void configure(StartupKernel kernel, Configuration config) { + this.config = config; + this.kernel = kernel; + this.configure(); + this.debug("Plugin \"" + this.getClass().getName() + "\" configured"); + } + + /** + * <p>This implementation doesn't do anything.</p> + */ + public void configure() { + // NO-OP implementation. + } + + /** + * <p>This implementation doesn't do anything.</p> + */ + public void initialize() { + // NO-OP implementation. + } + + /** + * <p>This implementation doesn't do anything.</p> + */ + public void notify(Instance instance, Configuration config) { + // NO-OP implementation. + } + + /** + * <p>This implementation doesn't do anything.</p> + */ + public void destroy() { + // NO-OP implementation. + } + + /** + * <p>Return the configured [EMAIL PROTECTED] StartupKernel} instance.</p> + */ + public StartupKernel getKernel() { + return(this.kernel); + } + + /** + * <p>Return the configured [EMAIL PROTECTED] Configuration} instance.</p> + */ + public Configuration getConfiguration() { + return(this.config); + } + + /** + * <p>Log a debug message.</p> + */ + public void debug(String message) { + this.kernel.getLogger().debug(message); + } + + /** + * <p>Log a debug message.</p> + */ + public void debug(String message, Throwable throwable) { + this.kernel.getLogger().debug(message, throwable); + } + + /** + * <p>Log a info message.</p> + */ + public void log(String message) { + this.kernel.getLogger().log(message); + } + + /** + * <p>Log a info message.</p> + */ + public void log(String message, Throwable throwable) { + this.kernel.getLogger().log(message, throwable); + } + + /** + * <p>Log a fatal error message.</p> + */ + public void error(String message) { + this.kernel.getLogger().error(message); + } + + /** + * <p>Log a fatal error message.</p> + */ + public void error(String message, Throwable throwable) { + this.kernel.getLogger().error(message, throwable); + } +} Added: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/LoggingPlugin.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/LoggingPlugin.java Tue Nov 2 18:03:53 2004 @@ -0,0 +1,269 @@ +/* =============================================================================== * + * Copyright (C) 1999-2004, The Apache Software Foundation. All rights reserved. * + * * + * 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.kernel.plugins; + +import java.net.URL; +import java.util.Enumeration; + +import org.apache.cocoon.kernel.deployment.Instance; +import org.apache.commons.logging.LogFactory; +import org.apache.commons.logging.impl.Log4jFactory; +import org.apache.log4j.Appender; +import org.apache.log4j.Category; +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.apache.log4j.spi.HierarchyEventListener; +import org.apache.log4j.spi.LoggerFactory; +import org.apache.log4j.spi.LoggerRepository; +import org.apache.log4j.spi.RepositorySelector; +import org.apache.log4j.xml.DOMConfigurator; + +/** + * <p>The [EMAIL PROTECTED] LoggingPlugin} enables the use of Log4J and Commons-Logging + * in a kernel-aware way.</p> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> + * @author Copyright © 2000-2004 <a href="http://www.apache.org/">The Apache + * Software Foundation</a>. All rights reserved. + */ +public class LoggingPlugin extends AbstractPlugin +implements LoggerRepository, RepositorySelector { + + /** <p>The original [EMAIL PROTECTED] LoggerRepository} of Log4J.</p> */ + private LoggerRepository repository = null; + /** <p>The logger originally associated with the kernel.</p> */ + private org.apache.cocoon.kernel.startup.Logger original = null; + + /** + * <p>Create a new [EMAIL PROTECTED] LoggingPlugin} instance.</p> + */ + public LoggingPlugin() { + this.repository = LogManager.getLoggerRepository(); + } + + public void initialize() { + /* Configure Log4J if we were told to do so */ + String conf = this.getConfiguration().getStringAttribute("log4j", null); + if (conf != null) try { + URL url = new URL(this.getConfiguration().locationURL(), conf); + DOMConfigurator configurator = new DOMConfigurator(); + configurator.doConfigure(url, this.repository); + } catch (Throwable throwable) { + this.error("Cannot configure Log4J", throwable); + } + + /* Error or no error, we _are_ using Log4J, no questions asked */ + this.debug("Switching logger implementation"); + this.original = this.getKernel().getLogger(); + this.getKernel().setLogger(new Wrapper(Logger.getLogger("kernel"))); + this.debug("Switched logger implementation"); + + /* Replace the Log4J Logger Repository */ + this.debug("Configuring Log4J"); + try { + LogManager.setRepositorySelector(this, null); + } catch (Throwable t) { + this.error("Unable to configure Log4J repository selector", t); + } + + /* And make sure that commons has the Log4J factory configured */ + String factory = Log4jFactory.class.getName(); + System.setProperty(LogFactory.FACTORY_PROPERTY, factory); + LogFactory.getLog(this.getClass()).debug("Commons-Logging configured"); + } + + public void destroy() { + this.debug("Restoring logger implementation"); + this.getKernel().setLogger(this.original); + this.debug("Restored logger implementation"); + this.repository.shutdown(); + } + + /* =========================================================================== */ + /* UNDERSTANDABLE LOG4J METHODS */ + /* =========================================================================== */ + + /** + * <p>Return ourselves.</p> + */ + public LoggerRepository getLoggerRepository() { + return(this); + } + + /** + * <p>Return the logger associated with the calling block.</p> + */ + public Logger getLogger(String arg0) { + return this.repository.getLogger(this.getLoggerName(arg0)); + } + + /** + * <p>Return the logger associated with the calling block.</p> + */ + public Logger getLogger(String arg0, LoggerFactory arg1) { + return this.repository.getLogger(this.getLoggerName(arg0), arg1); + } + + /** + * <p>Return the logger associated with the calling block.</p> + */ + public Logger getRootLogger() { + return this.repository.getLogger(this.getLoggerName(null)); + } + + /** + * <p>Check if the logger specified exists.</p> + */ + public Logger exists(String arg0) { + return this.repository.exists(this.getLoggerName(arg0)); + } + + /** + * <p>Canonicalize the name of the logger to return.</p> + */ + public String getLoggerName(String arg0) { + String name = Utilities.getCallerName(); + if (name == null) { + if (arg0 == null) return "unknown"; + if (arg0.length() == 0) return "unknown"; + return arg0; + } else { + if (arg0 == null) return name; + if (arg0.length() == 0) return name; + return (name + "." + arg0); + } + } + + /** + * <p>Simply ignore this call from the kernel.</p> + */ + public void resetConfiguration() { + // Nothing to do... + } + + /** + * <p>Simply ignore this call from the kernel.</p> + */ + public void shutdown() { + // Nothing to do... + } + + /* =========================================================================== */ + /* GOD KNOWS WHAT THIS DOES METHODS GO STRAIGHT TO LOG4J (TOO COMPLICATED) */ + /* =========================================================================== */ + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public void addHierarchyEventListener(HierarchyEventListener arg0) { + this.repository.addHierarchyEventListener(arg0); + } + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public boolean isDisabled(int arg0) { + return this.repository.isDisabled(arg0); + } + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public void setThreshold(Level arg0) { + this.repository.setThreshold(arg0); + } + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public void setThreshold(String arg0) { + this.repository.setThreshold(arg0); + } + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public void emitNoAppenderWarning(Category arg0) { + this.repository.emitNoAppenderWarning(arg0); + } + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public Level getThreshold() { + return this.repository.getThreshold(); + } + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public Enumeration getCurrentLoggers() { + return this.repository.getCurrentLoggers(); + } + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public Enumeration getCurrentCategories() { + return this.repository.getCurrentCategories(); + } + + /** + * <p>Forwarded directly to the Log4J original [EMAIL PROTECTED] LoggerRepository}.</p> + */ + public void fireAddAppenderEvent(Category arg0, Appender arg1) { + this.repository.fireAddAppenderEvent(arg0, arg1); + } + + /* =========================================================================== */ + /* WRAPPER FOR THE KERNEL LOGGER AROUND LOG4J */ + /* =========================================================================== */ + + /** + * <p>A simple wrapper for the internal kernel logger.</p> + */ + private static class Wrapper extends org.apache.cocoon.kernel.startup.Logger { + + private Logger logger = null; + + private Wrapper(Logger logger) { + if (logger == null) throw new NullPointerException("Null logger"); + this.logger = logger; + } + + public void debug(String message) { + this.logger.debug(message); + } + + public void debug(String message, Throwable throwable) { + this.logger.debug(message, throwable); + } + + public void log(String message) { + this.logger.info(message); + } + + public void log(String message, Throwable throwable) { + this.logger.info(message, throwable); + } + + public void error(String message) { + this.logger.error(message); + } + + public void error(String message, Throwable throwable) { + this.logger.error(message, throwable); + } + } +} Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/Plugin.java ============================================================================== --- cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/Plugin.java (original) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/Plugin.java Tue Nov 2 18:03:53 2004 @@ -12,13 +12,49 @@ * =============================================================================== */ package org.apache.cocoon.kernel.plugins; +import org.apache.cocoon.kernel.configuration.Configuration; +import org.apache.cocoon.kernel.deployment.Instance; +import org.apache.cocoon.kernel.startup.StartupKernel; + /** - * <p>The [EMAIL PROTECTED] Plugin} interface identifies a.</p> + * <p>The [EMAIL PROTECTED] Plugin} interface defines a kernel extension.</p> * + * <p>Kernel plug-ins follow a very simple lifecycle:</p> + * + * <ol> + * <li>[EMAIL PROTECTED] #configure(StartupKernel, Configuration)}</li> + * <li>[EMAIL PROTECTED] #initialize()}</li> + * <li> + * [EMAIL PROTECTED] #notify(String, Instance, Configuration)}<br /> + * <i>called as many times as many block instances are deployed</i> + * </li> + * <li>[EMAIL PROTECTED] #destroy()}</li> + * </ol> + * * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> * @author Copyright © 2000-2004 <a href="http://www.apache.org/">The Apache * Software Foundation</a>. All rights reserved. */ public interface Plugin { + + /** + * <p>Configure this plugin from a specified [EMAIL PROTECTED] Configuration}.</p> + */ + public void configure(StartupKernel kernel, Configuration configuration); + + /** + * <p>Initialize this kernel [EMAIL PROTECTED] Plugin}.</p> + */ + public void initialize(); + + /** + * <p>Receive notification of the creation of a new block [EMAIL PROTECTED] Instance}.</p> + */ + public void notify(Instance instance, Configuration configuration); + + /** + * <p>Destroy this kernel [EMAIL PROTECTED] Plugin}.</p> + */ + public void destroy(); } Added: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/Utilities.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/Utilities.java Tue Nov 2 18:03:53 2004 @@ -0,0 +1,56 @@ +/* =============================================================================== * + * Copyright (C) 1999-2004, The Apache Software Foundation. All rights reserved. * + * * + * 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.kernel.plugins; + +import org.apache.cocoon.kernel.deployment.Instance; + +/** + * <p>TODO.</p> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> + * @author Copyright © 2000-2004 <a href="http://www.apache.org/">The Apache + * Software Foundation</a>. All rights reserved. + */ +public class Utilities extends SecurityManager { + + /** <p>Our [EMAIL PROTECTED] Utilities} instance.</p> */ + private static Utilities instance = new Utilities(); + + /** <p>Deny normal construction.</p> */ + private Utilities() { + super(); + } + + /** + * <p>Retrieve the block instance calling this method.</p> + */ + public static Instance getCaller() { + Class context[] = Utilities.instance.getClassContext(); + if (context == null) return(null); + for (int x = 0; x < context.length; x++) { + if (context[x].getClassLoader() instanceof Instance) { + return((Instance)(context[x].getClassLoader())); + } + } + return(null); + } + + /** + * <p>Retrieve the block instance calling this method.</p> + */ + public static String getCallerName() { + Instance instance = Utilities.getCaller(); + if (instance != null) return (instance.getName()); + return(null); + } +} Added: cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/AbstractLogger.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/AbstractLogger.java Tue Nov 2 18:03:53 2004 @@ -0,0 +1,255 @@ +/* + * 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.kernel.startup; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import javax.xml.transform.TransformerException; + +import org.xml.sax.SAXException; + +/** + * <p>The [EMAIL PROTECTED] AbstractLogger} is a simple abstract [EMAIL PROTECTED] Logger} formatting + * log entries and outputting them.</p> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> + * @version 1.0 (CVS $Revision: 1.9 $) + */ +public abstract class AbstractLogger extends Logger { + + /** <p>Output debug, info, warn, error and fatal messages.</p> */ + public static final int DEBUG = 0; + /** <p>Output info, warn, error and fatal messages.</p> */ + public static final int INFO = 1; + /** <p>Output only fatal error messages.</p> */ + public static final int ERROR = 2; + + /* ====================================================================== */ + + /** <p>The logging level.</p> */ + protected int level = DEBUG; + /** <p>The timestamp formatter (if any).</p> */ + private SimpleDateFormat format = null; + + /* ====================================================================== */ + + /** + * <p>Create a new [EMAIL PROTECTED] AbstractLogger}.</p> + * + * @param level the minimum level of logging messages to output. + */ + public AbstractLogger(int level) { + this.format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS"); + if (level < DEBUG) this.level = DEBUG; + else if (level > ERROR) this.level = ERROR; + else this.level = level; + } + + /* ====================================================================== */ + + /** + * <p>Log a debug message.</p> + * + * @param message the message. + */ + public void debug(String message) { + this.out(DEBUG, message, null); + } + + /** + * <p>Log a debug message.</p> + * + * @param message the message. + * @param throwable the throwable. + */ + public void debug(String message, Throwable throwable) { + this.out(DEBUG, message, throwable); + } + + /** + * <p>Log a info message.</p> + * + * @param message the message. + */ + public void log(String message) { + this.out(INFO, message, null); + } + + /** + * <p>Log a info message.</p> + * + * @param message the message. + * @param throwable the throwable. + */ + public void log(String message, Throwable throwable) { + this.out(INFO, message, throwable); + } + + /** + * <p>Log a fatal error message.</p> + * + * @param message the message. + */ + public void error(String message) { + this.out(ERROR, message, null); + } + + /** + * <p>Log a fatal error message.</p> + * + * @param message the message. + * @param throwable the throwable. + */ + public void error(String message, Throwable throwable) { + this.out(ERROR, message, throwable); + } + + /* ====================================================================== */ + + /** + * <p>Write a line to the output.</p> + * + * @param line the line to write. + */ + protected abstract void output(String line); + + /* ====================================================================== */ + + /** + * <p>Generate output from this logger.</p> + * + * @param level the level of the log entry. + * @param message the message to log (if any). + * @param throwable the [EMAIL PROTECTED] Throwable} to log (if any). + */ + private void out(int level, String message, Throwable throwable) { + if (level < this.level) return; + + /* Prepare the header for output in a new buffer */ + StringBuffer buffer = new StringBuffer(64); + + /* If we got a time formatter, append the time */ + if (this.format != null) buffer.append(this.format.format(new Date())); + + /* Dump out the log level */ + if (buffer.length() > 0) buffer.append(" "); + switch (level) { + case DEBUG: buffer.append("[DEBUG] "); break; + case INFO: buffer.append("[INFO ] "); break; + case ERROR: buffer.append("[ERROR] "); break; + default: buffer.append("[?????] "); break; + } + + /* If both message and throwable were null, whopsie */ + if ((message == null) && (throwable == null)) { + this.output(buffer.append("null logging entry?").toString()); + return; + } + + /* If we want to re-use the header for the throwable, lets save it*/ + String header = (throwable != null ? buffer.toString() : null); + + /* If we have a message, we want to output it */ + if (message != null) this.output(buffer.append(message).toString()); + + /* If we have a throwable, we output it with the saved header */ + if (throwable != null) this.out(header, throwable, false); + } + + /** + * <p>Generate output from this logger for a [EMAIL PROTECTED] Throwable}.</p> + * + * @param header the header to use. + * @param throwable the [EMAIL PROTECTED] Throwable} to log. + * @param cause if the [EMAIL PROTECTED] Throwable} is the cause of another. + */ + private void out(String header, Throwable throwable, boolean cause) { + StringBuffer buffer = new StringBuffer(200); + + /* Check if this throwable has a cause */ + Throwable causedby = null; + if (throwable instanceof SAXException) { + causedby = ((SAXException)throwable).getException(); + } else causedby = throwable.getCause(); + + /* Print the logging header and an explaination */ + buffer.append(header); + buffer.append(cause ? "+ Caused by " : "Exception "); + + /* Print the Throwable class name */ + buffer.append(throwable.getClass().getName()); + buffer = this.out(buffer); + + /* Print the Throwable message */ + String message = throwable.getMessage(); + if (throwable instanceof TransformerException) { + message = ((TransformerException)throwable).getMessageAndLocation(); + } + if (message == null) message = "[Null Exception Message!]"; + /* Print the header for the message */ + buffer.append(header); + + /* Widgeting, many checks, one buffer append call */ + if (!cause) buffer.append("+--- "); + else buffer.append(causedby == null ? " +--- " : "| +--- "); + + /* Print out the message */ + buffer = this.out(buffer.append(message)); + + /* Analyze every single stack trace element */ + StackTraceElement trace[] = throwable.getStackTrace(); + for (int x = 0; x < trace.length; x++) { + + /* Per each stack trace element print the header */ + buffer.append(header); + + /* Widgeting, many checks, one buffer append call */ + if ((x + 1) == trace.length) { + /* What widgets to print if this the last trace element */ + if (causedby == null) + buffer.append(cause ? " + at " : "+ at "); + else buffer.append(cause ? "| + at " : "| at "); + } else { + /* What widgets to print if this the last trace element */ + if (cause) + buffer.append(causedby == null ? " | at " : "| | at "); + else buffer.append("| at "); + } + + /* And finally print the trace */ + buffer = this.out(buffer.append(trace[x].toString())); + } + + /* Recursively loop through the causes of the exception */ + if (causedby != null) { + buffer.append(header); + this.out(buffer.append("|")); + this.out(header, causedby, true); + } else this.out(buffer.append(header)); + } + + /** + * <p>Output a StringBuffer and return a new one.</p> + * + * @param buffer the buffer to output. + * @return a new buffer. + */ + private StringBuffer out(StringBuffer buffer) { + if (buffer != null) this.output(buffer.toString()); + return(new StringBuffer(200)); + } +} Added: cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ConsoleLogger.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ConsoleLogger.java Tue Nov 2 18:03:53 2004 @@ -0,0 +1,64 @@ +/* + * 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.kernel.startup; + +import java.io.PrintStream; + + +/** + * <p>The [EMAIL PROTECTED] ConsoleLogger} is a simple [EMAIL PROTECTED] Logger} implementation + * writing to [EMAIL PROTECTED] System#err}.</p> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> + * @version 1.0 (CVS $Revision: 1.6 $) + */ +public class ConsoleLogger extends AbstractLogger { + + /** The [EMAIL PROTECTED] PrintStream} used for output */ + private PrintStream out = null; + + /* ====================================================================== */ + + /** + * <p>Create a new [EMAIL PROTECTED] ConsoleLogger} logging everything to + * [EMAIL PROTECTED] System#err}.</p> + */ + public ConsoleLogger() { + this(DEBUG); + } + + /** + * <p>Create a new [EMAIL PROTECTED] ConsoleLogger} logging message at a specified level + * to [EMAIL PROTECTED] System#err}.</p> + * + * @param level the level of output. + */ + public ConsoleLogger(int level) { + super(level); + this.out = System.err; + } + + /* ====================================================================== */ + + /** + * <p>Write a line to the output.</p> + * + * @param line the line to write. + */ + protected void output(String line) { + this.out.println(line); + } +} Modified: cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/KernelLoader.java ============================================================================== --- cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/KernelLoader.java (original) +++ cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/KernelLoader.java Tue Nov 2 18:03:53 2004 @@ -37,8 +37,6 @@ /** <p>Deny public construction.</p> */ private KernelLoader(ClassLoader loader, URL libraries[]) { super(libraries, loader); - if (libraries == null) return; - for (int k = 0; k < libraries.length; k ++) urls.add(libraries[k]); } /** @@ -73,7 +71,10 @@ throws Throwable { if (loader == null) loader = Thread.currentThread().getContextClassLoader(); if (libraries == null) libraries = new URL[0]; + + /* Instantiate the deployer in a child classloader of the kernel loader */ KernelLoader kernel_loader = new KernelLoader(loader, libraries); + URLClassLoader child_loader = new URLClassLoader(libraries, kernel_loader); Class clazz = kernel_loader.loadClass(KernelLoader.CLASS); Class signature[] = new Class [] { KernelLoader.class }; @@ -103,6 +104,6 @@ public void addURL(StartupKernel kernel, URL urls[]) { if (this.kernel != kernel) throw new SecurityException("Invalid instance"); if (urls == null) return; - for (int x = 0; x < urls.length; x ++) super.addURL(urls[x]); + for (int x = 0; x < urls.length; x ++) this.addURL(kernel, urls[x]); } } Added: cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/Logger.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/Logger.java Tue Nov 2 18:03:53 2004 @@ -0,0 +1,90 @@ +/* + * 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.kernel.startup; + +/** + * <p>A [EMAIL PROTECTED] Logger} instance is used by the kernel internals to log messages and + * errors.</p> + * + * <p>Normally a kernel plugin will provide the real instance used by the kernel + * to log, and the initial [EMAIL PROTECTED] Logger} instance is used exclusively during + * the startup phase of the kernel.</p> + * + * <p>This implementation never logs.</p> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> + * @version 1.0 (CVS $Revision: 1.2 $) + */ +public class Logger { + + /** + * <p>Create a new [EMAIL PROTECTED] Logger}.</p> + */ + public Logger() { + super(); + } + + /** + * <p>Log a debug message.</p> + * + * @param message the message. + */ + public void debug(String message) { + } + + /** + * <p>Log a debug message.</p> + * + * @param message the message. + * @param throwable the throwable. + */ + public void debug(String message, Throwable throwable) { + } + + /** + * <p>Log a info message.</p> + * + * @param message the message. + */ + public void log(String message) { + } + + /** + * <p>Log a info message.</p> + * + * @param message the message. + * @param throwable the throwable. + */ + public void log(String message, Throwable throwable) { + } + + /** + * <p>Log a fatal error message.</p> + * + * @param message the message. + */ + public void error(String message) { + } + + /** + * <p>Log a fatal error message.</p> + * + * @param message the message. + * @param throwable the throwable. + */ + public void error(String message, Throwable throwable) { + } +} Modified: cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/Main.java ============================================================================== --- cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/Main.java (original) +++ cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/Main.java Tue Nov 2 18:03:53 2004 @@ -20,7 +20,6 @@ import org.apache.cocoon.kernel.Kernel; import org.apache.cocoon.kernel.configuration.Configuration; import org.apache.cocoon.kernel.configuration.ConfigurationBuilder; -import org.apache.cocoon.kernel.deployment.Deployer; /** * <p>A simple class initializing a [EMAIL PROTECTED] Kernel} from a the command line.</p> @@ -85,18 +84,24 @@ return; } - /* Parse the (possibly two) configurations */ - Configuration descriptors = ConfigurationBuilder.parse(args[1]); - Configuration instances = (args.length == 2 ? descriptors : - ConfigurationBuilder.parse(args[2])); + ConsoleLogger logger = new ConsoleLogger(); + try { + /* Parse the (possibly two) configurations */ + Configuration descriptors = ConfigurationBuilder.parse(args[1]); + Configuration instances = (args.length == 2 ? descriptors : + ConfigurationBuilder.parse(args[2])); - /* Create and initialize a new deployer */ - URL library = new File(args[0]).toURL(); - StartupKernel kernel = KernelLoader.load(library); - kernel.initialize(descriptors, instances); - - /* Add the shutdown hook */ - Runtime.getRuntime().addShutdownHook(new Thread(new Main(kernel))); + /* Create and initialize a new deployer */ + URL library = new File(args[0]).toURL(); + StartupKernel kernel = KernelLoader.load(library); + kernel.setLogger(logger); + kernel.initialize(descriptors, instances); + + /* Add the shutdown hook */ + Runtime.getRuntime().addShutdownHook(new Thread(new Main(kernel))); + } catch (Throwable throwable) { + logger.log("Unable to startup kernel", throwable); + } /* * If non-daemon threads are still running, this thread will siply exit but Modified: cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ServletLoader.java ============================================================================== --- cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ServletLoader.java (original) +++ cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ServletLoader.java Tue Nov 2 18:03:53 2004 @@ -12,7 +12,6 @@ * =============================================================================== */ package org.apache.cocoon.kernel.startup; -import java.lang.reflect.Proxy; import java.net.URL; import javax.servlet.Servlet; @@ -23,8 +22,6 @@ import org.apache.cocoon.kernel.Kernel; import org.apache.cocoon.kernel.configuration.Configuration; import org.apache.cocoon.kernel.configuration.ConfigurationBuilder; -import org.apache.cocoon.kernel.deployment.Deployer; -import org.apache.cocoon.kernel.deployment.Wiring; /** * <p>The [EMAIL PROTECTED] ServletLoader} is a [EMAIL PROTECTED] ServletContextListener} managing the @@ -98,6 +95,7 @@ String instances = context.getInitParameter("kernel-instances"); /* Load and initialize the kernel */ + ServletLogger logger = new ServletLogger(context); try { URL library_url = context.getResource(library); if (library_url == null) { @@ -106,6 +104,7 @@ throw new RuntimeException(message); } this.kernel = KernelLoader.load(library_url); + this.kernel.setLogger(logger); /* Parse the (possibly two) configurations and initialize the deployer */ if (configuration != null) { @@ -120,16 +119,13 @@ this.kernel.initialize(desc, inst); } } catch (Throwable t) { - context.log("Unable to intialize kernel", t); + logger.error("Unable to intialize kernel", t); throw new RuntimeException("Unable to initialize kernel", t); } /* Make the kernel available through the servlet context */ - ClassLoader loader = this.getClass().getClassLoader(); - Class interfaces[] = new Class[] { Kernel.class }; - Wiring wiring = new Wiring(this.kernel); - Kernel kernel = (Kernel) Proxy.newProxyInstance(loader, interfaces, wiring); - context.setAttribute(ServletLoader.ATTRIBUTE, kernel); + Wrapper wrapper = new Wrapper(this.kernel); + context.setAttribute(ServletLoader.ATTRIBUTE, wrapper); } /** @@ -145,6 +141,23 @@ throw new RuntimeException("Unable to destroy kernel", t); } finally { this.kernel = null; + } + } + + /** + * <p>A simple wrapper for the [EMAIL PROTECTED] Kernel}.</p> + */ + private static class Wrapper implements Kernel { + + private Kernel kernel = null; + + private Wrapper(Kernel kernel) { + if (kernel == null) throw new NullPointerException("Null kernel"); + this.kernel = kernel; + } + + public Object lookup(String name) { + return(this.kernel.lookup(name)); } } } Added: cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ServletLogger.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/ServletLogger.java Tue Nov 2 18:03:53 2004 @@ -0,0 +1,66 @@ +/* + * 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.kernel.startup; + +import javax.servlet.ServletContext; + + +/** + * <p>The [EMAIL PROTECTED] ServletLogger} is a simple [EMAIL PROTECTED] Logger} implementation + * logging individual lines to a [EMAIL PROTECTED] ServletContext}.</p> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> + * @version 1.0 (CVS $Revision: 1.3 $) + */ +public class ServletLogger extends AbstractLogger { + + /** <p>Our [EMAIL PROTECTED] ServletContext} instance.</p> */ + private ServletContext context = null; + + /** + * <p>Create a new [EMAIL PROTECTED] ServletLogger} associated with a specific + * [EMAIL PROTECTED] ServletContext}.</p> + * + * @param context the [EMAIL PROTECTED] ServletContext} to log to. + */ + public ServletLogger(ServletContext context) { + this(context, DEBUG); + } + + /** + * <p>Create a new [EMAIL PROTECTED] ServletLogger} associated with a specific + * [EMAIL PROTECTED] ServletContext}.</p> + * + * @param level the level of output. + * @param context the [EMAIL PROTECTED] ServletContext} to log to. + */ + public ServletLogger(ServletContext context, int level) { + super(level); + if (context == null) throw new NullPointerException("Null context"); + this.context = context; + } + + /* ====================================================================== */ + + /** + * <p>Write a line to the output.</p> + * + * @param line the line to write. + */ + protected void output(String line) { + this.context.log(line); + } +} Modified: cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/StartupKernel.java ============================================================================== --- cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/StartupKernel.java (original) +++ cocoon/whiteboard/kernel/sources/startup/org/apache/cocoon/kernel/startup/StartupKernel.java Tue Nov 2 18:03:53 2004 @@ -45,4 +45,13 @@ */ public void destroy(); + /** + * <p>Set the [EMAIL PROTECTED] Logger} used by the kernel internals.</p> + */ + public void setLogger(Logger logger); + + /** + * <p>Retrieve [EMAIL PROTECTED] Logger} used by the kernel internals.</p> + */ + public Logger getLogger(); }