cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Peter Hunsberger" <>
Subject Re: Unified expression handling and unified object model
Date Thu, 22 Mar 2007 16:15:26 GMT
On 3/22/07, Grzegorz Kossakowski <> wrote:
> Peter Hunsberger napisaƂ(a):
> I think that we are saying the same thing. Let me show the possible
> scenerio:
> 1. forms being submitted some <map:match/> in the sitemap catches the
> request from the browser
> 2. flow function "check()" is called
> it looks like:
> function check() {
>   var validationResult = _validate(...);
>   if (validationResult == true) cocoon.sendPage("succesPage");
>   else cocoon.sendPage("sendFormAgainAndShowValidationErrors", {
> validation : validationResult});
> }
> 3. from _validate function pipeline "run/_validate/something" is called
> and it looks like:
> <map:match pattern="run/_validate/*">
>   <map:generate src="..." type="..."/> <!-- obtain the data to be
> checked -->
>   <map:transform src="..." type="..."/> <!-- here data is validated,

With the  2.1 code base ours actually looks like:

            <map:match pattern="*/_validate/**">
                <map:generate src="cocoon:/{1}/requestdata"/>
                <map:transform src="stylesheets/resolve_request.xsl"/>
                <map:transform type="xslt-saxon7"
                <map:transform type="CTcheck"/>
                <map:serialize type="CTnull"/>

so you've essentially got it right, however, note that the actual
Schematron XSLT that does the validation comes from yet another
pipeline (shouldn't matter, but it's interesting).  CTcheck is a
transformer that walks the SAX events and builds the request
attributes we reuse later, CTnull is a serializer that does absolutely
nothing except output a single static element.

> HTTP status code is set for this pipeline according to the result of
> validation, report of validation is what this transformer returns as
> SAX-stream -->
>   <map:serialize type="xml"/> <!-- serialize the report so flowscript
> can catch it -->
> </map:match>

Why does the flowscript even have to catch it in a serialized version?
 You already passed processPipelineTo a SaxBuffer as the output
stream, it should already contain the SAX events, why do I also need a
serialized version?

> 4. now it's the time for decision what to do next if validationResult ==
> true then call pipeline "succesPage" which can look like this one:
> <map:match pattern="succesPage">
>   <map:generate src="thankYouForFillingTheFormCorrectly.jx" type="jx"/>
>   <map:serialize type="html"/>
> </map:match>
> OR validation failed so "sendFormAgainAndShowValidationErrors" pipeline
> is called and report of validation is passed in "validation" variable:
> <map:match pattern="sendFormAgainAndShowValidationErrors">
>   <map:generate src="xmodule:flowscript:validation"/> <!-- actually
> flowscript module does not exist but it's not that important -->
>   <!-- do some formatting on the report -->
>   <map:serialize type="html"/>
> </map:match>
> The last pipeline is going to be more complicated of course. You
> probably would like to aggregate the form data and display validation
> errors in form's context but it's not important here.

You probably wouldn't want to pass the validation results in as a
variable, they are pretty complex and can be very verbose, but as long
as you can use the results as input to a generator you're ok.

> One more remark: I've used xmodule and non-existing flowscript
> InputModule but it's only to show the idea, with new expression
> implementation it would be a little bit different.
> This should eliminate all doubts.

Not really, you're showing the old way (xmodule, InputModule) and
telling me the new way would be bit different.   But that's precisely
the issue; how is it different?

> > No, the  validation is purely an internal process that in theory may
> > not contribute anything to  the current pipeline (other than a true or
> > false in the flow).  Consider the validation step as a call to a third
> > party library function of some kind (but one that happens to be
> > running Cocoon) that is going to create an object for you that you can
> > examine.  Yes you could go to all the trouble of making this external
> > library serialize XML and then you could deserialize it and look at
> > it, but why bother if you can instead simply pass objects back and
> > forth?
> Serialization/deserialization step can be omitted the same way as it's
> done now with the "cocoon:/" protocol calls. And it's worth to pass the
> XML because at the end it's exactly you need...

No, no, no a 10000 times no (sorry, I'm getting carried away)! You do
NOT want the XML, you want the SAX events.  Pipelines don't handle XML
they handle SAX!

> Example above shows that "run/_validate/*" pipeline does not contribute
> to the original request from the browser.
> > I think so, the question is at what cost?  If the new way of doing
> > things is going to force me to always run a complete pipeline and only
> > access the results via serialization and deserialization with no way
> > to pass objects between the side pipeline call and the main pipeline
> > then I think the overhead is too high.  If there is some way to invoke
> > a side pipeline and later discover an object (a SAX buffer would be a
> > great generalization) that was created as a result of running it in
> > some extended object model (without worrying about whether anything
> > ever got serialized) then I'm fine with that...
> This new way does not forbid you to store objects in request attribute
> or extend Object Model and put them there. The point is that I can
> hardly see valid use case where you create some objects in side pipeline
> and want pass them to another pipeline. Cocoon's pipelines are about XML
> (SAX streams) not Objects/beans/pojos.
> I think that in use case you showed you'll be fine to just get XML form
> of report and no objects.

Don't mix up XML and SAX events they are not the same thing!  SAX
events are collections  of objects and primitives that are passed into
event handlers.  XML is serialized text.  I do not want to deal with
XML in the middle of running a pipeline!

For this particular use case a SAX buffer is essentially equivalent to
any other object, you basically want to have a standardized set of
interfaces that can be used to move the data between the called
pipeline and the receiving pipeline.  Whether you have a trivial
generator replay the SAX buffer or have a trival generator call some
standard methods on an object to generate the SAX events doesn't
really matter to me.

> As I said earlier the overhead wouldn't be that much with little effort
> of extending current code. Actually SAX pipelines, cocoon: protocol
> implementation and other similar stuff is to make the overhead minimal,
> doesn't it?

The overhead is minimal until you serialize and deserialize.
Deserialization has some serious overhead to it, it is VERY expensive!

Peter Hunsberger
View raw message