Paul Speed wrote:
> 
> I haven't looked at the implementation yet (I intend to when I have
> more than 2 seconds free) but I have been lurking in this
> discussion.
> 
> It seems to me that if a command could nest a chain then all things
> are possible.  In fact, you wouldn't even need the "jump to last
> command" logic since that step would be part of the master chain.
> 
> Craig's example might then be like:
> (1) LookupCommand
> (2) ExceptionCatcher
> (3) SelectLocale
> (4) SelectAction
> (5) Process Form
>     (a) CreateActionForm
>     (b) PopulateActionForm
>     (c) ValidateActionForm
> (6) CreateAction
> (7) ExecuteAction
> (8) PerformForward

Yah, except I screwed it up.  It's way too late.

(1) LookupCommand
(2) ExceptionCatcher
(3) SelectLocale
(4) Process Action
    (a) SelectAction
    (b) CreateActionForm
    (c) PopulateActionForm
    (d) ValidateActionForm
    (e) CreateAction
    (f) ExecuteAction
(8) PerformForward

> 
> I don't know how easy it would be to run a chain from a command, so
> it may not be feasible.  From a processing perspective, it seems
> clearer to me.
> 
> -Paul
> 
> Jing Zhou wrote:
> >
> > ----- Original Message -----
> > From: "Craig R. McClanahan" <[EMAIL PROTECTED]>
> > To: "Struts Developers List" <[EMAIL PROTECTED]>
> > Sent: Saturday, October 04, 2003 1:02 PM
> > Subject: Re: Struts-chain Behavior Discussion
> >
> > >
> > > They could indeed be made part of the chain, and "checking the current
> > > state to see if it's appropriate for me to do anything" is certainly
> > > more in the spirit of the original CoR pattern.  However, I worry a
> > > little that creating the need for that state information increases
> > > coupling between commands, and therefore increases the complexity of
> > > reusing commands in alternative chains.
> >
> > Exactly. The index-based jumping creates the need for a command to
> > recognize a fixed position to jump to. That is why I said
> > they have a similar problem - coupling between commands. They
> > have to either honor a state/flag or a fixed position. And such coupling
> > can be easily destroyed by adding a command in between without
> > recognizing the state/flag or changing the target position.
> >
> > >
> > > In the real-life use case we actually have in the CVS repository (the
> > > one in struts-chain, which actually does work :-), the case in question
> > > was to deal with the fact that the Struts request processing lifecycle
> > > has a branch in it, based on whether or not validation succeeds.  The
> > > basic flow goes like this (using the class name of the command
> > > implementation class, and presuming we're all pretty familiar with the
> > > corresponding RequestProcessor behavior):
> > >
> > > (1) LookupCommand (analogous to the processPreprocess() hook)
> > > (2) ExceptionCatcher (no direct analog - used to implement exception
> > > mapping behavior)
> > > (3) SelectLocale
> > > (4) SelectAction
> > > (5) CreateActionForm
> > > (6) PopulateActionForm
> > > (7) ValidateActionForm
> > > (8) CreateAction
> > > (9) ExecuteAction
> > > (10) PerformForward
> > >
> > > The conditional behavior happens in Step (7) -- if validation fails, an
> > > alternative path is desired:
> > > (7a) SelectInput (uses the "input" attribute on the <action>)
> > > (7b) PerformForward
> > >
> > > At the moment, this is implemented as a branch, to a separate chain that
> > > the author of ValidateActionForm need not even know the name of at
> > > design time (it's a configuration property).  If ValidateActionForm
> > > detects a failure, it looks up an alternate chain in the Catalog,
> > > executes this chain, and then returns true (so that steps 8-10 of the
> > > original chain are never executed).  Note that step (10) in the original
> > > chain and step (7b) in the alternate chain share a single Command
> > > implementation instance, because Struts ends up doing the same thing
> > > either way (RequestDispatcher.forward() or redirect based on what
> > > ActionForward it is passed).  Nothing had to be coded twice.
> > >
> >
> > My question is whether or not we could find a simpler
> > syntax in the chain-config.xml and implement "jump behavior".
> > This is because we could have a lot of "jump to the last command"
> > or "jump to the second to last command", etc.
> >
> > It is very easy to relate "branch behavior" and "jump behavior" to
> > a rule engine or workflow engine, so people might get me wrong
> > in the early reactions.
> >
> > Although we use the term "branch behavior" and "jump behavior"
> > in a chain, we should not see the "if" and "go to" statements in the
> > chain-config.xml file. So a chain is still a fully connected chain
> > (no skipping by definition).
> >
> > The "if" statement is simulated by commands which
> > provide "branch behavior" by terminating the current chain and
> > invoking a nested chain.
> >
> > Could we simulate the "go to" statement without breaking the chain?
> > Note that the chain's execution path should be remained connected
> > because we need to do post processing in the reversed order.
> >
> > The answer, I deeply believe, is yes. We know that index-based
> > jumping is flawed, so we should use label-based jumping. When
> > a command is added to a chain, an optional label could be
> > specified which must be unique within the chain.
> >
> > For example,
> > <chains>
> >   <chain name="servlet-standard">
> >       <command className="o.a.s.c.s.ValidationFormAction"
> >                         jumpLabel="last" />
> >       ....
> >       <!-- the label "last" is specified in the next command -->
> >      <command label="last"
> >                        className="o.a.s.c.s.PerformForward" />
> >   </chain>
> > </chains>
> >
> > Now, in the ValidationFormAction class, we almost do the same
> > thing as before except in two statements:
> >
> > >     ActionErrors errors = validate(context, actionConfig, actionForm);
> > >
> > >     // If there were no errors, proceed normally
> > >     if ((errors == null) || (errors.isEmpty()) {
> > >         return (false); // Proceed with the main chain
> > >     }
> > >
> > >     // Execute the specified validation failure command
> > >     try {
> > >         Catalog catalog = (Catalog)
> > >           context.get(getCatalogKey());
> >
> >            // we get the main chain again
> >            Command command = catalog.getCommand("servlet-standard");
> >            // execute the main chain starting with the given label
> >           ((Chain)command).execute(context, getJumpLabel());
> >
> > >     } catch (Exception e) {
> > >         ... deal with exception ...
> > >     }
> > >     return (true); // Terminate the main chain
> > >
> > > Craig
> > >
> >
> > Here, we introduce a concept of implicit chains. Whenever
> > you add a command with its label in a chain, an implicit
> > chain is defined starting from that command to the end of the
> > chain. The Chain.execute(Context ctx, String label) will
> > execute the chain from the labeled command.
> >
> > So, the "go to" statement is actually simulated by a nested
> > chain which is implicitly defined in the main chain.
> >
> > Obviously, we do not have to require each command to
> > honor a state/flag, and the fixed index problem is also
> > solved. Now, looped commands can be specified
> > as follows. (Note that you can not simulate the looped
> > commands using "branch behavior").
> >
> > <chains>
> >   <chain name="demo">
> >
> >       <command className="A" />
> >       <command label="start" className="B" />
> >       // ... other looped commands
> >
> >       <command jumpLabel="start" className="C" />
> >
> >   </chain>
> > </chains>
> >
> > This way also saves a lot of repeatedly defined
> > commands/chains in the chain-config.xml file.
> > What I am asking is still a Chain, but with additional
> > capabilities and more concise syntaxes. Although its
> > syntaxes looks like a "jump", its implementation
> > never jumps. (It may not be necessary to add new
> > execute method if we could put label into Context
> > somewhere, so API changes are very limited).
> >
> > Any ideas or comments on the algorithm? Are there
> > any technique flaws? If anywhere is not clear or
> > could be improved, please point it out.
> >
> > Jing
> > Netspread Carrier
> > http://www.netspread.com
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to