Well, there's Action chaining, and there's action chaining. It's a perfectly valid idea for an ActionMapping to select where control should go next, as Erik is doing. It's fundamental to the architechtural, and instrumental to how ActionForm validation works.
So, if we're talking about one ActionMapping forwarding (or redirecting) to another ActionMapping, then sure. Everything is above board, and you can follow the bouncing ball through the Struts Config and see what's happening. But, then there's Action chaining. Here, people have an Action class create an ActionForward on the fly, jam in some parameters, and toss it back to the controller. This is where Action classes start binding to Action classes, and the mudslide begins. It's my feeling that if Action classes start creating query strings and need to be coded in terms of what they need to send to the "next" Action, then you're starting to use Action classes to implement a business facade. Action classes should be clients of the facade, not the facade itself. In the current example, using an ActionMapping to call a DeleteAction and have it route back to some list afterwards seems fine to me. So, long as the DeleteAction doesn't know or care if its going back to a particular list or a given form. IMHO, an Action class should just return a simple semantic like "success", "failure", "cancel", and so forth, and let the ActionMapping decide how to handle the given gesture. And following Laird's example, an application could also include a workflow engine that would return a semantic to go get the whatchacallit. But the ActionMappings would hook up the semantic with the actual URI. The real "presentation logic" is that there's a JSP stored at /WEB-INF/pages/whatchacallit. On top of that, there's application/workflow logic that might say the semantic "whatchamcallit" should display the form that collects the whatchallit property. Where things get messy is that sometimes people come up with a multi-step server-side workflow, where they want to, say, copy and delete (or move) a record, and then return to a list. So you got the copy action looking at some flag that says "do delete next", and so it sets something in the request or action form, and forwards on to delete, which then looks at something that tells it to forward on to a list. In this case, we're starting to do a Rube Goldberg shuffle around Robin Hood's barn. There should just be a move action that calls both copy and delete through the business facade -- being the exact same methods an independant copy or delete Action would call. If there is more than a line or two of code involved in an atomic process like delete, then the Action classes are working too hard. IMHO, Action classes should not be considered atomic. Most often, there should be a 1:1 correlation between an Action class and your business facade. The business facade is your application's internal API. It defines what the application can do, what it needs to do it, and what it returns when something is done. The Action classes interact with the business facade by allowing access to the facade from the web tier. Other tiers could also interact with the same facade from other platforms. So, given the trivial move example, the Action should not even have to call copy and delete. There should be move method on the facade, and the facade should be the one calling copy and delete. Behind the facade are the atomic operations, like delete or copy. The facade then does any chaining or nesting between atomic operations. The atomic operations may be implemented using JDBC or EJB or CORBA or Lucene or a web service or whatever you like. But the actions don't need to know that, because they only talk to the facade. <preaching-to-the-choir>Of course, setting up a facade is some extra work, and so not everyone does it. Just like setting up an interface before defining a base class is some extra work. Using actions for your facade works, just like using base classes instead of interfaces works. In either case, you are trading a layer of indirection for reusability.</preaching-to-the-choir> But, now we may be getting into the stuff of the user list =:0) -Ted. -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>