cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Wallez <>
Subject Re: [RT] Cocoon Symmetry (short :)
Date Fri, 08 Feb 2002 18:28:05 GMT
Vadim Gritsenko wrote:

>Hi all,
>Preamble: I do remember we had talks about inward flows, etc... Then
>somebody (sorry, already forgot who it was) wrote about transformer
This is Jeremy Quinn (, the author of the FP taglib on 
Cocoon 1. He's currently looking for a simple way to store XML input by 
the user, to allow in-browser document edition.

>which writes file as a side effect... Then Kinga proposes to add
>handlers reacting on input stream/documents... And recently I have got
>an idea that it should be quite an elegant way to handle all this if
>Cocoon is designed symmetrically: whatever abstractions we have to
>handle outgoing flow, let apply to the in-flow.
>First of all, we already (almost) have symmetry in pipelines: generators
>are symmetrical to serializers. Generators are able to produce XML
>content out of almost anything we can think of: physical file, HTTP
>resource, SQL database, XMLDB database, incoming request, etc.
>Unfortunately, serializers are somewhat limited comparing to the
>generators: the only out option we have is output stream. Let's expand
>this to the other sources as well. Then we can have, say, file
>serializer. Coupled with the ability of Sources to handle input streams,
>one can save XML stream into file, XMLDB, and other sources were
>protocol handler exists.
I'm discussing off-list about this kind of things with Jeremy and I 
proposed, just like which is a two-way object, to extend 
Source so that is also becomes two-way :

public interface WriteableSource extends ModifiableSource {
  OutputStream getOutputStream();
  ContentHandler getContentHandler();

This allows for byte-based or XML-based repositories. A byte-based 
implementation will return a serializer to its input from 
getContentHandler, and an XML-based implementation will put a parser in 
front of getOutputStream.

Also WriteableSource extends ModifiableSource, because you're very 
likely to also read from where you write to. This integrates smoothly in 
the current Cocoon architecture : some SourceFactories will be able to 
create WriteableSources, other's won't.

> Second. Now Cocoon perfectly handles aggregation, both on sitemap level
>and using aggregated transformers. But what we have opposite to the
>aggregation? Nothing. Let's add separation notion: result will be
>several SAX streams. Every stream will have a destination pipeline. This
>pipeline will be retrieved by "separator", and generator of the pipeline
>will be replaced by the "separator" which will feed SAX events into this
>pipeline. As you see, it is same mechanism aggregator employs but
I also had such thoughts : do you know Transmorpher at ? It implements all this with a 
sitemap-like language. The whitepaper is really interesting.

>Third. To top all this, symmetrical component is to be developed to the
>X/C Include transformers. As "separator", it will extract parts of the
>stream and send them to the other pipelines.
>At last, let's consider an example. Let it be some request from the user
>to perform modification of the XML resource stored in the file (poor
>man's CMS ;)
><!-- inflow internal -->
><map:match pattern="get-data">
>  <map:generate src="data.xml"/>
>  <map:serialize type="/dev/null"/>
><map:match pattern="get-mods">
>  <map:generate type="request"/>
>  <map:transform src="request2data-mods.xsl"/>
>  <map:serialize type="/dev/null"/>
><!-- main -->
><map:match src="update">
><map:act type="validate-user-input">
>  <map:aggregate>
>    <map:part src="get-mods" element="mods"/>
>    <map:part src="get-data" element="data"/>
>  </map:aggregate>
>  <map:transform src="apply-mods--return-data-and-result.xsl"/>
>  <map:transform src="add-index-update.xsl"/>
>  <map:transform src="add-news-page-update.xsl"/>
>  <map:separate>
>    <map:part src="put-data" element="data"/>
>    <map:part src="update-index" element="index-update"/>
>    <map:part src="update-news" element="index-update"/>
>    <map:part src="update-result" element="result"/>
>  </map:separate>
><!-- outflow internal -->
><map:match pattern="put-data">
>  <map:generate type="/dev/null"/>
>  <map:serialize type="file" src="data.xml"/>
><map:match pattern="update-index">
>  <map:generate type="/dev/null"/>
>  <map:transform type="lucene"/>
>  <map:serialize type="/dev/null"/>
><map:match pattern="update-news">
>  <!-- ... -->
><map:match pattern="result">
>  <map:generate type="/dev/null"/>
>  <map:transform type="result2html"/>
>  <map:serialize type="html"/>
>PS: /dev/null: Currently, aggregator ignores serializer. That's to show
>that this is the dummy serializer.
A note about the syntax : for "separate" and "serialize" we should use 
"dest" instead of "src", which is confusing since this is where data is 
sent, and not where it comes from.

>Hope this makes some sense and can be a start for a good discussion :)
Sure, as it fills an important need and it seems many people have some 
thoughts about it.

Now we may have a problem with serializers : the request/response on 
which Cocoon is built requires a *single* response. A single serializer 
can write to the response, and others should act by side effect on the 
environment (using a WriteableSource) and cannot write back to the response.

We could introduce a distinction between serializers and "writers" that 
output to WriteableSources, but this would limit the reuseability of 
pipelines. So maybe this could be checked by the enhanced pileline 
(which would be a tree) : there should be one and only one serializer 
writing to the response in a pipeline.


Sylvain Wallez
Anyware Technologies -

To unsubscribe, e-mail:
For additional commands, email:

View raw message