You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cocoon.apache.org by Jo...@o2.com on 2003/01/28 08:21:10 UTC

@Geoff: Different stylesheets called on runtime?

Hi Geoff,

thanks for your help again. I had a day off, so there was no response from
me. And my mail yesterday did't seem to come through somehow.


I still don't get a couple of parts from your answer:

/********************************************* the
class***********************************************************/

package o2germany.SolutionDelivery.FraudManagement.actions;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentSelector;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.activity.Disposable;

import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.acting.ConfigurableComposerAction;

import org.apache.avalon.excalibur.datasource.DataSourceComponent;

public class StylesheetSelection extends ConfigurableComposerAction
implements
Disposable {

  protected ComponentSelector dbselector;
  DataSourceComponent datasource;

  public Map act(Redirector redirector, SourceResolver resolver,
MapobjectModel,
  String source, Parameters parameters) throws Exception {
  HashMap results = new HashMap();
  Request request = ObjectModelHelper.getRequest(objectModel);

  // Get the passed parameters (if there are any)
  int whichXSL;

  String report_id = request.getParameter("report_id");
  String service_id = request.getParameter("service_id");
  String nbt_pattern_id = request.getParameter("nbt_pattern_id");
  String search_txt = request.getParameter("search_txt");

  // Check against a database, bla, bla
  //    e.g whichXSL = 2;
 ...
  whichXSL = 2;
...
  // Now I want to choose the suitable XSL
  if( whichXSL == 1)
    // Choose number1.xsl
    results.put("number1");
  else if( whichXSL == 2)
    // Choose number2.xsl
    results.put("number2");
  else if( whichXSL == 3)
    // Choose number3.xsl
    results.put("number3");
  else
    results.put("default");

  return results;
}

/*****************************************************************************************************/


But I don't still get where to place these methods (and what they are):

/*****************************************************************************************************/
public void compose(ComponentManager manager) throws ComponentException
{
 ...
}

public void configure(Configuration conf) throws ConfigurationException
{
  ...
}

public void dispose()
{
 ...
}

/*****************************************************************************************************/
Where do they belong???

Is the sql-Part in the class or somwhere else?
...
 String nbt_pattern_id = request.getParameter("nbt_pattern_id");
 String search_txt = request.getParameter("search_txt");

  // Check against a database, bla, bla
  //    XXXXXXXXXXXX        should the sql be in here
XXXXXXXXXXXX ;
 ...
  whichXSL = 2;
...

I'm asking because you put the sql-part to the end.


Cheers
Jonny

----------------------------------------------------------------------------------------------------

This electronic message contains information from the mmo2 plc Group which
may be
privileged or confidential. The information is intended to be for the use
of the
individual(s) or entity named above. If you are not the intended recipient
be aware
that any disclosure, copying, distribution or use of the contents of this
information
is prohibited. If you have received this electronic message in error,
please notify
us by telephone or email (to the numbers or address above) immediately.



|---------+---------------------------->
|         |           "Geoff Howard"   |
|         |           <cocoon@leveragew|
|         |           eb.com>          |
|         |                            |
|         |           01/23/03 10:24 PM|
|         |           Please respond to|
|         |           cocoon-users     |
|         |                            |
|---------+---------------------------->
  >------------------------------------------------------------------------------------------------------------------------------|
  |                                                                                                                              |
  |       To:       <co...@xml.apache.org>                                                                                |
  |       cc:                                                                                                                    |
  |       Subject:  RE: Different stylesheets called on runtime?                                                                 |
  >------------------------------------------------------------------------------------------------------------------------------|




> -----Original Message-----
> From: Johannes.Becker@o2.com [mailto:Johannes.Becker@o2.com]
> Sent: Thursday, January 23, 2003 11:42 AM
> To: cocoon-users@xml.apache.org
> Subject: RE: Different stylesheets called on runtime?
>
> Hi Geff,
>
> thanks for your help. Ok.

Sure.  Ok,

>
> Example:
> _____________________________________________________________
> My XSP, that should choose which XSL to use.:

As an xsp is usually used to create a generator, you don't want to use it
to
select anything about pipeline behavior.  You can write actions in xsp, but
for now that will probably confuse things.  So, you'll take the logic from
the xsp you had, and reuse it in an action.

Before getting into that, though look at the sitemap.  I think Christian
already gave you your answer there but again, you'll want to do something
like this:

>
> Part of sitemap:
> ...
> <map:match pattern="differentXSLs">
<!-- you'll now need to strip out the transformer selection logic from the
xsp
  and just generate the xml that your xsl needs -->
>    <map:generate type="serverpages" src="differentXSLs.xsp"/>
     <map:act type="myAction">
>             <map:transform src="{whichXSL}.xsl"/>
>              ...
>             <map:serialize/>
             </map:act>
<!-- normally you'd put fall back behavior here - executed only when the
action
  fails.  For the example though we'll just make the action always
succeed.
  You may want to change things around - putting everything inside
the
action tag,
  putting only the transform in the action tag.  For the
example it doesn't
matter though.
 -->
> </map:match>
> ....
>
> So how and where should I place my action (and how should it look like)?
If you mean the compiled action, it goes in WEB-INF/classes or inside a jar
in
WEB-INF/lib

> How should my xsl look like then?
this shouldn't have to change.

Now the java action.  this is more complicated than I originally indicated
because of the database access, but it's still not that bad.  I simplified
a
few things, but resisted the urge to dumb it down.  For instance, you could
hard code the datasource name and get rid of configure().  You could skip
dispose() but I think that would lead to memory problems.  (avalon gurus -
is that right?) I have combined this quickly from a DB Action super class I
have and one subclass.

When this is compiled, it gets defined in the map:components section of the
sitemap:
<map:actions> ....
 <map:act name="myAction" src="you.yourcompany.acting.YourAction"
logger="sitemap.whateveryouwant"/>
....


package you.yourcompany.acting;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentSelector;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.activity.Disposable;

import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.acting.ConfigurableComposerAction;

import org.apache.avalon.excalibur.datasource.DataSourceComponent;

public class YourAction extends ConfigurableComposerAction implements
Disposable {

    protected ComponentSelector dbselector;
    DataSourceComponent datasource;

  public Map act(Redirector redirector, SourceResolver resolver, Map
objectModel,
                         String source, Parameters parameters) throws
Exception {
      HashMap results = new HashMap();
      Request request = ObjectModelHelper.getRequest(objectModel);

>       <!-- Get the passed parameters (if there are any) -->
>      int whichXSL;
>
>       String report_id = request.getParameter("report_id");
>       String service_id = request.getParameter("service_id");
>       String nbt_pattern_id = request.getParameter("nbt_pattern_id");
>       String search_txt = request.getParameter("search_txt");
>       ...
>
>      // Check against a database, bla, bla
>      ...
>
>
>     // Now I want to choose the suitable XSL
>     if( whichXSL == 1)
>       // Choose number1.xsl
                         results.put("number1");
>    else if( whichXSL == 2)
>       // Choose number2.xsl
                         results.put("number2");
>   else if( whichXSL == 3)
>       // Choose number3.xsl
                         results.put("number3");
    else {
             results.put("default");
             // not strictly necessary
             // could also return null to signal sitemap to execute
fallback.  up to
you.
    }
>    ...

  return results;
  } // end of act()

// Now, you glossed over the database stuff but there's a few methods
you'll
need to
// handle that.  They will be called by cocoon during the normal component
lifecycle
// and are designed to give us a chance to get at the resources and
information we need.

    /**
     * Compose the Actions so that we can select our databases.
     */
    public void compose(ComponentManager manager) throws ComponentException
{
        this.dbselector = (ComponentSelector)
manager.lookup(DataSourceComponent.ROLE + "Selector");
        super.compose(manager);
    }

             /**
              * Configure lets you specify which datasource to use in the
sitemap
component
              * definition rather than hardcoded in the compiled source
       *
              */
    public void configure(Configuration conf) throws ConfigurationException
{
      super.configure(conf);
      datasource = null;
      String dataSourceConfig = (String)settings.get("data-source");
      try {
                 datasource = (DataSourceComponent)
dbselector.select(dataSourceConfig);
                 getLogger().debug("DB Action using datasource: " +
dataSourceConfig);
      } catch(ComponentException e) {
                 getLogger().warn("Could not get data-source '" +
dataSourceConfig + "'
configured for DB Action");
      }
    }

             /**
              * This is called when the instance of this action is taken
out of the
pool.
       * Releasing resources is a good idea here.
              *
              */
    public void dispose() {
      this.datasource = null;
      this.dbselector = null;
    }

Now, the database stuff would happen like this:

             String sql = "select something from somewhere";

      try {
                   Connection conn = this.datasource.getConnection();
                   PreparedStatement statement = null;
                   statement = conn.prepareStatement(sql);
                         // normal jdbc stuff

                   }
                         */
      } catch(SQLException sqle) {
                   getLogger().error("SQL Exception: " + sqle.getMessage
());
                   getLogger().error("SQL State: " + sqle.getSQLState());
                   // return null; - if you want to have the sitemap do the
fallback on
sql errors
      }

That's it.  Feel free to point out the stuff that makes no sense.  It's
easier to answer specific questions than to try to write a whole tutorial
here (though this could get turned into one)

Geoff

>
> Cheers
> Jonny


---------------------------------------------------------------------
Please check that your question  has not already been answered in the
FAQ before posting.     <http://xml.apache.org/cocoon/faq/index.html>

To unsubscribe, e-mail:     <co...@xml.apache.org>
For additional commands, e-mail:   <co...@xml.apache.org>






---------------------------------------------------------------------
Please check that your question  has not already been answered in the
FAQ before posting.     <http://xml.apache.org/cocoon/faq/index.html>

To unsubscribe, e-mail:     <co...@xml.apache.org>
For additional commands, e-mail:   <co...@xml.apache.org>


RE: @Geoff: Different stylesheets called on runtime?

Posted by Geoff Howard <co...@leverageweb.com>.
I'm sorry I haven't gotten back - I saw this message yesterday (?) but
couldn't remember enough of the situation we were talking about to get back
to it quickly.  All of a sudden I have a lot of work and full time job
offers coming in at once and have needed to sort them through.  Anyone want
to hire a cocoon developer in D.C.?

Anyway, I'll make a quick not thought out answer below and then get back
later if that doesn't help:

> -----Original Message-----
> From: Johannes.Becker@o2.com [mailto:Johannes.Becker@o2.com]
> Sent: Tuesday, January 28, 2003 2:21 AM
> To: cocoon-users@xml.apache.org
> Subject: @Geoff: Different stylesheets called on runtime?


<snip/>
>   // Now I want to choose the suitable XSL
>   if( whichXSL == 1)
>     // Choose number1.xsl
>     results.put("number1");
>   else if( whichXSL == 2)
>     // Choose number2.xsl
>     results.put("number2");
>   else if( whichXSL == 3)
>     // Choose number3.xsl
>     results.put("number3");
>   else
>     results.put("default");
>
>   return results;
> }

results is a Map, so you need to give it key-value pairs.  Sorry if I wrote
the snippet above, must have been not thinking clearly.
results.put("xsl-choice","number1") and results.put("xsl-choice","number2")
and so on.  Then, in the sitemap you'll then refer to the value assigned by
your action using {xsl-choice}.

>
> But I don't still get where to place these methods (and what they are):
>
> /*****************************************************************
************************************/
> public void compose(ComponentManager manager) throws ComponentException
> {
>  ...
> }
>
> public void configure(Configuration conf) throws ConfigurationException
> {
>   ...
> }
>
> public void dispose()
> {
>  ...
> }
>
> /*****************************************************************
************************************/

Ok, they are defined as part of the component lifecycle in cocoon, which is
based on Avalon.  There is some information in the docs and at
jakarta.apache.org/avalon. But the brief story is:
1) Compose gives you access to the ComponentManager during the
initialization of this action.  You use this to get access to any other
Components that you need for your action.  In your case, this will be a
datasource component, which will let you select by name the jdbc connection
you set up in cocoon.xconf.  remember that cocoon can pool them, and so may
create a pool of 4 YourAction objects at startup, and may create more if
they are ever all busy.
2) Configure gives you access to the configuration you do when you define
this action in the sitemap inside <map:actions>  for instance, instead of
hardcoding the name of my jdbc connection, I set up the action using
<map:action ...><data-source>myjdbcname</data-source></map:action>.  This is
also called during initialization of the action, and it is called after
Compose.
3) Dispose give you a chance to clean up any resources held in instance
variables before the container shuts down an action instance.  Since the
first two methods above usually populate some instance variable, you'll want
to release them and clean up before shutting down.

