rleland 2003/08/12 21:53:43
Modified: src/share/org/apache/struts/actions DispatchAction.java
LocalStrings.properties LookupDispatchAction.java
Log:
Bug 18002 Enhancement patches provided -TWICE-- by Leonardo Quijano
This adds a 'default' and a 'cancel' handler to the DispatchAction and
LookupDispatchAction
DispatchAction - added a new method getMethodName for refactoring, added cancel
handler (default is to throw an exception).
LookupDispatchAction - general refactoring, a more accurate error reporting
(this action's error are a little bit too mysterious)
LocalStrings.properties - new error messages for LookupDispatchAction, added
some quotes - making error identification easier.
Revision Changes Path
1.17 +113 -57
jakarta-struts/src/share/org/apache/struts/actions/DispatchAction.java
Index: DispatchAction.java
===================================================================
RCS file:
/home/cvs/jakarta-struts/src/share/org/apache/struts/actions/DispatchAction.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- DispatchAction.java 11 Jul 2003 23:47:57 -0000 1.16
+++ DispatchAction.java 13 Aug 2003 04:53:43 -0000 1.17
@@ -123,9 +123,17 @@
* constraints over what types of handlers may reasonably be packaged into
* the same <code>DispatchAction</code> subclass.</p>
*
+ * <p><strong>NOTE</strong> - If the value of the request parameter is empty,
+ * a method named <code>unspecified</code> is called. The default action is
+ * to throw an exception. If the request was cancelled (a <code>html:cancel</code>
+ * button was pressed), the custom handler <code>cancelled</code> will be used
instead.
+ * You can also override the <code>getMethodName</code> method to override the
action's
+ * default handler selection.</p>
+ *
* @author Niall Pemberton <[EMAIL PROTECTED]>
* @author Craig R. McClanahan
* @author Ted Husted
+ * @author Leonardo Quijano
* @version $Revision$ $Date$
*/
public abstract class DispatchAction extends Action {
@@ -150,8 +158,8 @@
* The message resources for this package.
*/
protected static MessageResources messages =
- MessageResources.getMessageResources
- ("org.apache.struts.actions.LocalStrings");
+ MessageResources.getMessageResources
+ ("org.apache.struts.actions.LocalStrings");
/**
@@ -168,11 +176,11 @@
* are the same for all calls, so calculate them only once.
*/
protected Class[] types =
- {
- ActionMapping.class,
- ActionForm.class,
- HttpServletRequest.class,
- HttpServletResponse.class };
+ {
+ ActionMapping.class,
+ ActionForm.class,
+ HttpServletRequest.class,
+ HttpServletResponse.class};
@@ -197,25 +205,28 @@
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
- throws Exception {
+ throws Exception {
- // Identify the request parameter containing the method name
- String parameter = mapping.getParameter();
- if (parameter == null) {
- String message =
- messages.getMessage("dispatch.handler", mapping.getPath());
-
- log.error(message);
-
- throw new ServletException(message);
- }
+ if (isCancelled(request)) {
+ return cancelled(mapping, form, request, response);
+ } else {
+ // Identify the request parameter containing the method name
+ String parameter = mapping.getParameter();
+ if (parameter == null) {
+ String message =
+ messages.getMessage("dispatch.handler", mapping.getPath());
- // Identify the method name to be dispatched to.
- // dispatchMethod() will call unspecified() if name is null
- String name = request.getParameter(parameter);
+ log.error(message);
- // Invoke the named method, and return the result
- return dispatchMethod(mapping, form, request, response, name);
+ throw new ServletException(message);
+ }
+
+ // Get the method's name. This could be overridden in subclasses.
+ String name = getMethodName(mapping, form, request, response,
parameter);
+
+ // Invoke the named method, and return the result
+ return dispatchMethod(mapping, form, request, response, name);
+ }
}
@@ -226,23 +237,46 @@
* to provide default behavior different than throwing a ServletException.
*/
protected ActionForward unspecified(
- ActionMapping mapping,
- ActionForm form,
- HttpServletRequest request,
- HttpServletResponse response)
- throws Exception {
+ ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
String message =
- messages.getMessage(
- "dispatch.parameter",
- mapping.getPath(),
- mapping.getParameter());
+ messages.getMessage(
+ "dispatch.parameter",
+ mapping.getPath(),
+ mapping.getParameter());
log.error(message);
throw new ServletException(message);
}
+ /**
+ * Method which is dispatched to when the request is a cancel button submit.
+ * Subclasses of <code>DispatchAction</code> should override this method if
+ * they wish to provide default behavior different than throwing a
+ * ServletException.
+ *
+ */
+ protected ActionForward cancelled(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+
+ String message =
+ messages.getMessage(
+ "dispatch.cancelled",
+ mapping.getPath(),
+ mapping.getParameter());
+
+ log.error(message);
+
+ throw new ServletException(message);
+ }
// ----------------------------------------------------- Protected Methods
@@ -251,12 +285,12 @@
* Dispatch to the specified method.
* @since Struts 1.1
*/
- protected ActionForward dispatchMethod(ActionMapping mapping,
- ActionForm form,
- HttpServletRequest request,
- HttpServletResponse response,
- String name) throws Exception {
-
+ protected ActionForward dispatchMethod(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response,
+ String name) throws Exception {
+
// Make sure we have a valid method name to call.
// This may be null if the user hacks the query string.
if (name == null) {
@@ -267,32 +301,32 @@
Method method = null;
try {
method = getMethod(name);
-
- } catch (NoSuchMethodException e) {
+
+ } catch(NoSuchMethodException e) {
String message =
- messages.getMessage("dispatch.method", mapping.getPath(), name);
+ messages.getMessage("dispatch.method", mapping.getPath(), name);
log.error(message, e);
throw e;
}
ActionForward forward = null;
try {
- Object args[] = { mapping, form, request, response };
+ Object args[] = {mapping, form, request, response};
forward = (ActionForward) method.invoke(this, args);
-
- } catch (ClassCastException e) {
+
+ } catch(ClassCastException e) {
String message =
- messages.getMessage("dispatch.return", mapping.getPath(), name);
+ messages.getMessage("dispatch.return", mapping.getPath(), name);
log.error(message, e);
throw e;
-
- } catch (IllegalAccessException e) {
+
+ } catch(IllegalAccessException e) {
String message =
- messages.getMessage("dispatch.error", mapping.getPath(), name);
+ messages.getMessage("dispatch.error", mapping.getPath(), name);
log.error(message, e);
throw e;
-
- } catch (InvocationTargetException e) {
+
+ } catch(InvocationTargetException e) {
// Rethrow the target exception if possible so that the
// exception handling machinery can deal with it
Throwable t = e.getTargetException();
@@ -300,7 +334,7 @@
throw ((Exception) t);
} else {
String message =
- messages.getMessage("dispatch.error", mapping.getPath(), name);
+ messages.getMessage("dispatch.error", mapping.getPath(),
name);
log.error(message, e);
throw new ServletException(t);
}
@@ -321,9 +355,9 @@
* @exception NoSuchMethodException if no such method can be found
*/
protected Method getMethod(String name)
- throws NoSuchMethodException {
+ throws NoSuchMethodException {
- synchronized (methods) {
+ synchronized(methods) {
Method method = (Method) methods.get(name);
if (method == null) {
method = clazz.getMethod(name, types);
@@ -334,5 +368,27 @@
}
+ /**
+ * Returns the method name, given a parameter's value.
+ *
+ * @param mapping The ActionMapping used to select this instance
+ * @param form The optional ActionForm bean for this request (if any)
+ * @param request The HTTP request we are processing
+ * @param response The HTTP response we are creating
+ * @param parameter The <code>ActionMapping</code> parameter's name
+ *
+ * @return The method's name.
+ */
+ protected String getMethodName(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response,
+ String parameter)
+ throws Exception {
+
+ // Identify the method name to be dispatched to.
+ // dispatchMethod() will call unspecified() if name is null
+ return request.getParameter(parameter);
+ }
}
1.8 +10 -7
jakarta-struts/src/share/org/apache/struts/actions/LocalStrings.properties
Index: LocalStrings.properties
===================================================================
RCS file:
/home/cvs/jakarta-struts/src/share/org/apache/struts/actions/LocalStrings.properties,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- LocalStrings.properties 12 Aug 2003 03:26:53 -0000 1.7
+++ LocalStrings.properties 13 Aug 2003 04:53:43 -0000 1.8
@@ -1,14 +1,17 @@
-dispatch.error=Dispatch[{0}] to method {1} returned an exception
+dispatch.cancelled=Action[{0}] does not contain a cancel handler
+dispatch.error=Dispatch[{0}] to method '{1}' returned an exception
dispatch.handler=DispatchMapping[{0}] does not define a handler property
+dispatch.lookup=Action[{0}] does not contain handler for resource '{1}'
dispatch.mapping=ActionMapping[{0}] is not of type DispatchMapping
-dispatch.method=Action[{0}] does not contain method named {1}
-dispatch.parameter=Request[{0}] does not contain handler parameter named {1}. This
may be caused by whitespace in the label text.
-dispatch.return=Action[{0}] invalid return type for method {1}
+dispatch.method=Action[{0}] does not contain method named '{1}'
+dispatch.parameter=Request[{0}] does not contain handler parameter named '{1}'.
This may be caused by whitespace in the label text.
+dispatch.return=Action[{0}] invalid return type for method '{1}'
+dispatch.resource=Action[{0}] missing resource '{1}' in key method map
forward.path=No context-relative URI specified via the 'parameter' attribute
-forward.rd=Cannot create request dispatcher for path {0}
+forward.rd=Cannot create request dispatcher for path '{0}'
include.path=No context-relative URI specified via the 'parameter' attribute
-include.rd=Cannot create request dispatcher for path {0}
-switch.prefix=Invalid module prefix {0} was specified
+include.rd=Cannot create request dispatcher for path '{0}'
+switch.prefix=Invalid module prefix '{0}' was specified
switch.required=Switch requires both 'prefix' and 'page' request parameters
success.required=SuccessAction could not find an ActionForward named 'success' for
path '{0}'
mapping.parameter=ActionMapping[{0}] does not define a 'parameter' attribute
1.13 +87 -44
jakarta-struts/src/share/org/apache/struts/actions/LookupDispatchAction.java
Index: LookupDispatchAction.java
===================================================================
RCS file:
/home/cvs/jakarta-struts/src/share/org/apache/struts/actions/LookupDispatchAction.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- LookupDispatchAction.java 3 Jul 2003 02:42:58 -0000 1.12
+++ LookupDispatchAction.java 13 Aug 2003 04:53:43 -0000 1.13
@@ -2,7 +2,7 @@
* $Header$
* $Revision$
* $Date$
- *
+ *
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -69,6 +69,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang.StringUtils;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
@@ -143,11 +144,15 @@
*
* <strong>Notes</strong> - If duplicate values exist for the keys returned by
* getKeys, only the first one found will be returned. If no corresponding key
- * is found then an exception will be thrown.
+ * is found then an exception will be thrown. You can override the
+ * method <code>unspecified</code> to provide a custom handler. If the submit
+ * was cancelled (a <code>html:cancel</code> button was pressed), the custom
+ * handler <code>cancelled</code> will be used instead.
*
* @author Erik Hatcher
* @author Scott Carlson
* @author David Graham
+ * @author Leonardo Quijano
*/
public abstract class LookupDispatchAction extends DispatchAction {
@@ -178,46 +183,27 @@
* @exception Exception if an error occurs
*/
public ActionForward execute(
- ActionMapping mapping,
- ActionForm form,
- HttpServletRequest request,
- HttpServletResponse response)
- throws Exception {
-
- // Identify the request parameter containing the method name
- String parameter = mapping.getParameter();
- if (parameter == null) {
- String message = messages.getMessage("dispatch.handler",
mapping.getPath());
- throw new ServletException(message);
- }
-
- // Identify the string to lookup
- String name = request.getParameter(parameter);
- if (name == null) {
- String message =
- messages.getMessage("dispatch.parameter", mapping.getPath(),
parameter);
- throw new ServletException(message);
- }
-
- // Based on this request's Locale get the lookupMap
- Map lookupMap = null;
-
- synchronized (localeMap) {
- Locale userLocale = this.getLocale(request);
- lookupMap = (Map) this.localeMap.get(userLocale);
-
- if (lookupMap == null) {
- lookupMap = this.initLookupMap(request, userLocale);
- this.localeMap.put(userLocale, lookupMap);
+ ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+
+ if (isCancelled(request)) {
+ return cancelled(mapping, form, request, response);
+ } else {
+ // Identify the request parameter containing the method name
+ String parameter = mapping.getParameter();
+ if (parameter == null) {
+ String message = messages.getMessage("dispatch.handler",
mapping.getPath());
+ throw new ServletException(message);
}
- }
-
- // Find the key
- String key = (String) lookupMap.get(name);
- String methodName = (String) keyMethodMap.get(key);
+ // Identify the string to lookup
+ String methodName = getMethodName(mapping, form, request, response,
parameter);
- return this.dispatchMethod(mapping, form, request, response, methodName);
+ return dispatchMethod(mapping, form, request, response, methodName);
+ }
}
/**
@@ -230,7 +216,7 @@
this.keyMethodMap = this.getKeyMethodMap();
ModuleConfig moduleConfig =
- (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);
+ (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);
MessageResourcesConfig[] mrc = moduleConfig.findMessageResourcesConfigs();
@@ -250,7 +236,7 @@
}
}
}
-
+
return lookupMap;
}
@@ -260,5 +246,62 @@
* @return Resource key / method name map.
*/
protected abstract Map getKeyMethodMap();
+
+ /**
+ * Returns the method name, given a parameter's value.
+ *
+ * @param mapping The ActionMapping used to select this instance
+ * @param form The optional ActionForm bean for this request (if any)
+ * @param request The HTTP request we are processing
+ * @param response The HTTP response we are creating
+ * @param parameter The <code>ActionMapping</code> parameter's name
+ *
+ * @return The method's name.
+ */
+ protected String getMethodName(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response,
+ String parameter)
+ throws Exception {
+
+ // Identify the method name to be dispatched to.
+ // dispatchMethod() will call unspecified() if name is null
+ String keyName = request.getParameter(parameter);
+ if (StringUtils.isEmpty(keyName)) {
+ return null;
+ }
+
+ // Based on this request's Locale get the lookupMap
+ Map lookupMap = null;
+
+ synchronized(localeMap) {
+ Locale userLocale = this.getLocale(request);
+ lookupMap = (Map) this.localeMap.get(userLocale);
+
+ if (lookupMap == null) {
+ lookupMap = this.initLookupMap(request, userLocale);
+ this.localeMap.put(userLocale, lookupMap);
+ }
+ }
+
+ // Find the key for the resource
+ String key = (String) lookupMap.get(keyName);
+ if (key == null) {
+ String message = messages.getMessage(
+ "dispatch.resource", mapping.getPath(), keyName);
+ throw new ServletException(message);
+ }
+
+ // Find the method name
+ String methodName = (String) keyMethodMap.get(key);
+ if (methodName == null) {
+ String message = messages.getMessage(
+ "dispatch.lookup", mapping.getPath(), key);
+ throw new ServletException(message);
+ }
+
+ return methodName;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]