You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Miles Elam <mi...@pcextremist.com> on 2004/11/23 01:44:24 UTC

[RT] function sources

A while back, Ugo brought up his idea for "A Groovy Kind of Sitemap" 
which met with some friction.  On the one hand was the camp that felt 
that the sitemap/flowscript dichotomy was a case of overseparation of 
concerns.  On the other was the camp that absolutely wanted to keep a 
general purpose programming language away from the main URI/HTTP 
decision tree.  At the time, I was firmly in the second camp.

This is not to say that I now want scripting code embedded in the 
sitemap.  Far from it.  I still believe that the logic and management 
issues are absolutely two distinct concerns that warrant a Great Wall 
of SoC(tm) between them.  However, the feelings of overseparation were 
not without cause.  Let's face it, it's a major PITA to make two 
matchers for every scripted source: one for the <map:call /> and one 
internal pipeline for the flowscript sendPage() output -- and then make 
sure they all stay in sync.

So what do you say to function sources?  "Say what," you say?  Pipeline 
components that take a function call as their source.  Now hold on!  I 
can feel you slipping away and the cries of FS echoing in the distance. 
  Try this on for size:

<map:match type="regexp" pattern="document-(\d+)">
   <map:generate type="file" src="mytemplate.jx"/>
   <map:transform type="jxtemplatetransformer" src="getDocument({1})"/>
   <map:serialize type="xml"/>
</map:match>

Wait!  Wait!  Don't leave yet!  I'm not saying that the "src" attribute 
a straight call to the flow interpreter as it exists today.  Not at 
all.  I'm actually suggesting that we've been so caught up in 
continuations, we've almost forgotten how to write scripts without 
them.  And why not?  There are three kinds of people in this world: 
those that don't do web development, those that love continuations and 
those that don't know what continuations are.  But set aside 
continuations for now.  They are but one type of scripting contract.

What if there was an alternate scripting contract?  One that instead of 
requiring a sendPage, sendPageAndWait or redirect-to call, requires 
that *none* of these exist in the code path and that an object context 
is returned like the parameter of the sendPage* functions.

function getDocument (docid) {
   var myObject;
   //
   // *** hypothetical Hibernate call with a lookup via docid,
   // assignment to myObject and other sundry details ***
   //
   return myObject;
}

And why not?  Because it's a dynamic/scripted source?  Can you 
guarantee that src="http://someserver/foo" is not completely dynamic 
and backed by a script?  The contract strength is the same in that the 
source must follow certain expectations for the pipeline up to this 
point.  "src" is an injection of data.  Nothing more.  Nothing less.  
So yes, the object data could indeed be a content source and nicely fit 
into the "src" attribute paradigm.

Logic is kept at arm's length from the sitemap AND there are no blind 
"where's in coming out" logic paths.

So the following questions remain:
1. Does this ease overseparation concerns somewhat?
2. Does this avoid gratuitous FS-syndrome?
3. How easy would it be to wire this into the existing codebase (eg. 
JXTemplateTransformer)?
4. Could the same flow engine be used but with a different set of 
default objects/interfaces?
5. Am I completely off my rocker?

I think the answers to 1-3 are "yes".  I'm not familiar enough with 4 
to make any comment.  5 I'll leave as an exercise for the reader.

- Miles Elam


Re: [RT] function sources

Posted by Peter Hunsberger <pe...@gmail.com>.
On Wed, 24 Nov 2004 12:15:27 -0800, Miles Elam <mi...@pcextremist.com> wrote:
> On Nov 24, 2004, at 7:31 AM, Peter Hunsberger wrote:
> 
> 
> 
> > On Tue, 23 Nov 2004 12:16:16 -0800, Miles Elam <mi...@pcextremist.com>
> > wrote:
> >> Yes.  The "src" attribute is a String.  What you do with that String
> >> has always been implementation dependent.  It's just that the
> >> implementation has always (?) been to use the SourceResolver
> >> exclusively.
> >
> > I think that others are saying you can do your proposal by having the
> > source resolver understand a "script" source, which makes sense to me.
> >  IOW, really you just need to wrap the return from script engine to
> > that it can look like  a source and you've got what you want.  So, it
> > continues to exclusively go to the SourceResolver.  But this isn't the
> > complete answer, read on...
> 
> Yes, Vadim's suggestion has definitely rubbed me the right way.
> 
> > Note that, so far, having a scriptable source hasn't removed any need
> > for continuations because it doesn't address the issue of mapping the
> > source to the action.  To do this you'd need a new concept even beyond
> > sources, which I think is what you're trying to get at?
> 
> I'm a little confused as to where you're going with this so I am
> hesitant to comment authoritatively.  Sources have thus far been given
> a string, it's been processed, and a data chunk has been returned.  

Right, you haven't gotten rid of continuations in any way...

> I
> don't see that model changed by the addition of a script source.  What
> is required after looking into it is a change to the Interpreter
> interface, FOM_JavascriptInterpreter class, and the addition of an
> alternate to FOM_Cocoon.  As much as this might seem for a pet feature,
> it is actually not that bad.
> 
> In addition to the existing method:
> 
>     void callFunction(String funName, List params, Redirector
> redirector)
> 
> I propose the following variant be added to codify/enforce this new
> contract:
> 
>     Object callFunction(String funName, List params)
> 
> Whether it should be an Object return value (what is returned from the
> script function) or Serializable or ScriptableObject, I'm not sure.
> But it is my opinion that the script source should *absolutely not*
> break the pipeline viewpoint.  To do so would be extremely intrusive
> the existing design and codebase.  More on this last point later.

If you're fine with just having the scriptable source that's ok by me,
but in your original post part of your motivation seemed to be to get
rid of having to code a second sitemap fragment that wasn't obviously
glued to the original sitemap invocation of the flowscript.  Just
having a scriptable source doesn't solve that unless you're willing to
go back to using actions?

