cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Re: [RT] Managing Flow and Resources
Date Mon, 10 Dec 2001 15:56:39 GMT
Berin Loritsch wrote:

> Torsten Curdt wrote:
> 

>>> To be able to incorporate URLs to older points in the processing, the
>>> send-response() function could return as value an object that contains
>>> the URL to its continuation. You can pass this URL in the optional
>>> dictionary, as an additional argument, if you wish so.
>>>
>>> function addNumbers(HttpRequest request)
>>> {
>>>  send-response("first-page.xml", "my-pipeline");
>>>  first = request.getIntParameter("first");
>>>  send-response("second-page.xml", "my-pipeline", {"first" = first});
>>>  second = request.getIntParameter("second");
>>>  result = first + second;
>>>  send-response("third-page.xml", "my-pipeline", {"result" = result});
>>> }


Having looked at this example, something doesn't sit right with me.  This
has to do with the fundamental URL contracts.  This "flow" is managed within
one URL.  For instance, it could be mounted at "http://foo.com/add".  It
would behave like this:

URL: http://foo.com/add
PAGE:

     Enter First Number: _________
     [Submit]



URL: http://foo.com/add
PAGE:

     Enter Second Number: _________
     [Submit]



URL: http://foo.com/add
PAGE:

     The result is: _________
     [Done]



While this is a possibility, and might be helpful when you only want one
entry point for a form process, it does not address options when you have
multiple entry points.  Nor does it address content to url issues.  If we
want the flow to be managed externally, we must have a method to either
plant the target in the pipeline, or use redirects.  Niether are very clean.

In the first approach (embedding targets in the pipeline) we would have to
add a <parameter name="target" value="second-page.html"/> to embed in the
form.  I find this to be acceptable when you don't want to depend on the
redirection mechanism in a server--or when it is well known what the next
page is going to be.  This is in cases where there is only one "next page".

In the second approach, you must depend on the servers implementation of
redirects (while supposedly standard, I have run into some issues).  There
are also different type of redirects (a host of 30X HTTP response messages).
None of them really supports the notion of "normal" navigational flow between
form pages--though _many_ systems (like ColdFusion) routinely use them to
manage form flow.

For instance, with ColdFusion, it is concidered good practice to have two
templates per form page.  The first template is to display the form, and
the second to simply process it.  When the second is done, it simply redirects
the user to the next page.  I don't like this because it artificially polutes
the URI space with intermediate targets who's sole responsibility is to point
you to another resource.

In Cocoon the only way to manage the URI space as well as processing is
to use redirects and value substitution.  For instance, I would much rather
have a form explicitly say it's next page if it does not depend on user input
like this:

<form action="{target}"/>

The target is chosen by the flow manager, and given to the form so no
redirection has to take place.  This is better IMO than forcing the use
of redirects for these simple cases.

What about multiple targets from one form?  In those cases, it is much more
desirable to use redirections after we service the request.  Using the
psuedo-markup I expressed earlier the concepts could be stated like this:

<functions>
   <function name="addNumbers" pipeline="my-pipeline">
     <send-response page="first-page.xml">
       <parameter name="target" value="second-page.html"/>
     </send-response>
     <call-action name="getFirst"/>
     <validate>
       <on-error>
         <redirect-to "first-page.html"/>
       </on-error>
     </validate>
     <send-response page="second-page.xml">
       <parameter name="first" value="{first}"/>
       <parameter name="target" value="third-page.html"/>
     </send-response>
     <call-action name="getSecondResult"/>
     <send-response page="third-page.xml">
       <parameter name="result" value="{result}"/>
     </send-response>
   </function>
</functions>

This is not necessarily clean looking at it though.

The concept of "continuations" while a flexible and powerful concept must
come to grips with the concept of branching flows--which I do not think
it does.

I think that full FSM terminology is overkill, and would only serve to
frighten newbies.  However, digging through the archives, I came up with
a concept that would also work:

<flow name="addNumbers" start="first-page">
   <resource name="first-page">
     <pipeline type="my-pipeline" source="first-page.xml"/>
     <next name="second-page"/>
   </resource>
   <resource name="second-page">
     <action type="getFirst">
       <pipeline type="my-pipeline" source="second-page.xml"/>
       <next name="third-page"/>
     </action>
     <redirect-to resource="first-page"/>
   </resource>
   <resource name="third-page">
     <action type="getSecondResult">
       <pipeline type="my-pipeline" source="third-page.xml"/>
       <done/>
     </action>
     <redirect-to resource="second-page"/>
   </resource>
</flow>

This uses the same semantics for actions and provides the transitions,
handling errors.

-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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


Mime
View raw message