Author: pbenedict Date: Sun Aug 12 11:35:09 2007 New Revision: 565107 URL: http://svn.apache.org/viewvc?view=rev&rev=565107 Log: STR-286 and STR-1116: Populate and reset via list of events
Added: struts/struts1/trunk/core/src/main/java/org/apache/struts/config/PopulateEvent.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/ActionPostProcess.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/resources/struts-config_1_4.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=565107&r1=565106&r2=565107 ============================================================================== --- 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 Sun Aug 12 11:35:09 2007 @@ -49,6 +49,13 @@ public static final String CANCEL_KEY = "org.apache.struts.action.CANCEL"; /** + * The request attributes key under which chaining flag is stored. + * + * @since Struts 1.4 + */ + public static final String CHAIN_KEY = "org.apache.struts.action.CHAIN"; + + /** * <p>The base of the context attributes key under which our * <code>ModuleConfig</code> data structure will be stored. This will be * suffixed with the actual module prefix (including the leading "/" @@ -209,11 +216,4 @@ * 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"; } Modified: 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=diff&rev=565107&r1=565106&r2=565107 ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/servlet/ActionPostProcess.java Sun Aug 12 11:35:09 2007 @@ -47,7 +47,7 @@ // Set flag in request object, notifying chained actions that // this request was already processed. - request.setAttribute(Globals.FORWARD_KEY, Boolean.TRUE); + request.setAttribute(Globals.CHAIN_KEY, Boolean.TRUE); // Continue chain processing return false; 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=565107&r1=565106&r2=565107 ============================================================================== --- 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 Sun Aug 12 11:35:09 2007 @@ -27,6 +27,7 @@ import org.apache.struts.chain.contexts.ActionContext; import org.apache.struts.chain.contexts.ServletActionContext; import org.apache.struts.config.ActionConfig; +import org.apache.struts.config.PopulateEvent; import org.apache.struts.util.RequestUtils; import javax.servlet.http.HttpServletRequest; @@ -69,42 +70,37 @@ // ---------------------------------------------------------- Helper Methods /** - * Determines whether an action form should be populated + * Determines 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.4 */ protected boolean isPopulate(ActionContext context, ActionConfig actionConfig) { - ServletActionContext saContext = (ServletActionContext) context; - HttpServletRequest request = saContext.getRequest(); - - String strPopulate = actionConfig.getPopulate(); - return getResetOrPopulate(request, strPopulate); + String[] events = actionConfig.getPopulateNames(); + return getResetOrPopulate(context, events); } /** - * Determines whether an action form should be reset + * Determines 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.4 */ protected boolean isReset(ActionContext context, ActionConfig actionConfig) { - ServletActionContext saContext = (ServletActionContext) context; - HttpServletRequest request = saContext.getRequest(); - - String strReset = actionConfig.getReset(); - return getResetOrPopulate(request, strReset); + String[] events = actionConfig.getResetNames(); + return getResetOrPopulate(context, events); } /** * 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 + * @param events values 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 @@ -112,20 +108,50 @@ * * @since Struts 1.4 */ - private 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; - + private boolean getResetOrPopulate(ActionContext context, String[] events) { + // Reset configuration is not defined, but this should not happen + // because default value is provided + if ((events == null) || (events.length == 0)) { + return true; + } + + // First check against events that must be alone + if (events.length == 1) { + if (events[0].equals(PopulateEvent.ALL)) { + return true; + } + if (events[0].equals(PopulateEvent.NONE)) { + return false; + } + } + + // Then check against the list of combinable events + HttpServletRequest request = ((ServletActionContext) context).getRequest(); + for(int i = 0; i < events.length; i++) { + String attribute = events[i]; + if (attribute.equals(PopulateEvent.FORWARD)) { + if (RequestUtils.isRequestForwarded(request)) { + return true; + } + } else if (attribute.equals(PopulateEvent.INCLUDE)) { + if (RequestUtils.isRequestIncluded(request)) { + return true; + } + } else if (attribute.equals(PopulateEvent.CHAIN)) { + if (RequestUtils.isRequestChained(request)) { + return true; + } + } else if (attribute.equals(PopulateEvent.REQUEST)) { + if (RequestUtils.isRequestForwarded(request)) { + continue; + } + if (RequestUtils.isRequestIncluded(request)) { + continue; + } + 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=565107&r1=565106&r2=565107 ============================================================================== --- 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 Sun Aug 12 11:35:09 2007 @@ -41,23 +41,6 @@ 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 /** @@ -203,28 +186,21 @@ /** * <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; + protected String reset = PopulateEvent.ALL; + protected String[] resetNames = { PopulateEvent.ALL }; + /** - * <p>Identifies conditions for automatic form population with values + * <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; + protected String populate = PopulateEvent.ALL; + + protected String[] populateNames = { PopulateEvent.ALL }; /** * <p> Suffix used to match request parameter names to form bean property @@ -677,20 +653,35 @@ } /** - * <p>Reads when a corresponding action form should be reset - * ("request", "session" or "request,session").</p> + * <p> Gets the comma-delimiated list of events that specify when this + * action should be reset. </p> * * @since Struts 1.4 + * @see #getResetNames() + * @see #setReset(String) */ public String getReset() { return (this.reset); } /** - * @param reset identifies, when a corresponding action form should be - * reset ("request", "session" or "request,session"). + * <p> Gets the array of events names that specify when this + * action should be reset. </p> + * + * @since Struts 1.4 + * @see #getReset() + * @see PopulateEvent + */ + public String[] getResetNames() { + return (this.resetNames); + } + + /** + * @param reset the comma-delimited list of reset events * * @since Struts 1.4 + * @see #getReset() + * @see #getResetNames() */ public void setReset(String reset) { if (configured) { @@ -698,30 +689,47 @@ } this.reset = reset; + this.resetNames = reset.split(","); } /** - * <p>Reads when a corresponding action form should be automatically - * populated ("request", "session" or "request,session").</p> + * <p> Gets the comma-delimiated list of events that specify when this + * action should be populated. </p> * * @since Struts 1.4 + * @see #getPopulateNames() + * @see #setPopulate(String) */ public String getPopulate() { return (this.populate); } + + /** + * <p> Gets the array of events names that specify when this + * action should be populated. </p> + * + * @since Struts 1.4 + * @see #getPopulate() + * @see PopulateEvent + */ + public String[] getPopulateNames() { + return (this.populateNames); + } /** - * @param populate identifies, when a corresponding action form should be - * automatically populated ("request", "session" or "request,session"). + * @param populate the comma-delimited list of populate events * * @since Struts 1.4 + * @see #getPopulate() + * @see #getPopulateNames() */ public void setPopulate(String populate) { if (configured) { throw new IllegalStateException("Configuration is frozen"); } - this.populate= populate; + this.populate = populate; + this.populateNames = populate.split(","); } /** Added: struts/struts1/trunk/core/src/main/java/org/apache/struts/config/PopulateEvent.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/config/PopulateEvent.java?view=auto&rev=565107 ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/config/PopulateEvent.java (added) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/config/PopulateEvent.java Sun Aug 12 11:35:09 2007 @@ -0,0 +1,81 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.config; + +import javax.servlet.RequestDispatcher; + +/** + * Constants relating to the reset and population events of action forms. + * + * @since Struts 1.4 + */ +public abstract class PopulateEvent { + + /** + * Specifies that population must always occur. This type may not be + * combined with any other type. + */ + public static final String ALL = "all"; + + /** + * Specifies that population occurs when the form is cancelled. + */ + public static final String CANCEL = "cancel"; + + /** + * Specifies that population occurs when the current executing action has + * been forwarded by another action. It should be noted that if the 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. + */ + public static final String CHAIN = "chain"; + + /** + * Specifies that population occurs when the current requested is part of a + * forwarded request. Unlike [EMAIL PROTECTED] #CHAIN} which is limited to + * action-to-action behavior, the forward can be from any servlet resource. + * + * @see RequestDispatcher#forward(javax.servlet.ServletRequest, + * javax.servlet.ServletResponse) + */ + public static final String FORWARD = "forward"; + + /** + * Specifies that population occurs when the current requested is part of + * any included request. + * + * @see RequestDispatcher#include(javax.servlet.ServletRequest, + * javax.servlet.ServletResponse) + */ + public static final String INCLUDE = "include"; + + /** + * Specifies that population must never occur. This type may not be combined + * with any other type. + */ + public static final String NONE = "none"; + + /** + * Specifies that population occurs for an ordinary client request. + */ + public static final String REQUEST = "request"; +} Propchange: struts/struts1/trunk/core/src/main/java/org/apache/struts/config/PopulateEvent.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: struts/struts1/trunk/core/src/main/java/org/apache/struts/config/PopulateEvent.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL 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=565107&r1=565106&r2=565107 ============================================================================== --- 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 Sun Aug 12 11:35:09 2007 @@ -1113,15 +1113,36 @@ } /** + * Determines whether the current request is forwarded. + * + * @param request current HTTP request + * @return true if the request is forwarded; otherwise false + * @since Struts 1.4 + */ + public static boolean isRequestForwarded(HttpServletRequest request) { + return (request.getAttribute("javax.servlet.forward.request_uri") != null); + } + + /** + * Determines whether the current request is included. + * + * @param request current HTTP request + * @return true if the request is included; otherwise false + * @since Struts 1.4 + */ + public static boolean isRequestIncluded(HttpServletRequest request) { + return (request.getAttribute("javax.servlet.include.request_uri") != null); + } + + /** * 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. - * + * @return true if the request is chained; otherwise false * @since Struts 1.4 */ - public static boolean isForwarded(HttpServletRequest request) { - return request.getAttribute(Globals.FORWARD_KEY) != null; + public static boolean isRequestChained(HttpServletRequest request) { + return (request.getAttribute(Globals.CHAIN_KEY) != null); } } Modified: struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_4.dtd URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_4.dtd?view=diff&rev=565107&r1=565106&r2=565107 ============================================================================== --- struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_4.dtd (original) +++ struts/struts1/trunk/core/src/main/resources/org/apache/struts/resources/struts-config_1_4.dtd Sun Aug 12 11:35:09 2007 @@ -92,7 +92,7 @@ <!ENTITY % RequestScope "(request|session)"> <!-- Defines possible values for automatic form bean population --> -<!ENTITY % PopulateStrategy "(request|forward|request-forward|none)"> +<!ENTITY % PopulateStrategy "CDATA"> <!-- ========== Top Level Elements ======================================== --> @@ -427,10 +427,18 @@ because it will look like a filename extension and cause your Action to not be located. + populate Comma-delimited list of events that trigger the population + of an ActionForm. Since Struts 1.4. + [all] + prefix Prefix used to match request parameter names to ActionForm property names, if any. Optional if "name" is specified, else not allowed. + reset Comma-delimited list of events that trigger the reset() + method to be called on an ActionForm. Since Struts 1.4. + [all] + roles Comma-delimited list of security role names that are allowed access to this ActionMapping object. Since Struts 1.1. @@ -466,10 +474,6 @@ "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>