You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Stefano Mazzocchi <st...@apache.org> on 2002/06/18 17:35:57 UTC

[RT] Flowscript [was Re: [RT] Flowmaps]

Ovidiu Predescu wrote:
> 
> Guys,
> 
> I'm really overwhelmed by your reaction to the flow idea! Thanks all for
> sharing your thoughts!
> 
> First of all, I think the thanks should go to Christian Queinnec, who came
> up with the idea, and to Christopher Oliver, who implemented continuations
> in Rhino. I just put all the things together and implement the support in
> Cocoon.

Once flow docos are in place, we'll make sure to give all credits to
those who deserve it. For sure, you deserve lots of it.

> Now, there are few points that have been raised here. I'll try to answer to
> all of them in this email, both as a way to synthesize this great
> discussion, and to minimize the time I take to respond to individual
> messages (otherwise I can easily spend my entire evening replying). Please
> raise your issue again if you don't see an answer for it here.
> 
> 1. Stefano points out that flowmaps (I don't really like this term, a "map"
> is more appropriate for state machines, how about flowscript instead?)

You are right. The concept of 'flowmap' came because of a mental
parallel I had between a declarative approach and a procedural one...
but after understanding that we don't need that, being the HTTP
client/server model intrinsically declarative.

So +1 for 'flowscript'.

> should not be considered as ordinary resources, but a separate concept. I
> have no issue declaring them in a different way, just to emphasize this
> point. So something like
> 
>   <map:flowscripts default="calculator">
>    <map:flowscript name="calculator" language="javascript">
>      <map:script src="calc.js"/>
>    </map:flowscript>
>   </map:flowscripts>
> 
> should be OK. 

Hmmm, call me picky, but what's wrong with

   <map:flowscripts default="calculator">
    <map:flowscript name="calculator" src="calc.js"
language="javascript"/>
   </map:flowscripts>

> Beside a different name for elements, the fundamental
> difference between this syntax and Stefano's is that it allows multiple
> files to contain the implementation of a flow script.

yes, this is also a parallel with any other sitemap concept, such as
components, resources and views.
 
> Each named flow script declared in <map:flowscripts> could and should be
> independent on the others. Each script should have different set of global
> variables, which is different from another script, and of course, is
> different each user gets his/her own set of values for these variables.
> 
> This is an issue today, as it does not really happen. I'm working on solving
> it.

Great to hear that.
 
> 2. (Stefano) How to encode the continuation ids.
> 
> Stefano would like to have ContinuationURLEncodingTransformer, which takes
> care of encoding the continuation id. Sylvain points out that continuation
> ids can be passed not only as part of the URL, but also as request
> parameter.
> 
> I think it makes sense to have a transformer which encodes the continuation
> URL. This would make it very easy to change the way the continuation id is
> generated, without having to go to each XSP, JSP, whatever and change it.

Exactly.

> The transformer would probably work best when the continuation id is encoded
> in the URL. When the id is encoded as a request parameter, there will be
> some awareness required from the page designer to have this id enclosed
> inside a form.

Many ask to make continuations ID as transparent as session IDs. Do you
think this is possible/desirable?
 
> 3. (Stefano) Template languages other than XSP to be used with the flow
> layer.
> 
> This should certainly be possible, I've started with XSP because it was very
> easy to get implement. JSP and Velocity should be equally easy to implement
> though. We just need somebody to do it ;)

Great. Please explain how then, because I think lack of knowledge and
docos was the real issue (see how things changed with a single email)!
 
> 4. Stefano's callPipeline() function. Is this equivalent to
> sendPageAndContinue(), which is already implemented in the flow layer?

No, I don't think so (see below).

> It
> essentially allows you to have a page processed through a pipeline, and
> continue the execution of the script. BTW, I think your sitemap snippet has
> a bug in it, shouldn't it have the <map:match> names swapped?
> 
> Also in your callPipeline(), how does the output parameter get used?

That's the key issue: many people, in the past, pointed out that they
would like to reuse the concept of cocoon pipelines to create stuff but
send it somewhere else, not back to the client.

Currently, there is no way for a pipeline stage to call another pipeline
*detaching* it from the client output stream and attaching it a
different output stream. I would like the flowscript to be able to do
that.

> It
> should be the task of the sitemap pipeline where the file is written. Am I
> missing something?

It's *not* the sitemap concern to know where the output stream is. If
you look at how the sitemap is implemented, it's the sitemap caller's
concern to provide the output stream. Servlets call the sitemap engine
passing the ResponseOutputStream and the CLI calls the sitemap engine
passing FileOutputStreams.

But the granularity is all or nothing. I would like to be able to call a
pipeline 'detaching it' from the output stream that the container
passed.

Why? simply because it allows very creative uses of cocoon pipelines and
would instantly stop all those requests for 'forking pipelines' that
keep bugging me in the back of my mind.
 
> 5. Ivelin points out the potential of stale continuations.
> 
> I think this is indeed a real issue. One way to avoid it is to have
> continuations automatically expire after a time of inactivity, or do
> deactivate them manually in the flow script. The first approach is something
> I considered, and there are some hooks in the current code, but more support
> code needs to be written. The second approach can be implemented today: you
> can invalidate not only a single continuation, but the whole subtree of
> continuations which start from it. You just need to keep a hold on the
> continuation at the top of the tree, and invoke invalidate() on it.

Speaking of which, would it good to have a 'continuation' object in the
FOM?

> 6. Multi-page forms are not dominating, and continuation based compared to
> even driven (GUI-like) programming approaches.
> 
> I used to program GUIs a lot, I think for certain things, event-driven is
> better than using continuations. I do think however that continuations have
> a place, especially for multi-page forms. Now I think it depends a lot on
> the application, whether these forms are prevalent or not.

I agree and this is the reason why I think deprecating Actions is a bad
thing (at least, today). We'll provide options and guidelines, users
will decide what to do with the tools we provide.

