Author: mikus
Date: Fri Feb  9 22:32:27 2007
New Revision: 505640

URL: http://svn.apache.org/viewvc?view=rev&rev=505640
Log:
ASF Bugzilla Bug 2640 / Jira STR-286: do not autopopulate an action form 
corresponding to chained action.

Added:
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java
   (with props)
Modified:
    struts/struts1/trunk/core/src/main/java/org/apache/struts/Globals.java
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PopulateActionForm.java
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java
    
struts/struts1/trunk/core/src/main/resources/org/apache/struts/chain/chain-config.xml
    
struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_3.dtd

Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/Globals.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/Globals.java?view=diff&rev=505640&r1=505639&r2=505640
==============================================================================
--- struts/struts1/trunk/core/src/main/java/org/apache/struts/Globals.java 
(original)
+++ struts/struts1/trunk/core/src/main/java/org/apache/struts/Globals.java Fri 
Feb  9 22:32:27 2007
@@ -209,4 +209,11 @@
      * The property under which a transaction token is reported.
      */
     public static final String TOKEN_KEY = TAGLIB_PACKAGE + ".TOKEN";
+
+    /**
+     * The request attributes key under which forwarding flag is stored.
+     *
+     * @since Struts 1.4
+     */
+    public static final String FORWARD_KEY = 
"org.apache.struts.action.FORWARD";
 }

Added: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java?view=auto&rev=505640
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java
 (added)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java
 Fri Feb  9 22:32:27 2007
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Copyright 2007 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.chain.commands.servlet;
+
+import org.apache.struts.chain.contexts.ActionContext;
+import org.apache.struts.chain.contexts.ServletActionContext;
+import org.apache.struts.chain.commands.ActionCommandBase;
+import org.apache.struts.Globals;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>Performs post-processing functions in command chain</p>
+ *
+ * @version $Rev$ $Date$ 
+ * @since Struts 1.4
+ */
+public class ActionPostProcess extends ActionCommandBase {
+
+    /**
+     * <p>Performs additional functions after an Action or Command
+     * has been called.</p>
+     *
+     * @param context The <code>Context</code> for the current request
+     * @return <code>false</code> so that processing continues
+     * @throws Exception on any error
+     */
+    public boolean execute(ActionContext context) throws Exception {
+
+        ServletActionContext saContext = (ServletActionContext) context;
+        HttpServletRequest request = saContext.getRequest();
+
+        // Set flag in request object, notifying chained actions that
+        // this request was already processed.
+        request.setAttribute(Globals.FORWARD_KEY, Boolean.TRUE);
+
+        // Continue chain processing
+        return false;
+    }
+}

Propchange: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PopulateActionForm.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PopulateActionForm.java?view=diff&rev=505640&r1=505639&r2=505640
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PopulateActionForm.java
 (original)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/PopulateActionForm.java
 Fri Feb  9 22:32:27 2007
@@ -31,6 +31,8 @@
 import org.apache.struts.config.ActionConfig;
 import org.apache.struts.util.RequestUtils;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * <p>Populate the form bean (if any) for this request.  Sets the multipart
  * class from the action config in the request attributes.</p>
@@ -42,25 +44,94 @@
     private static final Log log = LogFactory.getLog(PopulateActionForm.class);
 
     // ------------------------------------------------------- Protected 
