KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > blandware > atleap > webapp > action > core > BaseAction


1 /*
2  * Copyright 2004 Blandware (http://www.blandware.com)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.blandware.atleap.webapp.action.core;
17
18 import com.blandware.atleap.common.Constants;
19 import com.blandware.atleap.webapp.util.core.ApplicationResources;
20 import com.blandware.atleap.webapp.util.core.SslUtil;
21 import com.blandware.atleap.webapp.util.core.TokenUtil;
22 import com.blandware.atleap.webapp.util.core.WebappConstants;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.struts.Globals;
26 import org.apache.struts.action.Action;
27 import org.apache.struts.action.ActionForm;
28 import org.apache.struts.action.ActionMapping;
29 import org.apache.struts.action.ActionMessages;
30 import org.springframework.context.ApplicationContext;
31 import org.springframework.web.context.support.WebApplicationContextUtils;
32
33 import javax.servlet.http.HttpServletRequest JavaDoc;
34 import javax.servlet.http.HttpServletResponse JavaDoc;
35 import javax.servlet.http.HttpSession JavaDoc;
36 import java.util.HashMap JavaDoc;
37
38
39 /**
40  * <p>Implementation of <strong>Action</strong> that contains base methods for
41  * logging and conducting pre/post perform actions. This class is intended to
42  * be a base class for all Struts actions.
43  * </p>
44  * <p>You can create action-forward with name "unsatisfiable" (it is reserved name) in order to check for token before form validation.
45  * The token will be reseted after checking.
46  * </p>
47  * <p><a HREF="BaseAction.java.htm"><i>View Source</i></a>
48  * </p>
49  *
50  * @author Matt Raible <a HREF="mailto:matt@raibledesigns.com">&lt;matt@raibledesigns.com&gt;</a>
51  * @author Andrey Grebnev <a HREF="mailto:andrey.grebnev@blandware.com">&lt;andrey.grebnev@blandware.com&gt;</a>
52  * @author Sergey Zubtcovskii <a HREF="mailto:sergey.zubtcovskii@blandware.com">&lt;sergey.zubtcovskii@blandware.com&gt;</a>
53  * @version $Revision: 1.20 $ $Date: 2006/03/16 11:09:40 $
54  */

55 public class BaseAction extends Action {
56
57     protected transient final Log log = LogFactory.getLog(BaseAction.class);
58     private static final String JavaDoc SECURE = "secure";
59     private ApplicationContext ctx = null;
60
61     /**
62      * Gets bean from Spring application context by its name
63      *
64      * @param name Name of bean to lookup
65      * @return Spring bean
66      */

67     protected Object JavaDoc getBean(String JavaDoc name) {
68         if ( ctx == null ) {
69             ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servlet.getServletContext());
70         }
71         return ctx.getBean(name);
72     }
73
74     /**
75      * Convenience method to get action messages
76      *
77      * @param request the current request
78      * @return the populated (or empty) messages
79      */

80     protected ActionMessages getMessages(HttpServletRequest JavaDoc request) {
81         ActionMessages messages = null;
82         HttpSession JavaDoc session = request.getSession();
83
84         if ( request.getAttribute(Globals.MESSAGE_KEY) != null ) {
85             messages =
86                     (ActionMessages) request.getAttribute(Globals.MESSAGE_KEY);
87             saveMessages(request, messages);
88         } else if ( session.getAttribute(Globals.MESSAGE_KEY) != null ) {
89             messages =
90                     (ActionMessages) session.getAttribute(Globals.MESSAGE_KEY);
91             saveMessages(request, messages);
92             session.removeAttribute(Globals.MESSAGE_KEY);
93         } else {
94             messages = new ActionMessages();
95         }
96         return messages;
97     }
98
99     /**
100      * Saves ActionMessages object which represents errors in request and session. It is done in order to display
101      * action errors even after redirect using our special ErrorsTag.
102      *
103      * @param request Request to save errors in (they will be saved in session too)
104      * @param errors ActionMessages object to save in request
105      * @see com.blandware.atleap.webapp.taglib.core.html.MessagesTag
106      */