> 7. Bruno's question regarding the advantage of flow scripts versus actions.
> 
> The advantage would be that with flow scripts you can describe all the
> actions in a single flow script, where each action becomes a separate
> function. Since these functions share the same global variables, it's very
> easy to share data between them. You can share data using the session
> object, but with explicit variables is much easier to follow what's going
> on.
> 
> If you don't care about sharing data between actions, then there's probably
> little value describing your action logic in a flow script. Other than the
> fact that you don't have to write Java code, which means compile, build war
> file, restart tomcat. With flow scripts, you just modify the script file and
> resend the request: the script is automatically reloaded and parsed by
> Cocoon, there's no need to restart anything.
> 
> 8. Vadim's idea about making the syntax easier.
> 
> I think the idea of having something as simple as:
> 
> <map:match pattern="calc/*">
>   <map:flow method="calculator" continuation="{1}" />
> </map:match>
> 
> makes a lot of sense. Using different matchers, the continuation id can be
> extracted from the request parameters, cookies, you name it. The only
> problem with it is that is a bit inflexible in terms of the URI design. If
> I'd like to have calc/kont/*, there's no easy way to specify it.
> 
> So I'd say we can have two alternative ways of writing this: using the above
> proposal and what is already implemented, for power users that want more
> control. How about this?

Sorry, but I lost you here.

> 9. Reinhard asks what happens if two different flow scripts have a function
> with a similar name name.
> 
> Since the flow scripts have their own variable space (not now due to some
> problems in the current implementation), there shouldn't be any problem.
> Each flow script can use its own variable and function names, without
> worrying about possible conflicts with other scripts.

Yes, and also I was thinking about having something like

 <map:call flow="calculator" method="calculator"/>

that provides sort of namespacing and avoids collisions.

> 10. Torsten asks how xmlform/precept could be implemented with flow scripts.
> 
> I think the more generic question is how to implement multi-page forms using
> flow scripts. It would also be nice if the validation could happen not only
> on the server side, but also in the client browser, using JavaScript if
> that's available.
> 
> Your example would become a lot simpler if you factor out the repetitive
> code in a function:
> 
> var validator;
> var instance;
> var prefix;
> 
> function wizard(uriPrefix) {
>   var id = cocoon.request.getParameter("someid");
> 
>   var factory = SchemaFactory.getInstance("ns");
>   //maybe we can get the schema from a pipeline??
>   var schema = factory.compile("someschema.xsd.dtd.rng.sch");
>   validator = schema.createValidator();
>   instance = new Instance();
>   prefix = uriPrefix;
> 
>   loadInstance(instance,id);
> 
>   do {
>     showAndValidatePage(1);
>     showAndValidatePage(2);
>     showAndValidatePage(3);
>   } while(!validator.isValid(instance));
> 
>   if(saveInstance(instance,id)) {
>    sendPage("success.html");
>   }
>   else {
>    sendPage("failed.html");
>   }
> }
> 
> function showAndValidatePage(number)
> {
>    do {
>     sendPage(prefix + "page" + number + ".html");
>     Instance.populate(instance, cocoon.request);
>    } while(!validator.isValid(instance, "page" + number));
> }
> 
> Torsten's example uses a heavily xmlform type of approach, where the data to
> be validated is kept in a Java object or a DOM tree. This is one way of
> doing things; another one would be to use explicit variables which, at the
> end of the validation, could be written in the database directly, or used to
> construct a object hierarchy which is then saved in the database using JDO,
> EJBs or whatever other means. The validation could be done directly in
> JavaScript, instead of a Schema approach. The code that does the validation
> could then be used on the client side as well.
> 
> As Stefano mentioned, the flow layer is an infrastructure which can be used
> to create higher level abstractions. Here are some things I am currently
> looking at, which can improve the usability of the flow script engine:
> 
> - automatic binding of JavaScript variables to form values. This would allow
> you to declare something like:
> 
>   var username, password;
> 
>   // Send a page to collect the user name and the password
>   sendPage("login.html");
> 
>   // When the user fills in the form and presses the submit button, the
>   // script restarts here. The flow engine automatically binds the username
>   // and password to the values submitted in the form.
> 
>   // make use of username and passwd here

I didn't know PHP had problems with this approach, but it smells a lot
anyway. I'm always afraid of implicity behavior, expecially when it's
user-triggerable.

This is not automatically a security hole, but it could become one since
you are letting potential attackers one step closer to your door. And
you are making things hidden so harder to spot.

I would be against anything so implicit.

> - automatic validation of form values on both server and client side. This
> should allow the same piece of JavaScript validation code to be executed
> both on the server and client side. More on this later.
> 
> 11. With respect to how to put a back button on a page, I think I replied to
> this some time ago. The idea is to use the <jpath:continuation select="1"/>
> which selects the previous continuation.

I agree with Torsten: I'd like to keep the flow layer detached from the
jpath logicsheet. (I would also use -1 as well to indicate backwards)

> As I mentioned in some other message, the continuations created during the
> execution will form a tree, or a list if the user never presses the back
> button and starts on a different path. At any given point you can access the
> continuations above you in the tree, which identify the past pages, by using
> the "select" attribute in <jpath:continuation>.
> 
> 12. Torsten: sub-flows, flow-2-flow, what are these? Is assembly of
> functions that represent independent flows enough?
> 
> 13. Piroumian asks how to cancel a continuation.
> 
> As I mentioned in several ocasions, sendPage() returns the saved
> continuation. If you want to cancel the continuation just invoke on it the
> invalidate() method. It will cancel all the receiver and all the
> continuations that inherit from it.

Cool. Ovidiu, we *definately* need more docs on what you wrote. It's
simply too undocumented right now... don't need to be XML-ized edited or
anything, just bare raw but with juicy info inside, we'll make them
better ourselves.

