You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Sylvain Wallez <sy...@anyware-tech.com> on 2003/03/03 23:23:34 UTC

Flow result storage : let's fix it before its too late !

Hi all,

A rather provocative subject, so let me first say that I like the flow, 
even if unfortunately I didn't have the occasion to use it up to know. 
Ovidiu did a wonderful job and Adrew is now adding features that make it 
more usable.

But I think we reached a point where we have to be careful at how the 
flow is slowly spreading inside other components and do some design 
before it's too late. This is mainly about the way the flow gives its 
output to other components : it adds two attributes to the *Environment* 
object, which is an object used internally by the pipeline machinery, 
and *should not be used* by other components (nor shoud it 
theroretically be accessible).

The way this Enviromnent object is fetched says it by itself :
  public void setup(SourceResolver resolver, Map objectModel, String 
src, Parameters params) {
    Object bean = ((Environment)resolver).getAttribute("bean-dict");
    WebContinuation kont = 
(WebContinuation)((Environment)resolver).getAttribute("kont");
    ...

This is a hack that relies on the fact that the SourceResolver also 
implements Environment, which is absolutely not guaranteed by its 
contract ! Furthermore, this "resolver" parameter in C2.1 should be 
considered deprecated and is replaced by the Excalibur SourceResolver 
which is a regular component looked up on the ComponentManager and 
doesn't implement Environment !

So why don't we use the ObjectModel to pass the flow information ? It 
already contains the request and the response, and this seems the 
natural place for flow values. And more : if we consider components such 
as FlowVelocityGenerator, why would we want to publish only flow data 
and not elements of the object model ? If everything was in the object 
model, we could have some generic publication code that would publish 
all that is in the object model, regardless of what it actually is, and 
thus no need for a second VelocityGenerator.

Thoughts ? What's the reason for using the Environment ?

Also, I prefer longer but more explicit names than "$this" to access the 
flow bean : "$flowDict" is not much longer but way more explicit in the 
huge name base that is Cocoon. Oversimplifying names leads to too much 
magic that kills the understandability of the whole thing.

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }



Re: Flow result storage : let's fix it before its too late !

Posted by Sylvain Wallez <sy...@anyware-tech.com>.
Stefano Mazzocchi wrote:

> Sylvain Wallez wrote:
>
>>>> So why don't we use the ObjectModel to pass the flow information ? 
>>>> It already contains the request and the response, and this seems 
>>>> the natural place for flow values. And more : if we consider 
>>>> components such as FlowVelocityGenerator, why would we want to 
>>>> publish only flow data and not elements of the object model ? If 
>>>> everything was in the object model, we could have some generic 
>>>> publication code that would publish all that is in the object 
>>>> model, regardless of what it actually is, and thus no need for a 
>>>> second VelocityGenerator.
>>>
>>>
>>> Well, actually I don't agree with you now. The flow script 
>>> establishes a contract with the presentation layer determined by the 
>>> object it passes to sendPage*() or the object it uses for the 
>>> XMLForm model. This, and only this, should be supplied to the 
>>> presentation layer. The presentation layer should not have access to 
>>> the request, session, etc, unless references to these are explicitly 
>>> passed by the flow script. 
>>
>
> Sorry, Sylvain, but I completely agree with Chris here.
>
>> I don't agree here : the flow is about business logic, and the 
>> presentation layer is about... presentation, which may often depend 
>> on information available in the request that aren't of any interest 
>> to the business logic. 
>
>
> nononononon
>
> The flow is about 'flow', it's about procedurally describing FSM 
> transitions. it's totally incorrect to state that 'flow := business 
> logic' because it is true that business logic influences the flow, but 
> the other way around it's not true.


Agree. My wording was too much restrictive.