107     protected void saveErrors(HttpServletRequest JavaDoc request, ActionMessages errors) {
108         saveErrors(request, errors, true);
109     }
110
111
112     /**
113      * Saves ActionMessages object which represents errors in request and session. It is done in order to display
114      * action errors even after redirect using our special ErrorsTag.
115      *
116      * @param request Request to save errors in (they will be saved in session too)
117      * @param errors ActionMessages object to save in request
118      * @param saveToSession Whether or not to save in session
119      * @see com.blandware.atleap.webapp.taglib.core.html.MessagesTag
120      */

121     protected void saveErrors(HttpServletRequest JavaDoc request, ActionMessages errors, boolean saveToSession) {
122         HttpSession JavaDoc session = request.getSession();
123         if ( errors == null || errors.isEmpty() ) {
124             request.removeAttribute(Globals.ERROR_KEY);
125             session.removeAttribute(WebappConstants.ERROR_KEY);
126         } else {
127             request.setAttribute(Globals.ERROR_KEY, errors);
128             if ( saveToSession ) {
129                 session.setAttribute(WebappConstants.ERROR_KEY, errors);
130             }
131         }
132     }
133
134     /**
135      * Saves ActionMessages object which represents messages in request and session. It is done in order to display
136      * action messages even after redirect using our special MessagesTag.
137      *
138      * @param request Request to save messages in (they will be saved in session too)
139      * @param messages ActionMessages object to save in request
140      * @see com.blandware.atleap.webapp.taglib.core.html.MessagesTag
141      */

142     protected void saveMessages(HttpServletRequest JavaDoc request, ActionMessages messages) {
143         HttpSession JavaDoc session = request.getSession();
144         if ( messages == null || messages.isEmpty() ) {
145             request.removeAttribute(Globals.MESSAGE_KEY);
146             session.removeAttribute(WebappConstants.MESSAGE_KEY);
147         } else {
148             request.setAttribute(Globals.MESSAGE_KEY, messages);
149             session.setAttribute(WebappConstants.MESSAGE_KEY, messages);
150         }
151     }
152
153     /**
154      * Convenience method for getting an action form base on it's mapped scope.
155      *
156      * @param mapping The ActionMapping used to select this instance
157      * @param request The HTTP request we are processing
158      * @return ActionForm the form from the specifies scope, or null if nothing
159      * found
160      */

161     protected ActionForm getActionForm(ActionMapping mapping,
162                                        HttpServletRequest JavaDoc request) {
163         ActionForm actionForm = null;
164
165         // Remove the obsolete form bean
166
if ( mapping.getAttribute() != null ) {
167             if ( "request".equals(mapping.getScope()) ) {
168                 actionForm =
169                         (ActionForm) request.getAttribute(mapping.getAttribute());
170             } else {
171                 HttpSession JavaDoc session = request.getSession();
172
173                 actionForm =
174                         (ActionForm) session.getAttribute(mapping.getAttribute());
175             }
176         }
177         return actionForm;
178     }
179
180     /**
181      * Convenience method to get the Configuration HashMap
182      * from the servlet context.
183      *
184      * @return the user's populated form from the session
185      */

186     protected HashMap JavaDoc getConfiguration() {
187         return (HashMap JavaDoc) this.getServlet().getServletContext().getAttribute(Constants.CONFIG);
188     }
189
190     // --------------------------------------------------------- Public Methods
191
// Don't use class variables in Action objects. These are not session safe.
192

193     /**
194      * Method to check and see if https is required for this resource
195      *
196      * @param mapping The ActionMapping used to select this instance
197      * @param request The HTTP request we are processing
198      * @param response The HTTP response we are creating
199      * @return boolean true if redirection to SSL is needed
200      */