> 14. Another question Piroumian has is how to validate against business
> logic. Since JavaScript is tightly integrated with Java, you can call Java
> logic from the flow script to do the business logic validation. This way you
> can invoke whatever logic you want. If this is too generic, then provide
> some use case and I'll try to sketch a solution.

I think you should provide a real-life example of use of a java data
model to show how java can be called from the flowscript.

> 15. Flow management: obtaining a list of all active flows.
> 
> All the flows are kept in an array, which is managed by a Cocoon component.
> Each flow is a tree of continuations, where each continuation is a
> JavaScript object which can be dynamically inspected for properties and so
> on.
> 
> 16. Sylvain: should flow scripts be inherited by sub-sitemaps?
> 
> I'm not sure of the security implications of allowing them to be inherited:
> what should be the behavior if a developer alters definitions from an
> inherited flow script?

My perception is that flowscripts are not components and should not be
inherited.

> 17. The proposal to use map:call with "function(arg, arg, ...)".
> 
> I think this is more like a syntactic sugar than real value. I don't think
> passing arguments via map:param would confuse people, the semantic is still
> the same as function invocation.

All right, let's remove this.

> 18. Access to continuations.
> 
> I think there is a bit of confusion of terms in this discussion. The
> continuation id is passed in the HTTP request in some way or another: as
> part of the URL, as a request parameter etc. This encoding should be visible
> to the sitemap only. I'd very much like to have it hidden from the view
> layer as well, so if we can avoid putting explicit URLs in page templates,
> that would be great! This reduces the dependency between the URL design in
> the sitemap and the view generation.
> 
> A continuation is a real object that lives on the server side, which is
> represented by its id in the request. A continuation object is returned by
> sendPage(). A continuation id is fairly much useless in a flow script, what
> you really need is the continuation object itself, which contains this
> information and more.

Yes, there is confusing between the 'continuation object' and the
'continuation id'.

Many don't like the fact that you have to explicitly pass along the
'continuation id', unlike sessions where the 'session id' is (generally)
transparently passed back and forth (which was one of the biggest values
of the Servlet API)

> 19. There are some other things that need to be fixed, but the following
> item is the biggest one.
> 
> Currently the global variable space is shared between _all_ the flow scripts
> and _all_ the users. This is clearly wrong, and it will change soon. What we
> should have is the global variable space common only to a flow script, and
> only to a single user. This has been a challenge so far with the Rhino, but
> I think I have a solution for it.
>
> Variables in this global variable space will act as session variables. To
> facilitate communication between applications or share constant values
> between users of the same application, an application and a global space
> will be introduced.
> 
> In this new approach, it should be possible to have multiple top level
> functions be invoked from the same sitemap, and have them share the same
> global variable scope, for a given user. This makes things a lot easier when
> programming with the flow layer, as you are not forced to always use
> continuations. You can store your application variables as global variables
> in a JavaScript script, and have multiple functions operated on them, where
> each function is called from the sitemap.

Great to hear.

> 20. My job - thanks Stefano for bringing it up. Here's my shameless plug :)
> If you think of using Cocoon for building Web apps or Web services, and you
> need support in doing so, I am providing consultancy for doing it, anytime,
> anywhere.

Good luck for all this!

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Re: [RT] Flowscript [was Re: [RT] Flowmaps]

Posted by Ovidiu Predescu <ov...@cup.hp.com>.
On 6/20/02 1:21 AM, "Stefano Mazzocchi" <st...@apache.org> wrote:

