Author: pbenedict
Date: Sun Dec 28 21:12:58 2008
New Revision: 729832

URL: http://svn.apache.org/viewvc?rev=729832&view=rev
Log:
STR-3168: Refactor out method resolution, set mapping parameter default to 
execute, delete static utils, replace tabs with spaces

Added:
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMethodResolver.java
   (with props)
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/MethodResolver.java
   (with props)
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMethodResolver.java
   (with props)
Removed:
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletDispatchUtils.java
Modified:
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/ExecuteDispatcher.java
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractDispatcher.java
    
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractEventMappingDispatcher.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/ServletEventMappingDispatcher.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/chain/commands/ExecuteDispatcher.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/ExecuteDispatcher.java?rev=729832&r1=729831&r2=729832&view=diff
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/ExecuteDispatcher.java
 (original)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/commands/ExecuteDispatcher.java
 Sun Dec 28 21:12:58 2008
@@ -51,65 +51,85 @@
      * @see ClassUtils#getApplicationInstance(String)
      */
     protected Dispatcher createDispatcher(String type, ActionContext context) 
throws Exception {
-       log.info("Initializing dispatcher of type: " + type);
-       return (Dispatcher) ClassUtils.getApplicationInstance(type);
+        log.info("Initializing dispatcher of type: " + type);
+        return (Dispatcher) ClassUtils.getApplicationInstance(type);
     }
 
     public boolean execute(ActionContext context) throws Exception {
-       // Skip processing if the current request is not valid
-       Boolean valid = context.getFormValid();
-       if ((valid == null) || !valid.booleanValue()) {
-           return CONTINUE_PROCESSING;
-       }
+        // Skip processing if the current request is not valid
+        Boolean valid = context.getFormValid();
+        if ((valid == null) || !valid.booleanValue()) {
+            return CONTINUE_PROCESSING;
+        }
 
         // Skip processing if no action is specified
         if (context.getAction() == null) {
             return CONTINUE_PROCESSING;
         }
 
-       // Skip processing if no dispatcher type specified
-       String dispatcherType = getDispatcherType(context);
-       if (dispatcherType == null) {
-           return CONTINUE_PROCESSING;
-       }
-
-       // Obtain (or create) the dispatcher cache
-       String cacheKey = Constants.DISPATCHERS_KEY + 
context.getModuleConfig().getPrefix();
-       Map dispatchers = (Map) context.getApplicationScope().get(cacheKey);
-       if (dispatchers == null) {
-           dispatchers = new HashMap();
-           context.getApplicationScope().put(cacheKey, dispatchers);
-       }
-
-       // Lookup (or create) the dispatch instance
-       Dispatcher dispatcher = null;
-       synchronized (dispatchers) {
-           ActionConfig actionConfig = context.getActionConfig();
-           String actionType = actionConfig.getType();
-           dispatcher = (Dispatcher) dispatchers.get(actionType);
-           if (dispatcher == null) {
-               dispatcher = createDispatcher(dispatcherType, context);
-               dispatchers.put(actionType, dispatcher);
-           }
-       }
-
-       // Dispatch
-       Object result = dispatcher.dispatch(context);
-       processDispatchResult(result, context);
+        // Skip processing if no dispatcher type specified
+        String dispatcherType = getDispatcherType(context);
+        if (dispatcherType == null) {
+            dispatcherType = defaultDispatcherType;
+            if (dispatcherType == null) {
+                return CONTINUE_PROCESSING;
+            }
+        }
+
+        // Obtain (or create) the dispatcher cache
+        String cacheKey = Constants.DISPATCHERS_KEY + 
context.getModuleConfig().getPrefix();
+        Map dispatchers = (Map) context.getApplicationScope().get(cacheKey);
+        if (dispatchers == null) {
+            dispatchers = new HashMap();
+            context.getApplicationScope().put(cacheKey, dispatchers);
+        }
+
+        // Lookup (or create) the dispatch instance
+        Dispatcher dispatcher = null;
+        synchronized (dispatchers) {
+            ActionConfig actionConfig = context.getActionConfig();
+            String actionType = actionConfig.getType();
+            dispatcher = (Dispatcher) dispatchers.get(actionType);
+
+            if (dispatcher == null) {
+                dispatcher = createDispatcher(dispatcherType, context);
+                dispatchers.put(actionType, dispatcher);
+            }
+        }
 
-       return CONTINUE_PROCESSING;
+        // Dispatch
+        Object result = dispatcher.dispatch(context);
+        processDispatchResult(result, context);
+
+        return CONTINUE_PROCESSING;
     }
 
+    /**
+     * Retrieves the fully-qualified dispatcher class name to instantiate when
+     * an action mapping does not specify a dispatcher.
+     * 
+     * @return the default dispatcher type (fully-qualified class name)
+     * @see #getDispatcherType(ActionContext)
+     * @see #setDefaultDispatcherType(String)
+     */
     public final String getDefaultDispatcherType() {
-       return defaultDispatcherType;
+        return defaultDispatcherType;
     }
 
