rleland     2003/08/12 21:53:43

  Modified:    src/share/org/apache/struts/actions DispatchAction.java
                        LocalStrings.properties LookupDispatchAction.java
  Log:
  Bug 18002 Enhancement patches provided -TWICE-- by Leonardo Quijano
  
  This adds a 'default' and a 'cancel' handler to the DispatchAction and 
LookupDispatchAction
  
  DispatchAction - added a new method getMethodName for refactoring, added cancel
  handler (default is to throw an exception).
  LookupDispatchAction - general refactoring, a more accurate error reporting
  (this action's error are a little bit too mysterious)
  LocalStrings.properties - new error messages for LookupDispatchAction, added
  some quotes - making error identification easier.
  
  Revision  Changes    Path
  1.17      +113 -57   
jakarta-struts/src/share/org/apache/struts/actions/DispatchAction.java
  
  Index: DispatchAction.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/actions/DispatchAction.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- DispatchAction.java       11 Jul 2003 23:47:57 -0000      1.16
  +++ DispatchAction.java       13 Aug 2003 04:53:43 -0000      1.17
  @@ -123,9 +123,17 @@
    * constraints over what types of handlers may reasonably be packaged into
    * the same <code>DispatchAction</code> subclass.</p>
    *
  + * <p><strong>NOTE</strong> - If the value of the request parameter is empty,
  + * a method named <code>unspecified</code> is called. The default action is
  + * to throw an exception. If the request was cancelled (a <code>html:cancel</code>
  + * button was pressed), the custom handler <code>cancelled</code> will be used 
instead.
  + * You can also override the <code>getMethodName</code> method to override the 
action's
  + * default handler selection.</p>
  + *
    * @author Niall Pemberton <[EMAIL PROTECTED]>
    * @author Craig R. McClanahan
    * @author Ted Husted
  + * @author Leonardo Quijano
    * @version $Revision$ $Date$
    */
   public abstract class DispatchAction extends Action {
  @@ -150,8 +158,8 @@
        * The message resources for this package.
        */
       protected static MessageResources messages =
  -     MessageResources.getMessageResources
  -        ("org.apache.struts.actions.LocalStrings");
  +            MessageResources.getMessageResources
  +            ("org.apache.struts.actions.LocalStrings");
   
   
       /**
  @@ -168,11 +176,11 @@
        * are the same for all calls, so calculate them only once.
        */
       protected Class[] types =
  -        {
  -            ActionMapping.class,
  -            ActionForm.class,
  -            HttpServletRequest.class,
  -            HttpServletResponse.class };
  +            {
  +                ActionMapping.class,
  +                ActionForm.class,
  +                HttpServletRequest.class,
  +                HttpServletResponse.class};
   
   
   
  @@ -197,25 +205,28 @@
                                    ActionForm form,
                                    HttpServletRequest request,
                                    HttpServletResponse response)
  -        throws Exception {
  +            throws Exception {
   
  -        // Identify the request parameter containing the method name
  -        String parameter = mapping.getParameter();
  -        if (parameter == null) {
  -            String message =
  -                messages.getMessage("dispatch.handler", mapping.getPath());
  -                
  -            log.error(message);
  -            
  -            throw new ServletException(message);
  -        }
  +        if (isCancelled(request)) {
  +            return cancelled(mapping, form, request, response);
  +        } else {
  +            // Identify the request parameter containing the method name
  +            String parameter = mapping.getParameter();
  +            if (parameter == null) {
  +                String message =
  +                        messages.getMessage("dispatch.handler", mapping.getPath());
   
  -        // Identify the method name to be dispatched to.
  -        // dispatchMethod() will call unspecified() if name is null
  -        String name = request.getParameter(parameter);
  +                log.error(message);
   
  -        // Invoke the named method, and return the result
  -        return dispatchMethod(mapping, form, request, response, name);
  +                throw new ServletException(message);
  +            }
  +
  +            // Get the method's name. This could be overridden in subclasses.
  +            String name = getMethodName(mapping, form, request, response, 
parameter);
  +
  +            // Invoke the named method, and return the result
  +            return dispatchMethod(mapping, form, request, response, name);
  +        }
       }
   
   
  @@ -226,23 +237,46 @@
        * to provide default behavior different than throwing a ServletException.
        */
       protected ActionForward unspecified(
  -        ActionMapping mapping,
  -        ActionForm form,
  -        HttpServletRequest request,
  -        HttpServletResponse response)
  -        throws Exception {
  +            ActionMapping mapping,
  +            ActionForm form,
  +            HttpServletRequest request,
  +            HttpServletResponse response)
  +            throws Exception {
   
           String message =
  -            messages.getMessage(
  -                "dispatch.parameter",
  -                mapping.getPath(),
  -                mapping.getParameter());
  +                messages.getMessage(
  +                        "dispatch.parameter",
  +                        mapping.getPath(),
  +                        mapping.getParameter());
   
           log.error(message);
   
           throw new ServletException(message);
       }
   
  +    /**
  +     * Method which is dispatched to when the request is a cancel button submit.
  +     * Subclasses of <code>DispatchAction</code> should override this method if
  +     * they wish to provide default behavior different than throwing a
  +     * ServletException.
  +     *
  +     */
  +    protected ActionForward cancelled(ActionMapping mapping,
  +                                      ActionForm form,
  +                                      HttpServletRequest request,
  +                                      HttpServletResponse response)
  +            throws Exception {
  +
  +        String message =
  +                messages.getMessage(
  +                        "dispatch.cancelled",
  +                        mapping.getPath(),
  +                        mapping.getParameter());
  +
  +        log.error(message);
  +
  +        throw new ServletException(message);
  +    }
   
       // ----------------------------------------------------- Protected Methods
   
  @@ -251,12 +285,12 @@
        * Dispatch to the specified method.
        * @since Struts 1.1
        */
  -     protected ActionForward dispatchMethod(ActionMapping mapping,
  -                                            ActionForm form,
  -                                            HttpServletRequest request,
  -                                            HttpServletResponse response,
  -                                            String name) throws Exception {
  -                                                
  +    protected ActionForward dispatchMethod(ActionMapping mapping,
  +                                           ActionForm form,
  +                                           HttpServletRequest request,
  +                                           HttpServletResponse response,
  +                                           String name) throws Exception {
  +
           // Make sure we have a valid method name to call.
           // This may be null if the user hacks the query string.
           if (name == null) {
  @@ -267,32 +301,32 @@
           Method method = null;
           try {
               method = getMethod(name);
  -            
  -        } catch (NoSuchMethodException e) {
  +
  +        } catch(NoSuchMethodException e) {
               String message =
  -                messages.getMessage("dispatch.method", mapping.getPath(), name);
  +                    messages.getMessage("dispatch.method", mapping.getPath(), name);
               log.error(message, e);
               throw e;
           }
   
           ActionForward forward = null;
           try {
  -            Object args[] = { mapping, form, request, response };
  +            Object args[] = {mapping, form, request, response};
               forward = (ActionForward) method.invoke(this, args);
  -            
  -        } catch (ClassCastException e) {
  +
  +        } catch(ClassCastException e) {
               String message =
  -                messages.getMessage("dispatch.return", mapping.getPath(), name);    
            
  +                    messages.getMessage("dispatch.return", mapping.getPath(), name);
               log.error(message, e);
               throw e;
  -            
  -        } catch (IllegalAccessException e) {
  +
  +        } catch(IllegalAccessException e) {
               String message =
  -                messages.getMessage("dispatch.error", mapping.getPath(), name);
  +                    messages.getMessage("dispatch.error", mapping.getPath(), name);
               log.error(message, e);
               throw e;
  -            
  -        } catch (InvocationTargetException e) {
  +
  +        } catch(InvocationTargetException e) {
               // Rethrow the target exception if possible so that the
               // exception handling machinery can deal with it
               Throwable t = e.getTargetException();
  @@ -300,7 +334,7 @@
                   throw ((Exception) t);
               } else {
                   String message =
  -                    messages.getMessage("dispatch.error", mapping.getPath(), name);
  +                        messages.getMessage("dispatch.error", mapping.getPath(), 
name);
                   log.error(message, e);
                   throw new ServletException(t);
               }
  @@ -321,9 +355,9 @@
        * @exception NoSuchMethodException if no such method can be found
        */
       protected Method getMethod(String name)
  -        throws NoSuchMethodException {
  +            throws NoSuchMethodException {
   
  -        synchronized (methods) {
  +        synchronized(methods) {
               Method method = (Method) methods.get(name);
               if (method == null) {
                   method = clazz.getMethod(name, types);
  @@ -334,5 +368,27 @@
   
       }
   
  +    /**
  +     * Returns the method name, given a parameter's value.
  +     *
  +     * @param mapping The ActionMapping used to select this instance
  +     * @param form The optional ActionForm bean for this request (if any)
  +     * @param request The HTTP request we are processing
  +     * @param response The HTTP response we are creating
  +     * @param parameter The <code>ActionMapping</code> parameter's name
  +     *
  +     * @return The method's name.
  +     */
  +    protected String getMethodName(ActionMapping mapping,
  +                                   ActionForm form,
  +                                   HttpServletRequest request,
  +                                   HttpServletResponse response,
  +                                   String parameter)
  +            throws Exception {
  +
  +        // Identify the method name to be dispatched to.
  +        // dispatchMethod() will call unspecified() if name is null
  +        return request.getParameter(parameter);
  +    }
   
   }
  
  
  
  1.8       +10 -7     
jakarta-struts/src/share/org/apache/struts/actions/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/actions/LocalStrings.properties,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- LocalStrings.properties   12 Aug 2003 03:26:53 -0000      1.7
  +++ LocalStrings.properties   13 Aug 2003 04:53:43 -0000      1.8
  @@ -1,14 +1,17 @@
  -dispatch.error=Dispatch[{0}] to method {1} returned an exception
  +dispatch.cancelled=Action[{0}] does not contain a cancel handler
  +dispatch.error=Dispatch[{0}] to method '{1}' returned an exception
   dispatch.handler=DispatchMapping[{0}] does not define a handler property
  +dispatch.lookup=Action[{0}] does not contain handler for resource '{1}'
   dispatch.mapping=ActionMapping[{0}] is not of type DispatchMapping
  -dispatch.method=Action[{0}] does not contain method named {1}
  -dispatch.parameter=Request[{0}] does not contain handler parameter named {1}.  This 
may be caused by whitespace in the label text.
  -dispatch.return=Action[{0}] invalid return type for method {1}
  +dispatch.method=Action[{0}] does not contain method named '{1}'
  +dispatch.parameter=Request[{0}] does not contain handler parameter named '{1}'.  
This may be caused by whitespace in the label text.
  +dispatch.return=Action[{0}] invalid return type for method '{1}'
  +dispatch.resource=Action[{0}] missing resource '{1}' in key method map
   forward.path=No context-relative URI specified via the 'parameter' attribute
  -forward.rd=Cannot create request dispatcher for path {0}
  +forward.rd=Cannot create request dispatcher for path '{0}'
   include.path=No context-relative URI specified via the 'parameter' attribute
  -include.rd=Cannot create request dispatcher for path {0}
  -switch.prefix=Invalid module prefix {0} was specified
  +include.rd=Cannot create request dispatcher for path '{0}'
  +switch.prefix=Invalid module prefix '{0}' was specified
   switch.required=Switch requires both 'prefix' and 'page' request parameters
   success.required=SuccessAction could not find an ActionForward named 'success' for 
path '{0}'
   mapping.parameter=ActionMapping[{0}] does not define a 'parameter' attribute
  
  
  
  1.13      +87 -44    
jakarta-struts/src/share/org/apache/struts/actions/LookupDispatchAction.java
  
  Index: LookupDispatchAction.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/actions/LookupDispatchAction.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- LookupDispatchAction.java 3 Jul 2003 02:42:58 -0000       1.12
  +++ LookupDispatchAction.java 13 Aug 2003 04:53:43 -0000      1.13
  @@ -2,7 +2,7 @@
    * $Header$
    * $Revision$
    * $Date$
  - * 
  + *
    *  ====================================================================
    *
    *  The Apache Software License, Version 1.1
  @@ -69,6 +69,7 @@
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
   
  +import org.apache.commons.lang.StringUtils;
   import org.apache.struts.Globals;
   import org.apache.struts.action.ActionForm;
   import org.apache.struts.action.ActionForward;
  @@ -143,11 +144,15 @@
    *
    *  <strong>Notes</strong> - If duplicate values exist for the keys returned by
    *  getKeys, only the first one found will be returned. If no corresponding key
  - *  is found then an exception will be thrown.
  + *  is found then an exception will be thrown. You can override the
  + *  method <code>unspecified</code> to provide a custom handler. If the submit
  + *  was cancelled (a <code>html:cancel</code> button was pressed), the custom
  + *  handler <code>cancelled</code> will be used instead.
    *
    * @author Erik Hatcher
    * @author Scott Carlson
    * @author David Graham
  + * @author Leonardo Quijano
    */
   public abstract class LookupDispatchAction extends DispatchAction {
   
  @@ -178,46 +183,27 @@
        * @exception Exception if an error occurs
        */
       public ActionForward execute(
  -        ActionMapping mapping,
  -        ActionForm form,
  -        HttpServletRequest request,
  -        HttpServletResponse response)
  -        throws Exception {
  -
  -        // Identify the request parameter containing the method name
  -        String parameter = mapping.getParameter();
  -        if (parameter == null) {
  -            String message = messages.getMessage("dispatch.handler", 
mapping.getPath());
  -            throw new ServletException(message);
  -        }
  -
  -        // Identify the string to lookup
  -        String name = request.getParameter(parameter);
  -        if (name == null) {
  -            String message =
  -                messages.getMessage("dispatch.parameter", mapping.getPath(), 
parameter);
  -            throw new ServletException(message);
  -        }
  -
  -        // Based on this request's Locale get the lookupMap
  -        Map lookupMap = null;
  -        
  -        synchronized (localeMap) {
  -            Locale userLocale = this.getLocale(request);
  -            lookupMap = (Map) this.localeMap.get(userLocale);
  -            
  -            if (lookupMap == null) {
  -                lookupMap = this.initLookupMap(request, userLocale);
  -                this.localeMap.put(userLocale, lookupMap);
  +            ActionMapping mapping,
  +            ActionForm form,
  +            HttpServletRequest request,
  +            HttpServletResponse response)
  +            throws Exception {
  +
  +        if (isCancelled(request)) {
  +            return cancelled(mapping, form, request, response);
  +        } else {
  +            // Identify the request parameter containing the method name
  +            String parameter = mapping.getParameter();
  +            if (parameter == null) {
  +                String message = messages.getMessage("dispatch.handler", 
mapping.getPath());
  +                throw new ServletException(message);
               }
  -        }
  -
  -        // Find the key
  -        String key = (String) lookupMap.get(name);
   
  -        String methodName = (String) keyMethodMap.get(key);
  +            // Identify the string to lookup
  +            String methodName = getMethodName(mapping, form, request, response, 
parameter);
   
  -        return this.dispatchMethod(mapping, form, request, response, methodName);
  +            return dispatchMethod(mapping, form, request, response, methodName);
  +        }
       }
   
       /**
  @@ -230,7 +216,7 @@
           this.keyMethodMap = this.getKeyMethodMap();
   
           ModuleConfig moduleConfig =
  -            (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);
  +                (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);
   
           MessageResourcesConfig[] mrc = moduleConfig.findMessageResourcesConfigs();
   
  @@ -250,7 +236,7 @@
                   }
               }
           }
  -        
  +
           return lookupMap;
       }
   
  @@ -260,5 +246,62 @@
        * @return Resource key / method name map.
        */
       protected abstract Map getKeyMethodMap();
  +
  +    /**
  +     * Returns the method name, given a parameter's value.
  +     *
  +     * @param mapping The ActionMapping used to select this instance
  +     * @param form The optional ActionForm bean for this request (if any)
  +     * @param request The HTTP request we are processing
  +     * @param response The HTTP response we are creating
  +     * @param parameter The <code>ActionMapping</code> parameter's name
  +     *
  +     * @return The method's name.
  +     */
  +    protected String getMethodName(ActionMapping mapping,
  +                                   ActionForm form,
  +                                   HttpServletRequest request,
  +                                   HttpServletResponse response,
  +                                   String parameter)
  +            throws Exception {
  +
  +        // Identify the method name to be dispatched to.
  +        // dispatchMethod() will call unspecified() if name is null
  +        String keyName = request.getParameter(parameter);
  +        if (StringUtils.isEmpty(keyName)) {
  +            return null;
  +        }
  +
  +        // Based on this request's Locale get the lookupMap
  +        Map lookupMap = null;
  +
  +        synchronized(localeMap) {
  +            Locale userLocale = this.getLocale(request);
  +            lookupMap = (Map) this.localeMap.get(userLocale);
  +
  +            if (lookupMap == null) {
  +                lookupMap = this.initLookupMap(request, userLocale);
  +                this.localeMap.put(userLocale, lookupMap);
  +            }
  +        }
  +
  +        // Find the key for the resource
  +        String key = (String) lookupMap.get(keyName);
  +        if (key == null) {
  +            String message = messages.getMessage(
  +                    "dispatch.resource", mapping.getPath(), keyName);
  +            throw new ServletException(message);
  +        }
  +
  +        // Find the method name
  +        String methodName = (String) keyMethodMap.get(key);
  +        if (methodName == null) {
  +            String message = messages.getMessage(
  +                    "dispatch.lookup", mapping.getPath(), key);
  +            throw new ServletException(message);
  +        }
  +
  +        return methodName;
  +    }
   
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to