> 
> > Let's consider this second thing; what you'd need is some new source,
> > lets call it "continuable-script".  Then in your sitemap you'd do:
> >
> > continuable-script:myfunc(...)
> 
> Oh for the love of God, no!  Explaining later.
> 
> > I think this makes some sense, but what you're asking for is more than
> > a source.  You're asking for a transparent hook into continuations
> > handling that eliminates the need for a second sitemap fragment, but
> > does not eliminate continuations.
> 
> No no no!  I want no part of continuations *at all* in this proposal.
> I'm suggesting that the existing interpreter handling be used, but the
> processing model would not include continuations in the equation.
> Coming up on the full explanation now.
> 
> > I'm not sure I'd want any kind of magic default handling either, I was
> > just throwing the idea out to see if it had any resonance with the
> > rest of the issue.  Now that I think I've got the entire concept of
> > what you're asking for I think your idea is a little cleaner.
> 
> Okay.  To clarify, adding support for calling a code path with
> continuations would have so many unintended consequences, it boggles
> the mind.  Let's say the script source is invoked from a transformer.
> If sendPageAndWait was called in the code, not only the programming
> stack must be serialized/persisted but the current status of the active
> pipeline up until the transformer in question.  What happens if the
> generator hasn't already finished sending it's SAX events?  What
> happens if the pipeline has already started sending data before the
> script function is called?  How do you restore state in arbitrary
> sitemap components.  Such a headache with little to no return on
> investment.

You missed the point here: the continuation isn't invoked immediately.
 It's invoked after serialization of the pipeline is complete.  The
"sendSource" function signals that this chunk of script has finished
creating some source object and is ready to hand it back to the
regular pipeline processing.  Now the pipeline resumes process as
normal except after serialization is completed you finish off creating
the dangling continuation.  The pattern becomes:

        <map:match pattern="*/foo/*">
            <map:aggregate element="wrapper">
                    <map:part src="cocoon:/{../1}/bar"/>
                    <map:part src="scriptable-source:myfunc({2})"/>
            </map:aggregate>
            <map:transform src="stylesheets/blxsl"/>
            <map:transform src="stylesheets/uixsl"/>
            <map:serialize type="xml"/>
        </map:match>

where the scriptable source looks like:

function myfunc( srcname )   {
        ...
var sourceBuilder = Packages.org...SomeClass();
var source = sourceBuilder.create( srcname, cocoon );  // Or such 
sendSource( source, params );   // Waits for continuation to complete
     ....
}

The "sendSource" doesn't immeaditely invoke the continuation.  Sorry
if I didn't explain this better but I assumed this was what you where
really after...  The benfit is that you now have a clear single
mapping of single pipeline fragment to single script fragment.