+    /**
+     * Retrieves the fully-qualified class name of the dispatcher to 
instantiate
+     * for the specified context.
+     * 
+     * @param context the current action context
+     * @return the class name or <code>null</code>
+     * @see #getDefaultDispatcherType()
+     */
     protected String getDispatcherType(ActionContext context) {
-       String dispatcherType = null;
-       if (context != null) {
-           dispatcherType = context.getActionConfig().getDispatcher();
-       }
-       return (dispatcherType != null) ? dispatcherType : 
defaultDispatcherType;
+        String dispatcherType = null;
+        if (context != null) {
+            dispatcherType = context.getActionConfig().getDispatcher();
+        }
+        return dispatcherType;
     }
 
     /**
@@ -134,37 +154,43 @@
      * @see ActionMapping#findRequiredForward(String)
      */
     protected void processDispatchResult(Object result, ActionContext context) 
{
-       // Null means the response was handled directly
-       if (result == null) {
-           return;
-       }
-
-       // A forward is the classical response
-       if (result instanceof ForwardConfig) {
-           context.setForwardConfig((ForwardConfig) result);
-           return;
-       }
-
-       // String represents the name of a forward
-       ActionConfig actionConfig = context.getActionConfig();
-       ActionMapping mapping = ((ActionMapping) actionConfig);
-       if (result instanceof String) {
-           context.setForwardConfig(mapping.findRequiredForward((String) 
result));
-           return;
-       }
-
-       // Select success if no return signature
-       if (result instanceof Void) {
-           
context.setForwardConfig(mapping.findRequiredForward(Action.SUCCESS));
-           return;
-       }
+        // Null means the response was handled directly
+        if (result == null) {
+            return;
+        }
 
-       // Unknown result type
-       throw new IllegalStateException("Unknown dispatch return type: " + 
result.getClass().getName());
+        // A forward is the classical response
+        if (result instanceof ForwardConfig) {
+            context.setForwardConfig((ForwardConfig) result);
+            return;
+        }
+
+        // String represents the name of a forward
+        ActionConfig actionConfig = context.getActionConfig();
+        ActionMapping mapping = ((ActionMapping) actionConfig);
+        if (result instanceof String) {
+            context.setForwardConfig(mapping.findRequiredForward((String) 
result));
+            return;
+        }
+
+        // Select success if no return signature
+        if (result == void.class) {
+            
context.setForwardConfig(mapping.findRequiredForward(Action.SUCCESS));
+            return;
+        }
+
+        // Unknown result type
+        throw new IllegalStateException("Unknown dispatch return type: " + 
result.getClass().getName());
     }
 
+    /**
+     * Stores the optional default dispatcher type (fully-qualified class 
name).
+     * 
+     * @param defaultDispatcherType the dispatcher type or <code>null</code>
+     * @see #getDefaultDispatcherType()
+     */
     public final void setDefaultDispatcherType(String defaultDispatcherType) {
-       this.defaultDispatcherType = defaultDispatcherType;
+        this.defaultDispatcherType = defaultDispatcherType;
     }
 
 }

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=729832&r1=729831&r2=729832&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
 Sun Dec 28 21:12:58 2008
@@ -34,7 +34,8 @@
 import org.apache.commons.logging.LogFactory;
 
 /**
- * TODO
+ * This abstract class is the stock template for {...@link Dispatcher}
+ * implementations.
  * 
  * @version $Rev$
  * @since Struts 1.4
@@ -57,11 +58,9 @@
     public static final String CANCELLED_METHOD_NAME = "cancelled";
 
     /**
-     * The name of the <code>unspecified</code> method.
-     * 
-     * @see #unspecified(ActionContext)
+     * The name of the <code>execute</code> method.
      */
-    public static final String UNSPECIFIED_METHOD_NAME = "unspecified";
+    public static final String EXECUTE_METHOD_NAME = "execute";
 
     /**
      * The message resources for this package.
@@ -81,58 +80,71 @@
      */
     private transient final HashMap methods;
 
+    private final MethodResolver methodResolver;
+
     /**
-     * Construct a new dispatcher.
+     * Constructs a new dispatcher with the specified method resolver.
+     * 
+     * @param methodResolver the method resolver
      */
