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]