You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by di...@apache.org on 2001/09/06 22:56:21 UTC
cvs commit: xml-cocoon2/xdocs parent-component-manager.xml docs-book.xml site-book.xml
dims 01/09/06 13:56:21
Modified: . build.xml
webapp sitemap.xmap
webapp/WEB-INF web.xml
webapp/docs/samples samples.xml
xdocs docs-book.xml site-book.xml
Added: src/org/apache/cocoon/samples/parentcm Configurator.java
Generator.java ParentComponentManager.java
Time.java TimeComponent.java
webapp/stylesheets/parentcm time.xsl
xdocs parent-component-manager.xml
Log:
Patch for "[Patch][Update] Parent Component Manager - updated documentation"
from "Leo Sutic" <le...@inspireinfrastructure.com>
Revision Changes Path
1.57 +7 -2 xml-cocoon2/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/build.xml,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- build.xml 2001/09/06 17:15:55 1.56
+++ build.xml 2001/09/06 20:56:21 1.57
@@ -425,16 +425,21 @@
<!-- =================================================================== -->
<target name="package" depends="compile" description="Generates the jar package">
<jar jarfile="${build.dir}/${name}.jar" manifest="${build.src}/Manifest.mf">
- <fileset dir="${build.dest}" includes="org/**"/>
+ <fileset dir="${build.dest}" includes="org/**" excludes="org/apache/cocoon/samples/**"/>
</jar>
</target>
<!-- =================================================================== -->
<!-- Copies the webapp directories -->
<!-- =================================================================== -->
- <target name="copy-webapp" depends="prepare">
+ <target name="copy-webapp" depends="prepare,compile">
<mkdir dir="${build.war}"/>
+ <mkdir dir="${build.war}/WEB-INF/classes"/>
+ <copy todir="${build.war}/WEB-INF/classes" filtering="off">
+ <fileset dir="${build.dest}" includes="org/apache/cocoon/samples/**"/>
+ </copy>
+
<copy todir="${build.war}" filtering="on">
<fileset dir="${webapp.dir}">
<exclude name="**/*.gif"/>
1.1 xml-cocoon2/src/org/apache/cocoon/samples/parentcm/Configurator.java
Index: Configurator.java
===================================================================
package org.apache.cocoon.samples.parentcm;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;
import org.apache.avalon.excalibur.naming.memory.MemoryInitialContextFactory;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
/**
* This class sets up the configuration used by the ParentComponentManager sample.
* The class also holds a reference to the initial context in which the configuration
* is available.
* <p>
* The configuration is bound to <code>org/apache/cocoon/samples/parentcm/ParentCMConfiguration</code>.
*
* @author <a href="leo.sutic@inspireinfrastructure.com">Leo Sutic</a>
*/
public class Configurator {
/**
* The Excalibur in-memory JNDI directory. Since the directory doesn't
* provide any persistence we must keep a reference to the initial context
* as a static member to avoid passing it around.
*/
public static Context initialContext = null;
static {
try {
//
// Create a new role.
//
DefaultConfiguration config = new DefaultConfiguration("roles", "");
DefaultConfiguration timeComponent = new DefaultConfiguration("role", "roles");
timeComponent.addAttribute("name", Time.ROLE);
timeComponent.addAttribute("default-class", TimeComponent.class.getName());
timeComponent.addAttribute("shorthand", "samples-parentcm-time");
config.addChild(timeComponent);
//
// Bind it - get an initial context.
//
Hashtable environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY, MemoryInitialContextFactory.class.getName());
initialContext = new InitialContext(environment);
//
// Create subcontexts and bind the configuration.
//
Context ctx = initialContext.createSubcontext("org");
ctx = ctx.createSubcontext("apache");
ctx = ctx.createSubcontext("cocoon");
ctx = ctx.createSubcontext("samples");
ctx = ctx.createSubcontext("parentcm");
ctx.rebind("ParentCMConfiguration", config);
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
1.1 xml-cocoon2/src/org/apache/cocoon/samples/parentcm/Generator.java
Index: Generator.java
===================================================================
package org.apache.cocoon.samples.parentcm;
import java.io.IOException;
import java.util.Map;
import java.util.Date;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.EntityResolver;
import org.xml.sax.SAXException;
import org.apache.avalon.framework.component.ComponentException;
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.parameters.Parameters;
import org.apache.avalon.excalibur.pool.Poolable;
import org.apache.cocoon.Constants;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.http.HttpRequest;
import org.apache.cocoon.environment.http.HttpResponse;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.generation.ComposerGenerator;
/**
* Generator for the parent component manager sample. The generator outputs
* a single tag <code><time><i>current time</i></time></code>.
* Where <code><i>current time</i></code> is the current time as obtained from the
* <code>Time</code> component.
*
* @author <a href="leo.sutic@inspireinfrastructure.com">Leo Sutic</a>
*/
public class Generator extends ComposerGenerator implements Poolable {
/**
* Current time.
*/
private Date time;
/**
* Looks up a <code>Time</code> component and obtains the current time.
*/
public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
throws ProcessingException, SAXException, IOException {
Time timeGiver = null;
try {
timeGiver = (Time) manager.lookup(Time.ROLE);
this.time = timeGiver.getTime ();
} catch (ComponentException ce) {
throw new ProcessingException ("Could not obtain current time.", ce);
} finally {
manager.release(timeGiver);
}
}
/**
* Generate XML data.
*/
public void generate() throws SAXException, ProcessingException {
AttributesImpl emptyAttributes = new AttributesImpl();
contentHandler.startDocument();
contentHandler.startElement("", "time", "time", emptyAttributes);
char[] text = this.time.toString().toCharArray();
contentHandler.characters(text, 0, text.length);
contentHandler.endElement("", "time", "time");
contentHandler.endDocument();
}
/**
* Prepare this object for another cycle.
*/
public void recycle () {
this.time = null;
}
}
1.1 xml-cocoon2/src/org/apache/cocoon/samples/parentcm/ParentComponentManager.java
Index: ParentComponentManager.java
===================================================================
package org.apache.cocoon.samples.parentcm;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;
import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
import org.apache.avalon.excalibur.naming.memory.MemoryInitialContextFactory;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.logger.Loggable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.log.Logger;
/**
* A sample parent component manager. This manager will lookup the configuration object
* given by the initialization parameter in JNDI, use it to configure an ExcaliburComponentManager
* and delegate any requests to it.
*
* @author <a href="leo.sutic@inspireinfrastructure.com">Leo Sutic</a>
*/
public class ParentComponentManager implements ComponentManager, Loggable, Initializable {
/**
* Our logger.
*/
private Logger logger;
/**
* The JNDI name where the component manager configuration can be found.
*/
private final String jndiName;
/**
* The delegate that will be configured and provide the
* functionality for this component manager.
*/
private final ExcaliburComponentManager delegate;
public ParentComponentManager(final String jndiName) {
this.jndiName = jndiName;
// Initialize it here so we can let it be final.
this.delegate = new ExcaliburComponentManager();
}
public boolean hasComponent(final String role) {
return delegate.hasComponent(role);
}
/**
* Initializes the CM by looking up the configuration object and using it to
* configure the delegate.
*/
public void initialize() throws Exception {
this.logger.debug("Looking up component manager configuration at : " + this.jndiName);
Hashtable environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY, MemoryInitialContextFactory.class.getName());
//
// Yes, this is cheating, but the Excalibur in-memory naming provider
// is transient. That is, it doesn't store objects persistently and
// is more like a HashMap.
//
// Should be:
// Context initialContext = new InitialContext(environment);
//
Context initialContext = Configurator.initialContext;
Configuration config = (Configuration) initialContext.lookup(this.jndiName);
// We ignore the setRoleManager call, as ExcaliburComponentManager handles that
// in configure().
this.delegate.setLogger(logger);
this.delegate.contextualize(new DefaultContext());
this.delegate.configure(config);
this.delegate.initialize();
this.logger.debug("Component manager successfully initialized.");
}
public Component lookup(final String role) throws ComponentException {
return this.delegate.lookup(role);
}
public void release(final Component component) {
this.delegate.release(component);
}
public void setLogger(final Logger logger) {
this.logger = logger;
}
}
1.1 xml-cocoon2/src/org/apache/cocoon/samples/parentcm/Time.java
Index: Time.java
===================================================================
package org.apache.cocoon.samples.parentcm;
import java.util.Date;
import org.apache.avalon.framework.component.Component;
/**
* Interface for a simple time-keeping component.
*/
public interface Time extends Component {
public final static String ROLE = "org.apache.cocoon.samples.parentcm.Time";
/**
* Gets the current time.
*/
public Date getTime ();
}
1.1 xml-cocoon2/src/org/apache/cocoon/samples/parentcm/TimeComponent.java
Index: TimeComponent.java
===================================================================
package org.apache.cocoon.samples.parentcm;
import java.util.Date;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.thread.ThreadSafe;
/**
* Implementing class for the parent component manager sample's
* <code>org.apache.cocoon.samples.parentcm.Time</code> component.
*/
public class TimeComponent implements Component, Time, ThreadSafe {
public Date getTime () {
return new Date();
}
}
1.49 +26 -18 xml-cocoon2/webapp/sitemap.xmap
Index: sitemap.xmap
===================================================================
RCS file: /home/cvs/xml-cocoon2/webapp/sitemap.xmap,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- sitemap.xmap 2001/09/06 14:19:46 1.48
+++ sitemap.xmap 2001/09/06 20:56:21 1.49
@@ -19,6 +19,7 @@
<map:generator name="velocity" src="org.apache.cocoon.generation.VelocityGenerator"/>
<map:generator name="jsp" src="org.apache.cocoon.generation.JspGenerator"/>
<map:generator name="stream" src="org.apache.cocoon.generation.StreamGenerator"/>
+ <map:generator name="parentcm" src="org.apache.cocoon.samples.parentcm.Generator"/>
</map:generators>
<map:transformers default="xslt">
@@ -549,7 +550,7 @@
<map:act type="form-validator">
<map:parameter name="descriptor" value="context:///docs/samples/formvalidation/descriptor.xml"/>
<map:parameter name="validate-set" value="car-reservation"/>
- <map:redirect-to resource="dynamic-page" target="docs/samples/formvalidation/OK"/>
+ <map:redirect-to resource="dynamic-page" target="docs/samples/formvalidation/OK"/>
</map:act>
<map:redirect-to resource="dynamic-page" target="docs/samples/formvalidation/ERROR"/>
</map:match>
@@ -575,22 +576,22 @@
<map:act type="session-isvalid">
<map:match type="sessionstate" pattern="1">
- <map:match type="next-page" pattern="1">
- <map:redirect-to resource="dynamic-page1" target="docs/samples/session-state"/>
- </map:match>
- <map:match type="next-page" pattern="2">
- <map:redirect-to resource="dynamic-page1" target="docs/samples/session-state"/>
- </map:match>
- </map:match>
+ <map:match type="next-page" pattern="1">
+ <map:redirect-to resource="dynamic-page1" target="docs/samples/session-state"/>
+ </map:match>
+ <map:match type="next-page" pattern="2">
+ <map:redirect-to resource="dynamic-page1" target="docs/samples/session-state"/>
+ </map:match>
+ </map:match>
<map:match type="sessionstate" pattern="2">
- <map:match type="next-page" pattern="1">
- <map:redirect-to resource="dynamic-page1" target="docs/samples/session-state"/>
- </map:match>
- <map:match type="next-page" pattern="2">
- <map:redirect-to resource="dynamic-page1" target="docs/samples/session-state"/>
- </map:match>
- </map:match>
+ <map:match type="next-page" pattern="1">
+ <map:redirect-to resource="dynamic-page1" target="docs/samples/session-state"/>
+ </map:match>
+ <map:match type="next-page" pattern="2">
+ <map:redirect-to resource="dynamic-page1" target="docs/samples/session-state"/>
+ </map:match>
+ </map:match>
<map:redirect-to resource="dynamic-page2" target="docs/samples/session-state/state0"/>
</map:act>
@@ -637,13 +638,13 @@
<!-- ========================== SOAP ============================== -->
<map:match pattern="soap/*.xsp">
- <map:generate type="serverpages" src="docs/samples/soap/{1}.xml"/>
- <map:transform src="docs/samples/soap/{1}.xsl"/>
+ <map:generate type="serverpages" src="docs/samples/soap/{1}.xml"/>
+ <map:transform src="docs/samples/soap/{1}.xsl"/>
<map:serialize/>
</map:match>
<map:match pattern="soap/service/*.xsp">
- <map:generate type="serverpages" src="docs/samples/soap/service/{1}.xml"/>
+ <map:generate type="serverpages" src="docs/samples/soap/service/{1}.xml"/>
<map:serialize type="xml"/>
</map:match>
@@ -655,6 +656,13 @@
</map:generate>
<map:transform src="stylesheets/news/news.xsl"/>
<map:serialize type="html"/>
+ </map:match>
+
+ <!-- ========================= Parent Component Manager ================================ -->
+ <map:match pattern="parentcm">
+ <map:generate type="parentcm" src="{1}"/>
+ <map:transform src="stylesheets/parentcm/time.xsl"/>
+ <map:serialize/>
</map:match>
<!-- ========================= Server ================================ -->
1.13 +8 -1 xml-cocoon2/webapp/WEB-INF/web.xml
Index: web.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/webapp/WEB-INF/web.xml,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- web.xml 2001/09/04 12:13:37 1.12
+++ web.xml 2001/09/06 20:56:21 1.13
@@ -115,6 +115,9 @@
<!-- For Database Driver: -->
@database-driver@
+
+ <!-- For parent ComponentManager sample: -->
+ org.apache.cocoon.samples.parentcm.Configurator
</param-value>
</init-param>
@@ -176,10 +179,14 @@
Cocoon honors the Loggable and Initializable interfaces for this class,
if it implements them.
+
+ Currently the parent CM is set to the Parent CM sample, which will look up
+ a configuration via JNDI at org/apache/cocoon/samples/parentcm/ParentCMConfiguration
+ and use it.
-->
<init-param>
<param-name>parent-component-manager</param-name>
- <param-value>org.apache.cocoon.components.ParentComponentManager/InitParameter</param-value>
+ <param-value>org.apache.cocoon.samples.parentcm.ParentComponentManager/org/apache/cocoon/samples/parentcm/ParentCMConfiguration</param-value>
</init-param>
<!--
1.13 +13 -8 xml-cocoon2/webapp/docs/samples/samples.xml
Index: samples.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/webapp/docs/samples/samples.xml,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- samples.xml 2001/09/01 09:30:05 1.12
+++ samples.xml 2001/09/06 20:56:21 1.13
@@ -82,11 +82,11 @@
Example of complex XSLT usage.
</sample>
<sample name="SVG welcome page" href="welcome-svg">
- A version of this page rendered as a series of SVG
- images embedded within an HTML page. This example
- uses the 'fragment extractor' transformer and generator
- to automatically extract the images and feed them through
- a separate pipeline.
+ A version of this page rendered as a series of SVG
+ images embedded within an HTML page. This example
+ uses the 'fragment extractor' transformer and generator
+ to automatically extract the images and feed them through
+ a separate pipeline.
</sample>
<sample name="sub sitemap" href="sub/welcome">
Example of a page served by a sub sitemap.
@@ -139,13 +139,18 @@
<sample name="Yahoo Screen Scrape" href="yahoo">
An example of HTML Generator scraping a part of the Yahoo main page.
</sample>
+ <sample name="Parent Component Manager" href="parentcm">
+ An example showing the use of a parent component manager. For this sample to work,
+ Cocoon2 must have been built with the include.webapp.libs flag set to true. (Otherwise
+ the sample classes are not found.)
+ </sample>
</group>
<group name="Web Applications">
<sample name="Protected Area" href="protected/login">
- An example web-application built around db-authenticator,
- form-validator, session-validator and session-invalidator
- actions.
+ An example web-application built around db-authenticator,
+ form-validator, session-validator and session-invalidator
+ actions.
</sample>
</group>
1.1 xml-cocoon2/webapp/stylesheets/parentcm/time.xsl
Index: time.xsl
===================================================================
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head>
<title>Sample of Parent Component Managers</title>
</head>
<body alink="#743e75" vlink="#00698c" link="#0086b2" bgcolor="#ffffff">
<table width="100%" height="100%">
<tr>
<td valign="center" align="center">
<table bgcolor="#000000" border="0" cellspacing="2" cellpadding="2" align="center">
<tr>
<td bgcolor="#0086b2" width="100%" align="left">
<font size="+1" face="arial,helvetica,sanserif" color="#ffffff">Current Time</font>
</td>
</tr>
<tr>
<td width="100%" bgcolor="#ffffff" align="center">
<p>
<font color="#000000" face="arial,helvetica,sanserif" size="+0">
The time below was obtained from a component managed by Cocoon2's parent component manager.<br/>
See <a href="documents/parent-component-manager">parent-component-manager.xml</a> for more information.
</font>
</p>
<p>
<font color="#000000" face="arial,helvetica,sanserif" size="+4">
<xsl:value-of select="time"/>
</font>
</p>
<p>
<font color="#000000" face="arial,helvetica,sanserif" size="+0">
<a href="./">Back</a>
</font>
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
1.27 +1 -0 xml-cocoon2/xdocs/docs-book.xml
Index: docs-book.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/xdocs/docs-book.xml,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- docs-book.xml 2001/09/05 12:14:13 1.26
+++ docs-book.xml 2001/09/06 20:56:21 1.27
@@ -73,6 +73,7 @@
<page id="datasources" label="Using Databases" source="datasources.xml"/>
<page id="extending" label="Extending C2" source="extending.xml"/>
<page id="avalon" label="Avalon" source="avalon.xml"/>
+ <page id="parent-component-manager" label="Parent CM" source="parent-component-manager.xml"/>
<page id="i18n" label="Internationalization" source="i18n-transformer.xml"/>
<separator/>
<page id="xsp" label="XSP" source="xsp.xml"/>
1.29 +1 -0 xml-cocoon2/xdocs/site-book.xml
Index: site-book.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/xdocs/site-book.xml,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- site-book.xml 2001/09/05 12:14:13 1.28
+++ site-book.xml 2001/09/06 20:56:21 1.29
@@ -75,6 +75,7 @@
<page id="datasources" label="Using Databases" source="datasources.xml"/>
<page id="extending" label="Extending C2" source="extending.xml"/>
<page id="avalon" label="Avalon" source="avalon.xml"/>
+ <page id="parent-component-manager" label="Parent CM" source="parent-component-manager.xml"/>
<page id="i18n" label="Internationalization" source="i18n-transformer.xml"/>
<separator/>
<page id="xsp" label="XSP" source="xsp.xml"/>
1.1 xml-cocoon2/xdocs/parent-component-manager.xml
Index: parent-component-manager.xml
===================================================================
<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "dtd/document-v10.dtd">
<document>
<header>
<title>Parent Component Manager</title>
<subtitle>in @doctitle@</subtitle>
<version>0.9</version>
<type>Technical document</type>
<authors>
<person name="Leo Sutic" email="leo.sutic@inspireinfrastructure.com"/>
</authors>
<abstract>This document describes how to use a parent component manager in @docname@.</abstract>
</header>
<body>
<s1 title="Parent Component Manager">
<p>When using Cocoon2 it is sometimes neccessary to obtain
components from other sources than the <code>user.roles</code> file,
or preferable to have a common component manager for several web applications.</p>
<p>The pattern chosen for Cocoon is the dynamic loading of a component manager class.
The initialization parameter parent-component-manager in web.xml specifies a class
that will be loaded, instantiated and used as a parent component manager for
Cocoon's component manager.</p>
<p>The recommended procedure is for the class, when it is initialized, to create a
delegate in the form of an <code>ExcaliburComponentManager</code>, configure it
by looking up a <code>Configuration</code> object via JNDI, and delegate any requests to it.</p>
<p>In order to provide a way to pass parameters to the parent component manager class
(the class specified in parent-component-manager), Cocoon will instantiate the class
via the constructor that takes a single <code>String</code> argument, passing
anything to the right of the first <code>'/'</code> in the parameter value to the
constructor. Subsequently Cocoon examines whether the class implements
<code>org.apache.avalon.framework.logger.Loggable</code> and/or
<code>org.apache.avalon.framework.activity.Initializable</code> and calls
<code>setLogger</code> and/or <code>initialize</code>, as appropriate.
The instance is then used as a parent component manager.
</p>
<p>Since that didn't make much sense in itself, let's look at the sample.</p>
<p>The goal is to define a component that can give us the time of day and
let it be managed by a parent component manager.</p>
<p>So, first we need to put a Configuration object into JNDI, and then
grab that object, use it to configure an ExcaliburComponentManager,
and pass on any requests to that manager.</p>
<s2 title="Step 1: Creating a configuration object">
<p>We'll do this the quick and dirty way. The static initializer of a class
will create a Configuration instance with a single role and bind it
to <code>org/apache/cocoon/samples/parentcm/ParentCMConfigration</code>.
</p>
<p>The following code was taken from org/apache/cocoon/samples/parentcm/Configurator.java</p>
<source>
public class Configurator {
static {
try {
//
// Create a new role.
//
DefaultConfiguration config = new DefaultConfiguration("roles", "");
DefaultConfiguration timeComponent = new DefaultConfiguration("role", "roles");
timeComponent.addAttribute("name", Time.ROLE);
timeComponent.addAttribute("default-class", TimeComponent.class.getName());
timeComponent.addAttribute("shorthand", "samples-parentcm-time");
config.addChild(timeComponent);
//
// Bind it - get an initial context.
//
Hashtable environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY,
MemoryInitialContextFactory.class.getName());
initialContext = new InitialContext(environment);
//
// Create subcontexts and bind the configuration.
//
Context ctx = initialContext.createSubcontext("org");
ctx = ctx.createSubcontext("apache");
ctx = ctx.createSubcontext("cocoon");
ctx = ctx.createSubcontext("samples");
ctx = ctx.createSubcontext("parentcm");
ctx.rebind("ParentCMConfiguration", config);
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}</source>
<p>To make sure the static initializer runs we make Cocoon force-load the class
by making a change to the web.xml file:</p>
<source>
<init-param>
<param-name>load-class</param-name>
<param-value>
<!-- For IBM WebSphere:
com.ibm.servlet.classloader.Handler -->
<!-- For Database Driver: -->
@database-driver@
<!-- For parent ComponentManager sample:
This will cause the static initializer to run,
and thus the Configuration object to be created
and bound. -->
org.apache.cocoon.samples.parentcm.Configurator
</param-value>
</init-param></source>
</s2>
<s2 title="Step 2: Write the component manager">
<p>Now that the configuration object is sitting there waiting for us, let's craft
the component manager. Please see the file org/apache/cocoon/samples/parentcm/ParentComponentManager.java
for an example. It is too much to paste in here.</p>
</s2>
<s2 title="Step 3: Tell Cocoon to use the component manager">
<p>Change the web.xml file to:</p>
<source>
<init-param>
<param-name>parent-component-manager</param-name>
<param-value>org.apache.cocoon.samples.parentcm.ParentComponentManager/(remove this line break)
org/apache/cocoon/samples/parentcm/ParentCMConfiguration</param-value>
</init-param></source>
<p>Cocoon will now do the following: First, it will split the parameter value at the first slash,
in this case ending up with the strings <code>"org.apache.cocoon.samples.parentcm.ParentComponentManager"</code>
and <code>"org/apache/cocoon/samples/parentcm/ParentCMConfiguration"</code>. The first string is the
class to instantiate. The second is the parameter that will be passed to the constructor.</p>
<p>Next, Cocoon loads the component manager class and uses reflection to find a constructor that
will accept a single <code>String</code> argument. Upon finding one, it instantiates the
class in a manner similar to:</p>
<source>
ComponentManager cm = new
org.apache.cocoon.samples.parentcm.ParentComponentManager(
"org/apache/cocoon/samples/parentcm/ParentCMConfiguration");</source>
<p>
After this Cocoon checks whether the parent component manager class implements <code>Initializable</code> and/or
<code>Loggable</code>. Since the <code>ParentComponentManager</code> class implements both, Cocoon
does the following (with simplification):
</p>
<source>
((Loggable) cm).setLogger(logger);
((Initializable) cm).initialize();</source>
<p>Finally, the instance is used as parent component manager of Cocoon's own component manager.</p>
</s2>
<s2 title="Step 4: Use the component">
<p>Cocoon2 components can now use the ComponentManager given to them by Cocoon to look up the
component managed by the parent component manager:</p>
<p>The following code was taken from org/apache/cocoon/samples/parentcm/Generator.java</p>
<source>
public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
throws ProcessingException, SAXException, IOException {
Time timeGiver = null;
try {
timeGiver = (Time) manager.lookup(Time.ROLE);
this.time = timeGiver.getTime ();
} catch (ComponentException ce) {
throw new ProcessingException ("Could not obtain current time.", ce);
} finally {
manager.release(timeGiver);
}
}</source>
</s2>
<p>And that concludes the tour. A parent component manager was initialized with a configuration
obtained via JNDI and its components used by a Cocoon generator.</p>
</s1>
</body>
</document>
----------------------------------------------------------------------
In case of troubles, e-mail: webmaster@xml.apache.org
To unsubscribe, e-mail: cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org