I'd love for someone else to solve the workflow problem for me once and
for all!

I'm not sure what others have or want in a workflow framework, but I hacked together one that I use on my day job that handles nth-level nesting. The navigation is managed via 2 Stacks and a custom action mapping class.

It is a bit intrusive and requires
a) the developer must ensure correct "sub navigation" (alternate flows)
b) action form is session scoped

Here is a crude drawing that I use to describe to other developers how it
works (in theory of course)
http://cvs.apache.org/~jmitchell/basic-workflow-theory.jpg


Having created and maintained this over the last year has got me thinking about what I would like to see in a chain-based workflow framwork. Unfortunately, I am not up-2-speed on Chain as much as I'd like to be, but that's something I've already been working on.

I'd like to develop and publish a workflow package that is based on
commons-chain.  I've only had a cursory look at commons-workflow, so I can't
speak to its pros or cons, but I really like what I've seen with
commons-chain so far and well.....it itches ;)

It's high on the todo list, but still on a back burner.  As always, work and
family come first.


-- James Mitchell Software Engineer / Open Source Evangelist EdgeTech, Inc. 678.910.8017 AIM: jmitchtx

----- Original Message ----- From: "Joe Germuska" <[EMAIL PROTECTED]>
To: "Wendy Smoak" <[EMAIL PROTECTED]>; "Struts Users Mailing List"
<[email protected]>
Sent: Thursday, January 06, 2005 6:38 PM
Subject: Re: Please explain Struts Chain



At 12:43 PM -0700 1/6/05, Wendy Smoak wrote:
Can someone explain what Struts Chain is or point me to some
documentation?
I see it mentioned occasionally, but I can't find anything that sets out
what it is, how it works, and why I might want to use it.

Geez, you want documentation?

Actually, I was starting to update the current docs the other night, and
it made me realize that there are things I'd like to change, so that they
work the way I want to write about them :^)

Anyway, to begin with: if you have never cared about the RequestProcessor
class, short of, perhaps specifying to use the TilesRequestProcessor, then
you can safely continue to not care about it, ignoring the fact that a
different class is doing what should amount to the same thing.

(The one exception being that you'll have to take some steps to use tiles,
but since you'll also have to start using the struts-tiles JAR, I imagine
we'll have a simple list of steps and most people still won't need to know
much more about it.)

What is it:

struts-chain is a replacement for the original RequestProcessor, designed
to eliminate the problem of integrating multiple libraries which extend
the request-processing life-cycle (RPLC).  The fact that RequestProcessor
was a class and not an interface, coupled with Java's single-inheritance
model, made it extremely cumbersome for developers to create reusable
libraries which modified parts of the RPLC.  Also, it had a fair amount of
logic embedded in its central "process()" method which was the backbone of
the process.  The idea was that you would only override methods called by
that one, never changing the base "process()" method itself.  If you
wanted to add entirely new steps which weren't in there, it was pretty
challenging.

How it works:

This first part is not specific to chain; it's how Struts has worked since
1.1:
the ActionServlet's doGet(request,response) method is called.  The
ActionServlet looks up the module for the request, and retrieve's that
module's request processor.  It calls "process(request,response)" on the
RequestProcessor, which does just about everything else that you think of
as Struts.

In Struts 1.3.x, "everything else that you think of as Struts" is
implemented as a series of commons-chain "Command" objects, each of which
is responsible for doing just a small part.  A Command executes on a
Context, which it reads to figure out the current application state, and
which it updates so that later commands can take advantage of its work.
So now, instead of subclassing RequestProcessor (and probably also
TilesRequestProcessor, if you're trying to make a library), you can simply
change the configuration which indicates the type and order of commands to
be executed.

Why you might want to use it:

Well, I hate to break it to you, but you don't have a choice!  That's not
true, actually you could change the struts-config to use the original
RequestProcessor, but by default, it uses the chain-based one and a
default chain configuration which will be included with Struts.  But it
can continue to be invisible to you if you prefer it that way.

But the question is more "why would I want to change the RPLC" than "Why
would I want to use Struts Chain to do it."  Without a common context of
complex applications to discuss, it is hard to describe solutions which
can be more gracefully achieved by extending or modifying the RPLC.  (Plus
I've come to take it for granted, from before there was a Struts Chain
with which to achieve it.)

Here's some examples of how we use a chain-based request processor in a
current production app.

[A] Early in every request, see if any user authentication system has
authenticated a current user.  Our client uses Netegrity SiteMinder, so we
have one command which looks for the request header that it adds and
copies it to a different location.  For testing, though, we have a much
simpler method which simply looks for a request parameter with a special
name, and puts it in the same location that the SiteMinder command uses.
After each of these guys has had a chance to operate, another command
looks in that location, and, if it finds an authenticated user ID, it
makes sure that the request has a fully populated User object available,
either by verifying that the current session User matches the ID or
creating and populating a User if it doesn't match, or if its missing.

You might have done this in RequestProcessor.preProcess in the past, but
you would have had to put all three pieces in one method, and it's a lot
harder to pass configuration values in that way. The way that the chain
digester processes the config XML, you can specify all kinds of
per-command config values very simply and in a way where their connection
to the thing that uses them is very clear.

[B] We also have a command which does an auth check; it tests the active
ActionMapping and, if it's of a specific "secure" type, it uses properties
from the action mapping to determine whether the current user can access
the action.  RequestProcessor had a single method where you could have
overridden the JAAS roles-based auth control that Struts provides out of
the box.

[C] We have a method which establishes an ActionContext class, which we
pass into our Action.execute() methods instead of the tradition
mapping/form/req/resp signature.  This ActionContext knows where in the
request or session scope to find important values, or classes and returns
them in a typesafe fashion, which I find preferable to having a number of
constants for putting things into the request or the session and a bunch
of casting when you take the things back out.

[D] And finally, we have a PagePrep action which operates between the
return from the Action and the tiles processing.  This is the thing I'm
always talking about which provides us with a straightforward way to
prepopulate forms, set up menus and select lists, and otherwise shepherd
data around so that the Actions and the JSPs on either side can be a bit
simpler and clearer.
------
In addition to all of these things, I have hopes that the chain model will
make it easier to develop widely sharable libraries for things like access
control, workflow management, and possibly even more sophisticated
configurable applications and reusable control-level components.  I'd love
for someone else to solve the workflow problem for me once and for all!

We'll see if that comes true, but I think it's much more palatable to do
that kind of stuff now than it was with the original RequestProcessor..

Hope this helps,
Joe

--
Joe Germuska            [EMAIL PROTECTED]  http://blog.germuska.com
"Narrow minds are weapons made for mass destruction"  -The Ex

---------------------------------------------------------------------
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