> Where do they belong???

I think you mean where do you make calls to them, and the answer is that you
don't call them.  They are life-cycle call back methods used by the
container that creates, maintains and destroys instances of your action
class.  This is a defining characteristic of component based architectures,
and is similar in concept to EJB if you are familiar at all with that.

>
> Is the sql-Part in the class or somwhere else?
> ...
>  String nbt_pattern_id = request.getParameter("nbt_pattern_id");
>  String search_txt = request.getParameter("search_txt");
>
>   // Check against a database, bla, bla
>   //    XXXXXXXXXXXX        should the sql be in here
> XXXXXXXXXXXX ;
>  ...
>   whichXSL = 2;
> ...

Yes, that's where you'd actually do your database work.  The lifecycle
methods will leave you with an instance variable reference to a Datasource,
from which you can get a pooled connection, so you'd start out your "bla,
bla" section with something like

java.sql.Connection conn = datasource.getConnection();

and then it's straight jdbc from there.

>
> I'm asking because you put the sql-part to the end.

I can't remember what in the world I sent you unfortunately.  I'll check it
out later and see if I can see where I confused you.  In the mean time, I'm
copying below a superclass I use for database actions that I write.  If an
avalon/cocoon guru is listening, I'd love confirmation that I'm doing the
right thing in dispose() by just null-ing them.

