Re: workflow extension question

2003-10-08 Thread Matthias Bauer
Adam,

I am not sure, but let me try to express in my own words, what I believe 
you want to do: The user tries to access startWizard1.do or 
startWizard2.do. They are both access protected, so if the user is not 
logged in, he will be forwarded to displayLogin.do. Now after he has 
correctly logged in, you want him to get to startWizard1.do or 
startWizard2.do, depending which action he chose before. Is this correct?

If this is the problem, you are trying to solve, it should be easy: 
Build an action (e. g. SaveCurrentRequestAction) and associate it with 
the global authenticationException forward. This action should simply 
store the requested path (you can get that from the request object) in 
the the session. Then after the login succeeds, you forward to this path.

Hope I got your question right,

--- Matthias



Adam L wrote:

Matthias:

  Thank you for the clearer explanation.

  If I understand this now, if I change all my current workflow violation
forwards to be of type ForwardNextStateViolationAction (they are all
currently just plain actions with a forward, no type specified), then the
existing workflow will work as originally designed, keeping the flow in
process, with both prev and next violations triggering and performing as
appropriate to this workflow, but an external workflow (launched from
another menu option) will be allowed to start if the user so chooses,
without being forced back into their first workflow.
 and the moral of the story is:
a truly modal workflow process should have violations defined as:
action path=/wkfAddNewInfoViolation
   forward=/content/displaySelectionScreen.jspa /
while a workflow process that can be interrupted by other workflows
will have violations defined as:
action path=/wkfAddNewInfoViolation
   type=ForwardNextStateViolationAction
  forward name=noNextStateViolation
   path=/content/displaySelectionScreen.jspa /
!-- external forward (external process selected) is implicit --
  /action
I think that indeed solves my problem.   Now  I'm trying to see how I can
use this for cases where an authentication fails, for instance a user is
required to be logged in first:
   set-property property=authClass
value=com.foo.workflow.authentication.LoggedInAuthentication /
  forward name=authenticationException path=/login.do /
 How would I chain them to the login (or whichever) process, and then bring
them back to the step they were trying to perform prior?   I'm currently
seeing this as having to declare several instances of the login process as
actions, some rigged to the main menu login, others rigged from each
workflow that requires this authentication.   This seems like a lot of
extraneous work, and also requires this new subflow to be defined for every
workflow where this authentication is utilized.  That, or wrap the process
in chain of Actions that pass a token along that somehow says when you're
done with this entire flow, come back to this location.   I'm going to have
to ponder on this.   Do you have any thoughts on how this could easily be
achieved using your framework?
 Thank you again for all your help and thought!

-- adam





- Original Message -
From: Matthias Bauer [EMAIL PROTECTED]
To: Struts Users Mailing List [EMAIL PROTECTED]
Sent: Tuesday, October 07, 2003 3:20 AM
Subject: Re: workflow extension question
 

Adam,

sorry that I obviously did not make myself clear enough. Look at the
following definitions:
global-forwards:
workflowViolation_wiz1step1: violatedWizard1Step1
workflowViolation_wiz1step2: violatedWizard1Step2
displayWizard1Step1
primaryWorkflow: wiz1step1
newState: displayed
nextState: submitted
submitWizard1Step1
primaryWorkflow: wiz1step1
prevState: displayed
newState: submitted
forward=success:  displayWizard1Step2
displayWizard1Step2
secondaryWorkflow: wiz1step1
prevState: submitted
primaryWorkflow: wiz1step2
newState: displayed
nextState: submitted
submitWizard1Step2
primaryWorkflow: wiz1step2
prevState: displayed
newState: submitted
violatedWizard1Step1
type: ForwardNextStateViolationAction
forward=noNextStateViolation: displayWizard1Step1
violatedWizard1Step2
type: ForwardNextStateViolationAction
secondaryWorkflow: wiz1step1
endWorkflow: true
forward=noNextStateViolation: displayWizard1Step2
This is what can happen: If the user has just executed
displayWizard1Step1 he can only execute submitWizard1Step1 without
causing a workflow violation. If for instance he follows a link from the
menu, the workflow wiz1step1 is executed, which causes the execution
of action violatedWizard1Step1. Upon workflow violation of
wiz1step1, this workflow is automatically cleaned up, so this action
does not need to do any other cleanup work. The action class
ForwardNextStateViolationAction forwards to the action the user has
chosen from the menu after that.
Upon prevState violations, i. e. if the user executes
submitWizard1Step1 without having executed displayWizard1Step1
before, the action violatedWizard1Step1  causes

