I've been working through some of the issues regarding this recently and I think I have at least a partial solution. My goal is to have my Webwork actions be usable both inside and outside the workflow as well as to utilize webwork validation and other features. I wrote an adapter so a Spring Web Flow action can execute a webwork action (complete with interceptors):
Code:
/**
* Allows webwork actions to be executed as Spring Webflow actions.
*/
public class WebworkFlowAdapter extends AbstractAction
{
private static final Log log = LogFactory.getLog(WebworkFlowAdapter.class);
/**
* Constant for the action's parameters.
*/
public static final String REQUEST_CONTEXT = "com.opensymphony.xwork.ActionContext.context";
private ActionProxy proxy;
private String actionName;
private String namespace;
private String methodName;
/**
* @see org.springframework.webflow.action.AbstractAction#doExecute(org.springframework.webflow.RequestContext)
*/
protected Event doExecute(RequestContext context) throws Exception
{
WebworkExternalContext webworkContext = (WebworkExternalContext) context
.getExternalContext();
ActionInvocation invocation = webworkContext.getActionInvocation();
// if the finalNamespace wasn't explicitly defined, assume the current one
if (this.namespace == null)
{
this.namespace = invocation.getProxy().getNamespace();
}
OgnlValueStack stack = ActionContext.getContext().getValueStack();
String finalNamespace = TextParseUtil.translateVariables(namespace, stack);
String finalActionName = TextParseUtil
.translateVariables(actionName, stack);
String finalMethodName = this.methodName != null ? TextParseUtil
.translateVariables(this.methodName, stack) : null;
HashMap extraContext = new HashMap();
extraContext.put(ActionContext.VALUE_STACK, ActionContext.getContext()
.getValueStack());
extraContext.put(ActionContext.PARAMETERS, ActionContext.getContext()
.getParameters());
extraContext.put(REQUEST_CONTEXT, context);
if (log.isDebugEnabled())
{
log.debug("Chaining to action " + finalActionName);
}
proxy = ActionProxyFactory.getFactory().createActionProxy(finalNamespace,
finalActionName, extraContext);
if (null != finalMethodName)
{
proxy.setMethod(finalMethodName);
}
proxy.setExecuteResult(false);
proxy.execute();
String resultCode = proxy.getInvocation().getResultCode();
return result(resultCode);
}
/**
* @return actionName
*/
public String getActionName()
{
return actionName;
}
/**
* @param actionName
*/
public void setActionName(String actionName)
{
this.actionName = actionName;
}
/**
* @return methodName
*/
public String getMethodName()
{
return methodName;
}
/**
* @param methodName
*/
public void setMethodName(String methodName)
{
this.methodName = methodName;
}
/**
* @return namespace
*/
public String getNamespace()
{
return namespace;
}
/**
* @param namespace
*/
public void setNamespace(String namespace)
{
this.namespace = namespace;
}
}
This code is based heavily on the ActionChainResult. You have to populate the action name, namespace, and (optional) method name as parameters to the action, but I think this will work. (I'm doing some refactoring of the dispatch portion of the WW FlowAction to fit more in line with what we're doing) I won't have time to try this out until Friday, but I'd thought I'd post it if anyone was interested. (Any comments from the Webwork/Struts 2.0 people would be appreciated)