View Javadoc

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