RE: Any way to dynamically change flow-of-control?

2001-01-24 Thread Rick Horowitz

Hi Curt,

I just read through the thread for this message, and your approach sounds 
very interesting.  I'd like to ask you some questions, interspersed below 
if you wouldn't mind...thanks in advance.

At 04:20 PM 1/12/01 -0800, you wrote:
  I bring this up because struts seems to have gone partway--better than
  any other framework I've seen--but not all the way in its support of
  this dialog box metaphor (it uses form beans).  What is now
  needed is a navigation stack of some kind--perhaps even something that
  is written/phrased in terms of "traditional" UI metaphors.

I've implemented something like this as follows.

I make frequent use of a metaphor whereby the form contains an edit
field with an adjacent button (text: "...") that allows lookup of
values in the edit field.  This allows the user to enter the value
directly if they know it, or to click on the "..." button to perform
a search.  (This presumes that there are too many choices for a
select field to make sense.)

Assume the user starts on screen A, and clicks the search button that takes 
them to screen B which displays a search form. The user fills out the 
search form, clicks OK, and is presented with screen C, which displays the 
search results.  The user then selects from among the search results by 
clicking an href link or a form button.  The user is then returned to 
screen A with the original screen A form data and the search results filled 
in.

Question:  I'm wondering how you move the user to the appropriate screens, 
given your approach described below.

The transition from screens A to B is easy.  This can be hard-coded in the 
struts-config.xml ActionMappings.  How do you determine the transitions for 
the other screens, though?

When the user is presented with screen B, he fills out the search form and 
selects either:

- OK:  we process the search request and transition to screen C if search 
is successful, and return to screen B with errors if search is unsuccessful.
- Cancel:  we obtain the data from the cache, set things up, and return the 
user to screen A
- Hits the browser back button:  ??

When the user is presented with screen C, he either:

- Selects a choice from the search results:  we obtain the data from the 
cache, set things up, and return the user to screen A
- Hits the browser back button:  ??

So this leaves me with a couple of questions:

1. How do we differentiate the transitions when processing the OK or Cancel 
from screen B?  The OK transition to screen C can be specified in the 
ActionMappings in struts-config.xml, but the Cancel request must obtain the 
information from the cache. I suppose this means the token used to store 
screen A's information is written to screen B's form, and retrieved IFF the 
user decides to Cancel screen B's action. True?

2. What happens when the user selects a search result choice on screen 
C?  We want to return the user to screen A.  Does this mean that screen C 
should also be implemented as a HTML form, and that we also write the token 
for screen A to this form?  How do you know which token to write onto 
screen C's form?  Do you just "know" that screen B needs to create a new 
cache entry, and that screen C needs to use the cache entry token that is 
submitted with screen B's request, and therefore code it that way?  Or do 
you have some other mechanism that you've designed?

more below...


I want to be able to perform the search and return to this screen
with both the existing data and the search results filled in.  I
want the user to be able to do this in multiple browser windows
without them interfering with each other.  I want the "back" button
to work as expected, because I know that as a user, I get very
annoyed with the inability to use this button.

When the back button is pressed, doesn't the previous page's request just 
get resent? What are the implications of this...any special processing 
required?


When the user clicks the "..." search, the entire calling state,
including the ActionForm bean, is copied into a cache which is
stored on a per-user basis.

Can you share your code showing how you obtain all of the calling state? 
Also, your cache code, as well, if possible...thanks.

 From the cache, I get a unique token to
refer to the calling state.  This token is then stored in a hidden
"caller" element on the new form.  If the user moves forward from
this screen by pressing either "OK" or "Cancel",

By "moves forward", do you mean possibly moving up the stack of screens, 
e.g. from screen C to screen A?

the original form
is restored from the cached information, the cached value becomes
eligible for destruction, and after a short grace period, the form
is removed from the cache.

Why do you have this short grace period?  Is this cached information still 
relevant?  Perhaps if the user hits forward and back again on the browser? 
Or something else?  I'm very unclear on how you would access this cached 
information.  For example, if we cache screen 

RE: Any way to dynamically change flow-of-control?

2001-01-24 Thread Curt Hagenlocher