Re: workflow extension question

2003-10-07 Thread Matthias Bauer
Adam,

sorry that I obviously did not make myself clear enough. Look at the 
following definitions:

global-forwards:
workflowViolation_wiz1step1: violatedWizard1Step1
workflowViolation_wiz1step2: violatedWizard1Step2
displayWizard1Step1
primaryWorkflow: wiz1step1
newState: displayed
nextState: submitted
submitWizard1Step1
primaryWorkflow: wiz1step1
prevState: displayed
newState: submitted
forward=success:  displayWizard1Step2
displayWizard1Step2
secondaryWorkflow: wiz1step1
prevState: submitted
primaryWorkflow: wiz1step2
newState: displayed
nextState: submitted
submitWizard1Step2
primaryWorkflow: wiz1step2
prevState: displayed
newState: submitted
violatedWizard1Step1
type: ForwardNextStateViolationAction
forward=noNextStateViolation: displayWizard1Step1
violatedWizard1Step2
type: ForwardNextStateViolationAction
secondaryWorkflow: wiz1step1
endWorkflow: true
forward=noNextStateViolation: displayWizard1Step2
This is what can happen: If the user has just executed 
displayWizard1Step1 he can only execute submitWizard1Step1 without 
causing a workflow violation. If for instance he follows a link from the 
menu, the workflow wiz1step1 is executed, which causes the execution 
of action violatedWizard1Step1. Upon workflow violation of 
wiz1step1, this workflow is automatically cleaned up, so this action 
does not need to do any other cleanup work. The action class 
ForwardNextStateViolationAction forwards to the action the user has 
chosen from the menu after that.

Upon prevState violations, i. e. if the user executes 
submitWizard1Step1 without having executed displayWizard1Step1 
before, the action violatedWizard1Step1  causes a forward to 
displayWizard1Step1.

If a workflow violation of  wiz1step2 happens, the action 
violatedWizard1Step2 is executed, which also ends and cleans up the 
workflow wiz1step1. Except the mechansims are identical to workflow 
wiz1step1.

This should meet your requirements. Or am I still missing something?

Concerning your question whether this approach is better than the one to 
end all workflows: In many cases you do not want to end all workflows, 
but only these that belong to a certain process (in our example all 
workflows belonging to wizard1).

Please let me know, if there are still further questions.

--- Matthias



Adam Levine wrote:

Matthias:
  I think I understand your answer.  But, I'm not sure where things 
would go.  If I'm understanding your explanation:

process1:wkfl1 - process1:wkfl2 - (violation) process2:wkfl1 landing 
page(initializer action)

the p2:w1 landing page would be a ForwardNextStateViolationAction
  the FordwardNextStateViolationAction has forwards:
 forward noNextStateViolation : goes to display page for p2:w1
but, if there IS a next state violation, here's where I get confused:
  If a nextState violation was encountered it forwards to the path 
that caused this workflow violation 

Which would lead me back to the p2:w1 landing page ?   That confuses me.

Can you explain why this approach is better than just a i know i want 
to end all previous processes at this point, without having to link in 
with other violation actions ?   Or can they co-exist together nicely ?

Thanks for your help.

-- adam



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


Re: workflow extension question

2003-10-07 Thread Adam L
Matthias:

   Thank you for the clearer explanation.

   If I understand this now, if I change all my current workflow violation
forwards to be of type ForwardNextStateViolationAction (they are all
currently just plain actions with a forward, no type specified), then the
existing workflow will work as originally designed, keeping the flow in
process, with both prev and next violations triggering and performing as
appropriate to this workflow, but an external workflow (launched from
another menu option) will be allowed to start if the user so chooses,
without being forced back into their first workflow.

  and the moral of the story is:
 a truly modal workflow process should have violations defined as:

 action path=/wkfAddNewInfoViolation
forward=/content/displaySelectionScreen.jspa /

 while a workflow process that can be interrupted by other workflows
will have violations defined as:

 action path=/wkfAddNewInfoViolation
type=ForwardNextStateViolationAction
   forward name=noNextStateViolation
