----- Original Message -----
From: "Craig R. McClanahan" <[EMAIL PROTECTED]>
To: "Struts Developers List" <[EMAIL PROTECTED]>
Sent: Tuesday, October 07, 2003 2:22 PM
Subject: Re: Struts-chain Behavior Discussion
> >
> >You do not need to determine Class4 was always run or not,
> >actually it is determined at runtime. Its definition is included
> >in every labeled chain by default.
> >
> It is absolutely necessary to understand the control flow if you want to
> customize it. The above would support all of the following flows
> (assuming that no command returns true prematurely):
> * Class1 - Class2 - Class3 - Class4
> * Class1 - Class3 - Class4
> * Class1 - Class2 - Class4
>
> Now, if I want to add a new step that has to occur before Class3, but is
> ONLY executed if Class3 will be executed, how do I do that? I have to
> change which command gets label L1, which is bad for the same reason
> that "goto" in programming languages is bad.
You could easily assign the label L1 to the new command before Class3
in the chain. A chain definition is normally very very small (5-30 lines)
comparing with programs (up to 8000 or more lines). I do not see any
difficulties to manipulate such a small section. Note that the thing we are
dealing with is a config file, not a program (with a "go to" from line 67 to
line 7598 :-)
>
> >
> >The idea is that you do not have to define a separate chain else where
> >if you could re-use a labeled chain in the current chain definition.
> >You could also ignore labels if any, just use the chain as is.
> >
> >
> If you're going to (potentially) ignore the labels and branches, why
> have them in the first place?
In the example, the L1 labeled chain is invoked by Class1 if it returns
false. If you do not need the particular L1 labeled chain in the current
chain definition, you could ignore it. But the label could serve as
an entry point for other chains outside the scope to invoke the L1
labeled chain if they find it useful.
>
> Or, to put it differently, conditional behavior should be a feature of
> the Command implementation ("is the world in the correct state for me to
> perform this action?"). If the current state is not correct, it should
> just return false to let the chain continue. That's why a change based
> on Ted's suggestion:
>
> (1) LookupCommand
> (2) ExceptionCatcher
> (3) SelectLocale
> (4) SelectAction
> (5) CreateActionForm
> (6) PopulateActionForm
> (7) ValidateActionForm (must save state in the Context)
> (NEW) SelectInput [skip if validation succeeded]
> (8) CreateAction [skip if validation failed]
> (9) ExecuteAction [skip if validation failed]
> (10) PerformForward
>
> is actually the cleanest overall approach. The user should not have to
> even *know* what conditions the commands care about to determine whether
> they are executed. Thus, you would end up with a clean and simple chain
> definition:
>
> <chain id="request-processor">
> <command class="LookupCommand"/>
> <command class="ExceptionCatcher"/>
> <command class="SelectLocale"/>
> <command class="SelectAction"/>
> <command class="CreateActionForm"/>
> <command class="PopulateActionForm"/>
> <command class="ValidateActionForm"/>
> <command class="SelectInput"/>
> <command class="CreateAction"/>
> <command class="ExecuteAction"/>
> <command class="PerformForward"/>
> </chain>
>
> Now, if I want to insert something that always happens before
> ValidateActionForm, I know exactly where it goes. I don't have to worry
> about whether ValidateActionForm is going to branch or skip, because
> it's not ... SelectInput and friends decide for themselves whether they
> are relevant.
>
> OK, I've convinced myself that this is the right approach :-). So I'll
> likely be changing struts-chain to this tonight, and adding the
> appropriate mechanisms for ValidateActionForm to pass on the success or
> failure state information.
I have not been fully convinced by this approach yet. Taking a general
chain definition as follows,
<chain>
<command class="C1"/>
<command class="C2"/>
<command class="C3"/>
...
<command class="C19"/>
<command class="C20"/>
</chain>
If I want to add a new command C before C19, I'll have to figure out
who set up a state before C19, even on one does it. Also,
I'll have to figure out where the state is located if any and see if the new
command C honor that state or not (command coupling problem).
Furthermore, assume the command C3 set up a state, but we could
see any commands between C3 and C19 could set up a second one
or third one. Where the states are stored systematically is another
question (state storage problem).
I could be convinced if I see a possible mechanism that deals with
the command coupling problem and state storage problem.
>
> Craig
>
Jing
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]