Rick-

 When the user is presented with screen B, he fills out the 
 search form and selects either:
 
 - OK:  we process the search request and transition to screen C if
 search is successful, and return to screen B with errors if search 
 is unsuccessful.

Actually, screen B and screen C are implemented in the same (.jsp)
file.  When first moving from screen A to screen B, there are no
results stored in the context of the request.  When screen B is
submitted to the Action, one of three things will happen.

- The results are stored in a "requestList" attribute
- The errors are stored in an "errorList" attribute
- A boolean "true" is stored in a "noResults" attribute

The .jsp displays the results as appropriate (using Struts logic
tags) under the same (form) header that was used to collect the
search criteria.  This also allows the user to immediately do a
different search without hitting the "Back" button.

 - Cancel:  we obtain the data from the cache, set things up, 
 and return the user to screen A

Yes.

 - Hits the browser back button:  ??

The browser simply restores screen A without any input from
the server.  We never can directly discover whether or not this
has happened without the type of JavaScript I'm trying to avoid.

 When the user is presented with screen C, he either:
 
 - Selects a choice from the search results:  we obtain the 
 data from the cache, set things up, and return the user to
 screen A

Yes.

 - Hits the browser back button:  ??

Again, the browser simply restores screen B without any input
from the server.

 So this leaves me with a couple of questions:
 
 1. How do we differentiate the transitions when processing the
 OK or Cancel from screen B? 

I look directly at the request.  The relevant code is:
if (request.getParameter("cancel") != null)
{
LookupForm oldform = lkupform.getSavedForm();
return oldform.processAction(request, response);
}

(LookupForm is a derivative of ActionForm that has the small
amount of additional state information needed to implement the
stack.)

 I suppose this means the token used to store screen A's
 information is written to screen B's form, and retrieved IFF
 the user decides to Cancel screen B's action. True?

It's also used when the user selects a search result choice
on screen C.

 2. What happens when the user selects a search result choice 
 on screen C?  We want to return the user to screen A.  Does
 this mean that screen C should also be implemented as a HTML
 form, and that we also write the token for screen A to this
 form?  How do you know which token to write onto screen C's
 form?  Do you just "know" that screen B needs to create a new 
 cache entry, and that screen C needs to use the cache entry 
 token that is submitted with screen B's request, and therefore
 code it that way?  Or do you have some other mechanism that
 you've designed?

Knowing that screens B and C share a .jsp and (by extension)
an ActionForm should make this a little clearer.  The actual
selection of a search result from screen C is done with a custom
tag that references a "LookupResult" action which I reuse for
all such lookups.  This tag
  app:lookupResult name="product" code="code" id="id"
produces this HTML
a href="LookupResult.do?caller=4amp;code=CACamp;id=36"

The caller is, again, a reference to the cached calling form.
The "code" and "id" are fields that identify the search result
chosen -- in this case, "code" is a human-readable possibly
unique value representing the record, and "id" is a surrogate
key to that record (and guaranteed unique).

The code is what will populate the field on the original form
(screen A) that we're looking up.  The id allows for any
required disambiguation.  (Usually, there is none.)

 When the back button is pressed, doesn't the previous page's 
 request just get resent? What are the implications of this...
 any special processing required?

