001: /*
002: * $Id: BaseAction.java 471754 2006-11-06 14:55:09Z husted $
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:
022: package org.apache.struts.apps.mailreader.actions;
023:
024: import org.apache.commons.beanutils.PropertyUtils;
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027: import org.apache.struts.action.ActionForm;
028: import org.apache.struts.action.ActionForward;
029: import org.apache.struts.action.ActionMapping;
030: import org.apache.struts.action.ActionMessage;
031: import org.apache.struts.action.ActionMessages;
032: import org.apache.struts.action.DynaActionForm;
033: import org.apache.struts.actions.MappingDispatchAction;
034: import org.apache.struts.apps.mailreader.Constants;
035: import org.apache.struts.apps.mailreader.dao.ExpiredPasswordException;
036: import org.apache.struts.apps.mailreader.dao.Subscription;
037: import org.apache.struts.apps.mailreader.dao.User;
038: import org.apache.struts.apps.mailreader.dao.UserDatabase;
039:
040: import javax.servlet.ServletException;
041: import javax.servlet.http.HttpServletRequest;
042: import javax.servlet.http.HttpSession;
043:
044: /**
045: * <p>
046: * Base Action for MailReader application.
047: * </p><p>
048: * All the BaseAction helper methods are prefixed with "do"
049: * so that they can be easily distinguished from Struts and Servlet API methods.
050: * BaseAction subclasses may also have prive "do" helpers of their own.
051: * </p><p>
052: * Methods are kept in alphabetical order, to make them easier to find.
053: * </p>
054: *
055: * @version $Rev: 471754 $ $Date: 2006-11-06 08:55:09 -0600 (Mon, 06 Nov 2006) $
056: */
057: public abstract class BaseAction extends MappingDispatchAction {
058:
059: // ---- Fields ----
060:
061: /**
062: * <p>
063: * Name of username field ["username"].
064: * </p>
065: */
066: public static String USERNAME = "username";
067:
068: /**
069: * <p>
070: * Name of password field ["password"].
071: * </p>
072: */
073: public static String PASSWORD = "password";
074:
075: /**
076: * <p>
077: * Name of task field ["task"].
078: * </p>
079: */
080: public final static String TASK = "task";
081:
082: // ---- Protected Variables ----
083:
084: /**
085: * <p>
086: * The <code>Log</code> instance for this application.
087: * </p>
088: */
089: protected Log log = LogFactory.getLog(Constants.PACKAGE);
090:
091: // ---- Protected Methods ----
092:
093: /**
094: * <p>
095: * Store User object in client session.
096: * If user object is null, any existing user object is removed.
097: * </p>
098: *
099: * @param request The request we are processing
100: * @param user The user object returned from the database
101: */
102: void doCacheUser(HttpServletRequest request, User user) {
103:
104: HttpSession session = request.getSession();
105: session.setAttribute(Constants.USER_KEY, user);
106: if (log.isDebugEnabled()) {
107: log.debug("LogonAction: User '" + user.getUsername()
108: + "' logged on in session " + 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,
122: String key) {
123: if (log.isTraceEnabled()) {
124: StringBuffer sb = new StringBuffer(128);
125: sb.append(Constants.LOG_CANCEL);
126: sb.append(method);
127: log.trace(sb.toString());
128: }
129: if (key != null) {
130: session.removeAttribute(key);
131: }
132: }
133:
134: /**
135: * <p>
136: * Return the local or global forward named "failure"
137: * or null if there is no such forward.
138: * </p>
139: *
140: * @param mapping Our ActionMapping
141: * @return Return the mapping named "failure" or null if there is no such mapping.
142: */
143: protected ActionForward doFindFailure(ActionMapping mapping) {
144: if (log.isTraceEnabled()) {
145: log.trace(Constants.LOG_FAILURE);
146: }
147: return mapping.findForward(Constants.FAILURE);
148: }
149:
150: /**
151: * <p>
152: * Return the local or global forward named "logon"
153: * or null if there is no such forward.
154: * </p>
155: *
156: * @param mapping Our ActionMapping
157: * @return Return the mapping named "logon" or null if there is no such mapping.
158: */
159: protected ActionForward doFindLogon(ActionMapping mapping) {
160: if (log.isTraceEnabled()) {
161: log.trace(Constants.LOG_LOGON);
162: }
163: return mapping.findForward(Constants.LOGON);
164: }
165:
166: /**
167: * <p>
168: * Return the mapping labeled "success"
169: * or null if there is no such mapping.
170: * </p>
171: *
172: * @param mapping Our ActionMapping
173: * @return Return the mapping named "success" or null if there is no such
174: * mapping.
175: */
176: protected ActionForward doFindSuccess(ActionMapping mapping) {
177: if (log.isTraceEnabled()) {
178: log.trace(Constants.LOG_SUCCESS);
179: }
180: return mapping.findForward(Constants.SUCCESS);
181: }
182:
183: /**
184: * <p>
185: * Helper method to fetch a String property from a DynaActionForm.
186: * </p>
187: * <p>
188: * Values are returned trimmed of leading and trailing whitespace.
189: * Zero-length strings are returned as null.
190: * </p>
191: *
192: * @param form Our DynaActionForm
193: * @param property The name of the property
194: * @return The value or null if an error occurs
195: */
196: protected String doGet(ActionForm form, String property) {
197: String initial;
198: try {
199: initial = (String) PropertyUtils.getSimpleProperty(form,
200: property);
201: } catch (Throwable t) {
202: initial = null;
203: }
204: String value = null;
205: if ((initial != null) && (initial.length() > 0)) {
206: value = initial.trim();
207: if (value.length() == 0) {
208: value = null;
209: }
210: }
211: return value;
212: }
213:
214: /**
215: * <p>
216: * Obtain the cached Subscription object, if any.
217: * </p>
218: *
219: * @param session Our HttpSession
220: * @return Cached Subscription object or null
221: */
222: protected Subscription doGetSubscription(HttpSession session) {
223: return (Subscription) session
224: .getAttribute(Constants.SUBSCRIPTION_KEY);
225: }
226:
227: /**
228: * <p>
229: * Obtain the cached Subscription object, if any.
230: * </p>
231: *
232: * @param request Our HttpServletRequest
233: * @return Cached Subscription object or null
234: */
235: protected Subscription doGetSubscription(HttpServletRequest request) {
236: HttpSession session = request.getSession();
237: return doGetSubscription(session);
238: }
239:
240: /**
241: * <p>
242: * Confirm user credentials. Post any errors and return User object
243: * (or null).
244: * </p>
245: *
246: * @param database Database in which to look up the user
247: * @param username Username specified on the logon form
248: * @param password Password specified on the logon form
249: * @param errors ActionMessages queue to passback errors
250: * @return Validated User object or null
251: * @throws org.apache.struts.apps.mailreader.dao.ExpiredPasswordException
252: * to be handled by Struts exception
253: * processor via the action-mapping
254: */
255: User doGetUser(UserDatabase database, String username,
256: String password, ActionMessages errors)
257: throws ExpiredPasswordException {
258:
259: User user = null;
260: if (database == null) {
261: errors.add(ActionMessages.GLOBAL_MESSAGE,
262: new ActionMessage("error.database.missing"));
263: } else {
264:
265: if (username.equals("Hermes")) {
266: throw new ExpiredPasswordException("Hermes");
267: }
268:
269: user = database.findUser(username);
270: if ((user != null) && !user.getPassword().equals(password)) {
271: user = null;
272: }
273: if (user == null) {
274: errors.add(ActionMessages.GLOBAL_MESSAGE,
275: new ActionMessage("error.password.mismatch"));
276: }
277: }
278:
279: return user;
280: }
281:
282: /**
283: * <p>
284: * Confirm user credentials. Post any errors and return User object
285: * (or null).
286: * </p>
287: *
288: * @param username Username specified on the logon form
289: * @param password Password specified on the logon form
290: * @param errors ActionMessages queue to passback errors
291: * @return Validated User object or null
292: * @throws org.apache.struts.apps.mailreader.dao.ExpiredPasswordException
293: * to be handled by Struts exception
294: * processor via the action-mapping
295: */
296: User doGetUser(String username, String password,
297: ActionMessages errors) throws ExpiredPasswordException {
298:
299: return doGetUser(doGetUserDatabase(), username, password,
300: errors);
301: }
302:
303: /**
304: * <p>
305: * Return a reference to the UserDatabase
306: * or null if the database is not available.
307: * </p>
308: *
309: * @return a reference to the UserDatabase or null if the database is not
310: * available
311: */
312: protected UserDatabase doGetUserDatabase() {
313: return (UserDatabase) servlet.getServletContext().getAttribute(
314: Constants.DATABASE_KEY);
315: }
316:
317: /**
318: * <p>
319: * Helper method to obtain User form session (if any).
320: * </p>
321: *
322: * @param session Our HttpSession
323: * @return User object, or null if there is no user.
324: */
325: protected User doGetUser(HttpSession session) {
326: return (User) session.getAttribute(Constants.USER_KEY);
327: }
328:
329: /**
330: * <p>
331: * Helper method to obtain User form session (if any).
332: * </p>
333: *
334: * @param request Our HttpServletRequest
335: * @return User object, or null if there is no user.
336: */
337: protected User doGetUser(HttpServletRequest request) {
338: HttpSession session = request.getSession();
339: return (User) session.getAttribute(Constants.USER_KEY);
340: }
341:
342: /**
343: * <p>
344: * Save any errors and the transactioonal token, and forward to the
345: * InputForard result.
346: * </p>
347: *
348: * @param mapping Our ActionMapping
349: * @param request Our HttpServletRequest
350: * @param errors Our ActionMessages collectoin
351: * @return The InputForward for this mappintg
352: */
353: protected ActionForward doInputForward(ActionMapping mapping,
354: HttpServletRequest request, 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 = " Unexpected error when saving User: ";
405:
406: try {
407: UserDatabase database = doGetUserDatabase();
408: database.save();
409: } catch (Exception e) {
410: String message = LOG_DATABASE_SAVE_ERROR
411: + 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,
428: String value) {
429: try {
430: DynaActionForm dyna = (DynaActionForm) form;
431: dyna.set(property, value);
432: } catch (Throwable t) {
433: return false;
434: }
435: return true;
436: }
437:
438: }
|