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