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>&lt;time&gt;<i>current time</i>&lt;/time&gt;</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>
  &lt;init-param&gt;
    &lt;param-name&gt;load-class&lt;/param-name&gt;
    &lt;param-value&gt;
      &lt;!-- For IBM WebSphere: 
      com.ibm.servlet.classloader.Handler --&gt;
  
      &lt;!-- For Database Driver: --&gt;
      @database-driver@
          
      &lt;!-- For parent ComponentManager sample:
              This will cause the static initializer to run,
              and thus the Configuration object to be created
              and bound. --&gt;
      org.apache.cocoon.samples.parentcm.Configurator 
    &lt;/param-value&gt;
  &lt;/init-param&gt;</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>
  &lt;init-param&gt;
    &lt;param-name&gt;parent-component-manager&lt;/param-name&gt;
    &lt;param-value&gt;org.apache.cocoon.samples.parentcm.ParentComponentManager/(remove this line break)
  org/apache/cocoon/samples/parentcm/ParentCMConfiguration&lt;/param-value&gt;
  &lt;/init-param&gt;</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