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]