Methods
+
     protected void populate(ActionContext context, ActionConfig actionConfig,
         ActionForm actionForm)
         throws Exception {
         ServletActionContext saContext = (ServletActionContext) context;
+        HttpServletRequest request = saContext.getRequest();
 
-        RequestUtils.populate(actionForm, actionConfig.getPrefix(),
-            actionConfig.getSuffix(), saContext.getRequest());
+        // Populate the form bean only if configured so
+        if (isPopulate(request, actionConfig)) {
+            RequestUtils.populate(actionForm, actionConfig.getPrefix(),
+                actionConfig.getSuffix(), saContext.getRequest());
+        }
     }
 
     protected void reset(ActionContext context, ActionConfig actionConfig,
         ActionForm actionForm) {
+
         ServletActionContext saContext = (ServletActionContext) context;
+        HttpServletRequest request = saContext.getRequest();
 
-        actionForm.reset((ActionMapping) actionConfig, saContext.getRequest());
+        // Reset the form bean only if configured so
+        if (isReset(request, actionConfig)) {
+            actionForm.reset((ActionMapping) actionConfig, 
saContext.getRequest());
+        }
 
         // Set the multipart class
         if (actionConfig.getMultipartClass() != null) {
             saContext.getRequestScope().put(Globals.MULTIPART_KEY,
                 actionConfig.getMultipartClass());
         }
+    }
+
+    // ---------------------------------------------------------- Helper 
Methods
+
+    /**
+     * Verifies whether an action form should be populated
+     * @param request current HTTP request
+     * @param actionConfig action config for current request
+     * @return true if action form should be populated
+     *
+     * @since Struts 1.3.7
+     */
+    protected boolean isPopulate(HttpServletRequest request, ActionConfig 
actionConfig) {
+        String strPopulate = actionConfig.getPopulate();
+        return getResetOrPopulate(request, strPopulate);
+    }
+
+    /**
+     * Verifies whether an action form should be reset
+     * @param request current HTTP request
+     * @param actionConfig action config for current request
+     * @return true if action form should be reset
+     *
+     * @since Struts 1.3.7
+     */
+    protected boolean isReset(HttpServletRequest request, ActionConfig 
actionConfig) {
+        String strReset = actionConfig.getReset();
+        return getResetOrPopulate(request, strReset);
+    }
+
+    /**
+     * Compares current request state (direct or forwarded) with configuration
+     * from action mapping.
+     * @param request current HTTP request
+     * @param strAttr value of either "reset" or "populate" attributes of
+     *        an action mapping
+     * @return true if action mapping is configured to reset (or populate)
+     *         corresponding action form; false if if action mapping is
+     *         configured not to reset (or populate) the action form.
+     *
+     * @since Struts 1.3.7
+     */
+    protected boolean getResetOrPopulate(HttpServletRequest request, String 
strAttr) {
+        // Reset configuration is not defined (should not happen,
+        // because default value are set to "request,forward".
+        if (strAttr == null) return true;
+
+        // Reads Globals.FORWARD_KEY attribute from the HTTP request object
+        boolean forwarded = RequestUtils.isForwarded(request);
+
+        // Forwarded request is configured for reset/populate
+        if (forwarded && strAttr.indexOf(ActionConfig.FORWARD_STR) > -1) 
return true;
+
+        // Direct request is configured for reset/populate
+        if (!forwarded && strAttr.indexOf(ActionConfig.REQUEST_STR) > -1) 
return true;
+
+        // Do not reset/populate if a user explicity set anything
+        // else besides "request" or "populate".
+        return false;
     }
 }

Modified: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java?view=diff&rev=505640&r1=505639&r2=505640
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java
 (original)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/config/ActionConfig.java
 Fri Feb  9 22:32:27 2007
@@ -41,6 +41,23 @@
 public class ActionConfig extends BaseConfig {
     private static final Log log = LogFactory.getLog(ActionConfig.class);
 
+    /**
+     * Literal that describes request condition for "reset" and "populate"
+     * properties.
+     *
+     * @since Struts 1.4
+     */
+    public static final String REQUEST_STR = "request";
+
+    /**
+     * Literal that describes forward condition for "reset" and "populate"
+     * properties.
+     *
+     * @since Struts 1.4
+     */
+    public static final String FORWARD_STR = "forward";
+
+
     // ----------------------------------------------------- Instance Variables
 
     /**
@@ -178,6 +195,32 @@
     protected String scope = "session";
 
     /**
+     * <p>Identifies conditions for automatic form reset.</p>
+     *
+     * <p>Possible values: null (not specified), "request", "forward" or
+     * "request-forward" (used when not specified). If not specified then
+     * the form bean is reset both for direct and for forwarded request.</p>
+     *
+     * @since Struts 1.4
+     */
+    protected String reset = REQUEST_STR + "-" + FORWARD_STR;
+
+    /**
+     * <p>Identifies conditions for automatic form population with values
+     * from HTTP request.</p>
+     *
+     * <p>Possible values: null (not specified), "request", "forward" or
+     * "request-forward" (used when not specified). If not specified then
+     * the form bean is populated both for direct and for forwarded request.
+     * This means that when a chained action mapping refers to the same
+     * form bean as originating action, then the form bean is repopulated
+     * and changes made by originating action are lost.</p>
+     *
+     * @since Struts 1.4
+     */
+    protected String populate = REQUEST_STR + "-" + FORWARD_STR;
+
+    /**
      * <p> Suffix used to match request parameter names to form bean property
      * names, if any. </p>
      */
@@ -626,6 +669,54 @@
     }
 
     /**
+     * <p>Reads when a corresponding action form should be reset
+     * ("request", "session" or "request,session").</p>
+     *
+     * @since Struts 1.4
+     */
+    public String getReset() {
+        return (this.reset);
+    }
+
+    /**
+     * @param reset identifies, when a corresponding action form should be
+     *        reset ("request", "session" or "request,session").
+     *
+     * @since Struts 1.4
+     */
+    public void setReset(String reset) {
+        if (configured) {
+            throw new IllegalStateException("Configuration is frozen");
+        }
+
+        this.reset = reset;
+    }
+
+    /**
+     * <p>Reads when a corresponding action form should be automatically
+     * populated ("request", "session" or "request,session").</p>
+     *
+     * @since Struts 1.4
+     */
+    public String getPopulate() {
+        return (this.populate);
+    }
+
+    /**
+     * @param populate identifies, when a corresponding action form should be
+     *        automatically populated ("request", "session" or 
"request,session").
+     *
+     * @since Struts 1.4
+     */
+    public void setPopulate(String populate) {
+        if (configured) {
+            throw new IllegalStateException("Configuration is frozen");
+        }
+
+        this.populate= populate;
+    }
+
+    /**
      * <p> Return suffix used to match request parameter names to form bean
      * property names, if any. </p>
      */