The ability to stack multiple sources into this mess really (via
aggregate or by sending them to a transform) doesn't really change
things, except that you've now got scripts wrapping scripts and
keeping things straight could get complicated.   Thus I should make it
clear you want both sendSource and a regular "return object" path out
of the script.  If you need multiple things on the return then maybe
you end up with sendSource and sendSourceAndWait (where the latter
assumes the semantics I've described to this point).

Thinking about it this points out you only need "script" as a source,
since the decision to invoke the continuation is made in the script
(sendSource vs. return). continuable-script isn't needed...

> This means that sendPage, sendPageAndWait and even redirect-to *must
> not ever* appear in the codepath.  In addition, I'm finding that access
> to the response object should be restricted as well.  I'm on the fence
> about setting cookies too.  Session data is open season though with the
> exception of invalidating the session altogether.  Once again, hidden
> side effects.
> 
> In the end, I'm aiming for a solution where looking at the sitemap
> tells you exactly what's going on from a high-level perspective.  I
> definitely do not want to jeopardize this management contract.  The
> script source gets invoked, it gets its data, it returns the data to
> the pipeline component and normal pipeline processing resumes
> uninterrupted.

Yes, I agree and that's what I want also.  What I think you're leaving
out is the action handling side of things?  If you don't want
continuations you've got to have actions.  Just sending a source to a
pipeline doesn't get rid of continuations?

> 
> > I meant implementation point of view.  With the new concept I'm not
> > sure you've separated concerns since now a single script has the
> > responsibility of producing both the source and then handling the
> > action upon return.  I don't really have a problem with this, maybe
> > others will?
> 
> How so?  What I'm proposing basically just says, "Give me data."  The
> pipeline is still responsible for what gets returned to the client.  Or
> were you referring to the fact that they both call the same JavaScript
> source files specified in the <map:flow> sitemap directive?  If so, I
> think separating them at that level would introduce more hardship, not
> lessen it.  I'm all about lessening hardship.

Yes, I was referring to the fact that you might have just a single
JavaScript file.  As I said I don't see a real problem with this...

> 
> > I think the complete implementation as I've sketched out is a tad
> > harder than just a source wrapper around a script produced object!  I
> > still think it sounds doable, but I've been through some of this code
> > and it it takes a lot of little turns and twists and this wouldn't
> > make it any simpler!
> 
> Looking closer at the problem, I see the following changes necessary:
> 
> 1. Script source resolver parses function call and arguments and passes
> them to...
> 2. An Interpreter method call that does not include a redirector
> where...
> 3. Processing this call neglects to put in any continuation plumbing
> normally associated with it and...
> 4. Instantiating a stripped down clone of FOM_Cocoon that does not have
> continuation, response or sendPage* handling (a SOM_Cocoon/Scripting
> Object Model if you will) which is then...
> 5. Passed to the JavaScript engine for processing to do the actual work
> and return a value to...
> 6. The script source which exposes the returned object (Object
> reference or InputStream?) to the pipeline component
> 
> The rest of the code seems to be there already.  When the script
> function only has the functionality necessary to do what is expected,
> the contract is enforced.  Accidental sendPage and redirect-to calls
> would result in runtime errors just like any call to a non-existent
> variable/function.  Return statements in "normal" flow function return
> an error.  Fail fast.  Fail loudly.  Fail clearly.

I'm still missing how you handle POST actions?

> >>>> 4. Could the same flow engine be used but with a different set of
> >>>> default objects/interfaces?
> >>>
> >>> I think so.
> >
> > Yes, in fact you'd want almost exactly today's code for the
> > implementation I describe, you basically just break sendPage into two
> > parts, one handled at "sendSource" time and the other when the
> > serializer terminates.  I have no idea how to glue the two pieces
> > together over the duration of the sitemap traversal of the rest of the
> > pipeline (or if it' really possible); I think it's some kind of
> > context stack but you need a pipeline expert to answer that question.
> 
> Ah!  Now I see the difference in our approaches/expectations.  You are
> assuming that the flow interpreter is in charge.  For standard flow, I
> agree that it is.  For my examples, I've been working under the
> assumption that it is not.  I'm making calls to a scripting interpreter
> for the duration of a function call, but the sitemap never truly
> relinquishes control.  The pipeline processing asks for data from the
> interpreter, and when that data is received, the pipeline resumes.  No
> sendPage/sendSource clones.  The called function returns useful data or
> it doesn't.  That amounts to a return statement.  No fanciness or
> special handling required at all.

Right, that's Vadm's simple plug in for source generation via a
script.  That doesn't get you everything you asked for in your
original e-mail...

> 
> -----
> 
> Oh!  Here's an issue.  How and where does the script source get a
> reference to the interpreter?  It would be dependent upon the
> sitemap/subsitemaps and their respective flow declarations.  Where does
> the handoff take place?

Now you're jumping into a completely different issue: the discussion
of relative/absolute URI resolution and subsitemaps and VPC's.  I'd
just assume that that get's ironed out in accordance with some of the
recent discussions and let the sitemap engine handle the invocation as
it sees fit? That is, sitemaps already know how to call the
interpreter....

-- 
Peter Hunsberger

Re: [RT] function sources

Posted by Miles Elam <mi...@pcextremist.com>.
On Nov 24, 2004, at 7:31 AM, Peter Hunsberger wrote:

> On Tue, 23 Nov 2004 12:16:16 -0800, Miles Elam <mi...@pcextremist.com> 
> wrote:
>> Yes.  The "src" attribute is a String.  What you do with that String
>> has always been implementation dependent.  It's just that the
>> implementation has always (?) been to use the SourceResolver
>> exclusively.
>
> I think that others are saying you can do your proposal by having the
> source resolver understand a "script" source, which makes sense to me.
>  IOW, really you just need to wrap the return from script engine to
> that it can look like  a source and you've got what you want.  So, it
> continues to exclusively go to the SourceResolver.  But this isn't the
> complete answer, read on...

Yes, Vadim's suggestion has definitely rubbed me the right way.

> Note that, so far, having a scriptable source hasn't removed any need
> for continuations because it doesn't address the issue of mapping the
> source to the action.  To do this you'd need a new concept even beyond
> sources, which I think is what you're trying to get at?

I'm a little confused as to where you're going with this so I am 
hesitant to comment authoritatively.  Sources have thus far been given 
a string, it's been processed, and a data chunk has been returned.  I 
don't see that model changed by the addition of a script source.  What 
is required after looking into it is a change to the Interpreter 
interface, FOM_JavascriptInterpreter class, and the addition of an 
alternate to FOM_Cocoon.  As much as this might seem for a pet feature, 
it is actually not that bad.

In addition to the existing method:

     void callFunction(String funName, List params, Redirector 
redirector)

I propose the following variant be added to codify/enforce this new 
contract:

     Object callFunction(String funName, List params)

Whether it should be an Object return value (what is returned from the 
script function) or Serializable or ScriptableObject, I'm not sure.  
But it is my opinion that the script source should *absolutely not* 
break the pipeline viewpoint.  To do so would be extremely intrusive 
the existing design and codebase.  More on this last point later.

> Let's consider this second thing; what you'd need is some new source,
> lets call it "continuable-script".  Then in your sitemap you'd do:
>
> continuable-script:myfunc(...)

Oh for the love of God, no!  Explaining later.

> I think this makes some sense, but what you're asking for is more than
> a source.  You're asking for a transparent hook into continuations
> handling that eliminates the need for a second sitemap fragment, but
> does not eliminate continuations.

No no no!  I want no part of continuations *at all* in this proposal.  
I'm suggesting that the existing interpreter handling be used, but the 
processing model would not include continuations in the equation.  
Coming up on the full explanation now.

> I'm not sure I'd want any kind of magic default handling either, I was
> just throwing the idea out to see if it had any resonance with the
> rest of the issue.  Now that I think I've got the entire concept of
> what you're asking for I think your idea is a little cleaner.

Okay.  To clarify, adding support for calling a code path with 
continuations would have so many unintended consequences, it boggles 
the mind.  Let's say the script source is invoked from a transformer.  
If sendPageAndWait was called in the code, not only the programming 
stack must be serialized/persisted but the current status of the active 
pipeline up until the transformer in question.  What happens if the 
generator hasn't already finished sending it's SAX events?  What 
happens if the pipeline has already started sending data before the 
script function is called?  How do you restore state in arbitrary 
sitemap components.  Such a headache with little to no return on 
investment.

This means that sendPage, sendPageAndWait and even redirect-to *must 
not ever* appear in the codepath.  In addition, I'm finding that access 
to the response object should be restricted as well.  I'm on the fence 
about setting cookies too.  Session data is open season though with the 
exception of invalidating the session altogether.  Once again, hidden 
side effects.

In the end, I'm aiming for a solution where looking at the sitemap 
tells you exactly what's going on from a high-level perspective.  I 
definitely do not want to jeopardize this management contract.  The 
script source gets invoked, it gets its data, it returns the data to 
the pipeline component and normal pipeline processing resumes 
uninterrupted.

> I meant implementation point of view.  With the new concept I'm not
> sure you've separated concerns since now a single script has the
> responsibility of producing both the source and then handling the
> action upon return.  I don't really have a problem with this, maybe
> others will?

How so?  What I'm proposing basically just says, "Give me data."  The 
pipeline is still responsible for what gets returned to the client.  Or 
were you referring to the fact that they both call the same JavaScript 
source files specified in the <map:flow> sitemap directive?  If so, I 
think separating them at that level would introduce more hardship, not 
lessen it.  I'm all about lessening hardship.

> I think the complete implementation as I've sketched out is a tad
> harder than just a source wrapper around a script produced object!  I
> still think it sounds doable, but I've been through some of this code
> and it it takes a lot of little turns and twists and this wouldn't
> make it any simpler!

Looking closer at the problem, I see the following changes necessary:

1. Script source resolver parses function call and arguments and passes 
them to...
2. An Interpreter method call that does not include a redirector 
where...
3. Processing this call neglects to put in any continuation plumbing 
normally associated with it and...
4. Instantiating a stripped down clone of FOM_Cocoon that does not have 
continuation, response or sendPage* handling (a SOM_Cocoon/Scripting 
Object Model if you will) which is then...
5. Passed to the JavaScript engine for processing to do the actual work 
and return a value to...
6. The script source which exposes the returned object (Object 
reference or InputStream?) to the pipeline component

The rest of the code seems to be there already.  When the script 
function only has the functionality necessary to do what is expected, 
the contract is enforced.  Accidental sendPage and redirect-to calls 
would result in runtime errors just like any call to a non-existent 
variable/function.  Return statements in "normal" flow function return 
an error.  Fail fast.  Fail loudly.  Fail clearly.

>>>> 4. Could the same flow engine be used but with a different set of
>>>> default objects/interfaces?
>>>
>>> I think so.
>
> Yes, in fact you'd want almost exactly today's code for the
> implementation I describe, you basically just break sendPage into two
> parts, one handled at "sendSource" time and the other when the
> serializer terminates.  I have no idea how to glue the two pieces
> together over the duration of the sitemap traversal of the rest of the
> pipeline (or if it' really possible); I think it's some kind of
> context stack but you need a pipeline expert to answer that question.

Ah!  Now I see the difference in our approaches/expectations.  You are 
assuming that the flow interpreter is in charge.  For standard flow, I 
agree that it is.  For my examples, I've been working under the 
assumption that it is not.  I'm making calls to a scripting interpreter 
for the duration of a function call, but the sitemap never truly 
relinquishes control.  The pipeline processing asks for data from the 
interpreter, and when that data is received, the pipeline resumes.  No 
sendPage/sendSource clones.  The called function returns useful data or 
it doesn't.  That amounts to a return statement.  No fanciness or 
special handling required at all.

-----

Oh!  Here's an issue.  How and where does the script source get a 
reference to the interpreter?  It would be dependent upon the 
sitemap/subsitemaps and their respective flow declarations.  Where does 
the handoff take place?

- Miles Elam


Re: [RT] function sources

Posted by Peter Hunsberger <pe...@gmail.com>.
On Tue, 23 Nov 2004 12:16:16 -0800, Miles Elam <mi...@pcextremist.com> wrote:
> On Nov 23, 2004, at 11:30 AM, Peter Hunsberger wrote:
> 
> > On Mon, 22 Nov 2004 16:44:24 -0800, Miles Elam <mi...@pcextremist.com>
> > wrote:
> >> So what do you say to function sources?
> >
> > Interesting.  Did you read my post yesterday on generic generators?
> 
> I hadn't then.  I just did.  It looks like we're on the same page and
> trying to solve similar problems from different points of view.
> 
> > In order to exploit such a beast you want to be able to wrap a source
> > with a liittle extra ornamentation than you normally do today.
> > It seems to me In a way that in a way we're attacking the same problem?
> 
> Yes.  The "src" attribute is a String.  What you do with that String
> has always been implementation dependent.  It's just that the
> implementation has always (?) been to use the SourceResolver
> exclusively.

I think that others are saying you can do your proposal by having the
source resolver understand a "script" source, which makes sense to me.
 IOW, really you just need to wrap the return from script engine to
that it can look like  a source and you've got what you want.  So, it
continues to exclusively go to the SourceResolver.  But this isn't the
complete answer, read on...

> > However, with a generic generator the existing sitemap and sendpage
> > remain, you just don't have to add any new target sitemap pipelines
> > for the flowscript functions since everything can go to the same
> > pipeline (which contains the generic generator).  Obviously this
> > doesn't apply if you want different transforms, we use a single
> > styling transform for 80% of our target pages anyway.
> 
> I don't want sendPage to go anywhere.  I love sendPage.  But this
> problem is not the same problem that sendPage solves.  In fact, it only
> loosely parallels the current usage of flow.  The only thing in common
> is a scripting language and passing objects to the caller.
> Continuations are not just an inconvenience.  They are the wrong
> approach in my opinion.

Well if you look at the perspective of "script:myfunc()" being a
source that calls the script engine you've still got continuations and
everything else available as you do today.  A script based source
looks to me like the input side of the continuations which can then
focus more exclusively on the action side.  This lets your script be
divided up into two seperate areas of concern also (so you're code is
even more broken up than before!).  Now potentially you've got:

sitemap -> script source -> flowscript -> [browser] -> 
sitemap -> continuation -> flowscript

(Or you can just skip continuations and write an action handler as
before, but that's definitely not what we want!)

Note that, so far, having a scriptable source hasn't removed any need
for continuations because it doesn't address the issue of mapping the
source to the action.  To do this you'd need a new concept even beyond
sources, which I think is what you're trying to get at?

Let's consider this second thing; what you'd need is some new source,
lets call it "continuable-script".  Then in your sitemap you'd do:

continuable-script:myfunc(...)

The continuable-script would then do a sendSource (equivalent to a
sendPage) at the point it thinks it is done producing the source data
(so to speak).  This would cause the flow script to return to the
sitemap which would then finish up more-or-less as normal, but all the
while retaining the context of the dangling sendSource.  Basically
SendSource would create some sort of flag/stack (?) that tells the
sitemap handler to treat the termination of the serializer as the
point to jump back into the rest of the flowscript sendPage handling
and at that point the normal sendPage handling would resume but
without the requirement for a second sitemap fragment.  This, I think
achieves what you're asking for?

I think this makes some sense, but what you're asking for is more than
a source.  You're asking for a transparent hook into continuations
handling that eliminates the need for a second sitemap fragment, but
does not eliminate continuations.

The biggest issue with this proposal is what happens if multiple
sitemap components invoke a continuable-script source?  I think the
answer is that you just stack up the continuations in a LIFO stack
handling them in reverse order upon return, but maybe others can see
issues with this?  From a conceptual point of view that could
potentially be very powerful but I get dizzy trying to figure out any
real use-cases; I'm sure I could invent some kind of UI/business logic
separation use-case, but at the moment I'm fighting a cold so I drop
this for future conversations if the idea seems worth pursuing at
all...

<snip>example discussion</snip>
> 
> > <snip>src generation description</snip>
> >
> >> Logic is kept at arm's length from the sitemap AND there are no blind
> >> "where's in coming out" logic paths.
> >
> > What if you could declare a pipeline "default" so that a "sendPage"
> > would always go to the default if no other match was found? Doesn't
> > solve the other issues, but helps with this one?
> 
> It would work, but have never been in favor of deceiving the developer
> in the name of a hack.  sendPage has a well-defined purpose.
> Short-circuiting that purpose will only lead to confusion.  If sendPage
> is causing the problem, it needs to be removed from that solution set,
> not gutted of its functionality.  Hence my terminology that function
> sources define a completely new contract that cannot be directly
> overlayed on top of the old.

I'm not sure I'd want any kind of magic default handling either, I was
just throwing the idea out to see if it had any resonance with the
rest of the issue.  Now that I think I've got the entire concept of
what you're asking for I think your idea is a little cleaner.

> >> So the following questions remain:
> >> 1. Does this ease overseparation concerns somewhat?
> >
> > Not sure, other simpler things might also help here.
> 
> Simpler from a conceptual standpoint or simpler from an implementation
> standpoint?

I meant implementation point of view.  With the new concept I'm not
sure you've separated concerns since now a single script has the
responsibility of producing both the source and then handling the
action upon return.  I don't really have a problem with this, maybe
others will?

> >> 2. Does this avoid gratuitous FS-syndrome?
> >
> > Not sure, seems a little strange.  I like the idea of being able to
> > build up  the source definition in flowscript.  I'm not sure if I'm
> > understanding exactly how you see it interacting with the sitemap.
> 
> From the user point of view?  The "src" attribute.  I see your point
> about making the contract clearer though.  Have any suggestions? 

I think I've sketched it out above? Basically it's your concept just
slightly rephrased...

> Bear
> in mind that only sitemap components that know how to handle the
> functionality will use it (eg. ones that don't use SourceResolver).  It
> would seem incredibly foolish to create a component that used "src" in
> this way and not even documenting that fact in the Javadocs.  I guess
> stranger things have happened though.
> 
> >> 3. How easy would it be to wire this into the existing codebase (eg.
> >> JXTemplateTransformer)?
> >
> > I think so.
> 
> Thanks for answering my poorly worded question.  I meant to say, "Would
> it be easy to wire this..."

I think the complete implementation as I've sketched out is a tad
harder than just a source wrapper around a script produced object!  I
still think it sounds doable, but I've been through some of this code
and it it takes a lot of little turns and twists and this wouldn't
make it any simpler!

> >> 4. Could the same flow engine be used but with a different set of
> >> default objects/interfaces?
> >
> > I think so.
> >

Yes, in fact you'd want almost exactly today's code for the
implementation I describe, you basically just break sendPage into two
parts, one handled at "sendSource" time and the other when the
serializer terminates.  I have no idea how to glue the two pieces
together over the duration of the sitemap traversal of the rest of the
pipeline (or if it' really possible); I think it's some kind of
context stack but you need a pipeline expert to answer that question.

-- 
Peter Hunsberger

Re: [RT] function sources

Posted by Miles Elam <mi...@pcextremist.com>.
On Nov 23, 2004, at 11:30 AM, Peter Hunsberger wrote:

> On Mon, 22 Nov 2004 16:44:24 -0800, Miles Elam <mi...@pcextremist.com> 
> wrote:
>> So what do you say to function sources?
>
> Interesting.  Did you read my post yesterday on generic generators?

I hadn't then.  I just did.  It looks like we're on the same page and 
trying to solve similar problems from different points of view.

> In order to exploit such a beast you want to be able to wrap a source
> with a liittle extra ornamentation than you normally do today.
> It seems to me In a way that in a way we're attacking the same problem?

Yes.  The "src" attribute is a String.  What you do with that String 
has always been implementation dependent.  It's just that the 
implementation has always (?) been to use the SourceResolver 
exclusively.

> However, with a generic generator the existing sitemap and sendpage
> remain, you just don't have to add any new target sitemap pipelines
> for the flowscript functions since everything can go to the same
> pipeline (which contains the generic generator).  Obviously this
> doesn't apply if you want different transforms, we use a single
> styling transform for 80% of our target pages anyway.

I don't want sendPage to go anywhere.  I love sendPage.  But this 
problem is not the same problem that sendPage solves.  In fact, it only 
loosely parallels the current usage of flow.  The only thing in common 
is a scripting language and passing objects to the caller.  
Continuations are not just an inconvenience.  They are the wrong 
approach in my opinion.

> I'm a little confused as to why you show the sitemap source connected
> to the transformer instead of the generator?

The JXTemplateGenerator is pulling data from two sources: the template 
file and the data from flow.  I chose a transformer so that each piece 
performed exactly one data gathering action.  Virtual pipeline 
components could mask the separation of the two if you made a virtual 
generator that was a combination of a file generator and a jx 
transformer.  The parsing has to happen anyway, and if the parsing is 
actually a bottleneck in your overall app compared to data acquisition, 
the parsing algorithm is horribly faulty or your data acquisition is by 
far the fastest on the planet.  FileGenerator caches, so reparsing 
isn't an issue.

> <snip>src generation description</snip>
>
>> Logic is kept at arm's length from the sitemap AND there are no blind
>> "where's in coming out" logic paths.
>
> What if you could declare a pipeline "default" so that a "sendPage"
> would always go to the default if no other match was found? Doesn't
> solve the other issues, but helps with this one?

It would work, but have never been in favor of deceiving the developer 
in the name of a hack.  sendPage has a well-defined purpose.  
Short-circuiting that purpose will only lead to confusion.  If sendPage 
is causing the problem, it needs to be removed from that solution set, 
not gutted of its functionality.  Hence my terminology that function 
sources define a completely new contract that cannot be directly 
overlayed on top of the old.

>> So the following questions remain:
>> 1. Does this ease overseparation concerns somewhat?
>
> Not sure, other simpler things might also help here.

Simpler from a conceptual standpoint or simpler from an implementation 
standpoint?

>> 2. Does this avoid gratuitous FS-syndrome?
>
> Not sure, seems a little strange.  I like the idea of being able to
> build up  the source definition in flowscript.  I'm not sure if I'm
> understanding exactly how you see it interacting with the sitemap.

 From the user point of view?  The "src" attribute.  I see your point 
about making the contract clearer though.  Have any suggestions?  Bear 
in mind that only sitemap components that know how to handle the 
functionality will use it (eg. ones that don't use SourceResolver).  It 
would seem incredibly foolish to create a component that used "src" in 
this way and not even documenting that fact in the Javadocs.  I guess 
stranger things have happened though.

>> 3. How easy would it be to wire this into the existing codebase (eg.
>> JXTemplateTransformer)?
>
> I think so.

Thanks for answering my poorly worded question.  I meant to say, "Would 
it be easy to wire this..."

>> 4. Could the same flow engine be used but with a different set of
>> default objects/interfaces?
>
> I think so.
>
>> 5. Am I completely off my rocker?
>
> Probably, but who isn't?

LOL!

- Miles Elam


Re: [RT] function sources

Posted by Peter Hunsberger <pe...@gmail.com>.
On Mon, 22 Nov 2004 16:44:24 -0800, Miles Elam <mi...@pcextremist.com> wrote:
> A while back, Ugo brought up his idea for "A Groovy Kind of Sitemap"
> which met with some friction.  On the one hand was the camp that felt
> that the sitemap/flowscript dichotomy was a case of overseparation of
> concerns.  On the other was the camp that absolutely wanted to keep a
> general purpose programming language away from the main URI/HTTP
> decision tree.  At the time, I was firmly in the second camp.
> 
> This is not to say that I now want scripting code embedded in the
> sitemap.  Far from it.  I still believe that the logic and management
> issues are absolutely two distinct concerns that warrant a Great Wall
> of SoC(tm) between them.  However, the feelings of overseparation were
> not without cause.  Let's face it, it's a major PITA to make two
> matchers for every scripted source: one for the <map:call /> and one
> internal pipeline for the flowscript sendPage() output -- and then make
> sure they all stay in sync.
> 
> So what do you say to function sources? 

Interesting.  Did you read my post yesterday on generic generators? 

http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=110114534905358&w=2

In order to exploit such a beast you want to be able to wrap a source
with a liittle extra ornamentation than you normally do today. It
seems to me In a way that in a way we're attacking the same problem?
However, with a generic generator the existing sitemap and sendpage
remain, you just don't have to add any new target sitemap pipelines
for the flowscript functions since everything can go to the same
pipeline (which contains the generic generator).  Obviously this
doesn't apply if you want different transforms, we use a single
styling transform for 80% of our target pages anyway.

I'm a little confused as to why you show the sitemap source connected
to the transformer instead of the generator?

<snip>src generation description</snip>

> Logic is kept at arm's length from the sitemap AND there are no blind
> "where's in coming out" logic paths.

What if you could declare a pipeline "default" so that a "sendPage"
would always go to the default if no other match was found? Doesn't
solve the other issues, but helps with this one?

> So the following questions remain:
> 1. Does this ease overseparation concerns somewhat?

Not sure, other simpler things might also help here.

> 2. Does this avoid gratuitous FS-syndrome?

Not sure, seems a little strange.  I like the idea of being able to
build up  the source definition in flowscript.  I'm not sure if I'm
understanding exactly how you see it interacting with the sitemap.

> 3. How easy would it be to wire this into the existing codebase (eg.
> JXTemplateTransformer)?

I think so.

> 4. Could the same flow engine be used but with a different set of
> default objects/interfaces?

I think so.

> 5. Am I completely off my rocker?

Probably, but who isn't?

> 
> I think the answers to 1-3 are "yes".  I'm not familiar enough with 4
> to make any comment.  5 I'll leave as an exercise for the reader.

-- 
Peter Hunsberger

Re: [RT] function sources

Posted by Miles Elam <mi...@pcextremist.com>.
On Nov 23, 2004, at 12:23 AM, Leszek Gawron wrote:

> Miles Elam wrote:
>> Try this on for size:
>> <map:match type="regexp" pattern="document-(\d+)">
>>   <map:generate type="file" src="mytemplate.jx"/>
>>   <map:transform type="jxtemplatetransformer" src="getDocument({1})"/>
>>   <map:serialize type="xml"/>
>> </map:match>
> Hmm what did you mean by that? JXTT is not parametrizable with src so 
> did you mean:
>
> <map:match type="regexp" pattern="document-(\d+)">
>   <map:generate type="jx" src="getDocument({1})"/>
>   <map:serialize type="xml"/>
> </map:match>

No, my example was a hypothetical, not based on current code.

>> What if there was an alternate scripting contract?  One that instead 
>> of requiring a sendPage, sendPageAndWait or redirect-to call, 
>> requires that *none* of these exist in the code path and that an 
>> object context is returned like the parameter of the sendPage* 
>> functions.
>> function getDocument (docid) {
>>   var myObject;
>>   //
>>   // *** hypothetical Hibernate call with a lookup via docid,
>>   // assignment to myObject and other sundry details ***
>>   //
>>   return myObject;
>> }
> something like this was already possible when it was not required for 
> the flowscript function to invoke sendPage or sendPageAndWait. Then 
> you could do something like:
>
> <map:match pattern="someUri">
>   <map:call function="myFunction">
>     <!-- the function stores result in request attribute -->
>     <map:generate src="request-attr:mydata" type="jx"/>
>     <map:serialize type="xml"/>
>   </map:call>
> </map:match>

No, that's not what I mean.  That is subverting an existing contract.  
I don't want to alter the map:call syntax at all.  It is great the way 
it is.  I'm talking about establishing a new scripting contract -- a 
separate contract -- one that specifically forbids the use of 
sendPage*() and redirect-to().

> This is like the function was an action really (which I found kind of 
> nice for fasst scripting actions - I usually used XSPs for that one 
> but the startup time was killing me, syntax also).
>
> Now this call wouldn't succeed. Every call to a function must result 
> with sendPage.

With the current flowscript, yes.  Once again, talking about a 
different contract.  I'm talking about finding some middle ground 
between a continuation-based flow model and the piecemeal 
sitemap/action model.  In other words, the ease of writing flow -- 
which let's face it, is much more convenient than writing an action -- 
with a reduction of scope where redirection is not possible, only data 
gathering.

I proposed the "src" attribute as a data vector because (a) that is an 
accepted data source input point, (b) a sitemap component would have to 
be rewritten anyway to take advantage, mitigating the action 
alternative, and (c) it's easier for users to conceptualize while 
simultaneously respecting SoC.  For a quick "get-in-get-out" problem, 
this would work.  Once they need to go to multiple pages and alternate 
outputs, they graduate to map:call and the continuation model; They 
switch to a different contract that fits their needs.

This would also serve as an easy introductory alternative to XSPs.  Not 
only does it respect SoC better than XSPs (which don't respect it at 
all), but the code reuse in flow would be a boon as well.  Continuation 
code could call the simple data gathering function they've already 
written.  The developer simply cannot write a simple data gathering 
function that calls continuation code.  It's a fail-fast model where 
the developer knows very quickly that they're doing something wrong.  
It's also a more natural transition from the simple publishing model to 
the interactive data processing model.

Function sources are a very specific, directed option unlike the use of 
an action.  With an action -- let's say an action was made to make 
non-exiting/non-continuation function calls -- you are talking about 
more complexity and far more side effects since the flow changes would 
still need to be made, a sitemap component would still need to be 
retrofitted, the sitemap would be harder to read, the sitemap syntax 
wouldn't necessarily tell you which components would be consuming the 
action's info, etc.  Also, what is the use case for data injection that 
spans multiple components but only injects the same content?  The 
actions I've found the most useful are the resource-exists and the 
authentication/authorization actions.  These dynamically alter the 
structure of the pipeline.  The actions which have historically 
provided information have for the most part been subsumed into input 
modules.  Why?  My take on it was that use of actions for content 
gathering muddied the sitemap semantics and required all sorts of 
{../../../1} configuration headaches.

<map:transform type="foo" src="getBar({1})"/>

Simple, descriptive, and limited in scope.  But the exact syntax is 
IMHO irrelevant.  It's the concept I'm more concerned about.  If it 
were a comma separated list like

<map:transform type="foo" src="getBar,{1}"/>

or considered another input source

<map:transform type="foo" src="func://getBar/{1}"/>

or parameters were specific to the transformer

<map:transform type="foo" src="getBar">
   <map:param name="src-param1" value="{1}"/>
</map:transform>

...although I can't say I cared for the last two.  The second to last 
is ripe for URI abuse.  The only major issue with the first two is that 
commas become reserved characters.

- Miles Elam


Re: [RT] function sources

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Miles Elam wrote:
> A while back, Ugo brought up his idea for "A Groovy Kind of Sitemap" 
> which met with some friction.  On the one hand was the camp that felt 
> that the sitemap/flowscript dichotomy was a case of overseparation of 
> concerns.  On the other was the camp that absolutely wanted to keep a 
> general purpose programming language away from the main URI/HTTP 
> decision tree.  At the time, I was firmly in the second camp.
> 
> This is not to say that I now want scripting code embedded in the 
> sitemap.  Far from it.  I still believe that the logic and management 
> issues are absolutely two distinct concerns that warrant a Great Wall of 
> SoC(tm) between them.  However, the feelings of overseparation were not 
> without cause.  Let's face it, it's a major PITA to make two matchers 
> for every scripted source: one for the <map:call /> and one internal 
> pipeline for the flowscript sendPage() output -- and then make sure they 
> all stay in sync.
> 
> So what do you say to function sources?  "Say what," you say?  Pipeline 
> components that take a function call as their source.  Now hold on!  I 
> can feel you slipping away and the cries of FS echoing in the distance. 
>  Try this on for size:
> 
> <map:match type="regexp" pattern="document-(\d+)">
>   <map:generate type="file" src="mytemplate.jx"/>
>   <map:transform type="jxtemplatetransformer" src="getDocument({1})"/>
>   <map:serialize type="xml"/>
> </map:match>
Hmm what did you mean by that? JXTT is not parametrizable with src so 
did you mean:

<map:match type="regexp" pattern="document-(\d+)">
   <map:generate type="jx" src="getDocument({1})"/>
   <map:serialize type="xml"/>
</map:match>


> 
> Wait!  Wait!  Don't leave yet!  I'm not saying that the "src" attribute 
> a straight call to the flow interpreter as it exists today.  Not at 
> all.  I'm actually suggesting that we've been so caught up in 
> continuations, we've almost forgotten how to write scripts without 
> them.  And why not?  There are three kinds of people in this world: 
> those that don't do web development, those that love continuations and 
> those that don't know what continuations are.  But set aside 
> continuations for now.  They are but one type of scripting contract.
> 
> What if there was an alternate scripting contract?  One that instead of 
> requiring a sendPage, sendPageAndWait or redirect-to call, requires that 
> *none* of these exist in the code path and that an object context is 
> returned like the parameter of the sendPage* functions.
> 
> function getDocument (docid) {
>   var myObject;
>   //
>   // *** hypothetical Hibernate call with a lookup via docid,
>   // assignment to myObject and other sundry details ***
>   //
>   return myObject;
> }
something like this was already possible when it was not required for 
the flowscript function to invoke sendPage or sendPageAndWait. Then you 
could do something like:

<map:match pattern="someUri">
   <map:call function="myFunction">
     <!-- the function stores result in request attribute -->
     <map:generate src="request-attr:mydata" type="jx"/>
     <map:serialize type="xml"/>
   </map:call>
</map:match>

This is like the function was an action really (which I found kind of 
nice for fasst scripting actions - I usually used XSPs for that one but 
the startup time was killing me, syntax also).

Now this call wouldn't succeed. Every call to a function must result 
with sendPage.

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
Project Manager                                    MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: [RT] function sources

Posted by Upayavira <uv...@upaya.co.uk>.
Miles Elam wrote:

> On Nov 23, 2004, at 11:46 AM, Vadim Gritsenko wrote:
>
>> Proposed URI syntax:
>>
>>   script:myMethod(param1, param2, param3)
>
>
> Yes!  Much clearer, and it fits well with the existing schema.  Still 
> has an issue with escaping commas from the parameters if you're 
> passing values from the sitemap matcher.  Perhaps that could be seen 
> as a sane matcher parameter issue?

script:myMethod("{1}", "{2}");

That way you're covered. And right now, I think that's the only way to 
do it. But, you do get into comma/quote hell somewhat. Otherwise, you 
want sitemap variables to be available to the source that is resolving 
the URL, and I can't think immediately of how to do that.

Regards, Upayavira

> I'm still unclear on how to hook into flow from here.  Are the default 
> flow objects (cocoon, continuation, etc.) passed on script 
> initialization?  I would imagine so since the request and continuation 
> values by definition have to be unique for each client request.  So 
> where does this variable injection occur?  Behind the scenes in the 
> flow interpreter itself or further up the chain closer to the flow 
> function caller?
>
> - Miles Elam
>
>


Re: [RT] function sources

Posted by Miles Elam <mi...@pcextremist.com>.
On Nov 23, 2004, at 11:46 AM, Vadim Gritsenko wrote:

> Proposed URI syntax:
>
>   script:myMethod(param1, param2, param3)

Yes!  Much clearer, and it fits well with the existing schema.  Still 
has an issue with escaping commas from the parameters if you're passing 
values from the sitemap matcher.  Perhaps that could be seen as a sane 
matcher parameter issue?

I'm still unclear on how to hook into flow from here.  Are the default 
flow objects (cocoon, continuation, etc.) passed on script 
initialization?  I would imagine so since the request and continuation 
values by definition have to be unique for each client request.  So 
where does this variable injection occur?  Behind the scenes in the 
flow interpreter itself or further up the chain closer to the flow 
function caller?

- Miles Elam


Re: [RT] function sources

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Miles Elam wrote:
> 3. How easy would it be to wire this into the existing codebase (eg. 
> JXTemplateTransformer)?

It is (relatively) easy, and it has nothing to do neither with 
JXTemplateTransformer, nor with Cocoon core in general.

What you want is easily implemented as a ScriptSource, implementation of a 
Source interface, which would parse function name and parameters from the URI, 
call a method, and serialize (if getInputStream is called), or XML-ize (if toSAX 
is called) returned object.

Proposed URI syntax:

   script:myMethod(param1, param2, param3)


Actually, it won't differ much from what is already possible in Gecko browsers, 
where GIF image source can be obtained as a result of method execution:

   <script>
     function getPicture(a,b,c) {
       return ...;
     }
   </script>
   <img src="javascript:getPicture('a', 'b', 'c')"/>


Vadim