On 3/22/07, Grzegorz Kossakowski <[EMAIL PROTECTED]> 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"
src="cocoon:/{1}/validationTemplate/{2}"/>
<map:transform type="CTcheck"/>
<map:serialize type="CTnull"/>
</map:match>
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