KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > appfuse > webapp > action > BaseAction


1 package org.appfuse.webapp.action;
2
3 import java.util.Date JavaDoc;
4 import java.util.Enumeration JavaDoc;
5 import java.util.HashMap JavaDoc;
6 import java.util.Map JavaDoc;
7
8 import javax.servlet.http.HttpServletRequest JavaDoc;
9 import javax.servlet.http.HttpServletResponse JavaDoc;
10 import javax.servlet.http.HttpSession JavaDoc;
11
12 import org.apache.commons.beanutils.ConvertUtils;
13 import org.apache.commons.beanutils.converters.IntegerConverter;
14 import org.apache.commons.beanutils.converters.LongConverter;
15 import org.apache.commons.lang.StringUtils;
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.apache.struts.Globals;
19 import org.apache.struts.action.ActionForm;
20 import org.apache.struts.action.ActionForward;
21 import org.apache.struts.action.ActionMapping;
22 import org.apache.struts.action.ActionMessages;
23 import org.apache.struts.actions.DispatchAction;
24
25 import org.appfuse.Constants;
26 import org.appfuse.util.ConvertUtil;
27 import org.appfuse.util.CurrencyConverter;
28 import org.appfuse.util.DateConverter;
29
30 import org.springframework.context.ApplicationContext;
31 import org.springframework.web.context.support.WebApplicationContextUtils;
32
33 /**
34  * Implementation of <strong>Action</strong> that contains base methods for
35  * Actions as well as determines with methods to call in subclasses. This class
36  * uses the name of the button to determine which method to execute on the
37  * Action.</p>
38  *
39  * <p>For example look at the following two buttons:</p>
40  *
41  * <pre>
42  * &lt;html:submit property="method.findName"&gt;
43  * &lt;bean:message key="email.find"/&gt;
44  * &lt;/html:submit&gt;
45  *
46  * &lt;html:submit property="method.findEmail"&gt;
47  * &lt;bean:message key="email.find"/&gt;
48  * &lt;/html:submit&gt;
49  * </pre>
50  *
51  * <p>The name of the button is set with the property parameter, i.e., the
52  * name of the first button is method.findName. The name of the second button
53  * is method.findEmail.</p>
54  *
55  * <p>As per HTML/HTTP, whatever submit button that is pushed causes only that
56  * submit button's name to be sent as a request parameter to the action.</p>
57  *
58  * <p>This action looks for the name by removing the prepender string "method.".
59  * The remaining part of the string is the name of the method to execute, e.g.,
60  * pushing the first button will execute the findName method and the second
61  * button will execute the findEmail method.</p>
62  *
63  * <p>This class extends DispatchAction and allows methods to be sent as
64  * regular GETs as well, i.e., &lt;a HREF="emailAction.do?method=findEmail"/&gt;
65  * would cause the findEmail method to be executed just as it would in a
66  * DispatchAction. Thus, you configure a ButtonNameDispatchAction exactly
67  * the way you configure a DispatchAction, i.e., set the mapping parameter
68  * to the name of the request parameter that holds the mehtod name.</p>
69  *
70  * <p>
71  * <a HREF="BaseAction.java.htm"><i>View Source</i></a>
72  *
73  * @author <a HREF="mailto:matt@raibledesigns.com">Matt Raible</a>
74  * @author Rick Hightower (based on his ButtonNameDispatchAction)
75  */