> Ovidiu Predescu wrote:
> 
>> I think the idea is to have something which just works by default, with no
>> configuration necessary. In addition to this, more experienced developers
>> can use the current method, which is more complex. Vadim's proposal is for
>> the first method. What is already implemented in the current code is the
>> second method.
> 
> Ah, ok. Just one point, the code above:
> 
> <map:match pattern="calc/*">
>  <map:flow method="calculator" continuation="{1}" />
> </map:match>
> 
> would not match "calc/" (at least, in the past I had problems with this,
> maybe behavior changed today, I'm not sure), probably
> 
> <map:match type="regexp" pattern="calc/?(.*)">
>  <map:flow method="calculator" continuation="{1}"/>
> </map:match>
> 
> is a better way to handle it. What do you think?

The approach you mention will also match things like "calculator", which is
probably not what we want.

Vadim already pointed out the first approach works fine, which I think is
what we need.

>>>> 9. Reinhard asks what happens if two different flow scripts have a function
>>>> with a similar name name.
>>>> 
>>>> Since the flow scripts have their own variable space (not now due to some
>>>> problems in the current implementation), there shouldn't be any problem.
>>>> Each flow script can use its own variable and function names, without
>>>> worrying about possible conflicts with other scripts.
>>> 
>>> Yes, and also I was thinking about having something like
>>> 
>>> <map:call flow="calculator" method="calculator"/>
>>> 
>>> that provides sort of namespacing and avoids collisions.
>> 
>> In the new scheme I'm working on, there's no potential for collisions, each
>> flow script has its own namespace, separated from the others.
> 
> Internally, yes, but how would you specify which flowscript you want to
> call between all those you have declared in your sitemap?
> 
> For example
> 
> <map:flowscripts default="a">
> <map:flowscript name="a">
>  <map:script src="first.js" language="javascript"/>
>  <map:script src="second.js" language="javascript"/>
> </map:flowscript>
> <map:flowscript name="b">
>  <map:script src="first.js" language="javascript"/>
>  <map:script src="third.js" language="javascript"/>
> </map:flowscript>
> </map:flowscripts>
> 
> as you can see, both flowscripts include the same script 'first.js', so
> the function calls between the two overlap completely. Let us assume
> that the function 'blah' is described in 'first.js', then you call it
> with
> 
> <map:flow function="blah" continuation="..."/>
> 
> and it defaults to the 'a' flowscript (since the
> map:flowscripts/@default attribute states so). But how would you call
> the 'blah' function of the 'b' flowscript?
> 
> I would follow the same pattern we use for components and use
> 
> <map:flow flowscript="b" function="blah" continuation="..."/>
> 
> I see no transparent ways to do this.

Sorry, you're right, I misunderstood what you have in mind. This would be
the right approach to differentiate between things.

>> The automatic binding happens under the strict control of the programmer.
>> What I was thinking to have is the ability to map a request parameter to a
>> script variable, _if_ the programmer requests so for a particular variable.
>> How the mapping is done is completely under the control of the programmer.
> 
> Ah, I get your point. You want to do something like what IE does with
> DOM in DHTML:
> 
> document.blah
> 
> is equivalent of 
> 
> document.getElementById("blah");
> 
> so that instead of doing
> 
> cocoon.getRequest().getParameter("password");
> 
> you call something like
> 
> request.password
> 
> directly. Is that your point?

Yes, we can use either this approach, or a separate mapping file, or a
programmatic way to specify the mapping between a variable name in a
function and a request parameter. I think the approach you mention above is
the easiest however.

>> The counting starts from a node in the tree and goes upwards, that was the
>> reason why the number is positive. To me this makes more sense than using
>> negative numbers, but I have no strong opinions.
> 
> I think you saw this from a development point of view, from a user point
> of view, the flow of the continuation goes with the arrow of time, so
> you go "back" to retrieve your past continuation. And "1" seems to imply
> a step 'forward' in the arrow of time (which doesn't make any sense and
> would confuse people at first, at least, that's what happened to me...
> but I'm by far not the average Cocoon user :)

OK, I got your point.

>>> Cool. Ovidiu, we *definately* need more docs on what you wrote. It's
>>> simply too undocumented right now... don't need to be XML-ized edited or
>>> anything, just bare raw but with juicy info inside, we'll make them
>>> better ourselves.
>> 
>> Yes, I know it's undocumented. I spent a lot of time describing the ideas on
>> emails, but didn't actually takes those and put in a document. I'll try to
>> come up with some docs, but there are simply too many things to work on at
>> the same time ;)
> 
> I would kindly suggest you to escape your 'ego trap' and start writing
> crude docs before anything else. I know it would be very nice if you
> could provide us with all we asked for already implemented, but then you
> become the bottleneck and the community suffers from this.
>
> Instead, if you provide even a very basic description of what we have
> there (don't worry, doesn't need to be coherent or well written, just
> contain the information for the other developers to catch up on your
> work), work can parallelize.
> 
> Hope you get my point.

Kevin O'Neill <ke...@rocketred.com.au> has volunteered to start collecting
some of the old email threads and assemble them in a more or less coherent
document, which describes the main ideas.

>>>> 14. Another question Piroumian has is how to validate against business
>>>> logic. Since JavaScript is tightly integrated with Java, you can call Java
>>>> logic from the flow script to do the business logic validation. This way
>>>> you
>>>> can invoke whatever logic you want. If this is too generic, then provide
>>>> some use case and I'll try to sketch a solution.
>>> 
>>> I think you should provide a real-life example of use of a java data
>>> model to show how java can be called from the flowscript.
>> 
>> This too is on my TODO list ;)
> 
> Ok, please, make *your* TODO list *ours*. :)

Yep, I've tried it.

But the code is crappy, and there's no documentation to explain the ideas.
The only place where these ideas are presented is on the mailing list, and
there the messages span across multiple months. I don't expect *my* TODO
list to suddenly become everybody else's. There is simply no critical mass
of developers that understand the ideas and the code enough for this to
happen. This is the reality of any open source project, the original
developer has to drive it to a certain point until people pick it up from
there.

> And don't worry if you don't have time, nobody really does... and who
> does is wasting it to work on something so stupid as Cocoon instead of
> appreciating what they have in their life, myself first :(

I concur to these statements ;)

Best regards,
-- 
Ovidiu Predescu <ov...@cup.hp.com>
http://www.geocities.com/SiliconValley/Monitor/7464/ (Apache, GNU, Emacs...)



---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


RE: [RT] Flowscript [was Re: [RT] Flowmaps]

Posted by Vadim Gritsenko <va...@verizon.net>.
> From: Stefano Mazzocchi [mailto:stefano@apache.org]

<snip/>

