Our current request logging simply logs all requests and includes session
id. By 'grepping' on session id, we could create a trace of a single user's
actions. We have not tried to do this and we would probably have to
organize the log output to facilitate the 'grep', but the information is
there to do so.
I like the idea of using Ant to compose a config file of what I'll simply
call 'web application components'. The bummer is that if you create such a
component, it is difficult to make it callable from multiple sources. We're
really talking about linking here in the classic software function call
linkage sense. Links in both Struts and IAF are 'staticaly linked' in the
configuration file. I desire more loose coupling, e.g. dynamic linkage, so
that components can be reused easily.
For example, suppose I had the following scenario:
Pages A.jsp and B.jsp both have links to C.jsp. If the user clicks on the
link to C.jsp from A.jsp, does some stuff on C.jsp and after awhile clicks
on a button called 'Done' on C.jsp, he should be brought back to A.jsp.
Now, if the user clicks on the link to C.jsp from B.jsp, when he clicks on
'Done', he should return to B.jsp. Graphically, well as near as I can get:
A.jsp -> C.jsp -> "does stuff" -> 'Done' -> A.jsp
B.jsp -> C.jsp -> "does stuff" -> 'Done' -> B.jsp
C.jsp represents a web application component. "does stuff" means the user
is performing non trivial application activities, including leaving C.jsp,
but they return to C.jsp somehow to hit the 'Done' button.
Please correct me if I am wrong here:
I believe that there is no way in Struts to accomplish the above scenario,
at least, out of the box. This is because each forwards tag in an
ActionMapping names an explicit path. This is what I mean by static
linking. The 'path' I want to return to is the caller, but the
ActionMapping doesn't know who the caller is until they call, at runtime.
In other words, the C.jsp page either links back to A.jsp or B.jsp, but not
both. If C.jsp calls an Action on 'Done', if limited to the forwards in its
ActionMapping, the Action can only forward to A.jsp or B.jsp, too. I could
definitely kludge something where A.jsp or B.jsp pass something so that
C.jsp knows where to return, but I'm looking for a general mechanism.
To support call-return such that the callee does not need to know who the
caller is, requires that the callee be able to refer to caller indirectly.
In most software runtime environment, stacks are used so that callers push
the next thing to do onto the stack so that it can be popped off later when
the callee returns. I would like allow Actions to call other Actions in
such a manner so that I can have more traditional programming flow control
in my web applications that allows for loose coupling of web application
components.
The real trick is to additionally support argument passing and return
capabilities for recursion. The idea is that this would support Ted's
ActionForm stack needs.
One solution I am thinking is to create CallAction and ReturnAction
sub-classes of Action. The CallAction pushes the name of an Action on the
stack. The ReturnAction simply pops the Action name off the stack and
forwards to it.
To use a programming metaphor, I would like to treat Actions like
statements. Some statements perform operations (get user input, do
something with input) and some perform flow control (call and return).
But how to handle passing arguments to support recursion (Ted's problem)?
You need a calling convention that formalizes how input arguments and
returned results are passed. You additionally need a call stack to keep
calls from overwriting themselves when called recursively.
Perhaps the ActionForms are the arguments and the ActionMapping is really
like a fuctional prototype, at least for the CallAction and ReturnActions?
Does any of this make sense?
didge
-----Original Message-----
From: Ted Husted [mailto:[EMAIL PROTECTED]]
Sent: Friday, June 08, 2001 7:58 AM
To: [EMAIL PROTECTED]
Subject: Re: Work flow RFC
"Frye, Dave" wrote:
> My second step was to define how requests are dispatched. IAF's
Dispatcher
> dispatches requests as follows:
> 1. Log the request
Is this an application log for all the sessions?
Could you retrieve the history of a user's session from here at runtime?
"Frye, Dave" wrote:
> <Dispatcher>
> <Actions>
> <Action Name="LogIn" Controller="app.LogInController">
> <NextAction>ShowLogInSuccess</NextAction>
> <DisplayBean>app.LogInBean</DisplayBean>
> <Validation Parameter="userID" ErrorMsg="User ID is blank"
> Rule="NotNull"/>
> <Validation Parameter="password" ErrorMsg="Password is blank"
> Rule="NotNull"/>
> </Action>
> <Action Name="ShowLogInSuccess" Controller="PageDisplay"
> Arguments="/Login.jsp">
> </Action>
> </Actions>
> </Dispatcher>
Incidentally, while many Struts developers organize their config files
by type, you can also organize it by package, and also combine David W's
validate.xml into the struts-config.xml, giving you something like:
<!-- logon package -->
<struts-config>
<form-beans>
<form-bean name="logonForm"
type="org.wxxi.gavel.logon.Form"/>
</form-beans>
<action-mappings>
<action path="/logon/Enter"
type="org.wxxi.gavel.logon.Enter"
name="logonForm"
scope="request"
validate="false"
input="/WEB-INF/jsp/logon/Form.jsp">
</action>
<action path="/logon/Submit"
type="org.wxxi.gavel.logon.Enter"
name="logonForm"
scope="request"
validate="true"
input="/WEB-INF/jsp/logon/Form.jsp">
<forward name="success" path="/menu.do"/>
</action>
</action-mappings>
</struts-config>
<form-validation>
<formset>
<form name="logonForm">
<field property="username" depends="required,mask">
<var name="mask" value="^[a-zA-Z0-9]*$"/>
<msg name="mask" key="logon.username.maskmsg"/>
<arg0 key="logon.username.displayname"/>
</field>
<field property="password" depends="required">
<arg0 key="logon.password.displayname"/>
</field>
</form>
</formset>
</form-validation>
... more <struts-config> and <form-validation> blocks ...
This approach would allow a configuration file for each package in your
application, so you could have Ant assemble them at runtime, as many
people now do with the application properties.
"Frye, Dave" wrote:
> My team did create a package that provided a sophisticated user, group,
> role-based security implementation that provided authentication for use
when
> no other security existed, however, it is provided as an optional package.
Hmmmm ... (repeat) Hmmmm ...
> However, IAF is lacking a method (as explained by
> Matthias) for keeping track of where the user has been, so it is
impossible
> to have call-return flexibilty. By call-return, I mean I would like to
call
> the functionality of an Action from multiple locations, and when that
Action
> is finished, I want to return to where I was called from.
Right now I'm considering using two mechanisms in tandem. One would be
an ActionForm stack, where you could park an ActionForm for future use.
This way if the flow branches or is interrupted you can get back the
interim state later. A centralized mechanism would help keep this
utility getting out of control and it could act as a cache (dispose
older items when newer were entered) to prevent overuse.
The other mechanism is some type of ActionForm listening. Here, an
object could register an interest in a certain ActionForm property, and
be alerted of its current state when it comes into context. (Of course,
this could be a subset of a larger event handling mechanism.) The idea
is that I could park an ActionForm on the stack, and have it be alerted
when other relevent ActionForms were accessed (created, read, or
updated). This could let the Form on the stack update itself with
related properties (foreign keys) that the user would otherwise have to
provide (client, vendor, product). Another use may be a master form to
collect properties from several sub-forms in a "wizard" workflow.
At some point, actions that might ordinarily return the user to a menu,
or some other "rest" state, could check the stack and automagically
return flow to the ActionForm's Action when present. Of course, a single
router action (or ancesstor method) could perform this service for every
relevant Action in an application.
Just thinking outloud ... comments welcome
-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel 716 737-3463.
-- http://www.husted.com/about/struts/