@@ -1271,6 +1362,16 @@
         if (scope != null) {
             sb.append(",scope=");
             sb.append(scope);
+        }
+
+        if (reset != null) {
+            sb.append(",reset=");
+            sb.append(reset);
+        }
+
+        if (populate != null) {
+            sb.append(",populate=");
+            sb.append(populate);
         }
 
         if (suffix != null) {

Modified: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java?view=diff&rev=505640&r1=505639&r2=505640
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java
 (original)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/util/RequestUtils.java
 Fri Feb  9 22:32:27 2007
@@ -1066,4 +1066,17 @@
         }
         return actionIdPath.toString();
     }
+
+    /**
+     * Verifies whether current request is forwarded from one action to
+     * another or not.
+     * @param request current HTTP request 
+     * @return true if the request contains Globals.FORWARD_KEY, which means
+     *         that request has been forwarded from another action.
+     *
+     * @since Struts 1.4
+     */
+    public static boolean isForwarded(HttpServletRequest request) {
+        return request.getAttribute(Globals.FORWARD_KEY) != null;
+    }
 }

Modified: 
struts/struts1/trunk/core/src/main/resources/org/apache/struts/chain/chain-config.xml
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/resources/org/apache/struts/chain/chain-config.xml?view=diff&rev=505640&r1=505639&r2=505640
==============================================================================
--- 
struts/struts1/trunk/core/src/main/resources/org/apache/struts/chain/chain-config.xml
 (original)
+++ 
struts/struts1/trunk/core/src/main/resources/org/apache/struts/chain/chain-config.xml
 Fri Feb  9 22:32:27 2007
@@ -200,6 +200,11 @@
         <!-- Execute the Action for this request -->
         <command
                 
className="org.apache.struts.chain.commands.servlet.ExecuteAction"/>
+
+
+        <!-- Perform action postprocess tasks -->
+        <command
+                
className="org.apache.struts.chain.commands.servlet.ActionPostProcess"/>
     </chain>
 
     <!-- ========== View Processing chain ======================== -->

Modified: 
struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_3.dtd
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_3.dtd?view=diff&rev=505640&r1=505639&r2=505640
==============================================================================
--- 
struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_3.dtd
 (original)
+++ 
struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_3.dtd
 Fri Feb  9 22:32:27 2007
@@ -91,6 +91,8 @@
 -->
 <!ENTITY % RequestScope "(request|session)">
 
+<!-- Defines possible values for automatic form bean population -->
+<!ENTITY % PopulateStrategy "(request|forward|request-forward|none)">
 
 <!-- ========== Top Level Elements ======================================== -->
 
@@ -452,6 +454,16 @@
                      action mapping, or set to "false" if you do not want the
                      validate method called.
                      [true]
+
+     reset           Allows to specify conditions for automatic form reset.
+                     Possible values: not specified, "request", "forward",
+                     "request-forward" or "none".
+                     [request-forward]
+
+     populate        Allows to specify conditions for automatic form population
+                     with HTTP request values. Possible values: not specified,
+                     "request", "forward", "request-forward" or "none".
+                     [request-forward]
 -->
 <!ELEMENT action (icon?, display-name?, description?, set-property*, 
exception*, forward*)>
 <!ATTLIST action         id             ID              #IMPLIED>
@@ -474,6 +486,8 @@
 <!ATTLIST action         type           %ClassName;     #IMPLIED>
 <!ATTLIST action         unknown        %Boolean;       #IMPLIED>
 <!ATTLIST action         validate       %Boolean;       #IMPLIED>
+<!ATTLIST action         reset          %PopulateStrategy; #IMPLIED>
+<!ATTLIST action         populate       %PopulateStrategy; #IMPLIED>
 
 
 <!-- The "controller" element describes the ControllerConfig bean


Reply via email to