-    public AbstractDispatcher() {
-       log = LogFactory.getLog(getClass());
-       methods = new HashMap();
+    public AbstractDispatcher(MethodResolver methodResolver) {
+        this.methodResolver = methodResolver;
+        log = LogFactory.getLog(getClass());
+        methods = new HashMap();
     }
 
     /**
      * Constructs the arguments that will be passed to the dispatched method.
+     * The construction is delegated to the method resolver instance.
      * 
      * @param context the current action context
      * @param method the target method of this dispatch
-     * 
      * @return the arguments array
-     * @see #dispatchMethod(ActionContext, Method, String)
-     */
-    protected abstract Object[] buildMethodArguments(ActionContext context, 
Method method);
+     * @throws IllegalStateException if the method does not have a supported
+     *         signature
+     * @see MethodResolver#buildArguments(ActionContext, Method)
+     */
+    Object[] buildMethodArguments(ActionContext context, Method method) {
+        Object[] args = methodResolver.buildArguments(context, method);
+        if (args == null) {
+            throw new IllegalStateException("Unsupported method signature: " + 
method.toString());
+        }
+        return args;
+    }
 
     public Object dispatch(ActionContext context) throws Exception {
-       // Resolve the method name; fallback to default if necessary
-       String methodName = resolveMethodName(context);
-       if ((methodName == null) || "".equals(methodName)) {
-           methodName = getDefaultMethodName();
-       }
-
-       // Ensure there is a specified method name to invoke.
-       // This may be null if the user hacks the query string.
-       if (methodName == null) {
-           return unspecified(context);
-       }
-
-       // Identify the method object to dispatch
-       Method method;
-       try {
-           method = getMethod(context, methodName);
-       } catch (NoSuchMethodException e) {
-           // The log message reveals the offending method name...
-           String path = context.getActionConfig().getPath();
-           String message = messages.getMessage(MSG_KEY_MISSING_METHOD_LOG, 
path, methodName);
-           log.error(message, e);
-
-           // ...but the exception thrown does not
-           // See r383718 (XSS vulnerability)
-           String userMsg = messages.getMessage(MSG_KEY_MISSING_METHOD, path);
-           NoSuchMethodException e2 = new NoSuchMethodException(userMsg);
-           e2.initCause(e);
-           throw e2;
-       }
+        // Resolve the method name; fallback to default if necessary
+        String methodName = resolveMethodName(context);
+        if ((methodName == null) || "".equals(methodName)) {
+            methodName = getDefaultMethodName();
+        }
+
+        // Ensure there is a specified method name to invoke.
+        // This may be null if the user hacks the query string.
+        if (methodName == null) {
+            return unspecified(context);
+        }
+
+        // Identify the method object to dispatch
+        Method method;
+        try {
+            method = getMethod(context, methodName);
+        } catch (NoSuchMethodException e) {
+            // The log message reveals the offending method name...
+            String path = context.getActionConfig().getPath();
+            String message = messages.getMessage(MSG_KEY_MISSING_METHOD_LOG, 
path, methodName);
+            log.error(message, e);
+
+            // ...but the exception thrown does not
+            // See r383718 (XSS vulnerability)
+            String userMsg = messages.getMessage(MSG_KEY_MISSING_METHOD, path);
+            NoSuchMethodException e2 = new NoSuchMethodException(userMsg);
+            e2.initCause(e);
+            throw e2;
+        }
 
-       // Invoke the named method and return its result
-       return dispatchMethod(context, method, methodName);
+        // Invoke the named method and return its result
+        return dispatchMethod(context, method, methodName);
     }
 
     /**
@@ -146,10 +158,10 @@
      * @see #buildMethodArguments(ActionContext, Method)
      */
     protected final Object dispatchMethod(ActionContext context, Method 
method, String name) throws Exception {
-       Action target = context.getAction();
-       String path = context.getActionConfig().getPath();
-       Object[] args = buildMethodArguments(context, method);
-       return invoke(target, method, args, path);
+        Action target = context.getAction();
+        String path = context.getActionConfig().getPath();
+        Object[] args = buildMethodArguments(context, method);
+        return invoke(target, method, args, path);
     }
 
     /**
@@ -158,22 +170,22 @@
      * @see #getMethod(ActionContext, String)
      */
     final void flushMethodCache() {
-       synchronized (methods) {
-           methods.clear();
-       }
+        synchronized (methods) {
+            methods.clear();
+        }
     }
 
     /**
      * Retrieves the name of the method to fallback upon if no method name can
      * be resolved. The default implementation returns
-     * {...@value #UNSPECIFIED_METHOD_NAME}.
+     * {...@link #EXECUTE_METHOD_NAME}.
      * 
      * @return the fallback method name; can be <code>null</code>
      * @see #resolveMethodName(ActionContext)
-     * @see #UNSPECIFIED_METHOD_NAME
+     * @see #EXECUTE_METHOD_NAME
      */
     protected String getDefaultMethodName() {
-       return UNSPECIFIED_METHOD_NAME;
+        return EXECUTE_METHOD_NAME;
     }
 
     /**
@@ -189,23 +201,23 @@
      * @see #flushMethodCache()
      */
     protected final Method getMethod(ActionContext context, String methodName) 
throws NoSuchMethodException {
-       synchronized (methods) {
-           // Key the method based on the class-method combination
-           StringBuffer keyBuf = new StringBuffer(100);
-           keyBuf.append(context.getAction().getClass().getName());
-           keyBuf.append(":");
-           keyBuf.append(methodName);
-           String key = keyBuf.toString();
-
-           Method method = (Method) methods.get(key);
-
-           if (method == null) {
-               method = resolveMethod(context, methodName);
-               methods.put(key, method);
-           }
+        synchronized (methods) {
+            // Key the method based on the class-method combination
+            StringBuffer keyBuf = new StringBuffer(100);
+            keyBuf.append(context.getAction().getClass().getName());
+            keyBuf.append(":");
+            keyBuf.append(methodName);
+            String key = keyBuf.toString();
+
+            Method method = (Method) methods.get(key);
+
+            if (method == null) {
+                method = resolveMethod(context, methodName);
+                methods.put(key, method);
+            }
 
-           return method;
-       }
+            return method;
+        }
     }
 
     /**
@@ -220,24 +232,28 @@
      * @throws Exception if the dispatch fails with an exception
      */
     protected final Object invoke(Object target, Method method, Object[] args, 
String path) throws Exception {
-       try {
-           return method.invoke(target, args);
-       } catch (IllegalAccessException e) {
-           String message = messages.getMessage(MSG_KEY_DISPATCH_ERROR, path);
-           log.error(message + ":" + method.getName(), e);
-           throw e;
-       } catch (InvocationTargetException e) {
-           // Rethrow the target exception if possible so that the
-           // exception handling machinery can deal with it
-           Throwable t = e.getTargetException();
-           if (t instanceof Exception) {
-               throw (Exception) t;
-           } else {
-               String message = messages.getMessage(MSG_KEY_DISPATCH_ERROR, 
path);
-               log.error(message + ":" + method.getName(), e);
-               throw new Exception(t);
-           }
-       }
+        try {
+            Object retval = method.invoke(target, args);
+            if (method.getReturnType() == void.class) {
+                retval = void.class;
+            }
+            return retval;
+        } catch (IllegalAccessException e) {
+            String message = messages.getMessage(MSG_KEY_DISPATCH_ERROR, path);
+            log.error(message + ":" + method.getName(), e);
+            throw e;
+        } catch (InvocationTargetException e) {
+            // Rethrow the target exception if possible so that the
+            // exception handling machinery can deal with it
+            Throwable t = e.getTargetException();
+            if (t instanceof Exception) {
+                throw (Exception) t;
+            } else {
+                String message = messages.getMessage(MSG_KEY_DISPATCH_ERROR, 
path);
+                log.error(message + ":" + method.getName(), e);
+                throw new Exception(t);
+            }
+        }
     }
 
     /**
@@ -250,11 +266,10 @@
      * @param context the current action context
      * @return <code>true</code> if the request is cancelled; otherwise
      *         <code>false</code>
-     * @see org.apache.struts.taglib.html.CancelTag
      */
     protected boolean isCancelled(ActionContext context) {
-       Boolean cancelled = context.getCancelled();
-       return (cancelled != null) && cancelled.booleanValue();
+        Boolean cancelled = context.getCancelled();
+        return (cancelled != null) && cancelled.booleanValue();
     }
 
     /**
@@ -270,7 +285,9 @@
      * @see #getMethod(ActionContext, String)
      * @see #invoke(Object, Method, Object[], String)
      */
-    protected abstract Method resolveMethod(ActionContext context, String 
methodName) throws NoSuchMethodException;
+    Method resolveMethod(ActionContext context, String methodName) throws 
NoSuchMethodException {
+        return methodResolver.resolveMethod(context, methodName);
+    }
 
     /**
      * Decides the method name that can handle the request.
@@ -280,7 +297,7 @@
      * @see #getDefaultMethodName()
      * @see #resolveMethod(ActionContext, String)
      */
-    protected abstract String resolveMethodName(ActionContext context);
+    abstract String resolveMethodName(ActionContext context);
 
     /**
      * Services the case when the dispatch fails because the method name cannot
@@ -294,10 +311,10 @@
      * @see #resolveMethodName(ActionContext)
      */
     protected Object unspecified(ActionContext context) throws Exception {
-       ActionConfig config = context.getActionConfig();
-       String msg = messages.getMessage(MSG_KEY_UNSPECIFIED, config.getPath());
-       log.error(msg);
-       throw new IllegalStateException(msg);
+        ActionConfig config = context.getActionConfig();
+        String msg = messages.getMessage(MSG_KEY_UNSPECIFIED, 
config.getPath());
+        log.error(msg);
+        throw new IllegalStateException(msg);
     }
 
 }