201     protected boolean checkSsl(ActionMapping mapping,
202                                HttpServletRequest JavaDoc request,
203                                HttpServletResponse JavaDoc response) {
204         String JavaDoc redirectString =
205                 SslUtil.getRedirectString(request,
206                         getServlet().getServletContext(),
207                         SECURE.equals(mapping.getParameter()));
208
209         if ( redirectString != null ) {
210             log.debug("protocol switch needed, redirecting...");
211
212             try {
213                 // Redirect the page to the desired URL
214
response.sendRedirect(response.encodeRedirectURL(redirectString));
215
216                 return true;
217             } catch ( Exception JavaDoc e ) {
218                 log.error("redirect to new protocol failed...");
219
220                 // Handle appropriately
221
}
222         }
223
224         return false;
225     }
226
227     /**
228      * Convenience method for removing the obsolete form bean.
229      *
230      * @param mapping The ActionMapping used to select this instance
231      * @param request The HTTP request we are processing
232      */

233     protected void removeFormBean(ActionMapping mapping,
234                                   HttpServletRequest JavaDoc request) {
235         // Remove the obsolete form bean
236
if ( mapping.getAttribute() != null ) {
237             if ( "request".equals(mapping.getScope()) ) {
238                 request.removeAttribute(mapping.getAttribute());
239             } else {
240                 HttpSession JavaDoc session = request.getSession();
241
242                 session.removeAttribute(mapping.getAttribute());
243             }
244         }
245     }
246
247     /**
248      * Convenience method to update a formBean in it's scope
249      *
250      * @param mapping The ActionMapping used to select this instance
251      * @param request The HTTP request we are processing
252      * @param form The ActionForm
253      */

254     protected void updateFormBean(ActionMapping mapping,
255                                   HttpServletRequest JavaDoc request, ActionForm form) {
256         // update the obsolete form bean
257
if ( mapping.getAttribute() != null ) {
258             if ( "request".equals(mapping.getScope()) ) {
259                 request.setAttribute(mapping.getAttribute(), form);
260             } else {
261                 HttpSession JavaDoc session = request.getSession();
262
263                 session.setAttribute(mapping.getAttribute(), form);
264             }
265         }
266     }
267
268     /**
269      * Retrieves localized message for specified keys with no arguments
270      *
271      * @param request Request to lookup message resources in
272      * @param key Key to search message for
273      * @return Message for key
274      */

275     protected String JavaDoc getMessage(HttpServletRequest JavaDoc request, String JavaDoc key) {
276         return ApplicationResources.getInstance(request.getSession().getServletContext()).getMessage(getLocale(request), key);
277     }
278
279
280     /* ============================== T O K E N S ===================================== */
281
282     /**
283      * <p>Returns <code>true</code> if there is a transaction token stored in
284      * the user's current session in all scopes beginning from default, and the
285      * value submitted as a request parameter with this action matches it.
286      * Returns <code>false</code> under any of the following circumstances:</p>
287      * <ul>
288      * <li>No session associated with this request</li>
289      * <li>No transaction token saved in the session</li>
290      * <li>No transaction token included as a request parameter</li>
291      * <li>The included transaction token value does not match the
292      * transaction token in the user's session</li>
293      * </ul>
294      *
295      * @param request The servlet request we are processing
296      * @param reset Should we reset the token after checking it?
297      * @return is token existing and valid
298      */

299     public synchronized boolean isTokenValid(HttpServletRequest JavaDoc request, boolean reset) {
300         return TokenUtil.getInstance().isTokenValid(request, reset);
301     }
302
303     /**
304      * <p>Returns <code>true</code> if there is a transaction token stored in
305      * the user's current session in all scopes beginning from default, and the
306      * value submitted as a request parameter with this action matches it.
307      * Returns <code>false</code> under any of the following circumstances:</p>
308      * <ul>
309      * <li>No session associated with this request</li>
310      * <li>No transaction token saved in the session</li>
311      * <li>No transaction token included as a request parameter</li>
312      * <li>The included transaction token value does not match the
313      * transaction token in the user's session</li>
314      * </ul>
315      *
316      * @param request The servlet request we are processing
317      * @return is token existing and valid
318      */

