You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by pi...@apache.org on 2004/11/04 23:58:41 UTC
svn commit: rev 56626 - in cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel: deployment description plugins
Author: pier
Date: Thu Nov 4 14:58:41 2004
New Revision: 56626
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/Block.java
cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Extension.java
cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/AbstractPlugin.java
cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/Plugin.java
Log:
Slimmer container, multiple plugin per extension, default configurations from descriptors.
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 Thu Nov 4 14:58:41 2004
@@ -53,7 +53,7 @@
/** <p>A {@link Set} containing all components being initialized.</p> */
private Set initializing = new HashSet();
/** <p>A {@link Map} of all initialized plugins.</p> */
- private Map plugins = new HashMap();
+ private Set plugins = new HashSet();
/** <p>A simple {@link Map} holding all instances and configurations.</p> */
private Map wrappers = new HashMap();
/** <p>A {@link Map} of all initialized singleton components.</p> */
@@ -107,18 +107,15 @@
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.logger.debug("Initializing plugins for: " + descriptor);
+
/* 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);
+ String plugins[] = descriptor.getPluginClassNames();
+ for (int x = 0; x < plugins.length; x ++) try {
+
+ /* Load the plugin class and instantiate it */
+ Class clazz = this.loader.loadClass(plugins[x]);
Plugin plugin = (Plugin) clazz.newInstance();
/* Create a proxy for ourselves implementing StartupKernel */
@@ -127,14 +124,18 @@
this.loader, new Class[] { StartupKernel.class }, wiring);
/* Configure the plugin with its configuration */
- plugin.configure(kernel, instances.child(element));
+ String element = plugin.getConfigurationElement();
+ Configuration configuration = instances.child(element);
+ plugin.configure(kernel, configuration);
plugin.initialize();
- this.plugins.put(element, plugin);
+ this.logger.debug("Recording plugin \"" + plugins[x] + "\" with "
+ + " element \"" + element + "\"");
+ this.plugins.add(plugin);
} catch (Throwable throwable) {
throw new KernelException("Unable to load and initialize plugin "
- + "class \"" + descriptor.getPlugin() + "\" declared "
- + "by extension \"" + descriptor + "\"", throwable);
+ + "class \"" + plugins[x] + "\" declared by extension \""
+ + descriptor + "\"", throwable);
}
}
@@ -155,16 +156,18 @@
/* Initialize all singletons */
this.logger.log("Initializing singleton instances:");
- Iterator wrappers = this.wrappers.keySet().iterator();
+ Iterator wrappers = this.wrappers.values().iterator();
while (wrappers.hasNext()) {
/* Retrieve the instance and configuration */
- String name = (String) wrappers.next();
- this.logger.log(" - [" + name + "] " + this.getBlock(name));
- if (this.getBlock(name).isSingletonComponent()) {
- this.singletons.put(name, this.instantiate(name));
+ Wrapper wrapper = (Wrapper) wrappers.next();
+ String name = wrapper.instance.getName();
+ Block block = wrapper.instance.getBlock();
+ if (block.isSingletonComponent()) {
+ this.logger.log(" - [" + name + "] " + block);
+ Object singleton = this.newComponentInstance(wrapper);
+ this.singletons.put(name, singleton);
}
}
-
} catch (DeployerException exception) {
throw new KernelException("Unable to initialize kernel", exception);
}
@@ -180,25 +183,32 @@
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);
+ Wrapper wrapper = (Wrapper) this.wrappers.get(current);
+ Instance instance = wrapper.instance;
+
+ this.logger.log(" - [" + current + "] " + instance.getBlock());
Method destructor = instance.getComponentDestroyerMethod();
+
+ Thread thread = Thread.currentThread();
+ ClassLoader context = thread.getContextClassLoader();
+ thread.setContextClassLoader(instance);
try {
if (destructor != null) destructor.invoke(component, NULL);
} catch (Throwable t) {
this.logger.error("Exception destroying singleton: " + current, t);
}
+ thread.setContextClassLoader(instance);
}
- Iterator plugins = this.plugins.keySet().iterator();
+ Iterator plugins = this.plugins.iterator();
while (plugins.hasNext()) {
- String current = (String) plugins.next();
- Plugin plugin = (Plugin) this.plugins.get(current);
+ Plugin plugin = (Plugin) plugins.next();
try {
plugin.destroy();
} catch (Throwable t) {
- this.logger.error("Exception destroying plugin: " + current, t);
+ String plugin_name = plugin.getClass().getName();
+ this.logger.error("Exception destroying plugin " + plugin_name, t);
}
}
}
@@ -210,29 +220,29 @@
throws KernelException {
/* Retrieve and check the instance */
- Instance instance = this.getInstance(name);
- if (instance == null) {
+ Wrapper wrapper = (Wrapper) this.wrappers.get(name);
+ if (wrapper == null) {
throw new KernelException("Block instance \"" + name + "\" unknown");
}
/* Prepare wiring and component */
- Object component = this.singletons.get(instance);
+ Object component = this.singletons.get(name);
if (component == null) try {
- component = this.instantiate(name);
+ component = this.newComponentInstance(wrapper);
} catch (Throwable t) {
throw new KernelException("Unable to create non-singleton component "
- + " instance for block \"" + instance.getBlock().toString()
+ + " instance for block \"" + wrapper.instance.getBlock()
+ "\" instantiated with name \"" + name + "\"", t);
}
Wiring wiring = new Wiring(component);
/* Create and return the proxy instance */
- Class interfaces[] = instance.getImplementedInterfaces();
+ Class interfaces[] = wrapper.instance.getImplementedInterfaces();
try {
return Proxy.newProxyInstance(this.loader, interfaces, wiring);
} catch (Throwable t) {
throw new KernelException("Unable to create component proxy instance "
- + " for block \"" + instance.getBlock().toString()
+ + " for block \"" + wrapper.instance.getBlock()
+ "\" instantiated with name \"" + name + "\"", t);
}
}
@@ -258,45 +268,26 @@
/**
* <p>Push a new {@link Block} {@link Instance} into this {@link Runtime}.</p>
*/
- protected void putInstance(String name, Instance inst, Configuration conf) {
+ protected void addInstance(String name, Instance inst, Configuration conf)
+ throws DeployerException {
if (name == null) throw new NullPointerException("Null name");
if (inst == null) throw new NullPointerException("Null instance");
if (conf == null) throw new NullPointerException("Null config");
- this.wrappers.put(name, new Wrapper(inst, conf));
+ if (this.wrappers.get(name) != null) {
+ throw new DeployerException("Instance \"" + name + "\" aready added");
+ } else {
+ this.wrappers.put(name, new Wrapper(inst, conf));
+ }
- Iterator iterator = this.plugins.keySet().iterator();
+ Iterator iterator = this.plugins.iterator();
while (iterator.hasNext()) {
- String plugin = (String) iterator.next();
- Configuration curr = conf.child(plugin);
- ((Plugin)this.plugins.get(plugin)).notify(inst, curr);
+ Plugin plugin = (Plugin) iterator.next();
+ Configuration curr = conf.child(plugin.getConfigurationElement());
+ plugin.notify(inst, curr);
}
}
/**
- * <p>Return the {@link Block} associated with the given name.</p>
- */
- protected Block getBlock(String name) {
- Wrapper wrapper = (Wrapper) this.wrappers.get(name);
- return (wrapper == null? null : wrapper.instance.getBlock());
- }
-
- /**
- * <p>Return the {@link Instance} associated with the given name.</p>
- */
- protected Instance getInstance(String name) {
- Wrapper wrapper = (Wrapper) this.wrappers.get(name);
- return (wrapper == null? null : wrapper.instance);
- }
-
- /**
- * <p>Return the {@link Configuration} associated with the given name.</p>
- */
- protected Configuration getConfiguration(String name) {
- Wrapper wrapper = (Wrapper) this.wrappers.get(name);
- return (wrapper == null? null : wrapper.configuration);
- }
-
- /**
* <p>Return the {@link Library} associated with this {@link Runtime}.</p>
*/
protected Library getLibrary() {
@@ -317,40 +308,57 @@
/**
* <p>Instantiate a new component given its block instance and name.</p>
*/
- private Object instantiate(String name)
+ private Object newComponentInstance(Wrapper wrapper)
throws DeployerException {
- Instance instance = this.getInstance(name);
- if (instance == null) {
- throw new DeployerException("Invalid instance \"" + name + "\"");
- }
+ Instance instance = wrapper.instance;
+ Configuration configuration = wrapper.configuration;
+ String name = instance.getName();
- /* Prepare a new instance */
+ /* Prepare a new component instance */
Object component = null;
Class clazz = instance.getComponentClass();
+ Thread thread = Thread.currentThread();
+ ClassLoader context = thread.getContextClassLoader();
+ thread.setContextClassLoader(instance);
try {
component = clazz.newInstance();
} catch (Throwable t) {
throw new DeployerException("Can't instantiate " + clazz.getName(), t);
+ } finally {
+ thread.setContextClassLoader(context);
}
/* Configure this component instance */
- Configuration configuration = this.getConfiguration(name);
if (this.initializing.contains(name)) {
+ thread.setContextClassLoader(context);
throw new DeployerException("Circular dependancy found initializing "
+ "instance \"" + name + "\"");
} else {
this.initializing.add(name);
- Factory.configure(component, this, configuration);
+ /* Configure with the defaults and with the local configuration */
+ Configuration defaults = instance.getBlock().getComponentDefaults();
+ context = thread.getContextClassLoader();
+ thread.setContextClassLoader(instance);
+ try {
+ Factory.configure(component, this, defaults);
+ Factory.configure(component, this, configuration);
+ } finally {
+ thread.setContextClassLoader(context);
+ }
this.initializing.remove(name);
}
/* Initialize the component and prepare the wiring */
Method initializer = instance.getComponentInitializerMethod();
+ context = thread.getContextClassLoader();
+ thread.setContextClassLoader(instance);
try {
/* Non singletons will never have an initializer method set */
if (initializer != null) initializer.invoke(component, NULL);
} catch (Throwable t) {
throw new DeployerException("Can't initialize component " + name, t);
+ } finally {
+ thread.setContextClassLoader(context);
}
/* Return the initialized component */
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 Thu Nov 4 14:58:41 2004
@@ -14,6 +14,7 @@
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.util.HashSet;
@@ -109,7 +110,7 @@
+ block + " declared at " + current.location());
}
Instance instance = new Instance(deployer, (Block) descriptor, name);
- deployer.putInstance(name, instance, current);
+ deployer.addInstance(name, instance, current);
} catch (DeployerException e) {
throw e;
} catch (Throwable t) {
@@ -151,6 +152,9 @@
Object value = curr.getAttributeAs("value", type);
descr.getWriteMethod().invoke(obj, new Object[] { value });
continue;
+ } catch (InvocationTargetException e) {
+ throw new DeployerException("Unable to set value for property \""
+ + prop + "\" specified at " + curr.location(), e.getCause());
} catch (Throwable t) {
throw new DeployerException("Unable to set value for property \""
+ prop + "\" specified at " + curr.location(), t);
@@ -161,6 +165,9 @@
Object value = depl.lookup(curr.getStringAttribute("component"));
descr.getWriteMethod().invoke(obj, new Object[] { value });
continue;
+ } catch (InvocationTargetException e) {
+ throw new DeployerException("Unable to set component for property \""
+ + prop + "\" specified at " + curr.location(), e.getCause());
} catch (Throwable t) {
throw new DeployerException("Unable to set component for property \""
+ prop + "\" specified at " + curr.location(), t);
@@ -187,7 +194,9 @@
/* No exceptions, continue */
continue;
-
+ } catch (InvocationTargetException e) {
+ throw new DeployerException("Unable to set component for property \""
+ + prop + "\" specified at " + curr.location(), e.getCause());
} catch (Throwable t) {
throw new DeployerException("Unable to set component for property \""
+ prop + "\" specified at " + curr.location(), t);
@@ -200,6 +209,9 @@
Object value = Proxy.newProxyInstance(depl.getLoader(), i, w);
descr.getWriteMethod().invoke(obj, new Object[] { value });
continue;
+ } catch (InvocationTargetException e) {
+ throw new DeployerException("Unable to set kernel for property \""
+ + prop + "\" specified at " + curr.location(), e.getCause());
} catch (Throwable t) {
throw new DeployerException("Unable to set kernel for property \""
+ prop + "\" specified at " + curr.location(), 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 Thu Nov 4 14:58:41 2004
@@ -228,4 +228,57 @@
/* Pop from the dependencies check */
dependencies.pop(identifier);
}
+
+ /**
+ * <p>Return a {@link String} representation of this instance.</p>
+ */
+ public String toString() {
+ return(super.toString() + "{" + this.getName() + "}");
+ }
+
+ /**
+ * <p>Invert the {@link Class} load order of this {@link ClassLoader}.</p>
+ */
+ public synchronized Class loadClass(String name)
+ throws ClassNotFoundException {
+ return this.loadClass(name, false);
+ }
+
+ /**
+ * <p>Invert the {@link Class} load order of this {@link ClassLoader}.</p>
+ */
+ protected synchronized Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ Class clazz = findLoadedClass(name);
+ if (clazz != null) return(clazz);
+
+ /* Just in case some dummy put the kernel implementation in the path */
+ if ((name.equals("org.apache.cocoon.kernel.Kernel")) ||
+ (name.equals("org.apache.cocoon.kernel.KernelException")) ||
+ (name.startsWith("org.apache.cocoon.kernel.configuration.")) ||
+ (name.startsWith("org.apache.cocoon.kernel.startup"))) {
+ return super.loadClass(name, resolve);
+ }
+
+ try {
+ clazz= this.findClass(name);
+ } catch (ClassNotFoundException e) {
+ clazz = this.getParent().loadClass(name);
+ }
+
+ if (resolve) resolveClass(clazz);
+ return clazz;
+ }
+
+ /**
+ * <p>Invert the resource resolution order of this {@link ClassLoader}.</p>
+ */
+ public synchronized URL getResource(String name) {
+ URL url= null;
+
+ url= this.findResource(name);
+ if (url == null) url= this.getParent().getResource(name);
+
+ return url;
+ }
}
Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Block.java
==============================================================================
--- cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Block.java (original)
+++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/description/Block.java Thu Nov 4 14:58:41 2004
@@ -37,6 +37,8 @@
private Identifier[] implementations = null;
/** <p>The array of identifiers of all required modules.</p> */
private Identifier[] requirements = null;
+ /** <p>The default {@link Configuration} for components.</p> */
+ private Configuration defaults = null;
/**
* <p>Create a new {@link Block} instance.</p>
@@ -79,6 +81,9 @@
throw new DeployerException("Non-singleton component declares "
+ "initializer or destroyer method at " + provides.location());
}
+
+ /* The default configuration */
+ this.defaults = configuration.child(NAMESPACE, "defaults");
}
/**
@@ -100,6 +105,14 @@
*/
public String getComponentDestroyer() {
return(this.initializer);
+ }
+
+ /**
+ * <p>Return the default {@link Configuration} for instances of this
+ * {@link Block}.</p>
+ */
+ public Configuration getComponentDefaults() {
+ return(this.defaults);
}
/**
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 Thu Nov 4 14:58:41 2004
@@ -12,7 +12,12 @@
* =============================================================================== */
package org.apache.cocoon.kernel.description;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
import org.apache.cocoon.kernel.configuration.Configuration;
+import org.apache.cocoon.kernel.configuration.ConfigurationException;
import org.apache.cocoon.kernel.deployment.DeployerException;
/**
@@ -25,10 +30,8 @@
*/
public class Extension extends Descriptor {
- /** <p>The name of the provided Java plugin.</p> */
- private String clazz = null;
- /** <p>The name of the configuration element in the instances file.</p> */
- private String element = null;
+ /** <p>The class names of the provided Java plugins.</p> */
+ private String plugins[] = null;
/**
* <p>Create a new {@link Extension} instance.</p>
@@ -44,32 +47,30 @@
}
/* Plugin provision */
- Configuration plugin = configuration.child(NAMESPACE, "plugin");
- this.clazz = plugin.getStringAttribute("class", null);
-
- /* No class? Abstract block, only libraries */
- if (this.clazz == null) {
- throw new DeployerException("Extension descriptor does not specify "
- + " plugin class name at " + plugin.location());
+ Set classes = new HashSet();
+ Iterator iterator = configuration.children(NAMESPACE, "plugin");
+ while (iterator.hasNext()) try {
+ Configuration plugin = (Configuration) iterator.next();
+ classes.add(plugin.getStringAttribute("class"));
+ } catch (ConfigurationException exception) {
+ Configuration current = exception.getConfiguration();
+ if (current == null) current = configuration;
+ String message = "Extension descriptor does not specify plugin ";
+ message += "class name at " + current.location();
+ throw new DeployerException(message, exception);
}
-
- /* Process initializer, destroyer, and singleton */
- this.element = plugin.getStringAttribute("configuration-element", null);
+ this.plugins = new String[classes.size()];
+ this.plugins = (String []) classes.toArray(this.plugins);
+
+ /* Retrieve the plugin configuration element name */
+ configuration = configuration.child("configuration");
}
/**
* <p>Return the class name of the provided Java™ class.</p>
*/
- public String getPlugin() {
- return(this.clazz);
- }
-
- /**
- * <p>Return the name of the element to be looked up in the configuration file
- * containing the configuration of this plugin.</p>
- */
- public String getPluginConfigurationElement() {
- return(this.element);
+ public String[] getPluginClassNames() {
+ return(this.plugins);
}
/**
Modified: cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/AbstractPlugin.java
==============================================================================
--- cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/AbstractPlugin.java (original)
+++ cocoon/whiteboard/kernel/sources/runtime/org/apache/cocoon/kernel/plugins/AbstractPlugin.java Thu Nov 4 14:58:41 2004
@@ -24,20 +24,35 @@
* @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 {
+public abstract class AbstractPlugin extends Logger implements Plugin {
/** <p>The configured {@link StartupKernel} instance.</p> */
private StartupKernel kernel = null;
/** <p>The global plugin {@link Configuration} member.</p> */
private Configuration config = null;
+ /** <p>The element configuration name.</p> */
+ private String element = null;
/**
* <p>Create a new {@link AbstractPlugin} instance.</p>
*/
- public AbstractPlugin() {
- super();
+ protected AbstractPlugin() {
+ this(null);
}
+ /**
+ * <p>Create a new {@link AbstractPlugin} instance.</p>
+ */
+ protected AbstractPlugin(String element) {
+ this.element = element;
+ }
+
+ /**
+ * <p>Return the configuration element name associated with this plugin.</p>
+ */
+ public String getConfigurationElement() {
+ return this.element;
+ }
/**
* <p>Configure this plugin from a specified {@link Configuration}.</p>
*
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 Thu Nov 4 14:58:41 2004
@@ -38,6 +38,11 @@
public interface Plugin {
/**
+ * <p>Return the configuration element name associated with this plugin.</p>
+ */
+ public String getConfigurationElement();
+
+ /**
* <p>Configure this plugin from a specified {@link Configuration}.</p>
*/
public void configure(StartupKernel kernel, Configuration configuration);