cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefano Mazzocchi <stef...@apache.org>
Subject Re: [RT] Flowmaps revisited
Date Wed, 10 Oct 2001 13:57:38 GMT
First of all, let me say once again that it's a hell of a pleasure to be
part of such architectural discussions: this is real fun for me :)

Daniela Gehle wrote:
> 
> Dear Cocooners,

Dear Daniela, welcome aboard the magic wonders of Cocoon RT series :)
 
> I've been following your discussions concerning the Flowmap topic with
> high interest, as our company is working on a web application showing
> exactly the same problems that could be solved by some kind of Flowmap
> or Transition Map (as I prefer to call it to avoid confusion with the
> ongoing Flowmap proposals).  

I believe that almost everybody working on web applications (even the
most simple ones) have the same problems of publishing resources
(states) and controlling the flow between them (transitions).

In fact, as you write below, a webapp can (and should!) be seen as a
finite state machine. The problem with currently available technologies
(even most advanced webapp frameworks developped by the ASF) is that the
information that "programs" the FSM (finite state machine) is built-in
into the programming layer. While I agree there is room for people to
like this approach, I don't and I'd like the FSM instructions *not* to
be part of the programming logic itself, but part of configurations that
drive the framework.

This follows the same pattern that saw Cocoon1 being hard to manage
because pipeline instructions were written inside documents and not
outside of them.

So, just like PI that dynamically assembled pipelines in reactors were
cool on paper but turned out to be impractical compared to a centralized
approach like the sitemap, I believe the exact same can be said for FSM
instructions.

So, I'm fully convinced that in order to enforce separation of concerns,
programming logic, documents and other component resources should *NOT*
contain information on states nor their transitions, not how to compose
them.

This information, the very heart of the web application, the blue-prints
to build it and manage it, should be found elsewhere.

This will finally give a "global" view of what a web application does
and how it does it in all places both in the publishing of each state
and in the operation performed during transition between one state and
another.
 
> We've been reading and discussing your
> proposed approaches carefully and found valuable inspiration in it.

Same here :)

> (Although some parts of your proposals are still covered with mist, for
> example the usage of filters in Berin's proposal. Maybe someone else can
> enlighten us. :-)

RT are what they are: random thoughs spoken loudly in order to sparkle
creative discussions. So they normally have black spots where lights has
yet to show the inner details.

> Resulting from these considerations we envision a slightly different and
> "lighter", but not less powerful way to implement flow control in Cocoon
> 2, which I would like to present you herein.
> 
> This approach is "lighter" in the sense that it can easily be integrated
> into the current Cocoon 2 framework using the actors concept.

Personally, I believe that global elagance has higher priority than
instant integration with existing solutions. Not that I don't care about
back portability, rather the opposite in face: I believe that a well
thought-out and designed technology is much more likely to remain
untouched once all the details are considered globally, rather than
incrementally.

Adding flowmap capacities to the existing sitemap might be possible, but
might sacrifice elegance and ease of use and I wouldn't want that at
this point.

> Once the
> Cocoon Sitemap implementation will change from compiled to interpreted,
> this approach can easily be adapted and integrated into the new Sitemap
> concept. But for now all we want is a generalized implementation without
> any changes affecting the Cocoon framework itself.

It would be great if this was possible, but again, just to let you know,
I personally don't consider this to be a very high priority: the sitemap
semantics already show some weak points and with the planned webapp
componentization, we already have lots of things to consider. The
flowmap concept is the other big thing that will have to find a good
place.

So, I'd rather discuss about the best way to do it, rather than how to
do it with existing semantics.

this said, again, if current semantics turns out to be what we wanted,
even better :)
 
> Of course we would like to contribute the implementation of this
> Transition Map approach to the Cocoon project, so please let me know
> what you think about it, if we misunderstood some of your points or if
> we are missing any important details. The proposal itself is not
> entirely fixed yet (and of course not yet coded as well :-), so you
> still have the opportunity to influence the design we propose, to make
> it perfectly fit into the Cocoon framework.