> We don't use MVC, because MVC is too simple and mixes too many 
> concerns in the 'controller/model' realms. But at least clears the 
> fact that the 'view' is totally separated.
>
> if you start giving access from the view to the model, you make 
> concerns overlap because part of the flow-logic gets connected to the 
> 'view'.
>
>> To name a few, we have the target language, the user-agent, the host 
>> name (which can decide of the skin in case of virtual host), etc.
>
>
> The flow doesn't stop you from using ObjectModel-aware pipeline 
> components, but as far as generating the 'view' of a controller-driven 
> state, it's the controller that should drive the process. The 
> controller, in our case, it's the flow layer.
>
> Example: suppose that you want to display a request parameter in a XSP 
> that was triggered by a flow call. You could do it in two ways:
>
> 1) using accessing the request directly from the XSP
>
> 2) accessing a parameter given by the flow, which accessed the request 
> parameter.
>
> Which one is better?
>
> The second.
>
> Why? because the information on 'what' request parameter to use, was 
> probably dictated by the flow itself. So, the contract created by the 
> request parameter is only included in the flow layer and doesn't 
> crosscut the view part.
>
> The view has a totally different contract with the controller, which 
> is the name of the parameter passed by the flow.
>
> The better defined and well isolated the contracts, the cleaner and 
> easier SoC-oriented-programming becomes, reducing maintenance costs in 
> the long run by *orders* of magnitude. 


While this sounds good from a theoretical and "cleanliness" point of 
view, we have to consider that some information available in the object 
model is of no use for state transition, but is needed only for proper 
work of the view. So my question is "why should the flow bother about 
these" ?

With the flow bean dict becoming the _only_ source of information for 
the view, we are defining a strong and unique application-wide contract. 
But the problem with this unique contract is that it must be fed on one 
end to be consumed on the other end. This a push-driven model where the 
flow has to put in the dict each and every data consumed by the view, 
even if that data never influences neither state transition nor business 
logic. Enhydra's XMLC works that way and I find it bad.

 From a maintainance point of view, this means that the view *and* the 
flow have both to be modified in order to provide the view with some 
data the flow doesn't care about. So I'm not sure there's a real benefit 
here.

Having the object model available in the view allows a mixed push/pull 
model where the flow pushes the data it is responsible for and the view 
pulls data that is not the flow concern.

>> This is also a wonder I have about the current way the flow is 
>> perceived : by filling an important hole in Cocoon, it seems to me 
>> the flow is now surpassing its initial role. The flow isn't 
>> responsible for _all_ data that drive the system output, but only 
>> (and this should not be taken as a pejorative restriction) of the 
>> business data.
>
>
> Do you still feel the same after the context I've given you above?


Yep.

>>>> Thoughts ? What's the reason for using the Environment ?
>>>>
>>>> Also, I prefer longer but more explicit names than "$this" to 
>>>> access the flow bean : "$flowDict" is not much longer but way more 
>>>> explicit in the 
>>>
>>>
>>> Actually, under normal circumstances you never need to use $this. 
>>> Its only reason for existence is to provide a means of 
>>> disambiguating the built-in "continuation" property, in case the 
>>> bean also has a property called "continuation":
>>>
>>> $continuation - the continuation object
>>> $this.continuation - a property named "continuation"
>>
>>
>> The problem is not about "$this" but more about populating the flow 
>> data as toplevel variables. Explicitely naming the flow through a 
>> "$flowData" or something like that makes it more understandable about 
>> where this data comes from and where the user can know more about it.
>
>
> My vision is that people should be suggested to see the flow as *THE* 
> glue between views. In short, the natural programmatic side of the 
> sitemap, which is a role that now actions have and took because of no 
> real alternative.
>
> As much as we don't specify
>
>  <act ...>
>   <generate src="{action:whatever}"/>
>  </act>
>
> I really don't see why we should 'namespace' the flow variables more 
> either.
>
> But maybe there is something in your reasoning that I'm missing.


Yep. Basically, I feel the contract imposed by the flow to other 
components to be too strong and wanting to rule too much of the system.

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }



Re: Flow result storage : let's fix it before its too late !

Posted by Stefano Mazzocchi <st...@apache.org>.
Sylvain Wallez wrote:

>>> So why don't we use the ObjectModel to pass the flow information ? It 
>>> already contains the request and the response, and this seems the 
>>> natural place for flow values. And more : if we consider components 
>>> such as FlowVelocityGenerator, why would we want to publish only flow 
>>> data and not elements of the object model ? If everything was in the 
>>> object model, we could have some generic publication code that would 
>>> publish all that is in the object model, regardless of what it 
>>> actually is, and thus no need for a second VelocityGenerator.
>>
>>
>>
>> Well, actually I don't agree with you now. The flow script establishes 
>> a contract with the presentation layer determined by the object it 
>> passes to sendPage*() or the object it uses for the XMLForm model. 
>> This, and only this, should be supplied to the presentation layer. The 
>> presentation layer should not have access to the request, session, 
>> etc, unless references to these are explicitly passed by the flow script. 

Sorry, Sylvain, but I completely agree with Chris here.

> I don't agree here : the flow is about business logic, and the 
> presentation layer is about... presentation, which may often depend on 
> information available in the request that aren't of any interest to the 
> business logic. 

nononononon

The flow is about 'flow', it's about procedurally describing FSM 
transitions. it's totally incorrect to state that 'flow := business 
logic' because it is true that business logic influences the flow, but 
the other way around it's not true.

We don't use MVC, because MVC is too simple and mixes too many concerns 
in the 'controller/model' realms. But at least clears the fact that the 
'view' is totally separated.

if you start giving access from the view to the model, you make concerns 
overlap because part of the flow-logic gets connected to the 'view'.

> To name a few, we have the target language, the 
> user-agent, the host name (which can decide of the skin in case of 
> virtual host), etc.

The flow doesn't stop you from using ObjectModel-aware pipeline 
components, but as far as generating the 'view' of a controller-driven 
state, it's the controller that should drive the process. The 
controller, in our case, it's the flow layer.

Example: suppose that you want to display a request parameter in a XSP 
that was triggered by a flow call. You could do it in two ways:

1) using accessing the request directly from the XSP

2) accessing a parameter given by the flow, which accessed the request 
parameter.

Which one is better?

The second.

Why? because the information on 'what' request parameter to use, was 
probably dictated by the flow itself. So, the contract created by the 
request parameter is only included in the flow layer and doesn't 
crosscut the view part.

The view has a totally different contract with the controller, which is 
the name of the parameter passed by the flow.

The better defined and well isolated the contracts, the cleaner and 
easier SoC-oriented-programming becomes, reducing maintenance costs in 
the long run by *orders* of magnitude.

> This is also a wonder I have about the current way the flow is perceived 
> : by filling an important hole in Cocoon, it seems to me the flow is now 
> surpassing its initial role. The flow isn't responsible for _all_ data 
> that drive the system output, but only (and this should not be taken as 
> a pejorative restriction) of the business data.

Do you still feel the same after the context I've given you above?

>>> Thoughts ? What's the reason for using the Environment ?
>>>
>>> Also, I prefer longer but more explicit names than "$this" to access 
>>> the flow bean : "$flowDict" is not much longer but way more explicit 
>>> in the 
>>
>>
>>
>> Actually, under normal circumstances you never need to use $this. Its 
>> only reason for existence is to provide a means of disambiguating the 
>> built-in "continuation" property, in case the bean also has a property 
>> called "continuation":
>>
>> $continuation - the continuation object
>> $this.continuation - a property named "continuation"
> 
> 
> 
> The problem is not about "$this" but more about populating the flow data 
> as toplevel variables. Explicitely naming the flow through a "$flowData" 
> or something like that makes it more understandable about where this 
> data comes from and where the user can know more about it.

My vision is that people should be suggested to see the flow as *THE* 
glue between views. In short, the natural programmatic side of the 
sitemap, which is a role that now actions have and took because of no 
real alternative.

