Fred.
At 07:02 PM 9/27/2003, you wrote:
I have been back tracking through Webwork, XWork, and OGNL for the last several of hours (not being familiar with the codebase), and might have tracked down the problem. Since I am just starting to use Webwork2, it would be great if someone else could tell me if this is the problem and whether my solution would be acceptable.
My app has an index.jsp page with an <ww:action id="homePage" name="homePage"/> and within the page a property tag: <ww:property value="lookAndFeel.title"/>
"lookAndFeel" is a property of the action specified by homePage. It is an object that has a property "title".
When I debug the code, the doStartTag() of the <ww:property> tag shows the valueStack retrieved from the ActionContext has a size of 0, and so it exits - no value output.
ActionTag.doEndTag calls executeAction(). After all the trouble of creating a new ActionContext and associating it the current thread (below), the next line calls the DefaultActionProxy.execute() class which on exit, restores the previous ActionContext. The ActionContext containing the valueStack with my Action class instance is gone.
ActionTag, Line 227, 228:
proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, name, createExtraContext(), executeResult);
proxy.execute();
Sooo... Possible solution: Have the ActionTag go back to the way it apparently worked in WW1, nesting around the contents of the JSP. Move the functionality in the doEndTag() to the doStartTag(). Split the functionality in DefaultActionProxy.execute() into an invoke() method and a pop()/restore() method. The pop() method is called in the doEndTag().
It might also be a thought to turn the ThreadLocal where ActionContext is stored into a stack itself and setContext() actually does a push() instead.
I can take a swag and fixing this, but would like some confirmation that this is the problem and would be an acceptable solution. Thank you.
Fred.
Index: lib/core/xwork-1.0-beta.jar =================================================================== RCS file: /cvs/webwork/lib/core/xwork-1.0-beta.jar,v retrieving revision 1.9 diff -u -r1.9 xwork-1.0-beta.jar Binary files /tmp/cvs4h4l4P and xwork-1.0-beta.jar differ Index: src/java/com/opensymphony/webwork/views/jsp/ActionTag.java =================================================================== RCS file: /cvs/webwork/src/java/com/opensymphony/webwork/views/jsp/ActionTag.java,v retrieving revision 1.6 diff -u -r1.6 ActionTag.java --- src/java/com/opensymphony/webwork/views/jsp/ActionTag.java 22 Sep 2003 05:50:03 -0000 1.6 +++ src/java/com/opensymphony/webwork/views/jsp/ActionTag.java 28 Sep 2003 08:41:26 -0000 @@ -97,14 +97,12 @@ } public int doEndTag() throws JspException { - // execute the action and save the proxy (and the namespace) as instance variables - executeAction(); - - if (getId() != null) { - pageContext.setAttribute(getId(), proxy.getAction()); - } + if ( null != proxy ) + { + proxy.restoreContext(); + } - return SKIP_BODY; + return EVAL_PAGE; } public int doStartTag() throws JspException { @@ -114,7 +112,14 @@ */ this.params = new HashMap(); - return EVAL_BODY_INCLUDE; + // execute the action and save the proxy (and the namespace) as instance variables + executeAction(); + + if (getId() != null) { + pageContext.setAttribute(getId(), proxy.getAction()); + } + + return EVAL_BODY_INCLUDE; } /** @@ -225,7 +230,7 @@ // execute at this point, after params have been set try { proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, name, createExtraContext(), executeResult); - proxy.execute(); + proxy.invoke(); } catch (Exception e) { log.error("Could not execute action: " + namespace + "/" + name, e); }
Index: src/java/com/opensymphony/xwork/ActionProxy.java =================================================================== RCS file: /cvs/xwork/src/java/com/opensymphony/xwork/ActionProxy.java,v retrieving revision 1.2 diff -u -r1.2 ActionProxy.java --- src/java/com/opensymphony/xwork/ActionProxy.java 10 Sep 2003 15:31:00 -0000 1.2 +++ src/java/com/opensymphony/xwork/ActionProxy.java 28 Sep 2003 08:40:18 -0000 @@ -37,4 +37,9 @@ OgnlValueStack getValueStack(); String execute() throws Exception; + + String invoke() throws Exception; + + void restoreContext(); + } Index: src/java/com/opensymphony/xwork/DefaultActionProxy.java =================================================================== RCS file: /cvs/xwork/src/java/com/opensymphony/xwork/DefaultActionProxy.java,v retrieving revision 1.3 diff -u -r1.3 DefaultActionProxy.java --- src/java/com/opensymphony/xwork/DefaultActionProxy.java 11 Sep 2003 05:13:58 -0000 1.3 +++ src/java/com/opensymphony/xwork/DefaultActionProxy.java 28 Sep 2003 08:40:18 -0000 @@ -117,15 +117,27 @@ } public String execute() throws Exception { - String retCode = null; - retCode = invocation.invoke(); + try + { + return invoke(); + } + finally + { + restoreContext(); + } + } - // save the context before overwriting it - lastContext = ActionContext.getContext(); - ActionContext.setContext(nestedContext); + public String invoke() throws Exception + { + return invocation.invoke(); + } - return retCode; - } + public void restoreContext() + { + // save the context before overwriting it + lastContext = ActionContext.getContext(); + ActionContext.setContext(nestedContext); + } protected void prepare() throws Exception { nestedContext = ActionContext.getContext();