I'd love to welcome you guys aboard and I think we'll all be happy to
invite you to join us in our effort toward the same goals.
 
> Ok, fastened your seat belts? - So let's start with the explanation:
> 
> ---------------------------------------------------
> Reminder: Pages, navigation and flow.
> ---------------------------------------------------
> One of our web applications requires the user to step through a number
> of pages in a controlled sequence (or "flow"). Each of these pages is
> accompanied by background "actions" performed by Java classes. These
> actions concern data generation as well as data processing. From each of
> these pages just a very small, context-dependant subset of other pages
> is accessible, and only these transitions should be displayed to the
> user.  What makes these transitions even more complicated, is that some
> of them require not just the target URL but additional data that will be
> processed by the underlying program logic.
> 
> This is very much in contrast to most of the common web applications
> where you have some kind of   general navigation menu accessible from
> each of the pages and provide the same navigational links for all of the
> pages.
> 
> Therefore we can distinguish two different types of navigation:
> 
> - navigation as a way to consistently structure and group resources
> (mostly in a hierarchical manner) and make them accessible for the user
> in a fashionable way (we could call this type of navigation "static
> navigation"), and
> 
> - navigation that refers to states in a flow and grants access to a
> subset of pages that are part of a flow. We call this type of navigation
> "flow navigation" from now on.
> 
> Static navigation is a pretty simple issue, so we will concentrate on
> flow navigation in this article. As a special aspect of the flow control
> presented here, the approach provides a mechanism to generate these
> "flow navigation" elements automatically from the state description in
> the Transition Map. As far as I know, this is a topic that has never
> been addressed on the Cocoon list before.

Not really, but sure not in such a great detail.

Berin and I already expressed the intention to have the possibility to
navigate to abstract states that do not represent a real resource. Such
as the "next" target after you completed a form, or something like that.

This is probably part of what you call "flow navigation".... hmmm, have
to think more about this...

> I don't want to confuse you - so I will touch this mechanism only
> marginally within this presentation, but in fact it is an important
> requirement that had fundamental influence on the presented design. If
> you are interested, let me know, and I will feed you with additional
> details.

Please do.
 
> ---------------------------------------------------
> What issues do we cover?
> ---------------------------------------------------
> Now that we know the rough picture it is time to look a little bit
> closer at what requirements have to be met exactly. This flow handling
> approach covers not only flow control itself but some additional aspects
> as well:
> 
> (1) Controlling the flow (i.e. state transitions) of the application.
> (2) Separation of data processing ("control" aspect of the MVC pattern)
> and data generation ("view" aspect of the MVC pattern).
> (3) User authentication and authorization.
> (4) Jumping to any visible state in the middle of the flow in one hop.
> (5) Automatic generation of "flow navigation" elements for each page.
> (6) Handle form submits.
> (7) Support generation of forms.

Hey, sound magical, doesn't it? :) I'd love to have something like this
in place. Really.
 
> We will see how all this works together later.
> 
> --------------------------------------------------------
> Sample application
> --------------------------------------------------------
> The problem description is borrowed from the concept of finite state
> machines and relies on a formal description of states and transitions.
> Please note that this is the main difference to the previous
> propositions on this list - we do not just concentrate on the states,
> but on transitions as well. Each transition requires a particular set of
> parameters tied to the transition. These parameters are used to generate
> flow navigation elements and forms.

Great. I agree this is the good place to start.
 
> Let me explain this with an example. Assume a flow representing an
> archive searching application requiring user authentication. For
> example, think of a newspaper article archive containing articles to
> several topics where autorized journalists are allowed to drop queries.
> The page sequence that is crossed  performing a query might look like
> this:
> 
> login -> topic-selection -> search-form -> result-list ->
> article-display
> 
> The main processing direction is forward, but a backward navigation to
> any of the previous pages has to be supported as well. If you are
> currently looking at a newspaper article (article-display page), you
> might want to jump to the page where you can change the selection of the
> topic (topic-selection page). Or you might want to change your password
> from any of the pages - this means that access to a "change-password"
> page must be possible from every page.

Yes and good usability will place even more navigation complexity even
for those static navigation resources. (to be honest, I tend to believe
a good site will almost never have static navigation for usability
reasons, but I might be wrong)
 
> This shows us that the flow is NOT just a simple sequence of pages
> processed in a row, but of a much more complex structure (which is not
> really easy to draw in ASCII graphics and therefore be omitted here :-).

Yes, I've already drawn these pictures on my whiteboard before and I
know what you mean. In fact, one of my feature-dreams is to be able to
draw a nice SVG poster of such complex FSM graph directly transforming
sitemap/flowmap information. But that is future stuff :)
 