> Ah, ok. Just one point, the code above:
> 
>   <map:match pattern="calc/*">
>    <map:flow method="calculator" continuation="{1}" />
>   </map:match>
> 
> would not match "calc/" (at least, in the past I had problems with
this,
> maybe behavior changed today, I'm not sure),

It matches (be sure).


> probably
> 
>   <map:match type="regexp" pattern="calc/?(.*)">

You mean "calc/(.*)?", right?


>    <map:flow method="calculator" continuation="{1}"/>
>   </map:match>
> 
> is a better way to handle it. What do you think?

<snip/>

> > > Yes, and also I was thinking about having something like
> > >
> > > <map:call flow="calculator" method="calculator"/>
> > >
> > > that provides sort of namespacing and avoids collisions.
> >
> > In the new scheme I'm working on, there's no potential for
collisions, each
> > flow script has its own namespace, separated from the others.
> 
> Internally, yes, but how would you specify which flowscript you want
to
> call between all those you have declared in your sitemap?
> 
> For example
> 
>  <map:flowscripts default="a">
>   <map:flowscript name="a">
>    <map:script src="first.js" language="javascript"/>
>    <map:script src="second.js" language="javascript"/>
>   </map:flowscript>
>   <map:flowscript name="b">
>    <map:script src="first.js" language="javascript"/>
>    <map:script src="third.js" language="javascript"/>
>   </map:flowscript>
>  </map:flowscripts>
> 
> as you can see, both flowscripts include the same script 'first.js',
so
> the function calls between the two overlap completely. Let us assume
> that the function 'blah' is described in 'first.js', then you call it
> with
> 
>  <map:flow function="blah" continuation="..."/>
> 
> and it defaults to the 'a' flowscript (since the
> map:flowscripts/@default attribute states so). But how would you call
> the 'blah' function of the 'b' flowscript?
> 
> I would follow the same pattern we use for components and use
> 
>  <map:flow flowscript="b" function="blah" continuation="..."/>

More consistent with the rest will be:

<map:flow type="b" function="blah" continuation="..."/>

Vadim


---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Re: [RT] Flowscript [was Re: [RT] Flowmaps]

Posted by Stefano Mazzocchi <st...@apache.org>.
Ovidiu Predescu wrote:

> > Hmmm, call me picky, but what's wrong with
> >
> >  <map:flowscripts default="calculator">
> >   <map:flowscript name="calculator" src="calc.js"
> > language="javascript"/>
> >  </map:flowscripts>
> 
> Because my calculator implementation may be composed of multiple script
> files. This is not the case in this simple example, but I may need to split
> the implementation for clarity in multiple files. Having the ability to
> specify multiple files by adding <map:script> as needed solves the problem.

Ah, got it. Cool, makes sense.
 
> > Many ask to make continuations ID as transparent as session IDs. Do you
> > think this is possible/desirable?
> 
> I think it is both desirable and possible. I think the responsibility for
> deciding this should be in the sitemap, and only in one place.

Totally agree. That would be the perfect scenario. Do you people have
any ideas on how we can achieve this in practice?
 
> >> Also in your callPipeline(), how does the output parameter get used?
> >
> > That's the key issue: many people, in the past, pointed out that they
> > would like to reuse the concept of cocoon pipelines to create stuff but
> > send it somewhere else, not back to the client.
> >
> > Currently, there is no way for a pipeline stage to call another pipeline
> > *detaching* it from the client output stream and attaching it a
> > different output stream. I would like the flowscript to be able to do
> > that.
> 
> Yes, that's right! HP's SOAP server based on Cocoon had to do some really
> nasty things to achieve this. I see what you mean, and it should be
> possible.

Great, I think so too.

> >> It
> >> should be the task of the sitemap pipeline where the file is written. Am I
> >> missing something?
> >
> > It's *not* the sitemap concern to know where the output stream is. If
> > you look at how the sitemap is implemented, it's the sitemap caller's
> > concern to provide the output stream. Servlets call the sitemap engine
> > passing the ResponseOutputStream and the CLI calls the sitemap engine
> > passing FileOutputStreams.
> >
> > But the granularity is all or nothing. I would like to be able to call a
> > pipeline 'detaching it' from the output stream that the container
> > passed.
> >
> > Why? simply because it allows very creative uses of cocoon pipelines and
> > would instantly stop all those requests for 'forking pipelines' that
> > keep bugging me in the back of my mind.
> 
> OK, I get it! That's indeed a nice feature to have.

Yep, this will sure make Cocoon fly :)

> >> 5. Ivelin points out the potential of stale continuations.
> >>
> >> I think this is indeed a real issue. One way to avoid it is to have
> >> continuations automatically expire after a time of inactivity, or do
> >> deactivate them manually in the flow script. The first approach is something
> >> I considered, and there are some hooks in the current code, but more support
> >> code needs to be written. The second approach can be implemented today: you
> >> can invalidate not only a single continuation, but the whole subtree of
> >> continuations which start from it. You just need to keep a hold on the
> >> continuation at the top of the tree, and invoke invalidate() on it.
> >
> > Speaking of which, would it good to have a 'continuation' object in the
> > FOM?
> 
> It is already there, together with the data object. Check-out the jpath.xsl
> logicsheet to see how this works.

uh, impressive :)

> >> 8. Vadim's idea about making the syntax easier.
> >>
> >> I think the idea of having something as simple as:
> >>
> >> <map:match pattern="calc/*">
> >>   <map:flow method="calculator" continuation="{1}" />
> >> </map:match>
> >>
> >> makes a lot of sense. Using different matchers, the continuation id can be
> >> extracted from the request parameters, cookies, you name it. The only
> >> problem with it is that is a bit inflexible in terms of the URI design. If
> >> I'd like to have calc/kont/*, there's no easy way to specify it.
> >>
> >> So I'd say we can have two alternative ways of writing this: using the above
> >> proposal and what is already implemented, for power users that want more
> >> control. How about this?
> >
> > Sorry, but I lost you here.
> 
> I think the idea is to have something which just works by default, with no
> configuration necessary. In addition to this, more experienced developers
> can use the current method, which is more complex. Vadim's proposal is for
> the first method. What is already implemented in the current code is the
> second method.

Ah, ok. Just one point, the code above:

  <map:match pattern="calc/*">
   <map:flow method="calculator" continuation="{1}" />
  </map:match>

