Date: 2004-09-19T07:44:30
   Editor: MichaelMcGrady <[EMAIL PROTECTED]>
   Wiki: Apache Struts Wiki
   Page: StrutsCatalogDispatchUtil
   URL: http://wiki.apache.org/struts/StrutsCatalogDispatchUtil

   no comment

Change Log:

------------------------------------------------------------------------------
@@ -27,9 +27,10 @@
 }}}
 == Universal Button Utility for Struts ==
 
-There is a persistent problem of handling multiple buttons, and this is especially a 
problem when the buttons are images.  Struts has provided a solution for this with 
DispatchAction and its progeny.  There are various other solutions.  I have provided 
one at StrutsCatalogImageTagUtil.  I have actually provided two solutions there. The 
following solution is, I think, superior in every way.  What it does is to merge the 
best parts of StrutsCataglogImageTagUtil and DispatchAction.  
+There is a persistent problem of handling multiple buttons, and this is especially a 
problem when the buttons are images.  Struts has provided a solution for this with 
DispatchAction and its progeny.  There are various other solutions.  I have provided 
one at StrutsCatalogImageTagUtil.  I have actually provided two solutions there. The 
following solution is, I think, superior in every way.  What it does is to merge the 
best parts of StrutsCataglogImageTagUtil and DispatchAction.  I would not recommend 
putting this sort of class into Struts.  Others might improve on this.  I expect they 
will.  Putting classes like this into Struts creates bloat that is difficult to 
jettison when improvements are found.  I really appreciate the functionality of such 
classes as DispatchAction, LookupDispatchAction and MappingDispatchAction, but 
actually putting them into Struts would be akin, I think, to Sun putting its tutorials 
into the actual code of Java.  
 
-This is a solution for Struts.  If you want a solution independent of Struts, again, 
please see StrutsCatalogImageTagUtil.  The principle reason for this class is the 
problem with <input type='image' name='whatever'> tags in HTML.  Those tag send the 
values in the name attribute as ''whatever.x=9'' and ''whatever.y=26''.  
DispatchAction and its progeny provide a melange of solutions but no common way to 
deal with ''<a href='whatever.do'>'', ''<input type='submit'>'', ''<input 
type='image'>'', ''<input type='file'>'', or whatever.  This class, DispatchUtil does 
that.  If you prefer to use a subclass, just provide the functionality in this class 
in a class extending Action.  Herbert Rabago came up with the idea of providing the 
functionality in a utility class and I really like that idea.  So, here we go.
+
+The principle reason for this class is the problem with <input type='image' 
name='whatever'> tags in HTML.  Those tag send the values in the name attribute as 
''whatever.x=9'' and ''whatever.y=26''.  DispatchAction and its progeny provide a 
melange of solutions but no common way to deal with ''<a href='whatever.do'>'', 
''<input type='submit'>'', ''<input type='image'>'', ''<input type='file'>'', or 
whatever.  This class, DispatchUtil does that.  If you prefer to use a subclass, just 
provide the functionality in this class in a class extending Action.  Herbert Rabago 
came up with the idea of providing the functionality in a utility class and I really 
like that idea.  So, here we go.
 
 == Uses ==
 
@@ -261,11 +262,164 @@
 }
 }}} 
 
-== SimpleDispatchAction ==
+== (new) DispatchAction ==
 
 === Discussion ===
 
+If, rather than having a utility class provide the functionality, you prefer an 
Action class.  Here is a redoing of the DispatchAction class to let you do that.  You 
use this class for '''ALL''' the progeny of DispatchAction class, i.e. this class 
replaces completely DispatchAction, LookupDispatchAction, and MappingDispatchAction.  
You can alter this class to get whatever subsidiary functionality you might want and 
which some might consider essential.
+
 === Code ===
+package com.crackwillow.struts.action;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.HashMap;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.util.MessageResources;
+
+public abstract class DispatchAction
+    extends Action {
+  protected           Class            clazz    = this.getClass();
+  protected static    Log              log      = 
LogFactory.getLog(SimpleDispatchAction.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 execute(ActionMapping mapping,
+                               ActionForm form,
+                               HttpServletRequest request,
+                               HttpServletResponse response)
+      throws Exception {
+    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(mapping, form, request, response, name);
+  }
+
+  protected ActionForward dispatchMethod(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(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(this, 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 paramProperty = mapping.getParameter();
+    if((paramProperty != null)) {
+      methodName = paramProperty.substring(0,paramProperty.indexOf('.'));
+    } else {
+      Enumeration enum = request.getParameterNames();
+      while(enum.hasMoreElements()) {
+        buttonValue = (String)enum.nextElement();
+        StdOut.log("log.dispatch","DispatchUtil buttonValue = " + buttonValue);
+        if(buttonValue.indexOf(".dispatch") >= 0) {
+          methodName = buttonValue;
+          break;
+        }
+      }
+    }
+    return methodName.substring(0,methodName.indexOf('.'));
+  }
+
+  protected Method getMethod(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;
+  }
+}
+}}}
 
 == Solution for Tags without Struts ==
 

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

Reply via email to