> Moreover, we have been cheating a little bit so far. The flow consists
> not only of pages - representing visible states of the system
> (accessible via an URL) - but also of hidden states where system
> operations are performed (like data verification or query processing).
> These hidden states can lead to visible states or to other hidden
> states.

Uh, this is what was left on my picture. Hmmmm, very interesting....
very interesting...
 
> Therefore, the login sequence of the above mentioned page flow should
> better be written like this:
> 
> login --(AUTH)--> [check-login] --(AUTH-OK)--> topic-selection ->..
> login <--(AUTH-NOT-OK)--|
> 
> Please note that in this notation the transitions themselves have unique
> names like (AUTH) or (AUTH-OK), and the hidden state [check-login] is
> marked with square brackets to illustrate the difference to   visible
> states. As its name proposes, the [check-login] state verifies and
> processes the data entered in the login form on the login page.

I love this! I've been drawing this using a different scheme:

 ---(get)---+-> login -+-----(get)---> topic-selection
            ^          |
            |          |
            +--(post)--+

but admittedly, your solution is much less HTTP-centric and much more
visually appealing.
 
> Another important point is that the transitions are transporting data
> from one state to another. The (AUTH) transition, for example, carries
> fields like username="paul" and password="foo". These fields will be
> evaluated by the subsequent state.

Yes.
 
> Now we can put together a description of all states and all transitions
> in a Transition Map:
> 
> --------------------------------------------------------
> The Transition Map
> --------------------------------------------------------
> <flow start="login" name="search-archive">
> <transitions>
>   <transition name="AUTH" target-state="check-login">
>     <parameters>
>       <parameter name="username" xpath="/environment/user"/>
>       <parameter name="password" xpath="/environment/pass"/>
>     </parameters>
>   </transition>

Shouldn't a transition be described by two states, the target *and* the
originating point? Maybe not, but this may generate collisions.

>   <transition name="AUTH-OK" target-state="topic-selection"/>
>   <transition name="AUTH-NOT-OK"  target-state="login"/>
>   <transition name="SELECTTOPIC" target-state="find-topic">
>     <parameters>
>       <parameter name="topic" xpath="/topics/topic"/>
>     </parameters>
>   </transition>
>   <transition name="LOGOUT" target-state="perform-logout"/>
>    ...
> </transitions>
> <states>
>   <state name="login" resource="*/login">
>     <if event="AUTH" transition="AUTH"/>
>     <if event="CHANGEPASS" transition="CHANGEPASS"/>
>   </state>
>   <state name="check-login">
>     <act type="LoginAction"/>
>     <if event="OK" transition="AUTH-OK"/>
>     <if event="ERROR" transition="AUTH-NOT-OK"/>
>   </state>
>   <state name="topic-selection" resource="*/topic-selection">
>     <if event="LOGOUT" transition="LOGOUT"/>
>     <if event="SELECT" transition="SELECTTOPIC"/>
>   </state>
>   <state name="perform-logout">
>     <act type="LoginAction"/>
>     <if event="OK" transition="LOGOUT-OK"/>
>     <if event="ERROR" transition="LOGOUT-NOT-OK"/>
>   </state>
>    ...
> </states>
> </flow>