would not match "calc/" (at least, in the past I had problems with this,
maybe behavior changed today, I'm not sure), probably

  <map:match type="regexp" pattern="calc/?(.*)">
   <map:flow method="calculator" continuation="{1}"/>
  </map:match>

is a better way to handle it. What do you think?

> >> 9. Reinhard asks what happens if two different flow scripts have a function
> >> with a similar name name.
> >>
> >> Since the flow scripts have their own variable space (not now due to some
> >> problems in the current implementation), there shouldn't be any problem.
> >> Each flow script can use its own variable and function names, without
> >> worrying about possible conflicts with other scripts.
> >
> > Yes, and also I was thinking about having something like
> >
> > <map:call flow="calculator" method="calculator"/>
> >
> > that provides sort of namespacing and avoids collisions.
> 
> In the new scheme I'm working on, there's no potential for collisions, each
> flow script has its own namespace, separated from the others.

Internally, yes, but how would you specify which flowscript you want to
call between all those you have declared in your sitemap?

For example

 <map:flowscripts default="a">
  <map:flowscript name="a">
   <map:script src="first.js" language="javascript"/>
   <map:script src="second.js" language="javascript"/>
  </map:flowscript>
  <map:flowscript name="b">
   <map:script src="first.js" language="javascript"/>
   <map:script src="third.js" language="javascript"/>
  </map:flowscript>
 </map:flowscripts>

as you can see, both flowscripts include the same script 'first.js', so
the function calls between the two overlap completely. Let us assume
that the function 'blah' is described in 'first.js', then you call it
with

 <map:flow function="blah" continuation="..."/>

and it defaults to the 'a' flowscript (since the
map:flowscripts/@default attribute states so). But how would you call
the 'blah' function of the 'b' flowscript?

I would follow the same pattern we use for components and use

 <map:flow flowscript="b" function="blah" continuation="..."/>

I see no transparent ways to do this.

> > [...]
> >
> >> - automatic binding of JavaScript variables to form values. This would allow
> >> you to declare something like:
> >>
> >>   var username, password;
> >>
> >>   // Send a page to collect the user name and the password
> >>   sendPage("login.html");
> >>
> >>   // When the user fills in the form and presses the submit button, the
> >>   // script restarts here. The flow engine automatically binds the username
> >>   // and password to the values submitted in the form.
> >>
> >>   // make use of username and passwd here
> >
> > I didn't know PHP had problems with this approach, but it smells a lot
> > anyway. I'm always afraid of implicity behavior, expecially when it's
> > user-triggerable.
> >
> > This is not automatically a security hole, but it could become one since
> > you are letting potential attackers one step closer to your door. And
> > you are making things hidden so harder to spot.
> >
> > I would be against anything so implicit.
> 
> No, no, I wanted to say something completely different. I replied to this
> topic already, but I'll repeat it here to be clear.
> 
> The automatic binding happens under the strict control of the programmer.
> What I was thinking to have is the ability to map a request parameter to a
> script variable, _if_ the programmer requests so for a particular variable.
> How the mapping is done is completely under the control of the programmer.

Ah, I get your point. You want to do something like what IE does with
DOM in DHTML:

 document.blah

is equivalent of 

 document.getElementById("blah");

so that instead of doing 

 cocoon.getRequest().getParameter("password");

you call something like

 request.password

directly. Is that your point?

> >> - automatic validation of form values on both server and client side. This
> >> should allow the same piece of JavaScript validation code to be executed
> >> both on the server and client side. More on this later.
> >>
> >> 11. With respect to how to put a back button on a page, I think I replied to
> >> this some time ago. The idea is to use the <jpath:continuation select="1"/>
> >> which selects the previous continuation.
> >
> > I agree with Torsten: I'd like to keep the flow layer detached from the
> > jpath logicsheet. (I would also use -1 as well to indicate backwards)
> 
> Again, I was only lazy to come up with a new logicsheet, so I reused things
> in the same logicsheet.
> 
> The counting starts from a node in the tree and goes upwards, that was the
> reason why the number is positive. To me this makes more sense than using
> negative numbers, but I have no strong opinions.

I think you saw this from a development point of view, from a user point
of view, the flow of the continuation goes with the arrow of time, so
you go "back" to retrieve your past continuation. And "1" seems to imply
a step 'forward' in the arrow of time (which doesn't make any sense and
would confuse people at first, at least, that's what happened to me...
but I'm by far not the average Cocoon user :)

> >> 13. Piroumian asks how to cancel a continuation.
> >>
> >> As I mentioned in several ocasions, sendPage() returns the saved
> >> continuation. If you want to cancel the continuation just invoke on it the
> >> invalidate() method. It will cancel all the receiver and all the
> >> continuations that inherit from it.
> >
> > Cool. Ovidiu, we *definately* need more docs on what you wrote. It's
> > simply too undocumented right now... don't need to be XML-ized edited or
> > anything, just bare raw but with juicy info inside, we'll make them
> > better ourselves.
> 
> Yes, I know it's undocumented. I spent a lot of time describing the ideas on
> emails, but didn't actually takes those and put in a document. I'll try to
> come up with some docs, but there are simply too many things to work on at
> the same time ;)

I would kindly suggest you to escape your 'ego trap' and start writing
crude docs before anything else. I know it would be very nice if you
could provide us with all we asked for already implemented, but then you
become the bottleneck and the community suffers from this.

Instead, if you provide even a very basic description of what we have
there (don't worry, doesn't need to be coherent or well written, just
contain the information for the other developers to catch up on your
work), work can parallelize.

Hope you get my point.

> >> 14. Another question Piroumian has is how to validate against business
> >> logic. Since JavaScript is tightly integrated with Java, you can call Java
> >> logic from the flow script to do the business logic validation. This way you
> >> can invoke whatever logic you want. If this is too generic, then provide
> >> some use case and I'll try to sketch a solution.
> >
> > I think you should provide a real-life example of use of a java data
> > model to show how java can be called from the flowscript.
> 
> This too is on my TODO list ;)

Ok, please, make *your* TODO list *ours*. :)

