View Javadoc

1   /*
2    * $Id: MappingDispatchAction.java 376812 2006-02-10 19:42:38Z husted $
3    *
4    * Copyright 2003,2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.struts.actions;
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.apache.struts.action.ActionForm;
23  import org.apache.struts.action.ActionForward;
24  import org.apache.struts.action.ActionMapping;
25  
26  import javax.servlet.ServletException;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  /***
31   * <p>An abstract <strong>Action</strong> that dispatches to a public method
32   * that is named by the <code>parameter</code> attribute of the corresponding
33   * ActionMapping.  This is useful for developers who prefer to combine many
34   * related actions into a single Action class.</p>
35   *
36   * <p>To configure the use of this action in your <code>struts-config.xml</code>
37   * file, create an entry like this:</p>
38   *
39   * <pre><code>
40   *   &lt;action path="/saveSubscription"
41   *           type="org.example.SubscriptionAction"
42   *           name="subscriptionForm"
43   *          scope="request"
44   *          input="/subscription.jsp"
45   *      parameter="method"/&gt;
46   * </code></pre>
47   *
48   * <p>where 'method' is the name of a method in your subclass of
49   * MappingDispatchAction that has the same signature (other than method name)
50   * of the standard Action.execute method.  For example, you might combine the
51   * methods for managing a subscription into a  single MappingDispatchAction
52   * class using the following methods:</p>
53   *
54   * <ul>
55   *
56   * <li>public ActionForward create(ActionMapping mapping, ActionForm form,
57   * HttpServletRequest request, HttpServletResponse response) throws
58   * Exception</li>
59   *
60   * <li>public ActionForward edit(ActionMapping mapping, ActionForm form,
61   * HttpServletRequest request, HttpServletResponse response) throws
62   * Exception</li>
63   *
64   * <li>public ActionForward save(ActionMapping mapping, ActionForm form,
65   * HttpServletRequest request, HttpServletResponse response) throws
66   * Exception</li>
67   *
68   * <li>public ActionForward delete(ActionMapping mapping, ActionForm form,
69   * HttpServletRequest request, HttpServletResponse response) throws
70   * Exception</li>
71   *
72   * <li>public ActionForward list(ActionMapping mapping, ActionForm form,
73   * HttpServletRequest request, HttpServletResponse response) throws
74   * Exception</li>
75   *
76   * </ul>
77   *
78   * <p>for which you would create corresponding &lt;action&gt; configurations
79   * that reference this class:</p>
80   *
81   * <pre><code>
82   *  &lt;action path="/createSubscription"
83   *          type="org.example.SubscriptionAction"
84   *          parameter="create"&gt;
85   *      &lt;forward name="success" path="/editSubscription.jsp"/&gt;
86   *  &lt;/action&gt;
87   *
88   *  &lt;action path="/editSubscription"
89   *          type="org.example.SubscriptionAction"
90   *          parameter="edit"&gt;
91   *      &lt;forward name="success" path="/editSubscription.jsp"/&gt;
92   *  &lt;/action&gt;
93   *
94   *  &lt;action path="/saveSubscription"
95   *          type="org.example.SubscriptionAction"
96   *          parameter="save"
97   *          name="subscriptionForm"
98   *          validate="true"
99   *          input="/editSubscription.jsp"
100  *          scope="request"&gt;
101  *      &lt;forward name="success" path="/savedSubscription.jsp"/&gt;
102  *  &lt;/action&gt;
103  *
104  *  &lt;action path="/deleteSubscription"
105  *          type="org.example.SubscriptionAction"
106  *          name="subscriptionForm"
107  *          scope="request"
108  *          input="/subscription.jsp"
109  *          parameter="delete"&gt;
110  *      &lt;forward name="success" path="/deletedSubscription.jsp"/&gt;
111  *  &lt;/action&gt;
112  *
113  *  &lt;action path="/listSubscriptions"
114  *          type="org.example.SubscriptionAction"
115  *          parameter="list"&gt;
116  *      &lt;forward name="success" path="/subscriptionList.jsp"/&gt;
117  *  &lt;/action&gt;
118  * </code></pre>
119  *
120  * <p><strong>NOTE</strong> - Unlike DispatchAction, mapping characteristics
121  * may differ between the various handlers, so you can combine actions in the
122  * same class that, for example, differ in their use of forms or validation.
123  * Also, a request parameter, which would be visible to the application user,
124  * is not required to enable selection of the handler method. </p>
125  *
126  * @version $Rev: 376812 $ $Date: 2005-05-14 21:27:02 -0400 (Sat, 14 May 2005)
127  *          $
128  * @since Struts 1.2
129  */
130 public class MappingDispatchAction extends DispatchAction {
131     // -------------------------------------------------------- Class Variables
132 
133     /***
134      * Commons Logging instance.
135      */
136     private static Log log = LogFactory.getLog(MappingDispatchAction.class);
137 
138     // --------------------------------------------------------- Public Methods
139 
140     /***
141      * Process the specified HTTP request, and create the corresponding HTTP
142      * response (or forward to another web component that will create it).
143      * Return an <code>ActionForward</code> instance describing where and how
144      * control should be forwarded, or <code>null</code> if the response has
145      * already been completed.
146      *
147      * This method dispatches the request to other methods of
148      * <code>MappingDispatchAction</code> using the 'parameter' attribute of
149      * <code>ActionMapping</code> and Java Introspection.
150      *
151      * @param mapping  The ActionMapping used to select this instance
152      * @param form     The optional ActionForm bean for this request (if any)
153      * @param request  The HTTP request we are processing
154      * @param response The HTTP response we are creating
155      * @return Return an <code>ActionForward</code> instance describing where
156      *         and how control should be forwarded, or <code>null</code> if
157      *         the response has already been completed.
158      * @throws Exception if an exception occurs
159      */
160     public ActionForward execute(ActionMapping mapping, ActionForm form,
161         HttpServletRequest request, HttpServletResponse response)
162         throws Exception {
163         // Use the overridden getMethodName.
164         return super.execute(mapping, form, request, response);
165     }
166 
167     /***
168      * Method which is dispatched to when there is no value for the parameter
169      * in the ActionMapping.  Subclasses of <code>MappingDispatchAction</code>
170      * should override this method if they wish to provide default behavior
171      * different than throwing a ServletException.
172      *
173      * @param mapping  The ActionMapping used to select this instance
174      * @param form     The optional ActionForm bean for this request (if any)
175      * @param request  The HTTP request we are processing
176      * @param response The HTTP response we are creating
177      * @return Return an <code>ActionForward</code> instance describing where
178      *         and how control should be forwarded, or <code>null</code> if
179      *         the response has already been completed.
180      * @throws Exception if an exception occurs
181      */
182     protected ActionForward unspecified(ActionMapping mapping, ActionForm form,
183         HttpServletRequest request, HttpServletResponse response)
184         throws Exception {
185         String message =
186             messages.getMessage("mapping.parameter", mapping.getPath());
187 
188         log.error(message);
189 
190         throw new ServletException(message);
191     }
192 
193     /***
194      * Returns the method name, given a parameter's value.
195      *
196      * @param mapping   The ActionMapping used to select this instance
197      * @param form      The optional ActionForm bean for this request (if
198      *                  any)
199      * @param request   The HTTP request we are processing
200      * @param response  The HTTP response we are creating
201      * @param parameter The <code>ActionMapping</code> parameter's name
202      * @return The method's name.
203      * @throws Exception if an error occurs
204      * @since Struts 1.2.0
205      */
206     protected String getMethodName(ActionMapping mapping, ActionForm form,
207         HttpServletRequest request, HttpServletResponse response,
208         String parameter) throws Exception {
209         // Return the unresolved mapping parameter.
210         return parameter;
211     }
212 }