Date: 2004-09-16T17:35:52
   Editor: MichaelMcGrady <[EMAIL PROTECTED]>
   Wiki: Apache Struts Wiki
   Page: StrutsCatalogSimpleDispatchAction
   URL: http://wiki.apache.org/struts/StrutsCatalogSimpleDispatchAction

   no comment

Change Log:

------------------------------------------------------------------------------
@@ -179,9 +179,143 @@
 
 '''Michael !McGrady'''
 
+'''Following a suggestion of Hubert Rabago, I have constructed a utility class 
!DispatchUtil so that you can get the same result by using'''
+{{{
+return new !DispatchUtil.dispatch(this,mapping,form,request,response);
+}}}
+'''in your action execute class, and, of course, providing the related actions.  That 
class follows.  Hubert is talking about putting something into !RequestUtils for 
struts that does the same thing.  Importantly, you can jettison all of 
!DispatchAction, !LookupDispatchAction and !MappingDispatchAction if you use this.  
You will have to change your action mapping struts-config.xml file for 
!MappingDispatchAction (you can get rid of those multiple entries and just use one) 
and will have to add .x where required in your submit, link and file buttons.'''
+
+{{{
+public class DispatchUtil {
+  protected static    Log              log      = 
LogFactory.getLog(DispatchUtil.class);
+  protected static    MessageResources messages = 
MessageResources.getMessageResources ("org.apache.struts.actions.LocalStrings");
+  protected           HashMap          methods  = new HashMap();
+  protected           Class[]          types    = { ActionMapping.class,
+                                                    ActionForm.class,          
+                                                    HttpServletRequest.class,
+                                                    HttpServletResponse.class };
+  public ActionForward dispatch(Action action,
+                                ActionMapping mapping,
+                                ActionForm form,
+                                HttpServletRequest request,
+                                HttpServletResponse response)
+      throws Exception {
+    Class  clazz    = action.getClass();
+    String name = getMethodName(request,mapping);
+      if ("execute".equals(name) || "perform".equals(name)){
+        // Prevent recursive calls
+        String message = messages.getMessage("dispatch.recursive", mapping.getPath());
+        log.error(message);
+        throw new ServletException(message);
+      }
+      return dispatchMethod(action,clazz,mapping, form, request, response, name);
+    }
+
+  protected ActionForward dispatchMethod(Action action,
+                                         Class clazz,
+                                         ActionMapping mapping,
+                                         ActionForm form,
+                                         HttpServletRequest request,
+                                         HttpServletResponse response,
+                                         String name)
+      throws Exception {
+    if (name == null) {
+      return this.unspecified(mapping, form, request, response);
+    }
+    Method method = null;
+    try {
+      method = getMethod(clazz,name);
+    } catch(NoSuchMethodException nsme) {
+      String message = messages.getMessage("dispatch.method", mapping.getPath(), 
name);
+      log.error(message, nsme);
+      throw nsme;
+    }
+
+    ActionForward forward = null;
+
+    try {
+      Object args[] = {mapping, form, request, response};
+      forward = (ActionForward) method.invoke(action, args);
+    } catch(ClassCastException cce) {
+      String message = messages.getMessage("dispatch.return", mapping.getPath(), 
name);
+      log.error(message, cce);
+      throw cce;
+    } catch(IllegalAccessException iae) {
+      String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
+      log.error(message, iae);
+      throw iae;
+    } catch(InvocationTargetException ite) {
+      Throwable t = ite.getTargetException();
+
+      if (t instanceof Exception) {
+        throw ((Exception) t);
+      } else {
+        String message = messages.getMessage("dispatch.error", mapping.getPath(), 
name);
+        log.error(message, ite);
+        throw new ServletException(t);
+      }
+    }
+    return (forward);
+  }
+
+  protected static String getMethodName(HttpServletRequest request,  ActionMapping 
mapping) {
+                                       String methodName  = null;
+                                       String buttonValue = null;
+                                       String parameter   = mapping.getParameter();
+    if((parameter != null) && (parameter.endsWith(".x"))) {
+      methodName = parameter.substring(0,parameter.indexOf('.'));
+    } else {
+      Enumeration enum = request.getParameterNames();
+      while(enum.hasMoreElements()) {
+        buttonValue = (String)enum.nextElement();
+        if(buttonValue.endsWith(".x")) {
+          methodName = buttonValue.substring(0,buttonValue.indexOf(".x"));
+        }
+      }
+    }
+    return methodName;
+  }
+
+  protected Method getMethod(Class clazz,String name)
+      throws NoSuchMethodException {
+    synchronized(methods) {
+      Method method = (Method) methods.get(name);
+
+      if (method == null) {
+        method = clazz.getMethod(name, types);
+        methods.put(name, method);
+      }
+
+      return (method);
+    }
+  }
+
+  protected ActionForward unspecified(ActionMapping mapping,                   
+                                      ActionForm form,
+                                      HttpServletRequest request,
+                                     HttpServletResponse response)
+     throws Exception {
+    String message = messages.getMessage( "dispatch.parameter", mapping.getPath(), 
getMethodName(request,mapping));
+    log.error(message);
+    throw new ServletException(message);
+  }
+
+  protected ActionForward cancelled(ActionMapping mapping,                            
                 
+                                    ActionForm form,
+                                    HttpServletRequest request,
+                                    HttpServletResponse response)
+      throws Exception {
+   return null;
+  }
+}
+}}}
+
 ----
 
-Seems to me that most of the SimpleDispatchAction duplicates whats already in the 
DispatchAction class. If we re-factored DispatchAction so that the parameter retrieval 
was moved into a new getParameter() method then all that would be needed to achieve 
what you want is a flavour that overrides the getParameter()/getMethodName() methods.
+Seems to me that most of the !SimpleDispatchAction duplicates whats already in the 
!DispatchAction class. If we re-factored !DispatchAction so that the parameter 
retrieval was moved into a new getParameter() method then all that would be needed to 
achieve what you want is a flavour that overrides the getParameter()/getMethodName() 
methods.
+
+
+
 
 Something along the lines of ...
 
@@ -222,4 +356,9 @@
 }}}
 
 '''Niall Pemberton'''
+
+'''Thanks, Niall, HOWEVER -------
+This is fundametally mistaken, Niall, and rests on an important misconception.  The 
data and the logic of !SimpleDispatchAction differ from all of !DispatchAction, 
!LookupDispatchAction, and !MappingDispatchAction.  The error here is thinking that 
just because they all get the name of the method to call that anything else is just a 
mere difference in internal logic.  That is not the case.  Using one instead of the 
other will break the code in lots of ways, and there are huge diffences between these 
classes.  None of the data used for the struts existing dispatch classes is used to 
determine the method in the !SimpleDispatchAction.'''
+
+''Michael !McGrady'''
 

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

Reply via email to