Modified: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractEventMappingDispatcher.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractEventMappingDispatcher.java?rev=729832&r1=729831&r2=729832&view=diff
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractEventMappingDispatcher.java
 (original)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractEventMappingDispatcher.java
 Sun Dec 28 21:12:58 2008
@@ -41,8 +41,8 @@
  * <p>
  * The <em>default</em> key is purely optional, but encouraged when nothing
  * matches (such as the user pressing the enter key). If this is not specified
- * and no parameters match the list of method keys, <code>null</code> is
- * returned which means the <code>unspecified</code> method will be invoked.
+ * and no parameters match the list of method keys, the method resolution
+ * returns <code>null</code>.
  * <p>
  * The order of the parameters are guaranteed to be iterated in the order
  * specified. If multiple buttons were accidently submitted, the first match in
@@ -60,6 +60,15 @@
     protected static final String DEFAULT_METHOD_KEY = "default";
 
     /**
+     * Constructs a new dispatcher with the specified method resolver.
+     * 
+     * @param methodResolver the method resolver
+     */
+    public AbstractEventMappingDispatcher(MethodResolver methodResolver) {
+        super(methodResolver);
+    }
+
+    /**
      * Determines whether the specified method key is a submission parameter.
      * 
      * @param context the current action context
@@ -70,38 +79,40 @@
     protected abstract boolean isSubmissionParameter(ActionContext context, 
String methodKey);
 
     protected final String resolveMethodName(ActionContext context) {
-       // Obtain the mapping parameter
-       String parameter = super.resolveMethodName(context);
-       assert parameter != null;
-
-       // Parse it as a comma-separated list
-       StringTokenizer st = new StringTokenizer(parameter, ",");
-       String defaultMethodName = null;
-
-       while (st.hasMoreTokens()) {
-           String methodKey = st.nextToken().trim();
-           String methodName = methodKey;
-
-           // The key can either be a direct method name or an alias
-           // to a method as indicated by a "key=value" signature
-           int equals = methodKey.indexOf('=');
-           if (equals > -1) {
-               methodName = methodKey.substring(equals + 1).trim();
-               methodKey = methodKey.substring(0, equals).trim();
-           }
-
-           // Set the default if it passes by
-           if (methodKey.equals(DEFAULT_METHOD_KEY)) {
-               defaultMethodName = methodName;
-           }
-
-           // Is it a match?
-           if (isSubmissionParameter(context, methodKey)) {
-               return methodName;
-           }
-       }
+        // Obtain the mapping parameter
+        String mappingParameter = super.resolveMethodName(context);
+        if (mappingParameter == null) {
+            return null;
+        }
+
+        // Parse it as a comma-separated list
+        StringTokenizer st = new StringTokenizer(mappingParameter, ",");
+        String defaultMethodName = null;
+
+        while (st.hasMoreTokens()) {
+            String methodKey = st.nextToken().trim();
+            String methodName = methodKey;
+
+            // The key can either be a direct method name or an alias
+            // to a method as indicated by a "key=value" signature
+            int equals = methodKey.indexOf('=');
+            if (equals > -1) {
+                methodName = methodKey.substring(equals + 1).trim();
+                methodKey = methodKey.substring(0, equals).trim();
+            }
+
+            // Set the default if it passes by
+            if (methodKey.equals(DEFAULT_METHOD_KEY)) {
+                defaultMethodName = methodName;
+            }
+
+            // Is it a match?
+            if (isSubmissionParameter(context, methodKey)) {
+                return methodName;
+            }
+        }
 
-       return defaultMethodName;
+        return defaultMethodName;
     }
 
 }

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=729832&r1=729831&r2=729832&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
 Sun Dec 28 21:12:58 2008
@@ -26,37 +26,77 @@
 /**
  * This abstract class is a template for choosing the target method that is
  * named by the <code>parameter</code> attribute of the corresponding
- * {...@link ActionMapping}.
+ * {...@link ActionMapping}. The attribute value, if not provided, defaults to
+ * <code>execute</code>.
  * 
  * @version $Rev$
  * @since Struts 1.4
  */
 public abstract class AbstractMappingDispatcher extends AbstractDispatcher {
 
+    private String defaultMappingParameter;
+
+    /**
+     * Constructs a new dispatcher with the specified method resolver.
+     * 
+     * @param methodResolver the method resolver
+     */
+    public AbstractMappingDispatcher(MethodResolver methodResolver) {
+        super(methodResolver);
+        setDefaultMappingParameter(EXECUTE_METHOD_NAME);
+    }
+
+    /**
+     * Retrieves the default mapping parameter value. This value is used by
+     * {...@link #resolveMethodName(ActionContext)} if the mapping did not 
provide
+     * a value.
+     * 
+     * @return the mapping parameter value or <code>null</code>
+     * @see #setDefaultMappingParameter(String)
+     */
+    protected final String getDefaultMappingParameter() {
+        return defaultMappingParameter;
+    }
+
     /**
      * Resolves the method name by obtaining the <code>parameter</code>
      * attribute from the {...@link ActionMapping}.
      * 
      * @param context {...@inheritdoc}
-     * @throws IllegalStateException if the parameter is absent
+     * @throws IllegalStateException if the parameter cannot be resolved
      * @return the parameter attribute value
      */
     protected String resolveMethodName(ActionContext context) {
-       // Null out an empty string parameter
-       ActionMapping mapping = (ActionMapping) context.getActionConfig();
-       String parameter = mapping.getParameter();
-       if ("".equals(parameter)) {
-           parameter = null;
-       }
-
-       // Parameter is required
-       if ((parameter == null)) {
-           String message = 
messages.getMessage(MSG_KEY_MISSING_MAPPING_PARAMETER, mapping.getPath());
-           log.error(message);
-           throw new IllegalStateException(message);
-       }
+        // Null out an empty string parameter
+        ActionMapping mapping = (ActionMapping) context.getActionConfig();
+        String parameter = mapping.getParameter();
+        if ("".equals(parameter)) {
+            parameter = null;
+        }
+
+        // Assign the default if the mapping did not provide a value
+        if (parameter == null) {
+            parameter = defaultMappingParameter;
+        }
 
-       return parameter;
+        // Parameter is required
+        if (parameter == null) {
+            String message = 
messages.getMessage(MSG_KEY_MISSING_MAPPING_PARAMETER, mapping.getPath());
+            log.error(message);
+            throw new IllegalStateException(message);
+        }
+
+        return parameter;
+    }
+
+    /**
+     * Stores the new default mapping parameter value.
+     * 
+     * @param defaultMappingParameter the parameter value
+     * @see #getDefaultMappingParameter()
+     */
+    protected final void setDefaultMappingParameter(String 
defaultMappingParameter) {
+        this.defaultMappingParameter = defaultMappingParameter;
     }
 
 }

