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.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 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());
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);
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);
throw cce;
} catch(IllegalAccessException iae) {
String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
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);
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();
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));
throw new ServletException(message);
}
protected ActionForward cancelled(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
return null;
}
}