319     public synchronized boolean isTokenValid(HttpServletRequest JavaDoc request) {
320         return TokenUtil.getInstance().isTokenValid(request);
321     }
322
323
324     /**
325      * <p>Returns <code>true</code> if there is a transaction token stored in
326      * the user's current session in specified scopes, and the value submitted
327      * as a request parameter with this action matches it. Returns
328      * <code>false</code> under any of the following circumstances:</p>
329      * <ul>
330      * <li>No session associated with this request</li>
331      * <li>No transaction token saved in the session</li>
332      * <li>No transaction token included as a request parameter</li>
333      * <li>The included transaction token value does not match the
334      * transaction token in the user's session</li>
335      * </ul>
336      *
337      * @param scopes array of scope names, if null check all scopes begin from
338      * default
339      * @param request The servlet request we are processing
340      * @return is token existing and valid
341      */

342     public synchronized boolean isTokenValid(String JavaDoc[] scopes, HttpServletRequest JavaDoc request) {
343         return TokenUtil.getInstance().isTokenValid(scopes, request);
344     }
345
346     /**
347      * <p>Returns <code>true</code> if there is a transaction token stored in
348      * the user's current session in specified scopes, and the value submitted
349      * as a request parameter with this action matches it. Returns
350      * <code>false</code> if:</p>
351      * <ul>
352      * <li>No session associated with this request</li>
353      * <li>No transaction token saved in the session</li>
354      * <li>No transaction token included as a request parameter</li>
355      * <li>The included transaction token value does not match the
356      * transaction token in the user's session</li>
357      * </ul>
358      *
359      * @param scopes array of scope names, if null check all scopes begin from
360      * default
361      * @param request The servlet request we are processing
362      * @param reset Should we reset the token after checking it?
363      * @return is token existing and valid
364      */

365     public synchronized boolean isTokenValid(String JavaDoc[] scopes, HttpServletRequest JavaDoc request, boolean reset) {
366         return TokenUtil.getInstance().isTokenValid(scopes, request, reset);
367     }
368
369     /**
370      * <p>Resets the saved transaction token in the user's session. This
371      * indicates that transactional token checking will not be needed
372      * on the next request that is submitted.</p>
373      *
374      * @param tokenScope name of token scope
375      * @param request The servlet request we are processing
376      */

377     public synchronized void resetToken(String JavaDoc tokenScope, HttpServletRequest JavaDoc request) {
378         TokenUtil.getInstance().resetToken(tokenScope, request);
379     }
380
381     /**
382      * <p>Resets the saved transaction token in the user's session. This
383      * indicates that transactional token checking will not be needed
384      * on the next request that is submitted.</p>
385      *
386      * @param request The servlet request we are processing
387      */

388     public synchronized void resetToken(HttpServletRequest JavaDoc request) {
389         TokenUtil.getInstance().resetToken(request);
390     }
391
392     /**
393      * <p>Saves a new transaction token in the user's current session, creating
394      * a new session if necessary.</p>
395      *
396      * @param tokenScope name of token scope, if null uses default
397      * @param request The servlet request we are processing
398      */

399     public synchronized void saveToken(String JavaDoc tokenScope, HttpServletRequest JavaDoc request) {
400         TokenUtil.getInstance().saveToken(tokenScope, request);
401     }
402
403     /**
404      * <p>Saves a new transaction token in the user's current session, creating
405      * a new session if necessary.</p>
406      *
407      * @param request The servlet request we are processing
408      */

409     public synchronized void saveToken(HttpServletRequest JavaDoc request) {
410         TokenUtil.getInstance().saveToken(request);
411     }
412
413     /**
414      * <p>Returns <code>true</code> if the current form's 'back' button was
415      * pressed. This method will check if the <code>WebappConstants.BACK_KEY</code>
416      * request attribute has been set, which normally occurs if the 'back'
417      * button generated by <strong>CancelTag</strong> of type 'back' was pressed by the user
418      * in the current request. If <code>true</code>, validation performed
419      * by an <strong>ActionForm</strong>'s <code>validate()</code> method
420      * will have been skipped by the controller servlet.</p>
421      *
422      * @param request The servlet request we are processing
423      * @return whether 'back' button was pressed
424      * @see org.apache.struts.taglib.html.CancelTag
425      */

426     public boolean isBackPressed(HttpServletRequest JavaDoc request) {
427         return (request.getAttribute(WebappConstants.BACK_KEY) != null);
428     }
429 }
430
Popular Tags