Added: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMethodResolver.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMethodResolver.java?rev=729832&view=auto
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMethodResolver.java
 (added)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMethodResolver.java
 Sun Dec 28 21:12:58 2008
@@ -0,0 +1,91 @@
+/*
+ * $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.dispatcher;
+
+import org.apache.struts.chain.contexts.ActionContext;
+
+import java.lang.reflect.Method;
+
+/**
+ * This abstract class is the stock template for resolving methods for a
+ * {...@link Dispatcher}. The implementation handles methods that accept no
+ * arguments or only an {...@link ActionContext} instance:
+ * <ul>
+ * <li><code><i>return_type</i> execute()</code></li>
+ * <li><code><i>return_type</i> execute(ActionContext context)</code></li>
+ * </ul>
+ * 
+ * @version $Rev$
+ * @since Struts 1.4
+ */
+public abstract class AbstractMethodResolver implements MethodResolver {
+
+    /**
+     * The argument listing for a method without arguments.
+     * 
+     * @see #EMPTY_ARGUMENT_TYPES
+     */
+    protected static final Object[] EMPTY_ARGUMENTS = new Object[] {};
+
+    /**
+     * The type listing used for a method without arguments.
+     * 
+     * @see #EMPTY_ARGUMENTS
+     */
+    protected static final Class[] EMPTY_ARGUMENT_TYPES = new Class[] {};
+
+    /**
+     * The argument listing for a method accepting the {...@link 
ActionContext}.
+     */
+    private static final Class[] ACTION_CONTEXT_ARGUMENT_TYPES = new Class[] { 
ActionContext.class };
+
+    public Object[] buildArguments(ActionContext context, Method method) {
+        Class[] parameterTypes = method.getParameterTypes();
+        switch (parameterTypes.length) {
+        case 0:
+            return EMPTY_ARGUMENTS;
+
+        case 1:
+            if (parameterTypes[0].isInstance(context)) {
+                return new Object[] { context };
+            }
+            return null;
+
+        default:
+            return null;
+        }
+    }
+
+    public Method resolveMethod(ActionContext context, String methodName) 
throws NoSuchMethodException {
+        Class actionClass = context.getAction().getClass();
+
+        // Does the method accept nothing?
+        try {
+            return actionClass.getDeclaredMethod(methodName, 
EMPTY_ARGUMENT_TYPES);
+        } catch (NoSuchMethodException e) {
+            // continue
+        }
+
+        // Does the method accept the action context?
+        return actionClass.getDeclaredMethod(methodName, 
ACTION_CONTEXT_ARGUMENT_TYPES);
+    }
+
+}

