1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.struts.apps.mailreader.actions;
20
21 import org.apache.commons.beanutils.PropertyUtils;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.struts.action.ActionForm;
25 import org.apache.struts.action.ActionForward;
26 import org.apache.struts.action.ActionMapping;
27 import org.apache.struts.action.ActionMessage;
28 import org.apache.struts.action.ActionMessages;
29 import org.apache.struts.action.DynaActionForm;
30 import org.apache.struts.actions.MappingDispatchAction;
31 import org.apache.struts.apps.mailreader.Constants;
32 import org.apache.struts.apps.mailreader.dao.ExpiredPasswordException;
33 import org.apache.struts.apps.mailreader.dao.Subscription;
34 import org.apache.struts.apps.mailreader.dao.User;
35 import org.apache.struts.apps.mailreader.dao.UserDatabase;
36
37 import javax.servlet.ServletException;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpSession;
40
41 /***
42 * <p>
43 * Base Action for MailReader application.
44 * </p><p>
45 * All the BaseAction helper methods are prefixed with "do"
46 * so that they can be easily distinguished from Struts and Servlet API methods.
47 * BaseAction subclasses may also have prive "do" helpers of their own.
48 * </p><p>
49 * Methods are kept in alphabetical order, to make them easier to find.
50 * </p>
51 *
52 * @version $Rev: 360442 $ $Date: 2005-12-31 13:10:04 -0700 (Sat, 31 Dec 2005) $
53 */
54 public abstract class BaseAction extends MappingDispatchAction {
55
56
57
58 /***
59 * <p>
60 * Name of username field ["username"].
61 * </p>
62 */
63 public static String USERNAME = "username";
64
65 /***
66 * <p>
67 * Name of password field ["password"].
68 * </p>
69 */
70 public static String PASSWORD = "password";
71
72 /***
73 * <p>
74 * Name of task field ["task"].
75 * </p>
76 */
77 public final static String TASK = "task";
78
79
80
81 /***
82 * <p>
83 * The <code>Log</code> instance for this application.
84 * </p>
85 */
86 protected Log log = LogFactory.getLog(Constants.PACKAGE);
87
88
89
90 /***
91 * <p>
92 * Store User object in client session.
93 * If user object is null, any existing user object is removed.
94 * </p>
95 *
96 * @param request The request we are processing
97 * @param user The user object returned from the database
98 */
99 void doCacheUser(HttpServletRequest request, User user) {
100
101 HttpSession session = request.getSession();
102 session.setAttribute(Constants.USER_KEY, user);
103 if (log.isDebugEnabled()) {
104 log.debug(
105 "LogonAction: User '"
106 + user.getUsername()
107 + "' logged on in session "
108 + session.getId());
109 }
110 }
111
112 /***
113 * <p>
114 * Helper method to log event and cancel transaction.
115 * </p>
116 *
117 * @param session Our HttpSession
118 * @param method Method being processed
119 * @param key Attrkibute to remove from session, if any
120 */
121 protected void doCancel(HttpSession session, String method, String key) {
122 if (log.isTraceEnabled()) {
123 StringBuffer sb = new StringBuffer(128);
124 sb.append(Constants.LOG_CANCEL);
125 sb.append(method);
126 log.trace(sb.toString());
127 }
128 if (key != null) {
129 session.removeAttribute(key);
130 }
131 }
132
133 /***
134 * <p>
135 * Return the local or global forward named "failure"
136 * or null if there is no such forward.
137 * </p>
138 *
139 * @param mapping Our ActionMapping
140 * @return Return the mapping named "failure" or null if there is no such mapping.
141 */
142 protected ActionForward doFindFailure(ActionMapping mapping) {
143 if (log.isTraceEnabled()) {
144 log.trace(Constants.LOG_FAILURE);
145 }
146 return mapping.findForward(Constants.FAILURE);
147 }
148
149 /***
150 * <p>
151 * Return the local or global forward named "logon"
152 * or null if there is no such forward.
153 * </p>
154 *
155 * @param mapping Our ActionMapping
156 * @return Return the mapping named "logon" or null if there is no such mapping.
157 */
158 protected ActionForward doFindLogon(ActionMapping mapping) {
159 if (log.isTraceEnabled()) {
160 log.trace(Constants.LOG_LOGON);
161 }
162 return mapping.findForward(Constants.LOGON);
163 }
164
165 /***
166 * <p>
167 * Return the mapping labeled "success"
168 * or null if there is no such mapping.
169 * </p>
170 *
171 * @param mapping Our ActionMapping
172 * @return Return the mapping named "success" or null if there is no such
173 * mapping.
174 */
175 protected ActionForward doFindSuccess(ActionMapping mapping) {
176 if (log.isTraceEnabled()) {
177 log.trace(Constants.LOG_SUCCESS);
178 }
179 return mapping.findForward(Constants.SUCCESS);
180 }
181
182 /***
183 * <p>
184 * Helper method to fetch a String property from a DynaActionForm.
185 * </p>
186 * <p>
187 * Values are returned trimmed of leading and trailing whitespace.
188 * Zero-length strings are returned as null.
189 * </p>
190 *
191 * @param form Our DynaActionForm
192 * @param property The name of the property
193 * @return The value or null if an error occurs
194 */
195 protected String doGet(ActionForm form, String property) {
196 String initial;
197 try {
198 initial = (String) PropertyUtils.getSimpleProperty(form, property);
199 } catch (Throwable t) {
200 initial = null;
201 }
202 String value = null;
203 if ((initial != null) && (initial.length() > 0)) {
204 value = initial.trim();
205 if (value.length() == 0) {
206 value = null;
207 }
208 }
209 return value;
210 }
211
212 /***
213 * <p>
214 * Obtain the cached Subscription object, if any.
215 * </p>
216 *
217 * @param session Our HttpSession
218 * @return Cached Subscription object or null
219 */
220 protected Subscription doGetSubscription(HttpSession session) {
221 return (Subscription) session.getAttribute(Constants.SUBSCRIPTION_KEY);
222 }
223
224 /***
225 * <p>
226 * Obtain the cached Subscription object, if any.
227 * </p>
228 *
229 * @param request Our HttpServletRequest
230 * @return Cached Subscription object or null
231 */
232 protected Subscription doGetSubscription(HttpServletRequest request) {
233 HttpSession session = request.getSession();
234 return doGetSubscription(session);
235 }
236
237 /***
238 * <p>
239 * Confirm user credentials. Post any errors and return User object
240 * (or null).
241 * </p>
242 *
243 * @param database Database in which to look up the user
244 * @param username Username specified on the logon form
245 * @param password Password specified on the logon form
246 * @param errors ActionMessages queue to passback errors
247 * @return Validated User object or null
248 * @throws org.apache.struts.apps.mailreader.dao.ExpiredPasswordException
249 * to be handled by Struts exception
250 * processor via the action-mapping
251 */
252 User doGetUser(UserDatabase database, String username,
253 String password, ActionMessages errors)
254 throws ExpiredPasswordException {
255
256 User user = null;
257 if (database == null) {
258 errors.add(
259 ActionMessages.GLOBAL_MESSAGE,
260 new ActionMessage("error.database.missing"));
261 } else {
262
263 if (username.equals("Hermes")) {
264 throw new ExpiredPasswordException("Hermes");
265 }
266
267 user = database.findUser(username);
268 if ((user != null) && !user.getPassword().equals(password)) {
269 user = null;
270 }
271 if (user == null) {
272 errors.add(
273 ActionMessages.GLOBAL_MESSAGE,
274 new ActionMessage("error.password.mismatch"));
275 }
276 }
277
278 return user;
279 }
280
281 /***
282 * <p>
283 * Confirm user credentials. Post any errors and return User object
284 * (or null).
285 * </p>
286 *
287 * @param username Username specified on the logon form
288 * @param password Password specified on the logon form
289 * @param errors ActionMessages queue to passback errors
290 * @return Validated User object or null
291 * @throws org.apache.struts.apps.mailreader.dao.ExpiredPasswordException
292 * to be handled by Struts exception
293 * processor via the action-mapping
294 */
295 User doGetUser(String username,
296 String password, ActionMessages errors)
297 throws ExpiredPasswordException {
298
299 return doGetUser(doGetUserDatabase(), username, password, errors);
300 }
301
302 /***
303 * <p>
304 * Return a reference to the UserDatabase
305 * or null if the database is not available.
306 * </p>
307 *
308 * @return a reference to the UserDatabase or null if the database is not
309 * available
310 */
311 protected UserDatabase doGetUserDatabase() {
312 return (UserDatabase) servlet.getServletContext().getAttribute(
313 Constants.DATABASE_KEY);
314 }
315
316 /***
317 * <p>
318 * Helper method to obtain User form session (if any).
319 * </p>
320 *
321 * @param session Our HttpSession
322 * @return User object, or null if there is no user.
323 */
324 protected User doGetUser(HttpSession session) {
325 return (User) session.getAttribute(Constants.USER_KEY);
326 }
327
328 /***
329 * <p>
330 * Helper method to obtain User form session (if any).
331 * </p>
332 *
333 * @param request Our HttpServletRequest
334 * @return User object, or null if there is no user.
335 */
336 protected User doGetUser(HttpServletRequest request) {
337 HttpSession session = request.getSession();
338 return (User) session.getAttribute(Constants.USER_KEY);
339 }
340
341 /***
342 * <p>
343 * Save any errors and the transactioonal token, and forward to the
344 * InputForard result.
345 * </p>
346 *
347 * @param mapping Our ActionMapping
348 * @param request Our HttpServletRequest
349 * @param errors Our ActionMessages collectoin
350 * @return The InputForward for this mappintg
351 */
352 protected ActionForward doInputForward(ActionMapping mapping,
353 HttpServletRequest request,
354 ActionMessages errors) {
355 this.saveErrors(request, errors);
356 this.saveToken(request);
357 return (mapping.getInputForward());
358 }
359
360 /***
361 * <p>
362 * Log a "processing" message for an Action.
363 * </p>
364 *
365 * @param mapping Our ActionMapping
366 * @param method Name of method being processed
367 */
368 protected void doLogProcess(ActionMapping mapping, String method) {
369 if (log.isDebugEnabled()) {
370 StringBuffer sb = new StringBuffer(128);
371 sb.append(" ");
372 sb.append(mapping.getPath());
373 sb.append(":");
374 sb.append(Constants.LOG_PROCESSING);
375 sb.append(method);
376 log.debug(sb.toString());
377 }
378 }
379
380 /***
381 * <p>
382 * Helper method to log event and save token.
383 * </p>
384 *
385 * @param request Our HttpServletRequest
386 */
387 protected void doSaveToken(HttpServletRequest request) {
388 if (log.isTraceEnabled()) {
389 log.trace(Constants.LOG_TOKEN);
390 }
391 saveToken(request);
392 }
393
394 /***
395 * <p>
396 * Persist the User object, including subscriptions, to the database.
397 * </p>
398 *
399 * @param user Our User object
400 * @throws javax.servlet.ServletException On any error
401 */
402 protected void doSaveUser(User user) throws ServletException {
403
404 final String LOG_DATABASE_SAVE_ERROR =
405 " Unexpected error when saving User: ";
406
407 try {
408 UserDatabase database = doGetUserDatabase();
409 database.save();
410 } catch (Exception e) {
411 String message = LOG_DATABASE_SAVE_ERROR + user.getUsername();
412 log.error(message, e);
413 throw new ServletException(message, e);
414 }
415 }
416
417 /***
418 * <p>
419 * Helper method to inject a String property into a DynaActionForm.
420 * </p>
421 *
422 * @param form Our DynaActionForm
423 * @param property The name of the property
424 * @param value The value for the property
425 * @return True if the assignment succeeds
426 */
427 protected boolean doSet(ActionForm form, String property, String value) {
428 try {
429 DynaActionForm dyna = (DynaActionForm) form;
430 dyna.set(property, value);
431 } catch (Throwable t) {
432 return false;
433 }
434 return true;
435 }
436
437 }