I like the concept very much. Really. I have to think more about what we
need, but I think this is a very useful place to start.
 
> A Transition Map can contain several flow definitions, each of them
> carrying a unique name and being responsible for a different functional
> unit (<flow start="..." name="...">).
> 
> The first part of each flow definition consists of the definition of all
> transitions (<transitions> ... </transitions>). Each transition is
> described by a unique name, a target state and the parameters that are
> required for this transition. These parameters are NOT necessary for the
> flow control itself, but they are for form handling and automatic
> generation of flow navigation elements. They result either from filling
> form fields or represent environmental data provided by the data
> generation classes. The latter can be evaluated automatically by using a
> specialized "FlowNavigation" transformer, but I don't want to mix up
> things here, so I'm concealing the details of this transformer for now.
> 
> To describe the flow as a whole we do not just need the transitions but
> also information about the states and by which transitions they are
> connected. 

Here is the tricky part.

> The state descriptions (<state>...</state>) distinguish
> between visible and hidden states. Visible states can be reached by
> requesting a specific URL - hidden states cannot.  Visible states carry
> the URL resource they are mapped to in the resource parameter of the
> <state> element; hidden states carry information about the handler that
> is executed when entering the state.

Ok.

> These handlers can be implemented as actors. 

Right.

> It might be possible for a visible state to contain a handler
> as well, but this is not recommended, because then the clean separation
> of visible and hidden states would be broken.

Agreed. I like this separation very much. In fact, I never liked the
action proposal in the sitemap since the granularity of reusability of
actors is visibly different from that of sitemap components.

But in flowmaps, actors really shine.
 
> The decision which of the possible transitions to follow at a specific
> point is done by evaluating the transition event parameters. These
> parameters are either URL parameters (in the case of a visible state) or
> result parameters of an action (in the case of a hidden state). Event
> parameters are written in Capitals in order easily distinguish them from
> ordinary parameters.

Or might be otherwise namespaced, but I think this is just an
implementation detail.
 
> --------------------------------------------------------
> Sitemap configuration: the FlowHandlerAction
> --------------------------------------------------------
> In order to control the flow and the state transitions there is a
> FlowHandlerAction hooked up in the Sitemap.