Propchange: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMethodResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/AbstractMethodResolver.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

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=729832&r1=729831&r2=729832&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
 Sun Dec 28 21:12:58 2008
@@ -39,16 +39,25 @@
     protected static final String DEFAULT_PARAMETER_NAME = "method";
 
     /**
+     * Constructs a new dispatcher with the specified method resolver.
+     * 
+     * @param methodResolver the method resolver
+     */
+    public AbstractParameterDispatcher(MethodResolver methodResolver) {
+        super(methodResolver);
+    }
+
+    /**
      * Retrieves the name of the parameter to fallback upon if the action
      * configuration did not set the <code>parameter</code> attribute. The
-     * default implementation returns {...@value #DEFAULT_PARAMETER_NAME}.
+     * default implementation returns {...@link #DEFAULT_PARAMETER_NAME}.
      * 
      * @return the fallback parameter name; can be <code>null</code>
      * @see #DEFAULT_PARAMETER_NAME
      * @see #getParameter(ActionContext)
      */
     protected String getDefaultParameterName() {
-       return DEFAULT_PARAMETER_NAME;
+        return DEFAULT_PARAMETER_NAME;
     }
 
     /**
@@ -63,24 +72,24 @@
      * @see #getDefaultParameterName()
      */
     protected String getParameter(ActionContext context) {
-       String parameter = context.getActionConfig().getParameter();
-       if ((parameter != null) && (parameter.trim().length() > 0)) {
-           return parameter;
-       }
-       return getDefaultParameterName();
+        String parameter = context.getActionConfig().getParameter();
+        if ((parameter != null) && (parameter.trim().length() > 0)) {
+            return parameter;
+        }
+        return getDefaultParameterName();
     }
 
     protected final String resolveMethodName(ActionContext context) {
-       String parameter = getParameter(context);
-       if ("".equals(parameter)) {
-           parameter = null;
-       }
-
-       if (parameter != null) {
-           return resolveParameterValue(context, parameter);
-       }
+        String parameter = getParameter(context);
+        if ("".equals(parameter)) {
+            parameter = null;
+        }
+
+        if (parameter != null) {
+            return resolveParameterValue(context, parameter);
+        }
 
-       return null;
+        return null;
     }
 
     /**

Added: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/MethodResolver.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/MethodResolver.java?rev=729832&view=auto
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/MethodResolver.java
 (added)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/MethodResolver.java
 Sun Dec 28 21:12:58 2008
@@ -0,0 +1,61 @@
+/*
+ * $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.dispatcher;
+
+import org.apache.struts.chain.contexts.ActionContext;
+
+import java.lang.reflect.Method;
+
+/**
+ * This interface defines a pluggable strategy for resolving a method and
+ * extracting its methods from an {...@link ActionContext}. A {...@link 
Dispatcher}
+ * may use the resolver to separate out its method resolution based on
+ * technology (such as servlets, portlets, etc.).
+ * 
+ * @version $Rev$
+ * @since Struts 1.4
+ */
+public interface MethodResolver {
+
+    /**
+     * 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 for the method, or <code>null</code> if the
+     *         method does not match any supported signatures
+     * @see #resolveMethod(ActionContext, String)
+     */
+    Object[] buildArguments(ActionContext context, Method method);
+
+    /**
+     * Decides the appropriate method instance for the specified method name.
+     * Implementations may introspect for any desired method signature.
+     * 
+     * @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
+     */
+    Method resolveMethod(ActionContext context, String methodName) throws 
NoSuchMethodException;
+
+}
\ No newline at end of file

Propchange: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/MethodResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/MethodResolver.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletEventMappingDispatcher.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletEventMappingDispatcher.java?rev=729832&r1=729831&r2=729832&view=diff
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletEventMappingDispatcher.java
 (original)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletEventMappingDispatcher.java
 Sun Dec 28 21:12:58 2008
@@ -25,8 +25,6 @@
 import org.apache.struts.chain.contexts.ServletActionContext;
 import org.apache.struts.dispatcher.AbstractEventMappingDispatcher;
 
