package com.crackwillow.struts.util.dispatch;
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;
import com.crackwillow.log.StdOut;
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 {
StdOut.log("log.button","ENTRY");
String methodName = getMethodName(request,mapping);
StdOut.log("log.button","methodName = " + methodName);
Class clazz = action.getClass();
if ("execute".equals(methodName) || "perform".equals(methodName)){
// Prevent recursive calls
String message = messages.getMessage("dispatch.recursive", mapping.getPath());
log.error(message);
throw new ServletException(message);
}
((com.crackwillow.struts.form.LogonDispatchUtilForm)form).setMethodCalled(methodName);
return dispatchMethod(action,clazz,mapping, form, request, response, methodName);
}
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 paramProperty = mapping.getParameter();
if((paramProperty != null && paramProperty.indexOf('.') != -1)) {
methodName = paramProperty;
} 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(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);
}
}