Back followed by submit will resend the previous request, yes.
I don't do anything special to handle this, and I don't think
there are any ramifications.  (I'm pretty sure I worked it out
so that there is no memory leaked, but I'm fuzzy on the details.)

 When the user clicks the "..." search, the entire calling state,
 including the ActionForm bean, is copied into a cache which is
 stored on a per-user basis.
 
 Can you share your code showing how you obtain all of the 
 calling state?  Also, your cache code, as well, if possible

I think I made that sound more sophisticated than it really is.
The calling state is just the calling ActionForm and Action.
The calling Action is what checks to see if the user has selected
the lookup in addition to its "real" processing job.  It also
knows how to redraw the original screen.

I make frequent use of a pattern whereby there is a single action
and .jsp which are responsible for initially displaying the form,
displaying the form with any errors after 

Re: Any way to dynamically change flow-of-control?

2001-01-12 Thread Laird J. Nelson

- Original Message -
From: [EMAIL PROTECTED]
 This should return you to the first screen, with all of the values
entered
 up to that point intact (okay, so that means its not a link but a form
 post), PLUS the value of the customer field. The 'Find Customer'
screen
 should be able to be invoked from a range of other screens.

Right; the "Find Customer" screen in this case is really a dialog box
(or would be in a normal client-server application, most likely).

 I guess that perhaps this could be done by an application in Struts
quite
 easily, but some standard approach enforced by the framework itself
would
 be nice.

Yes.  I'm not suggesting, BTW, that there be a whole set of UI objects
that should be shoved into the struts framework (that would be kind of
silly and overblown), but I am suggesting that whatever mechanism ends
up being put in place force the user to construct modular screens, i.e.
to build the Find Customer screen such that it can be invoked from many
places.  Most web sites I've seen or worked with are built assuming a
rigid flow--if you pluck the existing Find Customer screen out of the
flow and want to invoke it somewhere else you typically have to change a
lot of form action=xxx tags (and you typically break stuff).

Cheers,
Laird

--
[EMAIL PROTECTED]
http://www.amherst.edu/~ljnelson/
Good, cheap, fast: pick two.




RE: Any way to dynamically change flow-of-control?

2001-01-12 Thread Curt Hagenlocher

 I bring this up because struts seems to have gone partway--better than
 any other framework I've seen--but not all the way in its support of
 this dialog box metaphor (it uses form beans).  What is now 
 needed is a navigation stack of some kind--perhaps even something that
 is written/phrased in terms of "traditional" UI metaphors.

I've implemented something like this as follows.

I make frequent use of a metaphor whereby the form contains an edit
field with an adjacent button (text: "...") that allows lookup of
values in the edit field.  This allows the user to enter the value
directly if they know it, or to click on the "..." button to perform
a search.  (This presumes that there are too many choices for a
select field to make sense.)

I want to be able to perform the search and return to this screen
with both the existing data and the search results filled in.  I
want the user to be able to do this in multiple browser windows
without them interfering with each other.  I want the "back" button
to work as expected, because I know that as a user, I get very
annoyed with the inability to use this button.

When the user clicks the "..." search, the entire calling state,
including the ActionForm bean, is copied into a cache which is
stored on a per-user basis.  From the cache, I get a unique token to
refer to the calling state.  This token is then stored in a hidden
"caller" element on the new form.  If the user moves forward from
this screen by pressing either "OK" or "Cancel", the original form
is restored from the cached information, the cached value becomes
eligible for destruction, and after a short grace period, the form
is removed from the cache.  If the user presses the "Back" button,
the form remains in the cache longer, although it, too, will
eventually time out and be destroyed.

In any event, once the user's session is terminated, any saved forms
are destroyed.

This approach works very well for me.  A stack is implicitly defined
by the succession of "caller" elements without having to maintain
anything that looks like a stack on a global level.  I don't know
how well this approach scales, but short of keeping all of the state
information in the user's browser, I can't think of any way to
reduce its footprint.

--
Curt Hagenlocher
[EMAIL PROTECTED]



Re: Any way to dynamically change flow-of-control?

2001-01-11 Thread Elod Horvath

see interspersed comments below...


"Laird J. Nelson" wrote:
 
 - Original Message -
 
 I like to think of this as the "dialog box problem" that web UIs face.
 That is, each case above, in a "traditional" client-server program,
 would be implemented, usually, as a dialog box.  What's unique about a
 dialog box?  It pops up and gets in the way of where you (a) are or (b)
 were trying to go.  Only when you dismiss it are you "returned" to
 either (a) or (b).  On the web, of course, with our primitive HTML-based
 UIs, there are no such things as dialog boxes (unless you use
 javascript).  So "screen flow" becomes all important.
 
 I bring this up because struts seems to have gone partway--better than
 any other framework I've seen--but not all the way in its support of
 this dialog box metaphor (it uses form beans).  What is now needed is a
 navigation stack of some kind--perhaps even something that is
 written/phrased in terms of "traditional" UI metaphors.  I'm thinking
 about some kind of stack--and believe me, I haven't thought this all the
 way through yet--that can be accessed by Actions, but any given Action
 would typically say something like "OK, go to the next screen that I'm
 being told to go to, or if I'm not being told to go anywhere, go to this
 default location".  Or the Action might be able to say "oops, conditions
 aren't right to advance; pop the stack and go back to where we were a
 moment ago but display the following message".  Things on the stack
 would be *roughly* equivalent to screens--though I hesitate to use
 "screen" as I think that's one of the major shortcomings of the Turbine
 framework, because a "screen" on the web often exists as a separate
 entity only because the marketing department said it has to.

Actually, I've implemented just such a construct at work for the struts
based prototype of a significant financial web-application shell. There 
 
was some discussion on this list some time ago about something called a 
StateManager, which is essentially what this is.  And yes, the concept
of 
"screen" is fuzzy -- in my situation, a "screen" is really a [at times] 
complicated and changing frameset.  

The app/shell's flow follows a (process/state update/redraw) pattern 
in a [con]federation of sub-applications (and thus, controllers).  
See my attached diagram with numbered steps as follows:

1)  Application Request
Client-side user triggers a request to the server.