And don't worry if you don't have time, nobody really does... and who
does is wasting it to work on something so stupid as Cocoon instead of
appreciating what they have in their life, myself first :(

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Re: [RT] Flowscript [was Re: [RT] Flowmaps]

Posted by Ovidiu Predescu <ov...@apache.org>.
On 6/18/02 8:35 AM, "Stefano Mazzocchi" <st...@apache.org> wrote:

> Ovidiu Predescu wrote:
> [...]
>
>> First of all, I think the thanks should go to Christian Queinnec, who came
>> up with the idea, and to Christopher Oliver, who implemented continuations
>> in Rhino. I just put all the things together and implement the support in
>> Cocoon.
> 
> Once flow docos are in place, we'll make sure to give all credits to
> those who deserve it. For sure, you deserve lots of it.

Thanks!

>> 1. Stefano points out that flowmaps (I don't really like this term, a "map"
>> is more appropriate for state machines, how about flowscript instead?)
> 
> You are right. The concept of 'flowmap' came because of a mental
> parallel I had between a declarative approach and a procedural one...
> but after understanding that we don't need that, being the HTTP
> client/server model intrinsically declarative.
> 
> So +1 for 'flowscript'.

OK.

>> should not be considered as ordinary resources, but a separate concept. I
>> have no issue declaring them in a different way, just to emphasize this
>> point. So something like
>> 
>>   <map:flowscripts default="calculator">
>>    <map:flowscript name="calculator" language="javascript">
>>      <map:script src="calc.js"/>
>>    </map:flowscript>
>>   </map:flowscripts>
>> 
>> should be OK. 
> 
> Hmmm, call me picky, but what's wrong with
> 
>  <map:flowscripts default="calculator">
>   <map:flowscript name="calculator" src="calc.js"
> language="javascript"/>
>  </map:flowscripts>

Because my calculator implementation may be composed of multiple script
files. This is not the case in this simple example, but I may need to split
the implementation for clarity in multiple files. Having the ability to
specify multiple files by adding <map:script> as needed solves the problem.

>> Beside a different name for elements, the fundamental
>> difference between this syntax and Stefano's is that it allows multiple
>> files to contain the implementation of a flow script.
> 
> yes, this is also a parallel with any other sitemap concept, such as
> components, resources and views.

Yes.

> [...]
>
>> The transformer would probably work best when the continuation id is encoded
>> in the URL. When the id is encoded as a request parameter, there will be
>> some awareness required from the page designer to have this id enclosed
>> inside a form.
> 
> Many ask to make continuations ID as transparent as session IDs. Do you
> think this is possible/desirable?

I think it is both desirable and possible. I think the responsibility for
deciding this should be in the sitemap, and only in one place.

>> 3. (Stefano) Template languages other than XSP to be used with the flow
>> layer.
>> 
>> This should certainly be possible, I've started with XSP because it was very
>> easy to get implement. JSP and Velocity should be equally easy to implement
>> though. We just need somebody to do it ;)
> 
> Great. Please explain how then, because I think lack of knowledge and
> docos was the real issue (see how things changed with a single email)!

The only thing which needs to be implemented is the equivalent of the
jpath.xsl logicsheet. The idea of the logicsheet is very simple: to extract
data from a Java object model or DOM tree using XPath expressions. If you
look at the logicsheet, you'll get the idea.

> [...]
>
>> It
>> essentially allows you to have a page processed through a pipeline, and
>> continue the execution of the script. BTW, I think your sitemap snippet has
>> a bug in it, shouldn't it have the <map:match> names swapped?
>> 
>> Also in your callPipeline(), how does the output parameter get used?
> 
> That's the key issue: many people, in the past, pointed out that they
> would like to reuse the concept of cocoon pipelines to create stuff but
> send it somewhere else, not back to the client.
> 
> Currently, there is no way for a pipeline stage to call another pipeline
> *detaching* it from the client output stream and attaching it a
> different output stream. I would like the flowscript to be able to do
> that.

Yes, that's right! HP's SOAP server based on Cocoon had to do some really
nasty things to achieve this. I see what you mean, and it should be
possible.

>> It
>> should be the task of the sitemap pipeline where the file is written. Am I
>> missing something?
> 
> It's *not* the sitemap concern to know where the output stream is. If
> you look at how the sitemap is implemented, it's the sitemap caller's
> concern to provide the output stream. Servlets call the sitemap engine
> passing the ResponseOutputStream and the CLI calls the sitemap engine
> passing FileOutputStreams.
> 
> But the granularity is all or nothing. I would like to be able to call a
> pipeline 'detaching it' from the output stream that the container
> passed.
> 
> Why? simply because it allows very creative uses of cocoon pipelines and
> would instantly stop all those requests for 'forking pipelines' that
> keep bugging me in the back of my mind.

OK, I get it! That's indeed a nice feature to have.

>> 5. Ivelin points out the potential of stale continuations.
>> 
>> I think this is indeed a real issue. One way to avoid it is to have
>> continuations automatically expire after a time of inactivity, or do
>> deactivate them manually in the flow script. The first approach is something
>> I considered, and there are some hooks in the current code, but more support
>> code needs to be written. The second approach can be implemented today: you
>> can invalidate not only a single continuation, but the whole subtree of
>> continuations which start from it. You just need to keep a hold on the
>> continuation at the top of the tree, and invoke invalidate() on it.
> 
> Speaking of which, would it good to have a 'continuation' object in the
> FOM?

It is already there, together with the data object. Check-out the jpath.xsl
logicsheet to see how this works.

>> 6. Multi-page forms are not dominating, and continuation based compared to
>> even driven (GUI-like) programming approaches.
>> 
>> I used to program GUIs a lot, I think for certain things, event-driven is
>> better than using continuations. I do think however that continuations have
>> a place, especially for multi-page forms. Now I think it depends a lot on
>> the application, whether these forms are prevalent or not.
> 
> I agree and this is the reason why I think deprecating Actions is a bad
> thing (at least, today). We'll provide options and guidelines, users
> will decide what to do with the tools we provide.

OK.

>> 8. Vadim's idea about making the syntax easier.
>> 
>> I think the idea of having something as simple as:
>> 
>> <map:match pattern="calc/*">
>>   <map:flow method="calculator" continuation="{1}" />
>> </map:match>
>> 
>> makes a lot of sense. Using different matchers, the continuation id can be
>> extracted from the request parameters, cookies, you name it. The only
>> problem with it is that is a bit inflexible in terms of the URI design. If
>> I'd like to have calc/kont/*, there's no easy way to specify it.
>> 
>> So I'd say we can have two alternative ways of writing this: using the above
>> proposal and what is already implemented, for power users that want more
>> control. How about this?
> 
> Sorry, but I lost you here.

