Author: pbenedict Date: Thu Nov 27 11:00:56 2008 New Revision: 721261 URL: http://svn.apache.org/viewvc?rev=721261&view=rev Log: STR-3168: Extract out argument construction
Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractDispatcher.java struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMappingDispatcher.java struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractParameterDispatcher.java struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMappingDispatcher.java struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletParameterDispatcher.java Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractDispatcher.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractDispatcher.java?rev=721261&r1=721260&r2=721261&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractDispatcher.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractDispatcher.java Thu Nov 27 11:00:56 2008 @@ -20,8 +20,6 @@ */ package org.apache.struts.dispatcher; -import org.apache.struts.action.ActionForm; -import org.apache.struts.action.ActionMapping; import org.apache.struts.chain.contexts.ActionContext; import org.apache.struts.config.ActionConfig; import org.apache.struts.util.MessageResources; @@ -31,9 +29,6 @@ import java.lang.reflect.Method; import java.util.HashMap; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -56,7 +51,6 @@ /** * The name of the <code>cancelled</code> method. * - * @see #cancelled(ActionContext) * @see ActionContext#getCancelled() */ public static final String CANCELLED_METHOD_NAME = "cancelled"; @@ -132,18 +126,11 @@ /** * Dispatch to the specified method. * + * @param context the current action context * @param method The method to invoke * @param name The name of the method to invoke - * @param mapping The ActionMapping used to select this instance - * @param form The optional ActionForm bean for this request (if any) - * @param request The non-HTTP request we are processing - * @param response The non-HTTP response we are creating - * - * @return The forward to which control should be transferred, or - * <code>null</code> if the response has been completed. + * @return the return value of the method * @throws Exception if the dispatch fails with an exception - * @see #dispatchMethod(ActionMapping, ActionForm, HttpServletRequest, - * HttpServletResponse, String) */ protected abstract Object dispatchMethod(ActionContext context, Method method, String name) throws Exception; @@ -180,7 +167,7 @@ * @param methodName the name of the method to be introspected * @return the method of the specified name * @throws NoSuchMethodException if no such method can be found - * @see #resolveMethod(String, ActionContext) + * @see #resolveMethod(ActionContext, String) * @see #flushMethodCache() */ protected final Method getMethod(ActionContext context, String methodName) throws NoSuchMethodException { @@ -255,15 +242,15 @@ /** * Decides the appropriate method instance for the specified method name. * Implementations may introspect for any desired method signature. This - * resolution is only invoked if [EMAIL PROTECTED] #getMethod(String)} does not find a + * resolution is only invoked if [EMAIL PROTECTED] #getMethod(ActionContext, String)} does not find a * match in its method cache. * * @param context the current action context * @param methodName the method name to use for introspection * @return the method to invoke * @throws NoSuchMethodException if an appropriate method cannot be found - * @see #getMethod(String) - * @see #invoke(Object, Method, Object[], String, String) + * @see #getMethod(ActionContext, String) + * @see #invoke(Object, Method, Object[], String) */ protected abstract Method resolveMethod(ActionContext context, String methodName) throws NoSuchMethodException; Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMappingDispatcher.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMappingDispatcher.java?rev=721261&r1=721260&r2=721261&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMappingDispatcher.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMappingDispatcher.java Thu Nov 27 11:00:56 2008 @@ -24,16 +24,22 @@ import org.apache.struts.chain.contexts.ActionContext; /** - * <p> * This abstract class is a template for choosing the target method based on the * <code>parameter</code> attribute of the [EMAIL PROTECTED] ActionMapping}. - * </p> * * @version $Rev$ * @since Struts 1.4 */ public abstract class AbstractMappingDispatcher extends AbstractDispatcher { + /** + * Resolves the method name by obtaining the <code>parameter</code> + * attribute from the [EMAIL PROTECTED] ActionMapping}. + * + * @param context [EMAIL PROTECTED] + * @throws IllegalStateException if the parameter is absent + * @return the parameter attribute value + */ protected String resolveMethodName(ActionContext context) { // Null out an empty string parameter ActionMapping mapping = (ActionMapping) context.getActionConfig(); @@ -42,6 +48,7 @@ parameter = null; } + // Parameter is required if ((parameter == null)) { String message = messages.getMessage(MSG_KEY_MISSING_MAPPING_PARAMETER, mapping.getPath()); log.error(message); Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractParameterDispatcher.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractParameterDispatcher.java?rev=721261&r1=721260&r2=721261&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractParameterDispatcher.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractParameterDispatcher.java Thu Nov 27 11:00:56 2008 @@ -23,27 +23,8 @@ import org.apache.struts.chain.contexts.ActionContext; /** - * <p> * This abstract class is a template for choosing the target method based on a - * servlet request parameter. It is based upon the functionality of - * <code>org.apache.struts.actions.DispatchAction</code>. - * </p> - * <p> - * To configure the use of this dispatcher in your configuration, create an - * entry like below. The dispatcher will use the value of the request parameter - * named "method" (or whatever specified) to pick the appropriate method on the - * action. - * </p> - * - * <code> - * <action path="/saveSubscription" - * dispatcher="org.apache.struts.dispatcher.servlet.ServletParameterDispatcher" - * name="subscriptionForm" - * scope="request" - * input="/subscription.jsp" - * parameter="method"/> - * </code> - * <p> + * servlet request parameter. * * @version $Rev$ * @since Struts 1.4 @@ -77,7 +58,7 @@ * <code>parameter</code> attribute; otherwise fallback to the default * parameter name. * - * @param context the action context + * @param context the current action context * @return the mapping's parameter name * @see #getDefaultParameterName() */ @@ -102,6 +83,13 @@ return null; } + /** + * Extracts the value that is keyed by the specified parameter. + * + * @param context the current action context + * @param parameter the parameter name + * @return the parameter value + */ protected abstract String resolveParameterValue(ActionContext context, String parameter); } Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMappingDispatcher.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMappingDispatcher.java?rev=721261&r1=721260&r2=721261&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMappingDispatcher.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMappingDispatcher.java Thu Nov 27 11:00:56 2008 @@ -29,11 +29,95 @@ import javax.servlet.http.HttpServletResponse; +/** + * This servlet-based dispatcher uses the configuration value of the + * <code>parameter</code> attribute from the corresponding + * [EMAIL PROTECTED] org.apache.struts.action.ActionMapping} to pick the appropriate method + * on the action. Because mapping characteristics may differ between the various + * handlers, actions can be combined in the same class that, differ in their use + * of method signatures, forms, and/or validation. + * <p> + * For example, a single action may manage a subscription process by defining + * the following methods: + * <ul> + * <li><code>public ActionForward create(ActionMapping mapping, ActionForm form, + * HttpServletRequest request, HttpServletResponse response) throws Exception</code></li> + * <li><code>public ActionForward delete(ActionMapping mapping, ActionForm form, + * HttpServletRequest request, HttpServletResponse response) throws Exception</code></li> + * <li><code>public ActionForward edit(ActionMapping mapping, ActionForm form, + * HttpServletRequest request, HttpServletResponse response) throws Exception</code></li> + * <li><code>public ActionForward list(ActionMapping mapping, ActionForm form, + * HttpServletRequest request, HttpServletResponse response) throws Exception</code></li> + * <li><code>public ActionForward save(ActionMapping mapping, ActionForm form, + * HttpServletRequest request, HttpServletResponse response) throws Exception</code></li> + * </ul> + * for which a corresponding configuration would exist: + * + * <pre><code> + * <action path="/createSubscription" + * type="org.example.SubscriptionAction" + * dispatcher="org.apache.struts.dispatcher.servlet.ServletMappingDispatcher" + * parameter="create"> + * <forward path="/editSubscription.jsp"/> + * </action> + * + * <action path="/deleteSubscription" + * type="org.example.SubscriptionAction" + * dispatcher="org.apache.struts.dispatcher.servlet.ServletMappingDispatcher" + * parameter="delete" + * name="subscriptionForm" + * scope="request" + * input="/subscription.jsp"> + * <forward path="/deletedSubscription.jsp"/> + * </action> + * + * <action path="/editSubscription" + * type="org.example.SubscriptionAction" + * dispatcher="org.apache.struts.dispatcher.servlet.ServletMappingDispatcher" + * parameter="edit"> + * <forward path="/editSubscription.jsp"/> + * </action> + * + * <action path="/listSubscriptions" + * type="org.example.SubscriptionAction" + * dispatcher="org.apache.struts.dispatcher.servlet.ServletMappingDispatcher" + * parameter="list"> + * <forward path="/subscriptionList.jsp"/> + * </action> + * + * <action path="/saveSubscription" + * type="org.example.SubscriptionAction" + * dispatcher="org.apache.struts.dispatcher.servlet.ServletMappingDispatcher" + * parameter="save" + * name="subscriptionForm" + * scope="request" + * validate="true" + * input="/editSubscription.jsp"> + * <forward path="/savedSubscription.jsp"/> + * </action> + * </code></pre> + * + * @version $Rev$ + * @since Struts 1.4 + */ public class ServletMappingDispatcher extends AbstractMappingDispatcher { - protected Object dispatchMethod(ActionContext context, Method method, String name) throws Exception { + /** + * Constructs the arguments that will be passed to the dispatched method. + * + * @param context the current action context + * @param method the target method of this dispatch + * + * @return the arguments array + * @see #dispatchMethod(ActionContext, Method, String) + */ + protected Object[] buildMethodArguments(ServletActionContext context, Method method) { + return ServletDispatchUtils.buildClassicExecuteArguments(context); + } + + protected final Object dispatchMethod(ActionContext context, Method method, String name) throws Exception { Action target = context.getAction(); - Object[] args = ServletDispatchUtils.buildClassicExecuteArguments((ServletActionContext) context); + Object[] args = buildMethodArguments((ServletActionContext) context, method); String path = context.getActionConfig().getPath(); return invoke(target, method, args, path); } @@ -42,6 +126,11 @@ return ServletDispatchUtils.resolveClassicExecuteMethod(context, methodName); } + /** + * Sends the 404 HTTP error response. + * + * @return always <code>null</code> since the response is handled directly + */ protected Object unspecified(ActionContext context) throws Exception { HttpServletResponse response = ((ServletActionContext) context).getResponse(); response.sendError(HttpServletResponse.SC_NOT_FOUND); Modified: struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletParameterDispatcher.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletParameterDispatcher.java?rev=721261&r1=721260&r2=721261&view=diff ============================================================================== --- struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletParameterDispatcher.java (original) +++ struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletParameterDispatcher.java Thu Nov 27 11:00:56 2008 @@ -29,12 +29,70 @@ import javax.servlet.http.HttpServletResponse; +/** + * This servlet-based dispatcher uses the value of the request parameter to pick + * the appropriate method on the action. + * <p> + * To configure the use of this dispatcher in your configuration, create an + * entry like below: + * <p> + * <code> + * <pre> + * <action path="/saveSubscription" + * type="org.example.SubscriptionAction" + * dispatcher="org.apache.struts.dispatcher.servlet.ServletParameterDispatcher" + * parameter="method"/> + * name="subscriptionForm" + * scope="request" + * input="/subscription.jsp" + * </pre> + * </code> + * <p> + * This example will use the value of the request parameter named "method" to + * pick the appropriate method, which must have the same signature (other than + * method name) of the standard + * [EMAIL PROTECTED] Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, + * javax.servlet.ServletRequest, javax.servlet.ServletResponse) Action.execute} + * method. For example, you might have the following three methods in the same + * action: + * + * <ul> + * <li><code>public ActionForward delete(ActionMapping mapping, ActionForm form, + * HttpServletRequest request, HttpServletResponse response) throws Exception</code></li> + * <li><code>public ActionForward insert(ActionMapping mapping, ActionForm form, + * HttpServletRequest request, HttpServletResponse response) throws Exception</code></li> + * <li><code>public ActionForward update(ActionMapping mapping, ActionForm form, + * HttpServletRequest request, HttpServletResponse response) throws Exception</code></li> + * </ul> + * and call one of the methods with a URL like this: + * <p> + * <code>http://localhost:8080/myapp/saveSubscription.do?method=update</code> + * + * @version $Rev$ + * @since Struts 1.4 + */ public class ServletParameterDispatcher extends AbstractParameterDispatcher { - protected Object dispatchMethod(ActionContext context, Method method, String name) throws Exception { + /** + * Constructs the arguments that will be passed to the dispatched method. + * + * @param context the current action context + * @param method the target method of this dispatch + * + * @return the arguments array + * @see #dispatchMethod(ActionContext, Method, String) + */ + protected Object[] buildMethodArguments(ServletActionContext context, Method method) { + return ServletDispatchUtils.buildClassicExecuteArguments(context); + } + + /** + * @see #buildMethodArguments(ServletActionContext, Method) + */ + protected final Object dispatchMethod(ActionContext context, Method method, String name) throws Exception { Action target = context.getAction(); - Object[] args = ServletDispatchUtils.buildClassicExecuteArguments((ServletActionContext) context); String path = context.getActionConfig().getPath(); + Object[] args = buildMethodArguments((ServletActionContext) context, method); return invoke(target, method, args, path); } @@ -42,11 +100,25 @@ return ServletDispatchUtils.resolveClassicExecuteMethod(context, methodName); } + /** + * Extracts the value from the specified servlet parameter. + * + * @param context [EMAIL PROTECTED] + * @param parameter the servlet parameter name + * @return the servlet parameter value + */ protected String resolveParameterValue(ActionContext context, String parameter) { ServletActionContext servletContext = (ServletActionContext) context; return (String) servletContext.getParam().get(parameter); } + /** + * Sends the 404 HTTP error response. + * + * @param context [EMAIL PROTECTED] + * @return always <code>null</code> since the response is handled directly + * @throws Exception if the error code fails to set + */ protected Object unspecified(ActionContext context) throws Exception { HttpServletResponse response = ((ServletActionContext) context).getResponse(); response.sendError(HttpServletResponse.SC_NOT_FOUND);