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 ([EMAIL PROTECTED]), 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 java.net.URL 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
>reversed.
>
I also had such thoughts : do you know Transmorpher at
http://transmorpher.inrialpes.fr/ ? 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>
>
><map:match pattern="get-mods">
> <map:generate type="request"/>
> <map:transform src="request2data-mods.xsl"/>
> <map:serialize type="/dev/null"/>
></map:match>
>
><!-- 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>
></map:act>
></map:match>
>
><!-- outflow internal -->
><map:match pattern="put-data">
> <map:generate type="/dev/null"/>
> <map:serialize type="file" src="data.xml"/>
></map:match>
>
><map:match pattern="update-index">
> <map:generate type="/dev/null"/>
> <map:transform type="lucene"/>
> <map:serialize type="/dev/null"/>
></map:match>
>
><map:match pattern="update-news">
> <!-- ... -->
></map:match>
>
><map:match pattern="result">
> <map:generate type="/dev/null"/>
> <map:transform type="result2html"/>
> <map:serialize type="html"/>
></map:match>
>
>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 :)
>
>Vadim
>
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
--
Sylvain Wallez
Anyware Technologies - http://www.anyware-tech.com
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]