I think the idea is to have something which just works by default, with no
configuration necessary. In addition to this, more experienced developers
can use the current method, which is more complex. Vadim's proposal is for
the first method. What is already implemented in the current code is the
second method.

>> 9. Reinhard asks what happens if two different flow scripts have a function
>> with a similar name name.
>> 
>> Since the flow scripts have their own variable space (not now due to some
>> problems in the current implementation), there shouldn't be any problem.
>> Each flow script can use its own variable and function names, without
>> worrying about possible conflicts with other scripts.
> 
> Yes, and also I was thinking about having something like
> 
> <map:call flow="calculator" method="calculator"/>
> 
> that provides sort of namespacing and avoids collisions.

In the new scheme I'm working on, there's no potential for collisions, each
flow script has its own namespace, separated from the others.

> [...]
>
>> - automatic binding of JavaScript variables to form values. This would allow
>> you to declare something like:
>> 
>>   var username, password;
>> 
>>   // Send a page to collect the user name and the password
>>   sendPage("login.html");
>> 
>>   // When the user fills in the form and presses the submit button, the
>>   // script restarts here. The flow engine automatically binds the username
>>   // and password to the values submitted in the form.
>> 
>>   // make use of username and passwd here
> 
> I didn't know PHP had problems with this approach, but it smells a lot
> anyway. I'm always afraid of implicity behavior, expecially when it's
> user-triggerable.
> 
> This is not automatically a security hole, but it could become one since
> you are letting potential attackers one step closer to your door. And
> you are making things hidden so harder to spot.
> 
> I would be against anything so implicit.

No, no, I wanted to say something completely different. I replied to this
topic already, but I'll repeat it here to be clear.

The automatic binding happens under the strict control of the programmer.
What I was thinking to have is the ability to map a request parameter to a
script variable, _if_ the programmer requests so for a particular variable.
How the mapping is done is completely under the control of the programmer.

>> - automatic validation of form values on both server and client side. This
>> should allow the same piece of JavaScript validation code to be executed
>> both on the server and client side. More on this later.
>> 
>> 11. With respect to how to put a back button on a page, I think I replied to
>> this some time ago. The idea is to use the <jpath:continuation select="1"/>
>> which selects the previous continuation.
> 
> I agree with Torsten: I'd like to keep the flow layer detached from the
> jpath logicsheet. (I would also use -1 as well to indicate backwards)

Again, I was only lazy to come up with a new logicsheet, so I reused things
in the same logicsheet.

The counting starts from a node in the tree and goes upwards, that was the
reason why the number is positive. To me this makes more sense than using
negative numbers, but I have no strong opinions.

>> 13. Piroumian asks how to cancel a continuation.
>> 
>> As I mentioned in several ocasions, sendPage() returns the saved
>> continuation. If you want to cancel the continuation just invoke on it the
>> invalidate() method. It will cancel all the receiver and all the
>> continuations that inherit from it.
> 
> Cool. Ovidiu, we *definately* need more docs on what you wrote. It's
> simply too undocumented right now... don't need to be XML-ized edited or
> anything, just bare raw but with juicy info inside, we'll make them
> better ourselves.

Yes, I know it's undocumented. I spent a lot of time describing the ideas on
emails, but didn't actually takes those and put in a document. I'll try to
come up with some docs, but there are simply too many things to work on at
the same time ;)

>> 14. Another question Piroumian has is how to validate against business
>> logic. Since JavaScript is tightly integrated with Java, you can call Java
>> logic from the flow script to do the business logic validation. This way you
>> can invoke whatever logic you want. If this is too generic, then provide
>> some use case and I'll try to sketch a solution.
> 
> I think you should provide a real-life example of use of a java data
> model to show how java can be called from the flowscript.

This too is on my TODO list ;)

>> 16. Sylvain: should flow scripts be inherited by sub-sitemaps?
>> 
>> I'm not sure of the security implications of allowing them to be inherited:
>> what should be the behavior if a developer alters definitions from an
>> inherited flow script?
> 
> My perception is that flowscripts are not components and should not be
> inherited.

I think the same too, but I'll keep my eyes opened for counterexamples.

>> 17. The proposal to use map:call with "function(arg, arg, ...)".
>> 
>> I think this is more like a syntactic sugar than real value. I don't think
>> passing arguments via map:param would confuse people, the semantic is still
>> the same as function invocation.
> 
> All right, let's remove this.

OK.

>> 18. Access to continuations.
>> 
>> I think there is a bit of confusion of terms in this discussion. The
>> continuation id is passed in the HTTP request in some way or another: as
>> part of the URL, as a request parameter etc. This encoding should be visible
>> to the sitemap only. I'd very much like to have it hidden from the view
>> layer as well, so if we can avoid putting explicit URLs in page templates,
>> that would be great! This reduces the dependency between the URL design in
>> the sitemap and the view generation.
>> 
>> A continuation is a real object that lives on the server side, which is
>> represented by its id in the request. A continuation object is returned by
>> sendPage(). A continuation id is fairly much useless in a flow script, what
>> you really need is the continuation object itself, which contains this
>> information and more.
> 
> Yes, there is confusing between the 'continuation object' and the
> 'continuation id'.
> 
> Many don't like the fact that you have to explicitly pass along the
> 'continuation id', unlike sessions where the 'session id' is (generally)
> transparently passed back and forth (which was one of the biggest values
> of the Servlet API)

Yes, I should think of a better solution.

> [...]
>
>> 20. My job - thanks Stefano for bringing it up. Here's my shameless plug :)
>> If you think of using Cocoon for building Web apps or Web services, and you
>> need support in doing so, I am providing consultancy for doing it, anytime,
>> anywhere.
> 
> Good luck for all this!

Thanks!

Regards,
-- 
Ovidiu Predescu <ov...@apache.org>
http://www.geocities.com/SiliconValley/Monitor/7464/ (Apache, GNU, Emacs...)



---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org