-import java.lang.reflect.Method;
-
 import javax.servlet.http.HttpServletRequest;
 
 /**
@@ -59,8 +57,11 @@
 
     private static final long serialVersionUID = 1L;
 
-    protected Object[] buildMethodArguments(ActionContext context, Method 
method) {
-       return 
ServletDispatchUtils.buildClassicExecuteArguments((ServletActionContext) 
context);
+    /**
+     * Constructs a new servlet event mapping dispatcher.
+     */
+    public ServletEventMappingDispatcher() {
+        super(new ServletMethodResolver());
     }
 
     /**
@@ -68,12 +69,8 @@
      * suffixes (.x/.y), the method name has been found.
      */
     protected boolean isSubmissionParameter(ActionContext context, String 
methodKey) {
-       HttpServletRequest request = ((ServletActionContext) 
context).getRequest();
-       return (request.getParameter(methodKey) != null) || 
(request.getParameter(methodKey + ".x") != null);
-    }
-
-    protected Method resolveMethod(ActionContext context, String methodName) 
throws NoSuchMethodException {
-       return ServletDispatchUtils.resolveClassicExecuteMethod(context, 
methodName);
+        HttpServletRequest request = ((ServletActionContext) 
context).getRequest();
+        return (request.getParameter(methodKey) != null) || 
(request.getParameter(methodKey + ".x") != null);
     }
 
 }

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=729832&r1=729831&r2=729832&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
 Sun Dec 28 21:12:58 2008
@@ -24,8 +24,6 @@
 import org.apache.struts.chain.contexts.ServletActionContext;
 import org.apache.struts.dispatcher.AbstractMappingDispatcher;
 
-import java.lang.reflect.Method;
-
 import javax.servlet.http.HttpServletResponse;
 
 /**
@@ -39,16 +37,11 @@
  * 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>
+ * <li><code>public void create(ActionContext context)</code></li>
+ * <li><code>public void delete(ActionContext context)</code></li>
+ * <li><code>public String edit(ActionContext context)</code></li>
+ * <li><code>public ActionForward list(ActionContext context)</code></li>
+ * <li><code>public String save(ActionContext context)</code></li>
  * </ul>
  * for which a corresponding configuration would exist:
  * 
@@ -65,9 +58,9 @@
  *          
dispatcher=&quot;org.apache.struts.dispatcher.servlet.ServletMappingDispatcher&quot;
  *          parameter=&quot;delete&quot;
  *          name=&quot;subscriptionForm&quot;
- *          scope=&quot;request&quot;
- *          input=&quot;/subscription.jsp&quot;&gt;
+ *          scope=&quot;request&quot;&gt;
  *      &lt;forward path=&quot;/deletedSubscription.jsp&quot;/&gt;
+ *      &lt;forward name=&quot;input&quot; path=&quot;/subscription.jsp&quot;
  *  &lt;/action&gt;
  * 
  *  &lt;action path=&quot;/editSubscription&quot;
@@ -90,9 +83,9 @@
  *          parameter=&quot;save&quot;
  *          name=&quot;subscriptionForm&quot;
  *          scope=&quot;request&quot;
- *          validate=&quot;true&quot;
- *          input=&quot;/editSubscription.jsp&quot;&gt;
+ *          validate=&quot;true&quot;&gt;
  *      &lt;forward path=&quot;/savedSubscription.jsp&quot;/&gt;
+ *      &lt;forward name=&quot;input&quot; 
path=&quot;/editSubscription.jsp&quot;
  *  &lt;/action&gt;
  * </code></pre>
  * 
@@ -103,12 +96,11 @@
 
     private static final long serialVersionUID = 1L;
 
-    protected Object[] buildMethodArguments(ActionContext context, Method 
method) {
-       return 
ServletDispatchUtils.buildClassicExecuteArguments((ServletActionContext) 
context);
-    }
-
-    protected Method resolveMethod(ActionContext context, String methodName) 
throws NoSuchMethodException {
-       return ServletDispatchUtils.resolveClassicExecuteMethod(context, 
methodName);
+    /**
+     * Constructs a new servlet mapping dispatcher.
+     */
+    public ServletMappingDispatcher() {
+        super(new ServletMethodResolver());
     }
 
     /**
@@ -117,9 +109,9 @@
      * @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);
-       return null;
+        HttpServletResponse response = ((ServletActionContext) 
context).getResponse();
+        response.sendError(HttpServletResponse.SC_NOT_FOUND);
+        return null;
     }
 
 }

Added: 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMethodResolver.java
URL: 
http://svn.apache.org/viewvc/struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMethodResolver.java?rev=729832&view=auto
==============================================================================
--- 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMethodResolver.java
 (added)
+++ 
struts/struts1/trunk/core/src/main/java/org/apache/struts/dispatcher/servlet/ServletMethodResolver.java
 Sun Dec 28 21:12:58 2008
@@ -0,0 +1,132 @@
+/*
+ * $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.dispatcher.servlet;
+
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.chain.contexts.ActionContext;
+import org.apache.struts.chain.contexts.ServletActionContext;
+import org.apache.struts.config.ActionConfig;
+import org.apache.struts.dispatcher.AbstractMethodResolver;
+
+import java.lang.reflect.Method;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * This class helps resolve methods with servlet-based signatures. The 
following
+ * examples illustrate the method signatures supported:
+ * <ul>
+ * <li><code><i>return_type</i> execute()</code></li>
+ * <li><code><i>return_type</i> execute(ActionContext context)</code></li>
+ * <li><code><i>return_type</i> execute(ServletActionContext 
context)</code></li>
+ * <li><code><i>return_type</i> execute(ActionMapping mapping, ActionForm form,
+ HttpServletRequest request, HttpServletResponse response)</code></li>
+ * </ul>
+ * 
+ * @version $Rev$
+ * @since Struts 1.4
+ */
+public class ServletMethodResolver extends AbstractMethodResolver {
+
+    /**
+     * The set of argument type classes for the classic reflected method call.
+     * These are the same for all calls, so calculate them only once.
+     * 
+     * @see org.apache.struts.action.Action#execute(ActionMapping, ActionForm,
+     *      javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    private static final Class[] CLASSIC_EXECUTE_SIGNATURE = { 
ActionMapping.class, ActionForm.class,
+            HttpServletRequest.class, HttpServletResponse.class };
+
+    public Object[] buildArguments(ActionContext context, Method method) {
+        Object[] args = super.buildArguments(context, method);
+        if (args == null) {
+            Class[] parameterTypes = method.getParameterTypes();
+            switch (parameterTypes.length) {
+            case 4:
+                return buildClassicArguments((ServletActionContext) context);
+            default:
+                break;
+            }
+        }
+        return args;
+    }
+
+    /**
+     * Constructs the arguments to invoke the classic <code>execute</code>
+     * servlet signature from the specified context.
+     * 
+     * @param context the current context
+     * @return the arguments array
+     * @throws NullPointerException if context is <code>null</code>
+     * @see #resolveClassicMethod(ActionContext, String)
+     */
+    protected final Object[] buildClassicArguments(ServletActionContext 
context) {
+        ActionConfig mapping = context.getActionConfig();
+        ActionForm form = context.getActionForm();
+        HttpServletRequest request = context.getRequest();
+        HttpServletResponse response = context.getResponse();
+        return new Object[] { mapping, form, request, response };
+    }
+
+    /**
+     * Obtains the method instance with the classic <code>execute</code>
+     * servlet signature.
+     * 
+     * @param context the current context
+     * @param methodName the method name to introspect
+     * @return the found method in the action
+     * @throws NullPointerException if context is <code>null</code>
+     * @throws NoSuchMethodException if the method does not exist
+     * @see #buildClassicArguments(ServletActionContext)
+     * @see org.apache.struts.action.Action#execute(ActionMapping, ActionForm,
+     *      javax.servlet.ServletRequest, javax.servlet.ServletResponse)
+     */
+    protected final Method resolveClassicMethod(ActionContext context, String 
methodName) throws NoSuchMethodException {
+        Class actionClass = context.getAction().getClass();
+        return actionClass.getMethod(methodName, CLASSIC_EXECUTE_SIGNATURE);
+    }
+
+    public Method resolveMethod(ActionContext context, String methodName) 
throws NoSuchMethodException {
+        // First try to resolve anything the superclass supports
+        try {
+            return super.resolveMethod(context, methodName);
+        } catch (NoSuchMethodException e) {
+            // continue
+        }
+
+        // Can the method accept the servlet action context?
+        if (context instanceof ServletActionContext) {
+            try {
+                Class actionClass = context.getAction().getClass();
+                return actionClass.getDeclaredMethod(methodName, new Class[] { 
ServletActionContext.class });
+            } catch (NoSuchMethodException e) {
+                // continue
+            }
+        }
+
+        // Lastly, try the classical argument listing
+        return resolveClassicMethod(context, methodName);
+    }
+
+}

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

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

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=729832&r1=729831&r2=729832&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
 Sun Dec 28 21:12:58 2008
