I made the changes described below, and it fixed the problem. The changes were very small, but did effect the ActionProxy interface. The patch files for XWork and Webwork are attached. The only behavioral change is that I put the restoreContext() in a finally clause, so it would get executed regardless of whether an exception occurred in the Action invoke(). Seemed desirable. Feel free to change the method names. Let me know whether this is acceptable. This again puts the body of the JSP back in the body of the <ww:action> tag.

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();

Reply via email to