Patrick Lightbody wrote:
In your last email you talked about changes in the context and pre/postAs I've been working a LOT with AOP lately some of the ideas could be easily applied here too. One of the ideas is the generic "interceptor chain", i.e. to chain a bunch of proxies together and start it by simply invoking the first.
processing. I think I know what you are hinting at (simply the ActionFactory
and move the work in the Action implementation itself), but maybe you can go
in to more detail here? Also, how could it be an alternative way of
chaining?
For example:
Action myAction = ActionFactory.getAction("foo");
myAction.execute();
---
Action getAction(String name)
{
return new SecureAction(new ChainAction(new FooAction()));
}
---
public class SecureAction
extends ActionProxy
{
public SecureAction(Action nextAction)
{
this.next = nextAction;
}
public String execute()
throws Exception
{
// Do security check
// Delegate to next
return next.execute();
}
}
---
I hope the basic idea is obvious. Some chaining could be done by simply having proxies do stuff either before or after the execute() invocation. Having such things be proxies instead of actions separates them from real actions as they should typically not influence the result string (i.e. they have side-effects but don't effect the flow). Of course, just as servlet filters *can* return immediately instead of delegating to the next servlet, proxies can shortcut the flow here too (the SecureAction would be one example, which would return "unauthorized" if the executor is not allowed to call the action.
The ChainAction would be used to transfer parameters when a chain is executing. Like so:
ThreadLocal previousAction = new ThreadLocal();
public String execute()
throws Exception
{
Object previous = previousAction.get();
if (previous != null)
// Copy parameters from previous to current
previousAction.set(<currentTargetAction>);
try
{
return next.execute();
} finally
{
if (previous != null)
previousAction.set(previous);
}
}
---
This would allow the action itself to call other actions in its execute() method and have parameters be transferred transparently:
public String execute()
throws Exception
{
Action myAction1 = ActionFactory.getAction("foo1");
Action myAction2 = ActionFactory.getAction("foo2");
myAction1.execute();
myAction2.execute();
return SUCCESS;
}
--
Both the above actions would have secured execution (thanks to SecureAction) and copied parameters from the "parent", and with very little work. The action can then also decide whether to ignore what they return, or to return SUCCESS iff all actions succeed. A helper can easily run them in parallel. Etc. There are LOTS of possibilities here, but the main point is that the code would be very clean.
And, the "old way" to do "augmented actions" was to do a subclass and override execute(), do stuff (e.g. security checks), then do super.execute() which in turn could do things, and finally call doExecute(). That is (obviously?) a rather cumbersome, static, and generally boring way to do things, and I think using action proxy chains would be both easier and more dynamic. Plus, they could be configured in XML instead of specified explicitly through inheritance.
And, once you get into runtime attributes (which I have, courtesy of the AOP framework I'm fiddling with) it gets even cooler, because then you can configure the chain by using attributes. Like so:
/**
* @attributes
* filters=secure,chain,validation
* success=blah.vm
* error=failure.vm
*/
---
And if you feel like the above is providing too much info in code then simply introduce pre-packaged stacks:
<config>
<filters name="standard">
<filter name="secure"/>
<filter name="chain"/>
<filter name="validation"/>
</filters>
</config>
along with the runtime attribute definition:
/**
* @attributes
* filters=standard
*/
(BTW, I can *guarantee* you that before long we're going to see runtime attributes being pushed into IDE's rather than having them as Javadoc, so it's going to be really truly awesome)
and if you want to go really funky then redefine stacks like so:
<config>
<filters name="standard">
<filter name="mycustomfilter"/>
<filters name="defaultstandard"/>
</filters>
<filters name="defaultstandard">
<filter name="secure"/>
<filter name="chain"/>
<filter name="validation"/>
</filters>
</config>
and without changing any code/javadoc you just changed the way all actions that use the "standard" filter stack works. Pretty neat.
I've had trouble checking it out (SF has barfed all the time), but I *just* got it. Will look through today (I have the day off).Have you had a chance to look at the code in sandbox, especially the ActionFactory stuff as well as the chaining/view stuff?
(I started a new thread on this just so that we can keep track of the various topics)
(Good idea)
/Rickard ------------------------------------------------------- This sf.net email is sponsored by:ThinkGeek Welcome to geek heaven. http://thinkgeek.com/sf _______________________________________________ Opensymphony-webwork mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/opensymphony-webwork