@@ -20,13 +20,10 @@
  */
 package org.apache.struts.dispatcher.servlet;
 
-import org.apache.struts.action.Action;
 import org.apache.struts.chain.contexts.ActionContext;
 import org.apache.struts.chain.contexts.ServletActionContext;
 import org.apache.struts.dispatcher.AbstractParameterDispatcher;
 
-import java.lang.reflect.Method;
-
 import javax.servlet.http.HttpServletResponse;
 
 /**
@@ -49,20 +46,14 @@
  * </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
- * {...@link 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:
+ * pick the appropriate 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>
+ * <li><code>public void insert(ActionContext context)</code></li>
+ * <li><code>public void update(ServletActionContext context)</code></li>
  * </ul>
  * and call one of the methods with a URL like this:
  * <p>
@@ -75,12 +66,11 @@
 
     private static final long serialVersionUID = 1L;
 
-    protected Object[] buildMethodArguments(ActionContext context, Method 
method) {
-       return 
ServletDispatchUtils.buildClassicExecuteArguments((ServletActionContext) 
context);
-    }
-
-    protected Method resolveMethod(ActionContext context, String methodName) 
throws NoSuchMethodException {
-       return ServletDispatchUtils.resolveClassicExecuteMethod(context, 
methodName);
+    /**
+     * Constructs a new servlet parameter dispatcher.
+     */
+    public ServletParameterDispatcher() {
+        super(new ServletMethodResolver());
     }
 
     /**
@@ -91,8 +81,8 @@
      * @return the servlet parameter value
      */
     protected String resolveParameterValue(ActionContext context, String 
parameter) {
-       ServletActionContext servletContext = (ServletActionContext) context;
-       return (String) servletContext.getParam().get(parameter);
+        ServletActionContext servletContext = (ServletActionContext) context;
+        return (String) servletContext.getParam().get(parameter);
     }
 
     /**
@@ -103,9 +93,9 @@
      * @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);
-       return null;
+        HttpServletResponse response = ((ServletActionContext) 
context).getResponse();
+        response.sendError(HttpServletResponse.SC_NOT_FOUND);
+        return null;
     }
 
 }


Reply via email to