2)  Sub-application Controller Dispatch
Dispatches the request to the appropriate action handler.

3)  Action Request Processing
The actions process the request, invokes relevant business logic,
sets up data and state beans.

4)  Redirect Response
Initial request response is _always_ a redirect to a single URL
to redraw the application window.

5)  Window Redraw Request
There is one global window redraw request handled by the main
controller servlet.  This request "repaints" the entire browser
window based on the current state of the application.

6)  Main Controller Dispatch
Dispatches the request to the appropriate action handler.

7)  Action Request Processing
This sets up the request object and determines the correct views to
"forwards" to based on what's on top of the page stack.

8)  Request Forwarded (dispatched) to Views
   
9)  JSP Views Render Response

10) Final Result Response
Response to the redraw request.

(apologies for the detail level in these steps -- I lifted this diagram
 and description from the system overview documentation I'm working on
 at work (geared towards newbie developers in my group))

one side benefit of this indirected approach is that the application
has _total_ control over what the user sees...because all requests 
_always_ result in a redirect to the same _global_ repaint action,
the browser's navigation buttons are effectively disabled; the user always
gets presented what is currently at the top of the pagestack -- be it
error page, form, interjected "dialog" window, etc.  The framework
effectively hides the implementing JSP views from the browser's URL
location making it more difficult for the user to bookmark intermediate 
pages or the browser to track page history (something which is usually 
not desirable, especially with sensitive apps/sites).

I hope this was helpful...

e

