cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Andrew C. Oliver" <acoli...@apache.org>
Subject Re: [RT] Flowmaps
Date Sun, 16 Jun 2002 16:39:25 GMT
Thank you eversomuch!  Thats very helpful.  I'm going to take some time 
and digest it all and then
I'll provide any thoughts.

Stefano Mazzocchi wrote:

>Last time I wrote an RT about these things, the flowmap wasn't
>implemented. Today it's working, but there are things that I would like
>to change.
>
>This RT is to start a discussion that will hopefully lead to a coherent
>and community-driven design on what the flowmap engine will look like.
>
>First of all, since there is no clear howto about the current flowmap
>and I need to give you context in order to make you partecipate in the
>discussion, I'll write a basic explaination of what's going on.
>
>                              - oooo -
>
>How Ovidiu implemented the flowmap concept
>------------------------------------------
>
>First of all, do a 'cvs checkout' of HEAD if you haven't done so. I'm
>referring to the samples that you find in 
>
> /xml-cocoon2/src/webapp/samples/flow/examples/calc/
>
>which is a sample about a very simple web application that implements a
>calculator using the flowmap.
>
>First of all, I'll outline the 'procedural flow logic' of this
>application using highly-pseudo code:
>
> 1) tell me the first operand
> 2) tell me the second operand
> 3) tell me the operation to apply
> 4) here is your result
>
>You'll see how much similar to the actual implementing code this will
>look like. This is probably already a great advantage over anything that
>we had before.
>
>Let us look at the sitemap:
>
><map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
>
>  [skipping component declaration]
>
>  <map:resources>
>    <map:resource name="flow">
>      <map:script src="calc.js"/>
>    </map:resource>
>  </map:resources>
>
>  <map:pipelines>
>    <map:pipeline>
>      <map:match pattern="kont/*">
>        <map:continue with="{1}"/>
>      </map:match>
>
>      <map:match pattern="">
>        <map:call function="calculator">
>          <map:parameter name="prefix"
>value="/samples/flow/examples/calc/"/>
>        </map:call>
>      </map:match>
>
>      <map:match pattern="*.html">
>        <map:generate src="{1}.xsp" type="serverpages"/>
>        <map:serialize/>
>      </map:match>
>    </map:pipeline>
>  </map:pipelines>
></map:sitemap>
>
>So, Ovidiu added three concepts that weren't found in the previous
>sitemap implementations:
>
> 1) a new "map:script" component connects a sitemap resource with a
>flowmap (which is here implemented as a javascript program)
>
> 2) a new attribute "map:call/@function" allows you to pass control from
>the sitemap to the flowmap, calling the function defined in the
>attribute and passing the nested "map:parameter" to the function as a
>regular call.
>
> 3) a "map:continue" element indicates that the flow must be continued
>with the continuation passed in the attribute "@with".
>
>Let's look at the flowmap:
>
>  var prefix;
>
>  function calculator(uriPrefix)
>  {
>    prefix = uriPrefix;
>    var a = getNumber("a");
>    var b = getNumber("b", a);
>    var op = getOperator(a, b);
>
>    if (op == "plus")
>      sendResult(a, b, op, a + b);
>    else if (op == "minus")
>      sendResult(a, b, op, a - b);
>    else if (op == "multiply")
>      sendResult(a, b, op, a * b);
>    else if (op == "divide")
>      sendResult(a, b, op, a / b);
>    else
>      sendResult("Error: Unkown operator!");
>  }
>
>the 'calculator' function is the one that is called from the sitemap. As
>you can see, the procedural logic of your flow is *very well* described:
>I'm sure that it would takes a few minutes for anybody to understand
>what your application is doing.
>
>This is *NOT* possible with any other FSM-based approach.
>
>If you think about it, in Cocoon 1.x we used PI to encode state
>transitions in every stage, then we identified this as a problem and we
>centralized it into the sitemap: the location where you can understand
>what your URI does in a central and confortable location.
>
>Here we are doing it again, but instead of contralizing declarative
>client/server behavior, we are centralizing procedural web-app flow.
>
>But let's keep looking into the flowmap:
>
>   function getNumber(name, a, b)
>   {
>1     var uri = prefix + "getNumber" + name.toUpperCase() + ".html";
>2     sendPage(uri, { "a" : a, "b" : b });
>3     return parseFloat(cocoon.request.getParameter(name));
>   }
>
>This function collects the number required by the flow:
>
>line 1: the URI of the resource to use is created
>line 2: the URI is sent to the client, along with some parameters in a
>map
>line 3: a float is returned from the cocoon request parameter named with
>the given name
>
>Anybody who ever wrote a webapp would think we are nuts: line 2
>generates a response and line 3 reads a request. But here is where the
>flowmap gets magic, there are bunch of things that you don't see
>happening.
>
>So, let's look at that function from what really happens behind the
>lines, let us suppose we call
>
>  var a = getNumber("a");
>
>then
>
>a) the sitemap is called to process a the URI 'getNumberA.html'
>b) the sitemap matches with this matcher
>
>     <map:match pattern="*.html">
>        <map:generate src="{1}.xsp" type="serverpages"/>
>        <map:serialize/>
>      </map:match>
>
>c) the sitemap executes the "getNumberA.xsp", which is given by
>
><xsp:page
>  language="java"
>  xmlns:xsp="http://apache.org/xsp"
>  xmlns:jpath="http://apache.org/xsp/jpath/1.0"
>  
>
>
><document>
> <body>
>  <s1 title="Calculator">
>   <form>
>    <xsp:attribute name="action">
>     <xsp:expr>"kont/" + <jpath:continuation/></xsp:expr>
>    </xsp:attribute>
>
>    <p>Enter value of <strong>a</strong>: 
>          <input type="text" name="a"/></p>
>    <input type="submit" name="submit" value="Enter"/>
>   </form>
>  </s1>
> </body>
></document>
></xsp:page>
>
>where the "jpath" logicsheet is used to obtain the "continuation" of the
>current flow and is then encoded in the URI called.
>
>So, when the users hits 'submit', Cocoon will receive a request for an
>hypotetical URI "kont/39849834983498", then Cocoon will match it with:
>
>      <map:match pattern="kont/*">
>        <map:continue with="{1}"/>
>      </map:match>
>
>and resurrect the flow logic from where it was left. So, again, between
>
>   function getNumber(name, a, b)
>   {
>1     var uri = prefix + "getNumber" + name.toUpperCase() + ".html";
>2     sendPage(uri, { "a" : a, "b" : b });
>3     return parseFloat(cocoon.request.getParameter(name));
>   }
>
>line 2 and line 3, several things happen
>
> 1) control is given to the sitemap
> 2) the sitemap produces a response which encodes the continuation
> 3) this response is sent to the client
> 4) the client acts with the response
> 5) cocoon receives a request for a continuation-decoding URI
> 6) the flowmap is called with the given continuation (think of it as a
>starting point)
>
>If you think of the above as a command line environment, line 2 gives
>you the dialog where to enter the number and line 3 uses the number
>returned from the user.
>
>[the rest of the flowmap is easy to understand if you understood so far,
>so I'll skip it]
>
>                              - oooo -
>
>The problems with this approach
>-------------------------------
>
>First of all, let me say that I consider the above concept the biggest
>advancement in server-side web technology since servlets.
>
>This design not only makes it a breeze to implement MVC, but it shows
>you how natural and clear things become once you separate the procedural
>flow, from the declarative serving of resources.
>
>At the same time, I think there are a number of issues that we might
>solve before freezing the concept in a beta release:
>
>1) the semantics to call a flowmap from a sitemap are too implicit:
>users must assume to much from what they read (ie self-readability of
>the concept is very poor).
>
>2) the concept of continuations is not transparent, there is concern
>overlap between the view designers and the sitemap managers since the
>view designers must be aware of the URI location of the
>continuation-decoding URI.
>
>[NOTE: it is *not* required that you use continuations for your flow
>logic, you can use whatever means you have to control state as you did
>previously, such as REST-like passing style, sessions or cookies]
>
>3) there is currently only one way to implement the MVC "view" and that
>forces you to use XSP. This might not be a performance problem, but it
>might become a usability problem.
>
>Let's talk about each one of them independently.
>
>[NOTE: Giacomo and I spent a full evening and the next day (during
>"Italy vs. Mexico"! consider that!) talking about these things, so the
>above reflects design concepts of both of us]
>
>More explicit sitemap markup
>----------------------------
>
>Here is what I think would be a much better approach to connect a
>sitemap and a flowmap:
>
><map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
>
>  <map:flowmaps default="calculator">
>   <map:flowmap name="calculator" src="calc.js" language="javascript"/>
>  </map:flowmaps>
>  
>  <map:pipelines>
>   <map:pipeline>
>    <map:match pattern="">
>     <map:call function="calculator('prefix','/kont')"/>
>    </map:match>
>
>    <map:match pattern="kont/*">
>     <map:call with-continuation="{1}"/>
>    </map:match>
>
>    <map:match pattern="*.html">
>     <map:generate src="{1}.xsp" type="serverpages"/>
>     <map:serialize/>
>    </map:match>
>   </map:pipeline>
>  </map:pipelines>
>
></map:sitemap>
>
>There are a couple of major differences:
>
> 1) a flowmap isn't a sitemap resource, but it's something else. The
>above semantics reflect this.
>
> 2) you can have more than one flowmap in a sitemap (then you can define
>a default one or use a 'flowmap' attribute in "map:call" to identify
>which flowmap you are calling)
>
>[of course, in order to accomplish this, the implementation must
>completely isolate the different flowmaps and its global variables]
>
> 3) the "map:call" element is used to call sitemap resources (pipelines)
>and flowmap resources (functions), an attribute is used to indicate the
>behavior that should be used and it's consistent with the rest of the
>sitemap.
>
> 4) the "map:call" element can use both nested map:parameters or
>directly using the 'function(param, param)' syntax inside the attribute.
>This makes it more readable in some cases.
>
>Making continuations transparent
>--------------------------------
>
>I personally don't have a clear view of the usability of this concept
>myself: I like it very much, it's clear and consistent and it's similar
>to the session concept.
>
>The only thing is that we might provide a
>"ContinuationURLEncodingTransformer" of some sort to separate the
>concern of those who write the forms and those who write the sitemap,
>even if, passing the 'kont/' prefix as I showed above allows to keep the
>URI space totally self-contained in the sitemap.
>
>I'd be happy to hear more comments in this area (Daniel?)
>
>More ways to get flowmap data
>-----------------------------
>
>Currently, in order to have access to flowmap data (parameters or
>continuations), you need to use the XSP or write java code yourself (I'm
>not even sure the latest is possible, Ovidiu?)
>
>I'd like to have at least a few others:
>
> 1) XSTL
> 2) Velocity
> 3) JSP?
>
>I don't know how hard it is to implement them and I'd like to have
>suggestions on how to implement at least the first one (the problem with
>velocity is that its output must be parsed, unlike XSP, so Velocity
>templates are inherently slower than a compiled XSP, but at least they
>are easier to understand and to use for many, expecially HTML
>designers).
>
>Using JSP as an MVC view makes sense in those cases where a tool is
>required for HTML designers to connect to the parameters passed to the
>JSP. I personally don't care but others might.
>
>                              - oooo -
>
>Ok, almost there.
>
>There is only one big thing missing: when I thought originally at the
>flowmap concept, I wanted it to be interchangeable with the sitemap, now
>I've changed my mind and I think it makes sense to have a sitemap always
>up front, no matter how 'procedural' your web application is (might even
>have a single URI for the whole thing and handle everything inside the
>flowmap)
>
>At the same time, when I was explaining the flowmap concept to the guys
>at SwissRisk, we came up with an idea [gosh, forgot the name of the guy
>who suggested me to think in that direction, hope he is subscribed and
>makes himself known!].
>
>Consider this flowmap call
>
>   sendPage("hello.html");
>
>this means:
>
>  1) ask the sitemap to redirect to "hello.html"
>  2) send the output to the client
>  3) wait for a request to make me continue
>
>Now, suppose we do this
>
>   callPipeline("hello.html", input, output);
>
>where we mean:
>
> 1) call the internal "hello.html" URI connecting the input and output
>that I give you.
> 2) come back here without sending anything to the client
>
><drum-roll/>
>
>VOILA'! We have the ability to use serializers to write on disk, without
>even touching the sitemap!
>
>So, consider this sitemap:
>
><map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
>
>  <map:flowmaps default="editor">
>   <map:flowmap name="editor" src="editor.js" language="javascript"/>
>  </map:flowmaps>
>  
>  <map:pipelines>
>
>    <map:pipeline internal="true">
>      <map:match pattern="save2disk">
>        <map:generate type="stream">
>          <map:parameter name="content" value="content"/>
>        </map:generate>
>        <map:serialize type="xml"/>
>      </map:match>
>    </map:pipeline>
>
>    <map:pipeline>
>      <map:match pattern="save">
>       <map:call function="save2disk()"/>
>      </map:match>
>    </map:pipeline>
>
>  </map:pipelines>
></map:sitemap>
>
>and your flowmap is something like
>
>function save2disk() {
>	OutputStream output = new FileOutputStream("/usr/local/docs");
>	callPipeline("save",cocoon.request, output);
>}
>
>it would be *THAT* easy!
>
>[NOTE: the 'input' and 'output' parameters of the callPipeline() method
>will have to be carefully choosen, here I'm just making this up as an
>example, don't take this as a complete proposal, but just a way to
>sparkle discussion]
>
>                              - oooo -
>
>There are a few important issues with the flowmap:
>
> 1) documentation must be provided on the FOM (flowmap object model),
>sort of a DOM for flowmaps. Currently, objects like 'cocoon', 'log' and
>others are provided, but there is no documentation presenting this
>
> 2) mappings between java and javascript: I don't know how much coupling
>can be done between java and javascript in the flowmap, this must be
>documented more.
>
>                              - oooo -
>
>Ok, please, send your comments.
>
>Ciao.
>
>  
>




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


Mime
View raw message