Ah, ah, ah.  I just notice you have everything I wrote below.  Ok, don't
know why i didn't notice the results.put problem before but definitely do
what I said above (note that I used a different "key" value above than I did
originally below (in the sitemap snippet).

And now I see what you mean about the sql section I put at the end.  The
three methods are followed in my mail by just a floating snippet of java
that would go in the "bla, bla" section just as you guessed above.  I see
why that was confusing.

I also see that I sent you a sample which inlined the methods in my abstract
class I was going to send, so I won't confuse things now by including it.
If you want it, just say so and I'll send it as an attachment.

Geoff

>
>
> Cheers
> Jonny
>
> ------------------------------------------------------------------
> ----------------------------------
>
> This electronic message contains information from the mmo2 plc Group which
> may be
> privileged or confidential. The information is intended to be for the use
> of the
> individual(s) or entity named above. If you are not the intended recipient
> be aware
> that any disclosure, copying, distribution or use of the contents of this
> information
> is prohibited. If you have received this electronic message in error,
> please notify
> us by telephone or email (to the numbers or address above) immediately.
>
>
>
> |---------+---------------------------->
> |         |           "Geoff Howard"   |
> |         |           <cocoon@leveragew|
> |         |           eb.com>          |
> |         |                            |
> |         |           01/23/03 10:24 PM|
> |         |           Please respond to|
> |         |           cocoon-users     |
> |         |                            |
> |---------+---------------------------->
>
> >-----------------------------------------------------------------
> -------------------------------------------------------------|
>   |
>                                                                |
>   |       To:       <co...@xml.apache.org>
>                                                                |
>   |       cc:
>                                                                |
>   |       Subject:  RE: Different stylesheets called on runtime?
>                                                                |
>
> >-----------------------------------------------------------------
> -------------------------------------------------------------|
>
>
>
>
> > -----Original Message-----
> > From: Johannes.Becker@o2.com [mailto:Johannes.Becker@o2.com]
> > Sent: Thursday, January 23, 2003 11:42 AM
> > To: cocoon-users@xml.apache.org
> > Subject: RE: Different stylesheets called on runtime?
> >
> > Hi Geff,
> >
> > thanks for your help. Ok.
>
> Sure.  Ok,
>
> >
> > Example:
> > _____________________________________________________________
> > My XSP, that should choose which XSL to use.:
>
> As an xsp is usually used to create a generator, you don't want to use it
> to
> select anything about pipeline behavior.  You can write actions
> in xsp, but
> for now that will probably confuse things.  So, you'll take the logic from
> the xsp you had, and reuse it in an action.
>
> Before getting into that, though look at the sitemap.  I think Christian
> already gave you your answer there but again, you'll want to do something
> like this:
>
> >
> > Part of sitemap:
> > ...
> > <map:match pattern="differentXSLs">
> <!-- you'll now need to strip out the transformer selection logic from the
> xsp
>   and just generate the xml that your xsl needs -->
> >    <map:generate type="serverpages" src="differentXSLs.xsp"/>
>      <map:act type="myAction">
> >             <map:transform src="{whichXSL}.xsl"/>
> >              ...
> >             <map:serialize/>
>              </map:act>
> <!-- normally you'd put fall back behavior here - executed only when the
> action
>   fails.  For the example though we'll just make the action always
> succeed.
>   You may want to change things around - putting everything inside
> the
> action tag,
>   putting only the transform in the action tag.  For the
> example it doesn't
> matter though.
>  -->
> > </map:match>
> > ....
> >
> > So how and where should I place my action (and how should it look like)?
> If you mean the compiled action, it goes in WEB-INF/classes or
> inside a jar
> in
> WEB-INF/lib
>
> > How should my xsl look like then?
> this shouldn't have to change.
>
> Now the java action.  this is more complicated than I originally indicated
> because of the database access, but it's still not that bad.  I simplified
> a
> few things, but resisted the urge to dumb it down.  For instance,
> you could
> hard code the datasource name and get rid of configure().  You could skip
> dispose() but I think that would lead to memory problems.  (avalon gurus -
> is that right?) I have combined this quickly from a DB Action
> super class I
> have and one subclass.
>
> When this is compiled, it gets defined in the map:components
> section of the
> sitemap:
> <map:actions> ....
>  <map:act name="myAction" src="you.yourcompany.acting.YourAction"
> logger="sitemap.whateveryouwant"/>
> ....
>
>
> package you.yourcompany.acting;
>
> import java.sql.Connection;
> import java.sql.PreparedStatement;
> import java.sql.SQLException;
> import java.util.Collections;
> import java.util.HashMap;
> import java.util.Map;
>
> import org.apache.avalon.framework.configuration.Configuration;
> import org.apache.avalon.framework.configuration.ConfigurationException;
> import org.apache.avalon.framework.component.ComponentManager;
> import org.apache.avalon.framework.component.ComponentException;
> import org.apache.avalon.framework.component.ComponentSelector;
> import org.apache.avalon.framework.parameters.Parameters;
> import org.apache.avalon.framework.activity.Disposable;
>
> import org.apache.cocoon.environment.Redirector;
> import org.apache.cocoon.environment.Request;
> import org.apache.cocoon.environment.SourceResolver;
> import org.apache.cocoon.environment.ObjectModelHelper;
> import org.apache.cocoon.acting.ConfigurableComposerAction;
>
> import org.apache.avalon.excalibur.datasource.DataSourceComponent;
>
> public class YourAction extends ConfigurableComposerAction implements
> Disposable {
>
>     protected ComponentSelector dbselector;
>     DataSourceComponent datasource;
>
>   public Map act(Redirector redirector, SourceResolver resolver, Map
> objectModel,
>                          String source, Parameters parameters) throws
> Exception {
>       HashMap results = new HashMap();
>       Request request = ObjectModelHelper.getRequest(objectModel);
>
> >       <!-- Get the passed parameters (if there are any) -->
> >      int whichXSL;
> >
> >       String report_id = request.getParameter("report_id");
> >       String service_id = request.getParameter("service_id");
> >       String nbt_pattern_id = request.getParameter("nbt_pattern_id");
> >       String search_txt = request.getParameter("search_txt");
> >       ...
> >
> >      // Check against a database, bla, bla
> >      ...
> >
> >
> >     // Now I want to choose the suitable XSL
> >     if( whichXSL == 1)
> >       // Choose number1.xsl
>                          results.put("number1");
> >    else if( whichXSL == 2)
> >       // Choose number2.xsl
>                          results.put("number2");
> >   else if( whichXSL == 3)
> >       // Choose number3.xsl
>                          results.put("number3");
>     else {
>              results.put("default");
>              // not strictly necessary
>              // could also return null to signal sitemap to execute
> fallback.  up to
> you.
>     }
> >    ...
>
>   return results;
>   } // end of act()
>
> // Now, you glossed over the database stuff but there's a few methods
> you'll
> need to
> // handle that.  They will be called by cocoon during the normal component
> lifecycle
> // and are designed to give us a chance to get at the resources and
> information we need.
>
>     /**
>      * Compose the Actions so that we can select our databases.
>      */
>     public void compose(ComponentManager manager) throws
> ComponentException
> {
>         this.dbselector = (ComponentSelector)
> manager.lookup(DataSourceComponent.ROLE + "Selector");
>         super.compose(manager);
>     }
>
>              /**
>               * Configure lets you specify which datasource to use in the
> sitemap
> component
>               * definition rather than hardcoded in the compiled source
>        *
>               */
>     public void configure(Configuration conf) throws
> ConfigurationException
> {
>       super.configure(conf);
>       datasource = null;
>       String dataSourceConfig = (String)settings.get("data-source");
>       try {
>                  datasource = (DataSourceComponent)
> dbselector.select(dataSourceConfig);
>                  getLogger().debug("DB Action using datasource: " +
> dataSourceConfig);
>       } catch(ComponentException e) {
>                  getLogger().warn("Could not get data-source '" +
> dataSourceConfig + "'
> configured for DB Action");
>       }
>     }
>
>              /**
>               * This is called when the instance of this action is taken
> out of the
> pool.
>        * Releasing resources is a good idea here.
>               *
>               */
>     public void dispose() {
>       this.datasource = null;
>       this.dbselector = null;
>     }
>
> Now, the database stuff would happen like this:
>
>              String sql = "select something from somewhere";
>
>       try {
>                    Connection conn = this.datasource.getConnection();
>                    PreparedStatement statement = null;
>                    statement = conn.prepareStatement(sql);
>                          // normal jdbc stuff
>
>                    }
>                          */
>       } catch(SQLException sqle) {
>                    getLogger().error("SQL Exception: " + sqle.getMessage
> ());
>                    getLogger().error("SQL State: " + sqle.getSQLState());
>                    // return null; - if you want to have the
> sitemap do the
> fallback on
> sql errors
>       }
>
> That's it.  Feel free to point out the stuff that makes no sense.  It's
> easier to answer specific questions than to try to write a whole tutorial
> here (though this could get turned into one)
>
> Geoff
>
> >
> > Cheers
> > Jonny
>
>
> ---------------------------------------------------------------------
> Please check that your question  has not already been answered in the
> FAQ before posting.     <http://xml.apache.org/cocoon/faq/index.html>
>
> To unsubscribe, e-mail:     <co...@xml.apache.org>
> For additional commands, e-mail:   <co...@xml.apache.org>
>
>
>
>
>
>
> ---------------------------------------------------------------------
> Please check that your question  has not already been answered in the
> FAQ before posting.     <http://xml.apache.org/cocoon/faq/index.html>
>
> To unsubscribe, e-mail:     <co...@xml.apache.org>
> For additional commands, e-mail:   <co...@xml.apache.org>
>
>
>


---------------------------------------------------------------------
Please check that your question  has not already been answered in the
FAQ before posting.     <http://xml.apache.org/cocoon/faq/index.html>

To unsubscribe, e-mail:     <co...@xml.apache.org>
For additional commands, e-mail:   <co...@xml.apache.org>