As much as we don't specify

  <act ...>
   <generate src="{action:whatever}"/>
  </act>

I really don't see why we should 'namespace' the flow variables more either.

But maybe there is something in your reasoning that I'm missing.

-- 
Stefano Mazzocchi                               <st...@apache.org>
    Pluralitas non est ponenda sine necessitate [William of Ockham]
--------------------------------------------------------------------



Re: Flow result storage : let's fix it before its too late !

Posted by Sylvain Wallez <sy...@anyware-tech.com>.
Christopher Oliver wrote:

> First of all Sylvain, my name is Chris Oliver, not Andrew C. Oliver 
> (that's acoliver@apache.org).
>
> Sylvain Wallez wrote:
>
>> Hi all,
>>
>> A rather provocative subject, so let me first say that I like the 
>> flow, even if unfortunately I didn't have the occasion to use it up 
>> to know. Ovidiu did a wonderful job and Adrew is now adding features 
>> that make it more usable.
>>
>> But I think we reached a point where we have to be careful at how the 
>> flow is slowly spreading inside other components and do some design 
>> before it's too late. 
>
>
> I'm glad I've stimulated your interest. That was my intention - even 
> if you choose to cast it in terms of a perceived lack of design. The 
> changes I've made are not written in stone. On the contrary, I expect 
> them to change based on observations by others, including yours.


I'm very sorry if I offended you, since it wasn't intended so and I know 
the good things you've done up to now. I'm ringing a bell (and 
considering Gianugo and Stefano's answer it has been heard) about the 
current trend of the flow to provide too much features in its core and 
"insinuate" in other components because of its specificities (mainly 
related to using the Environment). We started to refactor the whole code 
base in blocks, and the flow starts going the opposite way.

Let's structure the flow in blocks : for example, can't the JS database 
stuff go into the database block ? The flow may provide some RAD-ish 
features, but they shouldn't be hard linked into the core.

>> This is mainly about the way the flow gives its output to other 
>> components : it adds two attributes to the *Environment* object, 
>> which is an object used internally by the pipeline machinery, and 
>> *should not be used* by other components (nor shoud it theroretically 
>> be accessible).
>
<snip/>

> I agree with you here. It should be no big deal to move the storage of 
> these values to the objectModel. 


That's good.

>> So why don't we use the ObjectModel to pass the flow information ? It 
>> already contains the request and the response, and this seems the 
>> natural place for flow values. And more : if we consider components 
>> such as FlowVelocityGenerator, why would we want to publish only flow 
>> data and not elements of the object model ? If everything was in the 
>> object model, we could have some generic publication code that would 
>> publish all that is in the object model, regardless of what it 
>> actually is, and thus no need for a second VelocityGenerator.
>
>
> Well, actually I don't agree with you now. The flow script establishes 
> a contract with the presentation layer determined by the object it 
> passes to sendPage*() or the object it uses for the XMLForm model. 
> This, and only this, should be supplied to the presentation layer. The 
> presentation layer should not have access to the request, session, 
> etc, unless references to these are explicitly passed by the flow script. 


I don't agree here : the flow is about business logic, and the 
presentation layer is about... presentation, which may often depend on 
information available in the request that aren't of any interest to the 
business logic. To name a few, we have the target language, the 
user-agent, the host name (which can decide of the skin in case of 
virtual host), etc.

This is also a wonder I have about the current way the flow is perceived 
: by filling an important hole in Cocoon, it seems to me the flow is now 
surpassing its initial role. The flow isn't responsible for _all_ data 
that drive the system output, but only (and this should not be taken as 
a pejorative restriction) of the business data.

>> Thoughts ? What's the reason for using the Environment ?
>>
>> Also, I prefer longer but more explicit names than "$this" to access 
>> the flow bean : "$flowDict" is not much longer but way more explicit 
>> in the 
>
>
> Actually, under normal circumstances you never need to use $this. Its 
> only reason for existence is to provide a means of disambiguating the 
> built-in "continuation" property, in case the bean also has a property 
> called "continuation":
>
> $continuation - the continuation object
> $this.continuation - a property named "continuation"


The problem is not about "$this" but more about populating the flow data 
as toplevel variables. Explicitely naming the flow through a "$flowData" 
or something like that makes it more understandable about where this 
data comes from and where the user can know more about it.

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }



Re: Flow result storage : let's fix it before its too late !

Posted by Christopher Oliver <re...@verizon.net>.
First of all Sylvain, my name is Chris Oliver, not Andrew C. Oliver 
(that's acoliver@apache.org).

Sylvain Wallez wrote:
> Hi all,
> 
> A rather provocative subject, so let me first say that I like the flow, 
> even if unfortunately I didn't have the occasion to use it up to know. 
> Ovidiu did a wonderful job and Adrew is now adding features that make it 
> more usable.
> 
> But I think we reached a point where we have to be careful at how the 
> flow is slowly spreading inside other components and do some design 
> before it's too late. 

I'm glad I've stimulated your interest. That was my intention - even if 
you choose to cast it in terms of a perceived lack of design. The 
changes I've made are not written in stone. On the contrary, I expect 
them to change based on observations by others, including yours.

> This is mainly about the way the flow gives its 
> output to other components : it adds two attributes to the *Environment* 
> object, which is an object used internally by the pipeline machinery, 
> and *should not be used* by other components (nor shoud it 
> theroretically be accessible).
> 
> The way this Enviromnent object is fetched says it by itself :
>  public void setup(SourceResolver resolver, Map objectModel, String src, 
> Parameters params) {
>    Object bean = ((Environment)resolver).getAttribute("bean-dict");
>    WebContinuation kont = 
> (WebContinuation)((Environment)resolver).getAttribute("kont");
>    ...
> 
> This is a hack that relies on the fact that the SourceResolver also 
> implements Environment, which is absolutely not guaranteed by its 
> contract ! Furthermore, this "resolver" parameter in C2.1 should be 
> considered deprecated and is replaced by the Excalibur SourceResolver 
> which is a regular component looked up on the ComponentManager and 
> doesn't implement Environment !


I agree with you here. It should be no big deal to move the storage of 
these values to the objectModel.

> 
> So why don't we use the ObjectModel to pass the flow information ? It 
> already contains the request and the response, and this seems the 
> natural place for flow values. And more : if we consider components such 
> as FlowVelocityGenerator, why would we want to publish only flow data 
> and not elements of the object model ? If everything was in the object 
> model, we could have some generic publication code that would publish 
> all that is in the object model, regardless of what it actually is, and 
> thus no need for a second VelocityGenerator.

Well, actually I don't agree with you now. The flow script establishes a 
contract with the presentation layer determined by the object it passes 
to sendPage*() or the object it uses for the XMLForm model. This, and 
only this, should be supplied to the presentation layer. The 
presentation layer should not have access to the request, session, etc, 
unless references to these are explicitly passed by the flow script.

> 
> Thoughts ? What's the reason for using the Environment ?
> 
> Also, I prefer longer but more explicit names than "$this" to access the 
> flow bean : "$flowDict" is not much longer but way more explicit in the 

Actually, under normal circumstances you never need to use $this. Its 
only reason for existence is to provide a means of disambiguating the 
built-in "continuation" property, in case the bean also has a property 
called "continuation":

$continuation - the continuation object
$this.continuation - a property named "continuation"


Re: Flow result storage : let's fix it before its too late !

Posted by Sylvain Wallez <sy...@anyware-tech.com>.
Sylvain Wallez wrote:

> Ovidiu did a wonderful job and Adrew is now adding features that make 
> it more usable.

Damn, I meant "Christopher". Sorry for mixing first names between 
"Olivers" :-/

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }