You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Jeff Smith <je...@centralscheduling.net> on 2003/04/16 21:24:12 UTC

Page Context Stack - a general solution to the problem of returning to your start page

A while back I posted a question asking if anybody had a struts-friendly
solution to returning to your starting location after running a wizard or
chained action sequence. While struts supports this if the starting location
is fixed, it doesn't seem to for a sequence that could be launched from
multiple locations. (I call these "floating" action sequences.)

I never did get a response from anyone. (I think my question got buried
under a flurry of activity on more popular threads. :-)

So I went ahead and implemented something that seems to work fairly well. In
fact, I generalized the problem to that of creating a page context stack,
with push and pop capabilities. Using this, in theory, one could even
implement nested wizard processes using multiple floating sequences -
pushing page contexts on the way in and popping them on the way out. And the
best part is that you still use struts-config.xml to specify the chains.

The problem is, I still don't know if I've re-invented a wheel here. Would
this be useful to anybody else?

Jefficus


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re: Page Context Stack - a general solution to the problem of returning to your start page

Posted by Matthias Bauer <Ma...@livinglogic.de>.
Cody Sherr wrote:

>I encountered exactly the same problem in a project, and was interested
>in your original posting. I think that workflows are a common
>requirement in web applications. 
>
>We implemented something similar to what you described, a stack of
>return paths that was stored in the session that could be pushed and
>popped when calculating the forward to return.
>
>A drawback is that the user can navigate anywhere in your application,
>they're not necessarily going to "pop" when they leave a workflow. 
>
>There is a workflow extension to struts. I decided not to use it because
>it would be a large migration problem for existing actions.
>  
>

There will be a new release of the workflow extension in a week or so, 
that is integrated with the Struts 1.1 mechanisms. It does no longer 
force you to rewrite your actions like you have to do now, as this is 
indeed a formidable downside of the current implementation.

The code changes for the new release are all in place already. I just 
need to finish documentation and tests first.

--- Matthias



---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re: Page Context Stack - a general solution to the problem of returning to your start page

Posted by Dan Allen <da...@mojavelinux.com>.
> Your response sounded a touch cynical. Have I missed something here?

Nope, just wanted to get down to business.  Thank you very much for
the thorough discussion, it has my brain churning...

Dan

-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Daniel Allen, <da...@mojavelinux.com>
http://www.mojavelinux.com/
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
"While they're pumping, you're soaking them" 
 -- Speed Loader TV Advert
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


RE: Re[2]: Page Context Stack - a general solution to the problem of returning to your start page

Posted by Andrew Hill <an...@gridnode.com>.
This is very similar to what we are doing. We have an object which we call
an OperationContext that has an id (tacked onto urls) and allows us to track
stuff associated with the operation in progress by storing this object in
the session under that unique id. We even store the actionForm there and
have overridden the RequestProcessor to look for it there first if that
action is using a session scoped form. One advantage of this is that it
allows us to more safely implement our requirement of being able to edit
multiple things of a particular form type (same action mapping) in different
windows simultaneously - which can be problematic for session scoped forms
with the normal method of using a fixed attribute for the form. (While most
of these operations are crud actions , we need a session bean as not all the
fields are shown at any one time - and we also have to support resuming the
operation after ging somewhere else)

Our app is quite complex, and entries for one type of object may need the
user to select from a list of another type of object. Often the user will
not have created the second object yet. To allow them to go off and create
it and then come back without losing their unsaved changes we allow these
OperationContexts to be stacked in a similar manner to that described below
by Jeff - although we dont have a central registry of OperationContexts as
such.

When the user abandons an operation we have to do tricky stuff to ensure
that the abandoned object was removed from the session. I think Jeffs way
might handle this better, but it seems more suited to handling processes
rather than editing of entities.

-----Original Message-----
From: Jeff Smith [mailto:jeffs@centralscheduling.net]
Sent: Friday, 25 April 2003 05:13
To: struts-user@jakarta.apache.org
Subject: Re[2]: Page Context Stack - a general solution to the problem
of returning to your start page


Hi Dan,

Thursday, April 24, 2003, 2:21:14 PM, you said:

DA> Jeff Smith (jeffs@centralscheduling.net) wrote:

>> Hi Struts-o-philes,
>>
>> Thursday, April 24, 2003, 12:51:41 PM, you said:
>>
>> CS> We implemented something similar to what you described, a stack of
>> CS> return paths that was stored in the session that could be pushed and
>> CS> popped when calculating the forward to return.
>>
>> CS> A drawback is that the user can navigate anywhere in your
application,
>> CS> they're not necessarily going to "pop" when they leave a workflow.
>>
>> I don't see it as a drawback, but as an opportunity. We actually have
>> stack contexts. So if a user jumps out of the stack and starts a
>> different stack (a process with a different context id) then we know
>> he has left the first stack and we can close it out, if need be.
>>
>> Otherwise, if/when he returns to the first stack, we can offer to take
him
>> back to where he left off, or restart, because we still have his state
>> info in session.

DA> Do you have code for this?  It is all talk until there is some code
DA> to look at.

Implementation is happening as we speak, so I can't share "live" code
yet. But here's the broad strokes of what we're doing.

Each workflow/wizard/sequence/thingie has a unique context ID number.

When we call the first step in the sequence, it grabs the
"where-did-I-come-from" URL (technique described in a previous
posting) and gives it and the context id to URLStack.

The URLStack looks at the
context id. If it does not yet have a stack with that id, go ahead and
process the wizard steps, creating a stack with the given ID to hold
the pushed URLs for this process. The URLStack object is then placed in the
session scope if it isn't already there.

Subsequent steps in the wizard each report themselves to the URLStack,
so that it can keep track of where we are in the process as we move
through the pages. If the user ever jumps out of the wizard, he stops
reporting changes to the URLStack for that context id, so URLStack
always has a record of where we were in the process just before we
jumped out.

If at some point we report a start step for a context, and there
already *IS* a stack with that id, then obviously we are returning to
a workflow that has been abandoned earlier in the session, so we inspect
further:

a) Has this context been flagged as non-resumable? (A flag set in a
config file, based on context id, but can also be overridden when the
start-step is reported to the URLStack.) If so, then the
information in the session from the previous abandoned attempt is
considered obsolete, it is all removed from session and the wizard
continues as though nothing had happened.

b) If the context was flagged as resumable, then the
existing information is considered to be still good and the user is
prompted to see whether he wants to continue with his previous attempt
at the wizard or start again.

For example, a 4 page registration wizard would be marked as
resumable, since subsequent work on the site will not have
invalidated the user's address or phone number information.

On the other hand, a process like "Print My Shopping Cart" probably
should be non-resumable, since the shopping cart could very easily
have changed in the interim.

An interesting case is the shopping cart checkout
sequence. Until we have authorized the card, the flow should be
resumable. But once we've computed a dollar amount and want to go
process the payment, we probably want that step to be non-resumable.
(Otherwise, users could start to process a single item, then abort the
credit card check, add some more things to the cart and then resume
the payment with the total still in place from the aborted shopping
cart run. Very ugly.) For this reason, we are considering making the
resumability flag more granular, flipping it on at the last step
possible in the process, rather than just at the start-step.

Your response sounded a touch cynical. Have I missed something here?

--
Jefficus
mailto:jeffs@centralscheduling.net


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re[2]: Page Context Stack - a general solution to the problem of returning to your start page

Posted by Jeff Smith <je...@centralscheduling.net>.
Hi Dan,

Thursday, April 24, 2003, 2:21:14 PM, you said:

DA> Jeff Smith (jeffs@centralscheduling.net) wrote:

>> Hi Struts-o-philes,
>> 
>> Thursday, April 24, 2003, 12:51:41 PM, you said:
>> 
>> CS> We implemented something similar to what you described, a stack of
>> CS> return paths that was stored in the session that could be pushed and
>> CS> popped when calculating the forward to return.
>> 
>> CS> A drawback is that the user can navigate anywhere in your application,
>> CS> they're not necessarily going to "pop" when they leave a workflow. 
>> 
>> I don't see it as a drawback, but as an opportunity. We actually have
>> stack contexts. So if a user jumps out of the stack and starts a
>> different stack (a process with a different context id) then we know
>> he has left the first stack and we can close it out, if need be.
>> 
>> Otherwise, if/when he returns to the first stack, we can offer to take him
>> back to where he left off, or restart, because we still have his state
>> info in session.

DA> Do you have code for this?  It is all talk until there is some code
DA> to look at.

Implementation is happening as we speak, so I can't share "live" code
yet. But here's the broad strokes of what we're doing.

Each workflow/wizard/sequence/thingie has a unique context ID number.

When we call the first step in the sequence, it grabs the
"where-did-I-come-from" URL (technique described in a previous
posting) and gives it and the context id to URLStack.

The URLStack looks at the
context id. If it does not yet have a stack with that id, go ahead and
process the wizard steps, creating a stack with the given ID to hold
the pushed URLs for this process. The URLStack object is then placed in the
session scope if it isn't already there.

Subsequent steps in the wizard each report themselves to the URLStack,
so that it can keep track of where we are in the process as we move
through the pages. If the user ever jumps out of the wizard, he stops
reporting changes to the URLStack for that context id, so URLStack
always has a record of where we were in the process just before we
jumped out.

If at some point we report a start step for a context, and there
already *IS* a stack with that id, then obviously we are returning to
a workflow that has been abandoned earlier in the session, so we inspect further:

a) Has this context been flagged as non-resumable? (A flag set in a
config file, based on context id, but can also be overridden when the
start-step is reported to the URLStack.) If so, then the
information in the session from the previous abandoned attempt is
considered obsolete, it is all removed from session and the wizard
continues as though nothing had happened.

b) If the context was flagged as resumable, then the
existing information is considered to be still good and the user is
prompted to see whether he wants to continue with his previous attempt
at the wizard or start again.

For example, a 4 page registration wizard would be marked as
resumable, since subsequent work on the site will not have
invalidated the user's address or phone number information.

On the other hand, a process like "Print My Shopping Cart" probably
should be non-resumable, since the shopping cart could very easily
have changed in the interim.

An interesting case is the shopping cart checkout
sequence. Until we have authorized the card, the flow should be
resumable. But once we've computed a dollar amount and want to go
process the payment, we probably want that step to be non-resumable.
(Otherwise, users could start to process a single item, then abort the
credit card check, add some more things to the cart and then resume
the payment with the total still in place from the aborted shopping
cart run. Very ugly.) For this reason, we are considering making the
resumability flag more granular, flipping it on at the last step
possible in the process, rather than just at the start-step.

Your response sounded a touch cynical. Have I missed something here?

-- 
Jefficus                     
mailto:jeffs@centralscheduling.net


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re: Page Context Stack - a general solution to the problem of returning to your start page

Posted by Dan Allen <da...@mojavelinux.com>.
Jeff Smith (jeffs@centralscheduling.net) wrote:

> Hi Struts-o-philes,
> 
> Thursday, April 24, 2003, 12:51:41 PM, you said:
> 
> CS> We implemented something similar to what you described, a stack of
> CS> return paths that was stored in the session that could be pushed and
> CS> popped when calculating the forward to return.
> 
> CS> A drawback is that the user can navigate anywhere in your application,
> CS> they're not necessarily going to "pop" when they leave a workflow. 
> 
> I don't see it as a drawback, but as an opportunity. We actually have
> stack contexts. So if a user jumps out of the stack and starts a
> different stack (a process with a different context id) then we know
> he has left the first stack and we can close it out, if need be.
> 
> Otherwise, if/when he returns to the first stack, we can offer to take him
> back to where he left off, or restart, because we still have his state
> info in session.

Do you have code for this?  It is all talk until there is some code
to look at.

Dan

-- 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Daniel Allen, <da...@mojavelinux.com>
http://www.mojavelinux.com/
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
[Frodo]: "He deserves death." 
[Gandalf]: "Deserves it! I daresay he does. Many that live 
deserve death. And some that die deserve life.  Can you give 
it to them?  Then do not be too eager to deal out death in 
judgement. For even the very wise cannot see all ends."
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re[2]: Page Context Stack - a general solution to the problem of returning to your start page

Posted by Jeff Smith <je...@centralscheduling.net>.
Hi Struts-o-philes,

Thursday, April 24, 2003, 12:51:41 PM, you said:

CS> We implemented something similar to what you described, a stack of
CS> return paths that was stored in the session that could be pushed and
CS> popped when calculating the forward to return.

CS> A drawback is that the user can navigate anywhere in your application,
CS> they're not necessarily going to "pop" when they leave a workflow. 

I don't see it as a drawback, but as an opportunity. We actually have
stack contexts. So if a user jumps out of the stack and starts a
different stack (a process with a different context id) then we know
he has left the first stack and we can close it out, if need be.

Otherwise, if/when he returns to the first stack, we can offer to take him
back to where he left off, or restart, because we still have his state
info in session.

CS> -Cody Sherr

Jefficus


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


RE: Page Context Stack - a general solution to the problem ofreturning to your start page

Posted by Marco Tedone <m_...@hotmail.com>.
We had the same problem in my project. We solved by implementing an XML
configuration file showing the relevant actions for visited page. In few
words it works like this:

1) When needed (in our case it means when an application exception is
thrown) we retrieve the last page visited by the user (like
/appname/login.jsp)
2) With this value, we match what we called a 'relevant action' to
forward the user to (generally defined in global forwards)

The XML configuration file looks like the following:

<?xml version="1.0" encoding="UTF-8"?>

<xmlop>

  <action>
    <lastPage>xml-op/Login.jsp</lastPage>
    <relevantAction>LOGIN</relevantAction>
  </action>

  <action>
    <lastPage>xml-op/Page.jsp</lastPage>
    <relevantAction>PAGE</relevantAction>
  </action>

</xmlop>  

Where the value of <relevantAction> represent a forward in struts. We
loaded the XML configuration info at startup asking help to a Struts
PlugIn and to commons-digester; now you can define a general Action
(let's say MyForwardAction) which retrieves from the request the last
page visited (xml-op/Login.jsp, where xml-op is the name of the
servlet-mapping) and then sets a mapping.findForward("String") value
with the value returned by <relevantAction>. This way, even if you're
writing another configuration file, the integrity between actions in
your application is kept, even if a blocking exception is thrown.

Hope it will help,

Marco

> -----Original Message-----
> From: Cody Sherr [mailto:csherr@covalent.net] 
> Sent: 24 April 2003 19:52
> To: Struts Users Mailing List
> Subject: Re: Page Context Stack - a general solution to the 
> problem ofreturning to your start page
> 
> 
> 
> I encountered exactly the same problem in a project, and was 
> interested in your original posting. I think that workflows 
> are a common requirement in web applications. 
> 
> We implemented something similar to what you described, a 
> stack of return paths that was stored in the session that 
> could be pushed and popped when calculating the forward to return.
> 
> A drawback is that the user can navigate anywhere in your 
> application, they're not necessarily going to "pop" when they 
> leave a workflow. 
> 
> There is a workflow extension to struts. I decided not to use 
> it because it would be a large migration problem for existing actions.
> 
> -Cody Sherr
> 
> On Wed, 2003-04-16 at 12:24, Jeff Smith wrote:
> > A while back I posted a question asking if anybody had a 
> > struts-friendly solution to returning to your starting 
> location after 
> > running a wizard or chained action sequence. While struts supports 
> > this if the starting location is fixed, it doesn't seem to for a 
> > sequence that could be launched from multiple locations. (I 
> call these 
> > "floating" action sequences.)
> > 
> > I never did get a response from anyone. (I think my question got 
> > buried under a flurry of activity on more popular threads. :-)
> > 
> > So I went ahead and implemented something that seems to work fairly 
> > well. In fact, I generalized the problem to that of creating a page 
> > context stack, with push and pop capabilities. Using this, 
> in theory, 
> > one could even implement nested wizard processes using multiple 
> > floating sequences - pushing page contexts on the way in 
> and popping 
> > them on the way out. And the best part is that you still use 
> > struts-config.xml to specify the chains.
> > 
> > The problem is, I still don't know if I've re-invented a 
> wheel here. 
> > Would this be useful to anybody else?
> > 
> > Jefficus
> > 
> > 
> > 
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: struts-user-help@jakarta.apache.org
> > 
> > 
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re: Page Context Stack - a general solution to the problem of returning to your start page

Posted by Cody Sherr <cs...@covalent.net>.
I encountered exactly the same problem in a project, and was interested
in your original posting. I think that workflows are a common
requirement in web applications. 

We implemented something similar to what you described, a stack of
return paths that was stored in the session that could be pushed and
popped when calculating the forward to return.

A drawback is that the user can navigate anywhere in your application,
they're not necessarily going to "pop" when they leave a workflow. 

There is a workflow extension to struts. I decided not to use it because
it would be a large migration problem for existing actions.

-Cody Sherr

On Wed, 2003-04-16 at 12:24, Jeff Smith wrote:
> A while back I posted a question asking if anybody had a struts-friendly
> solution to returning to your starting location after running a wizard or
> chained action sequence. While struts supports this if the starting location
> is fixed, it doesn't seem to for a sequence that could be launched from
> multiple locations. (I call these "floating" action sequences.)
> 
> I never did get a response from anyone. (I think my question got buried
> under a flurry of activity on more popular threads. :-)
> 
> So I went ahead and implemented something that seems to work fairly well. In
> fact, I generalized the problem to that of creating a page context stack,
> with push and pop capabilities. Using this, in theory, one could even
> implement nested wizard processes using multiple floating sequences -
> pushing page contexts on the way in and popping them on the way out. And the
> best part is that you still use struts-config.xml to specify the chains.
> 
> The problem is, I still don't know if I've re-invented a wheel here. Would
> this be useful to anybody else?
> 
> Jefficus
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: struts-user-help@jakarta.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org