-- 
___
Elod Horvath ('e')   /  ITFAIS Records (http://www.itfais.com/)
Unknown Document



Re: Any way to dynamically change flow-of-control?

2001-01-11 Thread Ted Husted

"Felciano, Ramon" wrote:
 - Confirm pages ("Are you sure that ?" with "Continue" and
"Cancel"
 buttons)
 - Pick lists ("We couldn't find the product ID you entered; please
select
 from the following list")
 - Alert pages for (possibly unexpected) server-side events that
occured
 since the last client-server traffic passed through.

Just a wild idea here: 

An action is not required to forward to a path or action, but has
everything it needs to answer the request itself (and return a null
action forwarding).

So how about if the action wrote pages like this dynamically, the
old-fashioned servlet way, perhaps using a standard "message box" type
library? 

The responses in the dynamic page could then be set to forward to
whatever actions or paths were appropriate to the circumstances,
without having to write a physical JSP for every conceivable
combination.


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel 716 425-0252; Fax 716 223-2506.
-- http://www.husted.com/





Re: Any way to dynamically change flow-of-control?

2001-01-11 Thread JamesW


This is a very interesting discussion; this sort of functionality appears
to be missing from all of the servlet based frameworks out there (with
possibly the exception of Hammock?).

An example of what I would like struts to be able to support (and this
example may have already been put forward, but here's my take on it anyway)
is a screen (okay, 'form') that has multiple fields, plus say a customer
field. You can either enter the name of the customer, or click on a link
next to the field called 'Find Customer...'. This takes you to the 'Find
Customer' form where you can enter search parameters and then see a list of
customers matching those parameters (the 'Customer List' form). The 'List
Customer' form may let you return to the 'Find Customer' form for another
type of search, or click on a link next to one of the matching customers.
This should return you to the first screen, with all of the values entered
up to that point intact (okay, so that means its not a link but a form
post), PLUS the value of the customer field. The 'Find Customer' screen
should be able to be invoked from a range of other screens.

I guess that perhaps this could be done by an application in Struts quite
easily, but some standard approach enforced by the framework itself would
be nice.

Regards,
James W.

--
This e-mail is from Cards Etc Pty Ltd (ACN: 069 533 302). It may contain
privileged and confidential information. It is intended for the named
recipient(s) only. If you are not an intended recipient, please notify us
immediately by reply e-mail or by phone on +61 2 9212 7773  delete this
e-mail from your system.
--





Re: Any way to dynamically change flow-of-control?

2001-01-10 Thread Craig R. McClanahan

Hi Ramon,

See interspersed comments below.

"Felciano, Ramon" wrote:

 Hi --

 I'm evaluating Struts (+Turbine+Rocks) as a framework for our web apps

 We often want to insert certain UI actions based on exceptional user
 behavior. A simple example is an authentication  screen that gets inserted
 "just in time". For example, if the normal flow of control is from page A
 -- page B, where page B requires authentication, then 98% of the time, the
 user goes A -- B. However, the very first time this happens we want to
 insert an authentication page: A -- Logon -- B. Other situations where
 this type of intermittent insertion of additional UI and flow logic would be
 helpful include:

 - Confirm pages ("Are you sure that ?" with "Continue" and "Cancel"
 buttons)
 - Pick lists ("We couldn't find the product ID you entered; please select
 from the following list")
 - Alert pages for (possibly unexpected) server-side events that occured
 since the last client-server traffic passed through.


That is an interesting approach.


 I realize that these can all be implemented on a case-by-case basis, with
 each Action class deciding whether to insert a new flow element or not. A's
 Action class could check the authentication state and decide whether to go
 to Login or B accordingly. In the pick list example, this could be done by
 returning the user to the original form and using JSP logic to notice the
 error and display a list of options to choose from. However, if the page is
 a complex one, displaying a specialized form for just this input value can
 be useful.

 I guess I'm wondering whether there is any generalized support for this that
 might better separate the nature of these exception events? For example, in
 the login example, it doesn't make sense to me that A's Action class make
 the decision as to whether to show the login form, since the authentication
 is bound to B. In particular, I'd like to be able to reroute to Logon when
 needed, but otherwise continue with the "normal" flow of logic. Thus, if at
 a later date the "normal" flow of logic dictates A -- C, I only want to
 change this in one place (A's success forward property), and still benefit
 from the just-in-time authentication. Same thing for confirm pages, etc...


Within Struts 1.0, an approach to handling these things generically would be to
subclass the ActionServlet controller servlet, and override a method like
processActionPerform (which actually calls the selected Action) or
processActionForward (which forwards control to the returned logical page
name).  You could then inspect the current state of the world, and inject
flow-of-control changes like this while still utilizing the superclass's basic
functionality.

To make the types of things you inject somewhat configurable, you might also
want to use your own custom ActionMapping subclass, with extra bean properties
that describe (to your override method) what exceptional things to do and when
to do them -- the selected ActionMapping instance is made available to most of
the processing calls, so this information would be easily accessible.

In future versions, one of the directions I really want to look is a more
"workflow" like organization of processing within Struts (both for the basic
processing that the controller servlet does for you, and for letting you glue
together finer grained tasks, in addition to (or instead of) the relatively
coarse grained Actions that are currently supported.  Doing the sorts of dynamic
flow-of-control changes you are talking about would seem to fit into that model
pretty well, especially if you could "script" them in the struts-config file.


 Finally, and on a different topic, can someone please point me to the most
 recent discussion (or docs) regarding how to do Form validation with struts?
 The [outdated?] user guide first suggests not doing it in the ActionForm
 class, then provides a ValidatingActionForm that seems to encourage the
 practice...


The user guide is under active development to bring it up to the 1.0 APIs -- I
would expect the version you get with tonight's nightly build to be pretty up to
date.

On the particular issue of validation, the ActionForm class (you don't need
ValidatingActionForm any more) has a method:

public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request)

that is used for form beans that want to validate.  You return null if no errors
are encountered, or an ActionErrors object that is a collection of error message
keys (along with the field names the errors are assocaited with).


 Thanks in advance for your time.

 Ramon


Craig McClanahan