001: /*
002: * $Id: MappingDispatchAction.java 480570 2006-11-29 13:39:37Z niallp $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts.actions;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.struts.action.ActionForm;
026: import org.apache.struts.action.ActionForward;
027: import org.apache.struts.action.ActionMapping;
028:
029: import javax.servlet.ServletException;
030: import javax.servlet.http.HttpServletRequest;
031: import javax.servlet.http.HttpServletResponse;
032:
033: /**
034: * <p>An abstract <strong>Action</strong> that dispatches to a public method
035: * that is named by the <code>parameter</code> attribute of the corresponding
036: * ActionMapping. This is useful for developers who prefer to combine many
037: * related actions into a single Action class.</p>
038: *
039: * <p>To configure the use of this action in your <code>struts-config.xml</code>
040: * file, create an entry like this:</p>
041: *
042: * <pre><code>
043: * <action path="/saveSubscription"
044: * type="org.example.SubscriptionAction"
045: * name="subscriptionForm"
046: * scope="request"
047: * input="/subscription.jsp"
048: * parameter="method"/>
049: * </code></pre>
050: *
051: * <p>where 'method' is the name of a method in your subclass of
052: * MappingDispatchAction that has the same signature (other than method name)
053: * of the standard Action.execute method. For example, you might combine the
054: * methods for managing a subscription into a single MappingDispatchAction
055: * class using the following methods:</p>
056: *
057: * <ul>
058: *
059: * <li>public ActionForward create(ActionMapping mapping, ActionForm form,
060: * HttpServletRequest request, HttpServletResponse response) throws
061: * Exception</li>
062: *
063: * <li>public ActionForward edit(ActionMapping mapping, ActionForm form,
064: * HttpServletRequest request, HttpServletResponse response) throws
065: * Exception</li>
066: *
067: * <li>public ActionForward save(ActionMapping mapping, ActionForm form,
068: * HttpServletRequest request, HttpServletResponse response) throws
069: * Exception</li>
070: *
071: * <li>public ActionForward delete(ActionMapping mapping, ActionForm form,
072: * HttpServletRequest request, HttpServletResponse response) throws
073: * Exception</li>
074: *
075: * <li>public ActionForward list(ActionMapping mapping, ActionForm form,
076: * HttpServletRequest request, HttpServletResponse response) throws
077: * Exception</li>
078: *
079: * </ul>
080: *
081: * <p>for which you would create corresponding <action> configurations
082: * that reference this class:</p>
083: *
084: * <pre><code>
085: * <action path="/createSubscription"
086: * type="org.example.SubscriptionAction"
087: * parameter="create">
088: * <forward name="success" path="/editSubscription.jsp"/>
089: * </action>
090: *
091: * <action path="/editSubscription"
092: * type="org.example.SubscriptionAction"
093: * parameter="edit">
094: * <forward name="success" path="/editSubscription.jsp"/>
095: * </action>
096: *
097: * <action path="/saveSubscription"
098: * type="org.example.SubscriptionAction"
099: * parameter="save"
100: * name="subscriptionForm"
101: * validate="true"
102: * input="/editSubscription.jsp"
103: * scope="request">
104: * <forward name="success" path="/savedSubscription.jsp"/>
105: * </action>
106: *
107: * <action path="/deleteSubscription"
108: * type="org.example.SubscriptionAction"
109: * name="subscriptionForm"
110: * scope="request"
111: * input="/subscription.jsp"
112: * parameter="delete">
113: * <forward name="success" path="/deletedSubscription.jsp"/>
114: * </action>
115: *
116: * <action path="/listSubscriptions"
117: * type="org.example.SubscriptionAction"
118: * parameter="list">
119: * <forward name="success" path="/subscriptionList.jsp"/>
120: * </action>
121: * </code></pre>
122: *
123: * <p><strong>NOTE</strong> - Unlike DispatchAction, mapping characteristics
124: * may differ between the various handlers, so you can combine actions in the
125: * same class that, for example, differ in their use of forms or validation.
126: * Also, a request parameter, which would be visible to the application user,
127: * is not required to enable selection of the handler method. </p>
128: *
129: * @version $Rev: 480570 $ $Date: 2006-11-29 07:39:37 -0600 (Wed, 29 Nov 2006) $
130: * @since Struts 1.2
131: */
132: public class MappingDispatchAction extends DispatchAction {
133: // -------------------------------------------------------- Class Variables
134:
135: /**
136: * Commons Logging instance.
137: */
138: private static Log log = LogFactory
139: .getLog(MappingDispatchAction.class);
140:
141: // --------------------------------------------------------- Public Methods
142:
143: /**
144: * Process the specified HTTP request, and create the corresponding HTTP
145: * response (or forward to another web component that will create it).
146: * Return an <code>ActionForward</code> instance describing where and how
147: * control should be forwarded, or <code>null</code> if the response has
148: * already been completed.
149: *
150: * This method dispatches the request to other methods of
151: * <code>MappingDispatchAction</code> using the 'parameter' attribute of
152: * <code>ActionMapping</code> and Java Introspection.
153: *
154: * @param mapping The ActionMapping used to select this instance
155: * @param form The optional ActionForm bean for this request (if any)
156: * @param request The HTTP request we are processing
157: * @param response The HTTP response we are creating
158: * @return Return an <code>ActionForward</code> instance describing where
159: * and how control should be forwarded, or <code>null</code> if
160: * the response has already been completed.
161: * @throws Exception if an exception occurs
162: */
163: public ActionForward execute(ActionMapping mapping,
164: ActionForm form, HttpServletRequest request,
165: HttpServletResponse response) throws Exception {
166: // Use the overridden getMethodName.
167: return super .execute(mapping, form, request, response);
168: }
169:
170: /**
171: * Method which is dispatched to when there is no value for the parameter
172: * in the ActionMapping. Subclasses of <code>MappingDispatchAction</code>
173: * should override this method if they wish to provide default behavior
174: * different than throwing a ServletException.
175: *
176: * @param mapping The ActionMapping used to select this instance
177: * @param form The optional ActionForm bean for this request (if any)
178: * @param request The HTTP request we are processing
179: * @param response The HTTP response we are creating
180: * @return Return an <code>ActionForward</code> instance describing where
181: * and how control should be forwarded, or <code>null</code> if
182: * the response has already been completed.
183: * @throws Exception if an exception occurs
184: */
185: protected ActionForward unspecified(ActionMapping mapping,
186: ActionForm form, HttpServletRequest request,
187: HttpServletResponse response) throws Exception {
188: String message = messages.getMessage("mapping.parameter",
189: mapping.getPath());
190:
191: log.error(message);
192:
193: throw new ServletException(message);
194: }
195:
196: /**
197: * <p>Returns the parameter value.</p>
198: *
199: * @param mapping The ActionMapping used to select this instance
200: * @param form The optional ActionForm bean for this request (if any)
201: * @param request The HTTP request we are processing
202: * @param response The HTTP response we are creating
203: * @return The <code>ActionMapping</code> parameter's value
204: */
205: protected String getParameter(ActionMapping mapping,
206: ActionForm form, HttpServletRequest request,
207: HttpServletResponse response) throws Exception {
208:
209: return mapping.getParameter();
210:
211: }
212:
213: /**
214: * Returns the method name, given a parameter's value.
215: *
216: * @param mapping The ActionMapping used to select this instance
217: * @param form The optional ActionForm bean for this request (if
218: * any)
219: * @param request The HTTP request we are processing
220: * @param response The HTTP response we are creating
221: * @param parameter The <code>ActionMapping</code> parameter's name
222: * @return The method's name.
223: * @throws Exception if an error occurs
224: * @since Struts 1.2.0
225: */
226: protected String getMethodName(ActionMapping mapping,
227: ActionForm form, HttpServletRequest request,
228: HttpServletResponse response, String parameter)
229: throws Exception {
230: // Return the unresolved mapping parameter.
231: return parameter;
232: }
233: }
|