> From: Sylvain Wallez [mailto:[EMAIL PROTECTED]] > > 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.
Ok :) > >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 : I do remember this; also Berin has said something about Sources in Avalon which are also 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. I don't get this. Why do you need output stream if Cocoon's pipeline is SAX stream? Serializer will need only to call getContentHandler() on the source and send everything to it. Then, source implementation will convert SAX events into byte stream (for files, or HTTP byte stream for remote sources (destinations :), or will forward events to XMLDB resource) as it receives them. Did I miss something? > Also WriteableSource extends ModifiableSource, because you're very > likely to also read from where you write to. Agreed. > This integrates smoothly in > the current Cocoon architecture : some SourceFactories will be able to > create WriteableSources, other's won't. May be. Have to look at it closely :) > > 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. Nope. > >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. That's something minor we can fix as we go :) > >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. Agreed. I prefer do not make any distinctions. > 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. I think that even check is not required. If you think how separator works (extracts certain elements and forwards to the other pipelines), you will see that every map:part is processed consecutively. Suppose that you have to serializers requiring output stream, than the first serializer which gets output stream, will process it to the end, will close it, and only then any other serializer will have a chance to get ouput stream. And at this moment, it will be already closed. Vadim > Sylvain > > -- > Sylvain Wallez > Anyware Technologies - http://www.anyware-tech.com --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]