This is what I don't like that much. I think flowmaps are important
enough to require a more specific hook-up semantics and the action
framework might allow this, but maybe there are more elegant solutions.
(I'm picky, I know)

> More precisely, the
> FlowHandlerAction will be performed for each URL that is representing a
> (visible) state in the flow.  The FlowHandlerAction has to be fed with
> the name of the flow for each pattern match within a flow.
> 
> The Sitemap contains something like
> 
> <map:match pattern="in-the-flow/*">
>   <map:act type="FlowHandler">
>     <map:parameter name="search-archive"/>
>   </map:act>
>   <map:act type="AuthenticationAction">
>     <map:redirect-to uri="in-the-flow/login"/>
>   </map:act>
>   <map:generate type="saxlet" src="templates/{1}.xml"/>
>   <map:transform src="styles/{1}.xsl"/>
>   <map:serialize/>
> </map:match>
> 
> The Transition Map file itself will be specified within the definition
> section of the FlowHandlerAction:
> 
> <map:actions>
>   <map:action name="FlowHandler" src="org.bar.foo.FlowHandlerAction">
>     <map-file>transitionmap.xmap</map-file>
>   </map:action>
> </map:actions>

This is exactly the inelegance I was talking about: sounds like an hack
to me. 
Let's work out a specific semantic addition for flowmaps.
 
> --------------------------------------------------------
> Are all the promised features there?
> --------------------------------------------------------
> (1) Controlling the flow (i.e. state transitions) of the application? -
> Yes.
> 
> (2) Separation of data processing ("control" aspect of the MVC pattern)
> and data generation ("view" aspect of the MVC pattern)?
> 
> Yes. Control is performed by the handlers of the hidden states, data
> generation is performed by the specific Generator (ServerPagesGenerator,
> SAXLet Generator,...) for each page representing a visible state.
> 
> (3) User authentication and authorization?
> 
> Yes. Except for the login process itself which is performed by the
> LoginAction Handler of the "check-login" state, user authentication and
> authorization are located in the AuthenticationAction used in the
> Sitemap. Please note that this is one of the main differences to Berin's
> proposal, were an authorization mechanism was part of the flowmap
> itself. We decided to put the authentication and authorization aspects
> apart, because not all applications rely on the same consistent
> authentication/authorization mechanism. Therefore, in order to be open
> to any authentication/authorization requirements, it seemed to make more
> sense to  place them in actors called from within the Sitemap or the
> Transition Map. Of course, a combination of both approaches is perfectly
> possible.

I think we must elaborate more on this, but I want more feedback before
stating something on this topic since I'm not really an expert on this.
 
> (4) Jumping to any visible state in the middle of the flow in one hop?
> 
> Yes. This is possible, provided that the necessary ordinary and event
> parameters for the march along the transitions leading to the desired
> target state are passed along with the HTTP request. As long as the
> required parameters for the transitions between the states are contained
> in the URL, the state machine will jump from state to state without
> bothering the user with displaying pages belonging to intermediate
> states.
> For example: If you want to jump to the state "search-form" without
> crossing the "login" page, you can enter the URL:
> http://foo.bar/in-the-flow/login?username=Paul&password=foo&AUTH=true&topic=squirrels&SELECT=true.
> Starting from the "login" state the subsequent states "check-login",
> "topic-selection" and "find-topic" are automatically crossed, leading to
> the target state "search-form" (and displaying the "search-form" page to
> the user).

Or even have a sitemap matcher retokenize your encoded URI to come up
with that information. A great thing would be to automatically provide a
form with all the fields already complete but those missing or invalid.
So, for example the password doesn't need to be explicitly written in
the URI but everything else.

> (5) Automatic generation of "flow navigation" elements for each page?
> 
> Yes. This task will be performed by a specialized FlowNavigation
> transformer using the xpath attributes of the transition descriptions in
> the  Transition Map, matching them against XML elements of the generated
> data and inserting generic "flow navigation" controls in the XML data
> that is being processed.

Hmmm, this might lead to concern overlap so we must be careful, but in
general, I see some great value on this.
 
> (6) Handle form submits?
> 
> Yes. Default target of a form submit is always the current page (=state)
> itself. 

YES! This is a conclusion that I drew as well.

> The FlowHandlerAction checks if there's an event parameter
> triggering a transition leading to another state (according to the state
> and transition description in the Transition Map) or if there is no
> matching event parameter and the page itself has to be generated.
>
> (7) Support generation of forms?
> 
> Yes, this is possible in combination with flows, but not implemented
> yet. Using a form descriptor similar to the <parameters> element of the
> transition description in the Transition Map, forms can be generated in
> a unified way, with the default form submit target being the current
> page.

This should definately work closer with Berin's project on XForm.
Probably he'll have more things to say on this.
 
> -------------------------------------------------------------
> How does this proposal fit into the future plans for Cocoon?
> -------------------------------------------------------------
> That's a point pretty hard to answer for me, because I cannot sneak in
> the heads of the Cocoon front row developers. All I could do is point
> out the aspects we've been considering. Now it's your turn, please throw
> your stones. ;-)

>>From what I can see (a superficial global view), I love it. Really, I
think there is some great innovation and very well designed.

I think you also considered a high priority to use the existing
framework without changing things, but I repeat that I'd like to shoot
for elegance at this point than back compatibility, expecially for such
an important thing.

So, good job, welcome aboard and let's keep beating the iron.

Ciao.

Stefano.


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


Mime
View raw message