path=/content/displaySelectionScreen.jspa /
!-- external forward (external process selected) is implicit --
   /action


 I think that indeed solves my problem.   Now  I'm trying to see how I can
use this for cases where an authentication fails, for instance a user is
required to be logged in first:
set-property property=authClass
value=com.foo.workflow.authentication.LoggedInAuthentication /
   forward name=authenticationException path=/login.do /

  How would I chain them to the login (or whichever) process, and then bring
them back to the step they were trying to perform prior?   I'm currently
seeing this as having to declare several instances of the login process as
actions, some rigged to the main menu login, others rigged from each
workflow that requires this authentication.   This seems like a lot of
extraneous work, and also requires this new subflow to be defined for every
workflow where this authentication is utilized.  That, or wrap the process
in chain of Actions that pass a token along that somehow says when you're
done with this entire flow, come back to this location.   I'm going to have
to ponder on this.   Do you have any thoughts on how this could easily be
achieved using your framework?

  Thank you again for all your help and thought!

-- adam





- Original Message -
From: Matthias Bauer [EMAIL PROTECTED]
To: Struts Users Mailing List [EMAIL PROTECTED]
Sent: Tuesday, October 07, 2003 3:20 AM
Subject: Re: workflow extension question


 Adam,

 sorry that I obviously did not make myself clear enough. Look at the
 following definitions:

 global-forwards:
 workflowViolation_wiz1step1: violatedWizard1Step1
 workflowViolation_wiz1step2: violatedWizard1Step2

 displayWizard1Step1
 primaryWorkflow: wiz1step1
 newState: displayed
 nextState: submitted

 submitWizard1Step1
 primaryWorkflow: wiz1step1
 prevState: displayed
 newState: submitted
 forward=success:  displayWizard1Step2

 displayWizard1Step2
 secondaryWorkflow: wiz1step1
 prevState: submitted
 primaryWorkflow: wiz1step2
 newState: displayed
 nextState: submitted

 submitWizard1Step2
 primaryWorkflow: wiz1step2
 prevState: displayed
 newState: submitted

 violatedWizard1Step1
 type: ForwardNextStateViolationAction
 forward=noNextStateViolation: displayWizard1Step1

 violatedWizard1Step2
 type: ForwardNextStateViolationAction
 secondaryWorkflow: wiz1step1
 endWorkflow: true
 forward=noNextStateViolation: displayWizard1Step2

 This is what can happen: If the user has just executed
 displayWizard1Step1 he can only execute submitWizard1Step1 without
 causing a workflow violation. If for instance he follows a link from the
 menu, the workflow wiz1step1 is executed, which causes the execution
 of action violatedWizard1Step1. Upon workflow violation of
 wiz1step1, this workflow is automatically cleaned up, so this action
 does not need to do any other cleanup work. The action class
 ForwardNextStateViolationAction forwards to the action the user has
 chosen from the menu after that.

 Upon prevState violations, i. e. if the user executes
 submitWizard1Step1 without having executed displayWizard1Step1
 before, the action violatedWizard1Step1  causes a forward to
 displayWizard1Step1.

 If a workflow violation of  wiz1step2 happens, the action
 violatedWizard1Step2 is executed, which also ends and cleans up the
 workflow wiz1step1. Except the mechansims are identical to workflow
 wiz1step1.

 This should meet your requirements. Or am I still missing something?

 Concerning your question whether this approach is better than the one to
 end all workflows: In many cases you do not want to end all workflows,
 but only these that belong to a certain process (in our example all
 workflows belonging to wizard1).

 Please let me know, if there are still further questions.

 --- Matthias



 Adam Levine wrote:

  Matthias:
I think I understand your answer.  But, I'm not sure where things
  would go.  If I'm

Re: workflow extension question

2003-10-06 Thread Matthias Bauer
Adam,

there is a solution to your requirement. If I get you right, here is 
what you want to do: You are in a modal dialog. If the user clicks on 
some link he violates the workflow. The action that violates the 
workflow should check whether this is a nextState violation. Upon 
nextState violation you end all relevant workflows and forward to the 
action that caused the workflow violation.

Here is how you can check whether it is a nextState violation: There is 
an action contained in the workflow package that can easily be used for 
this: ForwardNextStateViolationAction. Use this class in the action that 
handles workflow violations. It chooses the forward 
noNextStateViolation, if there was no nextState violation encountered 
(i. e. it must have been a prevState violation). If a nextState 
violation was encountered it forwards to the path that caused this 
workflow violation (this can be an arbitrary action choosen from your 
menu). Have a look at the action's code: It uses the method 
WorkflowUtils.getNextStateViolationAction that provides the required 
information.

Hope this additional info helps.

--- Matthias

Adam L wrote:

Matthias:
   Now to take you up on your offer.is something missing?
   What thoughts do you have on a end all previous workflows property?
The thought is this:
  - my user is working through a process, and gets bored or distracted
  - rather than using the provided cancel button, they use a nav link
to go elsewhere (ie, a terms and conditions or what's new page)
  - my thought is to let them do this, perhaps they'll jump back
(browser back) to the step they were on and continue their path
  - but, if they don't ever come back, and end up starting another
workflow process, they'll be dumped right back to their first workflow.
  - being thrown back to a place you wanted to leave would be confusing
 So, the answer to this is an initialization page for each process
that basically says cancel out all existing workflows and states, and start
this workflow instead.
 Yes, ideally, the user should use the opt-out mechanism provided
to them, but you can't expect that to happen. And, I'm not keen on designing
for a modal experience unless absolutely necessary.  One could go through
every possible action and add a noWorkflowChecks everywhere, but that
still doesn't resolve the issue of them starting a new process w/o
explicitly terminating an existing one.
 To illustrate what I'm seeing:

!-- the landing page for initializing this process --
action
   path=/content/startNewTask
   forward=/content/displayTaskStartScreen.do
 set-property property=authClass
value=com.foo.workflow.authentication.LoggedInAuthentication /
set-property property=endAllExistingWorkflows value=true
 new property
 set-property property=primaryWorkflow value=wkfAddNewTraitStart/
 set-property property=newState value=initialized/
 !-- not logged in authentication exception --
   forward name=authenticationException path=/login.jsp /
/action
Any thoughts?

-- adam

 

- Original Message -
From: Matthias Bauer [EMAIL PROTECTED]
To: Struts Users Mailing List [EMAIL PROTECTED]
Sent: Monday, September 15, 2003 1:59 AM
Subject: Re: workflow - Re: integration with other app


   

Fortunately I am far enough away to avoid your kiss ;-)

Please let me know, if you believe something is missing. I am sure I
 

can
 

give you some more hints on how to solve a specific task. The Struts
Workflow Extension is a very powerful, yet low-level framework. Thus,
 

it
 

offers very much flexibility but sometimes the right way to achieve a
solution is not as apparent as desired.
Just in case you are interested: We are also offering commercial
 

support
 

for this extension and Struts itself.

--- Matthias

Adam Levine wrote:



 

Matthias:
I could kiss you!   I've been struggling with this issue and have
been going bald over the last week doing a lot of my own engine
work.   I can't wait to try this out and see if it doesn't work for me
as cleanly as it looks.


From: Matthias Bauer [EMAIL PROTECTED]
Reply-To: Struts Users Mailing List [EMAIL PROTECTED]
To: Struts Users Mailing List [EMAIL PROTECTED]
Subject: Re: workflow - Re: integration with other app
Date: Fri, 12 Sep 2003 08:35:36 +0200
Martin,

the Struts Workflow Extension http://www.livinglogic.de/Struts/
addresses some of the issues you raise. Especially the thing about a
workflow scope. But it is also easily possible to build reusable
action sequences: Consider for instance a confirmation dialog that
demands the user to press a Yes and No button. You will need this
multiple times within an application, but you normally want to code
the necessary actions only once and reuse them in different contexts
(i. e. with a customized question and return action).
Please let me know, when you have any questions related to the Struts
Workflow Extension.
--- Matthias

Martin Naskovski wrote:



 

Re: workflow extension question

2003-10-06 Thread Adam Levine
Matthias:
  I think I understand your answer.  But, I'm not sure where things would 
go.  If I'm understanding your explanation:

process1:wkfl1 - process1:wkfl2 - (violation) process2:wkfl1 landing 
page(initializer action)

the p2:w1 landing page would be a ForwardNextStateViolationAction
  the FordwardNextStateViolationAction has forwards:
 forward noNextStateViolation : goes to display page for p2:w1
but, if there IS a next state violation, here's where I get confused:
  If a nextState violation was encountered it forwards to the path that 
caused this workflow violation 

Which would lead me back to the p2:w1 landing page ?   That confuses me.

Can you explain why this approach is better than just a i know i want to 
end all previous processes at this point, without having to link in with 
other violation actions ?   Or can they co-exist together nicely ?

Thanks for your help.

-- adam



From: Matthias Bauer [EMAIL PROTECTED]
Reply-To: Struts Users Mailing List [EMAIL PROTECTED]
To: Struts Users Mailing List [EMAIL PROTECTED]
Subject: Re: workflow extension question
Date: Mon, 06 Oct 2003 13:46:56 +0200
Adam,

there is a solution to your requirement. If I get you right, here is what 
you want to do: You are in a modal dialog. If the user clicks on some link 
he violates the workflow. The action that violates the workflow should check 
whether this is a nextState violation. Upon nextState violation you end all 
relevant workflows and forward to the action that caused the workflow 
violation.

Here is how you can check whether it is a nextState violation: There is an 
action contained in the workflow package that can easily be used for this: 
ForwardNextStateViolationAction. Use this class in the action that handles 
workflow violations. It chooses the forward noNextStateViolation, if there 
was no nextState violation encountered (i. e. it must have been a prevState 
violation). If a nextState violation was encountered it forwards to the path 
that caused this workflow violation (this can be an arbitrary action choosen 
from your menu). Have a look at the action's code: It uses the method 
WorkflowUtils.getNextStateViolationAction that provides the required 
information.

Hope this additional info helps.

--- Matthias

Adam L wrote:

Matthias:
   Now to take you up on your offer.is something missing?
   What thoughts do you have on a end all previous workflows property?
The thought is this:
  - my user is working through a process, and gets bored or distracted
  - rather than using the provided cancel button, they use a nav 
link
to go elsewhere (ie, a terms and conditions or what's new page)
  - my thought is to let them do this, perhaps they'll jump back
(browser back) to the step they were on and continue their path
  - but, if they don't ever come back, and end up starting another
workflow process, they'll be dumped right back to their first workflow.
  - being thrown back to a place you wanted to leave would be 
confusing

 So, the answer to this is an initialization page for each process
that basically says cancel out all existing workflows and states, and 
start
this workflow instead.

 Yes, ideally, the user should use the opt-out mechanism provided
to them, but you can't expect that to happen. And, I'm not keen on 
designing
for a modal experience unless absolutely necessary.  One could go through
every possible action and add a noWorkflowChecks everywhere, but that
still doesn't resolve the issue of them starting a new process w/o
explicitly terminating an existing one.

 To illustrate what I'm seeing:

!-- the landing page for initializing this process --
action
   path=/content/startNewTask
   forward=/content/displayTaskStartScreen.do
 set-property property=authClass
value=com.foo.workflow.authentication.LoggedInAuthentication /
set-property property=endAllExistingWorkflows value=true
 new property
 set-property property=primaryWorkflow value=wkfAddNewTraitStart/
 set-property property=newState value=initialized/
 !-- not logged in authentication exception --
   forward name=authenticationException path=/login.jsp /
/action
Any thoughts?

-- adam



- Original Message -
From: Matthias Bauer [EMAIL PROTECTED]
To: Struts Users Mailing List [EMAIL PROTECTED]
Sent: Monday, September 15, 2003 1:59 AM
Subject: Re: workflow - Re: integration with other app





Fortunately I am far enough away to avoid your kiss ;-)

Please let me know, if you believe something is missing. I am sure I


can


give you some more hints on how to solve a specific task. The Struts
Workflow Extension is a very powerful, yet low-level framework. Thus,

it


offers very much flexibility but sometimes the right way to achieve a
solution is not as apparent as desired.
Just in case you are interested: We are also offering commercial


support


for this extension and Struts itself.

--- Matthias

Adam Levine wrote:





Matthias:
I could kiss you!   I've been

RE: workflow extension question

2003-10-03 Thread shirishchandra.sakhare
Hi,
I think what you are saying (The scenarios you have described )is not possible with 
the current workflow implementation.

Because when a user leaves a workflow(Like you said, he is bored and clicks on a menu 
link.), then there is a workflow violation and the workFLow for whicch this violation 
occured is cleared or flushed.SO there si no chance that the user can come back to 
this workflow again.


COrrect me if i got this wrong.But as you said, I will also be interested in getting a 
few more features to this extension(Like the ability to rollback workflo state in case 
of exception in actions execution).Right now I am trying to get some features(with 
some help from Matthias :-))) working for our project.Hope that the current 
implementation solves our needs.

regards,
Shirish

-Original Message-
From: Adam L [mailto:[EMAIL PROTECTED]
Sent: Friday, October 03, 2003 3:49 AM
To: Struts Users Mailing List
Subject: workflow extension question


Matthias:
Now to take you up on your offer.is something missing?

What thoughts do you have on a end all previous workflows property?
The thought is this:
   - my user is working through a process, and gets bored or distracted
   - rather than using the provided cancel button, they use a nav link
to go elsewhere (ie, a terms and conditions or what's new page)
   - my thought is to let them do this, perhaps they'll jump back
(browser back) to the step they were on and continue their path
   - but, if they don't ever come back, and end up starting another
workflow process, they'll be dumped right back to their first workflow.
   - being thrown back to a place you wanted to leave would be confusing

  So, the answer to this is an initialization page for each process
that basically says cancel out all existing workflows and states, and start
this workflow instead.

  Yes, ideally, the user should use the opt-out mechanism provided
to them, but you can't expect that to happen. And, I'm not keen on designing
for a modal experience unless absolutely necessary.  One could go through
every possible action and add a noWorkflowChecks everywhere, but that
still doesn't resolve the issue of them starting a new process w/o
explicitly terminating an existing one.

  To illustrate what I'm seeing:

!-- the landing page for initializing this process --
action
path=/content/startNewTask
forward=/content/displayTaskStartScreen.do
  set-property property=authClass
value=com.foo.workflow.authentication.LoggedInAuthentication /
 set-property property=endAllExistingWorkflows value=true
 new property
  set-property property=primaryWorkflow value=wkfAddNewTraitStart/
  set-property property=newState value=initialized/
  !-- not logged in authentication exception --
forward name=authenticationException path=/login.jsp /
/action


Any thoughts?

-- adam

 - Original Message -
 From: Matthias Bauer [EMAIL PROTECTED]
 To: Struts Users Mailing List [EMAIL PROTECTED]
 Sent: Monday, September 15, 2003 1:59 AM
 Subject: Re: workflow - Re: integration with other app
 
 
 
 
 Fortunately I am far enough away to avoid your kiss ;-)
 
 Please let me know, if you believe something is missing. I am sure I
can
 give you some more hints on how to solve a specific task. The Struts
 Workflow Extension is a very powerful, yet low-level framework. Thus,
it
 offers very much flexibility but sometimes the right way to achieve a
 solution is not as apparent as desired.
 
 Just in case you are interested: We are also offering commercial
support
 for this extension and Struts itself.
 
 --- Matthias
 
 
 Adam Levine wrote:
 
 
 
 Matthias:
  I could kiss you!   I've been struggling with this issue and have
 been going bald over the last week doing a lot of my own engine
 work.   I can't wait to try this out and see if it doesn't work for me
 as cleanly as it looks.
 
 
 
 
 From: Matthias Bauer [EMAIL PROTECTED]
 Reply-To: Struts Users Mailing List [EMAIL PROTECTED]
 To: Struts Users Mailing List [EMAIL PROTECTED]
 Subject: Re: workflow - Re: integration with other app
 Date: Fri, 12 Sep 2003 08:35:36 +0200
 
 Martin,
 
 the Struts Workflow Extension http://www.livinglogic.de/Struts/
 addresses some of the issues you raise. Especially the thing about a
 workflow scope. But it is also easily possible to build reusable
 action sequences: Consider for instance a confirmation dialog that
 demands the user to press a Yes and No button. You will need this
 multiple times within an application, but you normally want to code
 the necessary actions only once and reuse them in different contexts
 (i. e. with a customized question and return action).
 
 Please let me know, when you have any questions related to the Struts
 Workflow Extension.
 
 --- Matthias
 
 Martin Naskovski wrote:
 
 
 
 One thing I find particularly cumbersome in Struts is web page
 workflow. Currently, if I want to push Cancel for instance, or
 Submit on a certain