76 public class BaseAction extends DispatchAction {
77     protected final Log log = LogFactory.getLog(getClass());
78     private static final Long JavaDoc defaultLong = null;
79
80     static {
81         ConvertUtils.register(new CurrencyConverter(), Double JavaDoc.class);
82         ConvertUtils.register(new DateConverter(), Date JavaDoc.class);
83         ConvertUtils.register(new DateConverter(), String JavaDoc.class);
84         ConvertUtils.register(new LongConverter(defaultLong), Long JavaDoc.class);
85         ConvertUtils.register(new IntegerConverter(defaultLong), Integer JavaDoc.class);
86     }
87
88     /**
89      * Convenience method to get Spring-initialized beans
90      *
91      * @param name
92      * @return Object bean from ApplicationContext
93      */

94     public Object JavaDoc getBean(String JavaDoc name) {
95         ApplicationContext ctx =
96             WebApplicationContextUtils.getRequiredWebApplicationContext(servlet.getServletContext());
97         return ctx.getBean(name);
98     }
99
100     /**
101      * @see org.appfuse.util.ConvertUtil#convert(java.lang.Object)
102      */

103     protected Object JavaDoc convert(Object JavaDoc o) throws Exception JavaDoc {
104         return ConvertUtil.convert(o);
105     }
106
107     /**
108      * @see org.appfuse.util.ConvertUtil#convertLists(java.lang.Object)
109      */

110     protected Object JavaDoc convertLists(Object JavaDoc o) throws Exception JavaDoc {
111         return ConvertUtil.convertLists(o);
112     }
113
114     /**
115      * Convenience method to initialize messages in a subclass.
116      *
117      * @param request the current request
118      * @return the populated (or empty) messages
119      */

120     public ActionMessages getMessages(HttpServletRequest JavaDoc request) {
121         ActionMessages messages = null;
122         HttpSession JavaDoc session = request.getSession();
123
124         if (request.getAttribute(Globals.MESSAGE_KEY) != null) {
125             messages = (ActionMessages) request.getAttribute(Globals.MESSAGE_KEY);
126             saveMessages(request, messages);
127         } else if (session.getAttribute(Globals.MESSAGE_KEY) != null) {
128             messages = (ActionMessages) session.getAttribute(Globals.MESSAGE_KEY);
129             saveMessages(request, messages);
130             session.removeAttribute(Globals.MESSAGE_KEY);
131         } else {
132             messages = new ActionMessages();
133         }
134
135         return messages;
136     }
137
138     /**
139      * Gets the method name based on the mapping passed to it
140      */

141     private String JavaDoc getActionMethodWithMapping(HttpServletRequest JavaDoc request, ActionMapping mapping) {
142         return getActionMethod(request, mapping.getParameter());
143     }
144
145     /**
146      * Gets the method name based on the prepender passed to it.
147      */

148     protected String JavaDoc getActionMethod(HttpServletRequest JavaDoc request, String JavaDoc prepend) {
149         String JavaDoc name = null;
150         
151         // for backwards compatibility, try with no prepend first
152
name = request.getParameter(prepend);
153         if (name != null) {
154             // trim any whitespace around - this might happen on buttons
155
name = name.trim();
156             // lowercase first letter
157
return name.replace(name.charAt(0), Character.toLowerCase(name.charAt(0)));
158         }
159         
160         Enumeration JavaDoc e = request.getParameterNames();
161
162         while (e.hasMoreElements()) {
163             String JavaDoc currentName = (String JavaDoc) e.nextElement();
164
165             if (currentName.startsWith(prepend + ".")) {
166                 if (log.isDebugEnabled()) {
167                     log.debug("calling method: " + currentName);
168                 }
169
170                 String JavaDoc[] parameterMethodNameAndArgs = StringUtils.split(currentName, ".");
171                 name = parameterMethodNameAndArgs[1];
172                 break;
173             }
174         }
175         
176         return name;
177     }
178
179     /**
180      * Override the execute method in DispatchAction to parse
181      * URLs and forward to methods without parameters.</p>
182      * <p>
183      * This is based on the following system:
184      * <p/>
185      * <ul>
186      * <li>edit*.html -> edit method</li>
187      * <li>save*.html -> save method</li>
188      * <li>view*.html -> search method</li>
189      * </ul>
190      */

191     public ActionForward execute(ActionMapping mapping, ActionForm form,
192                                  HttpServletRequest JavaDoc request,
193                                  HttpServletResponse JavaDoc response)
194     throws Exception JavaDoc {
195         
196         if (isCancelled(request)) {
197             try {
198                 getMethod("cancel");
199                 return dispatchMethod(mapping, form, request, response, "cancel");
200             } catch (NoSuchMethodException JavaDoc n) {
201                 log.warn("No 'cancel' method found, returning null");
202                 return cancelled(mapping, form, request, response);
203             }
204         }
205
206         // Check to see if methodName indicated by request parameter
207
String JavaDoc actionMethod = getActionMethodWithMapping(request, mapping);
208         
209         if (actionMethod != null) {
210             return dispatchMethod(mapping, form, request, response, actionMethod);
211         } else {
212             String JavaDoc[] rules = {"edit", "save", "search", "view"};
213             for (int i = 0; i < rules.length; i++) {
214                 // apply the rules for automatically appending the method name
215
if (request.getServletPath().indexOf(rules[i]) > -1) {
216                     return dispatchMethod(mapping, form, request, response, rules[i]);
217                 }
218             }
219         }
220         
221         return super.execute(mapping, form, request, response);
222     }
223
224     /**
225      * Convenience method for getting an action form base on it's mapped scope.
226      *
227      * @param mapping The ActionMapping used to select this instance
228      * @param request The HTTP request we are processing
229      * @return ActionForm the form from the specifies scope, or null if nothing
230      * found
231      */

232     protected ActionForm getActionForm(ActionMapping mapping, HttpServletRequest JavaDoc request) {
233         ActionForm actionForm = null;
234
235         // Remove the obsolete form bean
236
if (mapping.getAttribute() != null) {
237             if ("request".equals(mapping.getScope())) {
238                 actionForm = (ActionForm) request.getAttribute(mapping.getAttribute());
239             } else {
240                 HttpSession JavaDoc session = request.getSession();
241                 actionForm = (ActionForm) session.getAttribute(mapping.getAttribute());
242             }
243         }
244
245         return actionForm;
246     }
247
248     /**
249      * Convenience method to get the Configuration HashMap
250      * from the servlet context.
251      *
252      * @return the user's populated form from the session
253      */

254     public Map JavaDoc getConfiguration() {
255         Map JavaDoc config = (HashMap JavaDoc) getServlet().getServletContext().getAttribute(Constants.CONFIG);
256
257         // so unit tests don't puke when nothing's been set
258
if (config == null) {
259             return new HashMap JavaDoc();
260         }
261
262         return config;
263     }
264
265     /**
266      * Convenience method for removing the obsolete form bean.
267      *
268      * @param mapping The ActionMapping used to select this instance
269      * @param request The HTTP request we are processing
270      */

271     protected void removeFormBean(ActionMapping mapping, HttpServletRequest JavaDoc request) {
272         // Remove the obsolete form bean
273
if (mapping.getAttribute() != null) {
274             if ("request".equals(mapping.getScope())) {
275                 request.removeAttribute(mapping.getAttribute());
276             } else {
277                 HttpSession JavaDoc session = request.getSession();
278                 session.removeAttribute(mapping.getAttribute());
279             }
280         }
281     }
282
283     /**
284      * Convenience method to update a formBean in it's scope
285      *
286      * @param mapping The ActionMapping used to select this instance
287      * @param request The HTTP request we are processing
288      * @param form The ActionForm
289      */

290     protected void updateFormBean(ActionMapping mapping, HttpServletRequest JavaDoc request, ActionForm form) {
291         // Remove the obsolete form bean
292
if (mapping.getAttribute() != null) {
293             if ("request".equals(mapping.getScope())) {
294                 request.setAttribute(mapping.getAttribute(), form);
295             } else {
296                 HttpSession JavaDoc session = request.getSession();
297                 session.setAttribute(mapping.getAttribute(), form);
298             }
299         }
300     }
301 }
302
Popular Tags