You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by hu...@apache.org on 2005/12/07 18:01:15 UTC

svn commit: r354803 - in /struts/apps/trunk/mailreader/src: java/org/apache/struts/apps/mailreader/ java/org/apache/struts/apps/mailreader/actions/ java/org/apache/struts/apps/mailreader/resources/ webapp/ webapp/WEB-INF/

Author: husted
Date: Wed Dec  7 09:01:07 2005
New Revision: 354803

URL: http://svn.apache.org/viewcvs?rev=354803&view=rev
Log:
MailReader 
* Refactor Edit* and Save* classes into MappingDispatch classes.

Added:
    struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/RegistrationAction.java
    struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/SubscriptionAction.java
Modified:
    struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/Constants.java
    struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/BaseAction.java
    struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogoffAction.java
    struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogonAction.java
    struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/WelcomeAction.java
    struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/resources/ApplicationResources.properties
    struts/apps/trunk/mailreader/src/webapp/MainMenu.jsp
    struts/apps/trunk/mailreader/src/webapp/Registration.jsp
    struts/apps/trunk/mailreader/src/webapp/WEB-INF/struts-config.xml
    struts/apps/trunk/mailreader/src/webapp/WEB-INF/web.xml
    struts/apps/trunk/mailreader/src/webapp/WEB-INF/webtest.xml
    struts/apps/trunk/mailreader/src/webapp/Welcome.jsp

Modified: struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/Constants.java
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/Constants.java?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/Constants.java (original)
+++ struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/Constants.java Wed Dec  7 09:01:07 2005
@@ -80,6 +80,11 @@
 
 
     /**
+     * The parameter under which the host name is stored.
+     */
+    public static final String HOST = "host";
+
+    /**
      * The session scope attribute under which the User object
      * for the currently logged in user is stored.
      */
@@ -136,5 +141,49 @@
      */
     public static final String LOG_SUCCESS = LOG_RESULT  + SUCCESS ;
 
-    
+
+    /**
+     * The message to log when populating a form.
+     */
+    public static final String LOG_POPULATE_FORM = " Populating form from: ";
+
+    /**
+     * The message to log when populating a subscription.
+     */
+    public static final String LOG_POPULATE_SUBSCRIPTION = " Populating subscription: ";
+
+    /**
+     * The message to log when populating a user.
+     */
+    public static final String LOG_POPULATE_USER = " Populating user: ";
+
+    /**
+     * The message to log when forwarding to a 'success' result.
+     */
+    public static final String LOG_PROCESSING = " Processing: ";
+
+
+    /**
+     * The message to log when cancelling a transaction.
+     */
+    public static final String LOG_CANCEL = " Transaction cancelled: ";
+
+
+    /**
+     * The message to log when setting a transactional token.
+     */
+    public static final String LOG_TOKEN = " Setting transactional control token";
+
+
+    /**
+     * The message to log when checking a transactional token.
+     */
+    public static final String LOG_TOKEN_CHECK = " Checking transactional control token";
+
+
+    /**
+     * The resource key for an error with the transactional token.
+     */
+    public static final String MSG_TRANSACTION_TOKEN = "error.transaction.token";
+
 }

Modified: struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/BaseAction.java
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/BaseAction.java?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/BaseAction.java (original)
+++ struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/BaseAction.java Wed Dec  7 09:01:07 2005
@@ -20,22 +20,26 @@
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
+import javax.servlet.ServletException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.struts.action.Action;
 import org.apache.struts.action.ActionForward;
 import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.ActionMessages;
 import org.apache.struts.apps.mailreader.Constants;
 import org.apache.struts.apps.mailreader.dao.UserDatabase;
 import org.apache.struts.apps.mailreader.dao.User;
+import org.apache.struts.apps.mailreader.dao.Subscription;
+import org.apache.struts.actions.DispatchAction;
+import org.apache.struts.actions.MappingDispatchAction;
 
 /**
  * Base Action for MailReader application.
  *
  * @version $Rev$ $Date$
  */
-public class BaseAction extends Action {
+public class BaseAction extends MappingDispatchAction {
 
     // ----------------------------------------------------- Instance Variables
 
@@ -49,21 +53,31 @@
     /**
      * Return a reference to the UserDatabase
      * or null if the database is not available.
-     * @param request The request we are processing
      * @return a reference to the UserDatabase or null if the database is not available
      */
-    protected UserDatabase getUserDatabase(HttpServletRequest request) {
+    protected UserDatabase doGetUserDatabase() {
         return (UserDatabase) servlet.getServletContext().getAttribute(
                 Constants.DATABASE_KEY);
     }
 
+
+    protected Subscription doGetSubscription(HttpSession session) {
+        return (Subscription) session.getAttribute(Constants.SUBSCRIPTION_KEY);
+    }
+
+
+    protected Subscription doGetSubscription(HttpServletRequest request) {
+        HttpSession session = request.getSession();
+        return doGetSubscription(session);
+    }
+
     /**
      * Return the local or global forward named "failure"
      * or null if there is no such forward.
      * @param mapping Our ActionMapping
      * @return Return the mapping named "failure" or null if there is no such mapping.
      */
-    protected ActionForward findFailure(ActionMapping mapping) {
+    protected ActionForward doFindFailure(ActionMapping mapping) {
         if (log.isTraceEnabled()) {
             log.trace(Constants.LOG_FAILURE);
         }
@@ -76,7 +90,7 @@
      * @param mapping Our ActionMapping
      * @return Return the mapping named "logon" or null if there is no such mapping.
      */
-    protected ActionForward findLogon(ActionMapping mapping, HttpSession session) {
+    protected ActionForward doFindLogon(ActionMapping mapping, HttpSession session) {
         if (log.isTraceEnabled()) {
             log.trace(Constants.LOG_LOGON_NONE  + session.getId());
             log.trace(Constants.LOG_LOGON);
@@ -84,27 +98,116 @@
         return (mapping.findForward(Constants.LOGON));
     }
 
+    protected ActionForward doFindLogon(ActionMapping mapping, HttpServletRequest request) {
+        HttpSession session = request.getSession();
+        return doFindLogon(mapping,session);
+    }
+
     /**
      * Return the mapping labeled "success"
      * or null if there is no such mapping.
      * @param mapping Our ActionMapping
      * @return Return the mapping named "success" or null if there is no such mapping.
      */
-    protected ActionForward findSuccess(ActionMapping mapping) {
+    protected ActionForward doFindSuccess(ActionMapping mapping) {
         if (log.isTraceEnabled()) {
             log.trace(Constants.LOG_SUCCESS);
         }
         return mapping.findForward(Constants.SUCCESS);
     }
 
+    /**
+     * Helper method to obtain User form session (if any).
+     * @param session Our HttpSession
+     * @return User object, or null if there is no user.
+     */
+    protected User doGetUser(HttpSession session) {
+        return (User) session.getAttribute(Constants.USER_KEY);
+    }
 
     /**
      * Helper method to obtain User form session (if any).
-     * @param session
+     * @param request Our HttpServletRequest
      * @return User object, or null if there is no user.
      */
-    protected User getUser(HttpSession session) {
+    protected User doGetUser(HttpServletRequest request) {
+        HttpSession session = request.getSession();
         return (User) session.getAttribute(Constants.USER_KEY);
     }
+
+    /**
+     * Log a "processing" message for an Action.
+     * @param mapping Our ActionMapping
+     * @param method Name of method being processed
+     */
+    protected void doLogProcess(ActionMapping mapping, String method) {
+        if (log.isDebugEnabled()) {
+            StringBuffer sb = new StringBuffer(128);
+            sb.append(" ");
+            sb.append(mapping.getPath());
+            sb.append(":");
+            sb.append(Constants.LOG_PROCESSING);
+            sb.append(method);
+            log.debug(sb.toString());
+        }
+    }
+
+    /**
+     * Helper method to log event and cancel transaction.
+     * @param session Our HttpSession
+     * @param method Method being processed
+     * @param key Attrkibute to remove from session, if any
+     */
+    protected void doCancel (HttpSession session, String method, String key) {
+        if (log.isTraceEnabled()) {
+            StringBuffer sb = new StringBuffer(128);
+            sb.append(Constants.LOG_CANCEL);
+            sb.append(method);
+            log.trace(sb.toString());
+        }
+        if (key!=null) session.removeAttribute(key);
+    }
+
+    /**
+     * Helper method to log event and save token.
+     * @param request Our HttpServletRequest
+     */
+    protected void doSaveToken(HttpServletRequest request) {
+        if (log.isTraceEnabled()) {
+            log.trace(Constants.LOG_TOKEN);
+        }
+        saveToken(request);
+    }
+
+
+    /**
+      * <p>
+      * Persist the User object, including subscriptions, to the database.
+      * </p>
+      * @param user Our User object
+      * @throws javax.servlet.ServletException On any error
+      */
+     protected void doSaveUser(User user) throws ServletException {
+
+         final String LOG_DATABASE_SAVE_ERROR = " Unexpected error when saving User: ";
+
+         try {
+             UserDatabase database = doGetUserDatabase();
+             database.save();
+         } catch (Exception e) {
+             String message = LOG_DATABASE_SAVE_ERROR + user.getUsername();
+             log.error(message, e);
+             throw new ServletException(message, e);
+         }
+     }
+
+    protected ActionForward doInputForward(ActionMapping mapping, HttpServletRequest request, ActionMessages errors) {
+
+        this.saveErrors(request, errors);
+        this.saveToken(request);
+        return (mapping.getInputForward());
+
+    }
+
 
 }

Modified: struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogoffAction.java
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogoffAction.java?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogoffAction.java (original)
+++ struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogoffAction.java Wed Dec  7 09:01:07 2005
@@ -69,7 +69,7 @@
         session.removeAttribute(Constants.USER_KEY);
         session.invalidate();
 
-        return findSuccess(mapping);
+        return doFindSuccess(mapping);
 
     }
 

Modified: struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogonAction.java
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogonAction.java?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogonAction.java (original)
+++ struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/LogonAction.java Wed Dec  7 09:01:07 2005
@@ -134,7 +134,7 @@
         throws Exception {
 
         // Local variables
-        UserDatabase database = getUserDatabase(request);
+        UserDatabase database = doGetUserDatabase();
         String username = (String) PropertyUtils.getSimpleProperty(form,
                 USERNAME);
         String password = (String) PropertyUtils.getSimpleProperty(form,
@@ -152,7 +152,7 @@
 
         SaveUser(request,user);
 
-        return findSuccess(mapping);
+        return doFindSuccess(mapping);
 
     }
 

Added: struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/RegistrationAction.java
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/RegistrationAction.java?rev=354803&view=auto
==============================================================================
--- struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/RegistrationAction.java (added)
+++ struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/RegistrationAction.java Wed Dec  7 09:01:07 2005
@@ -0,0 +1,304 @@
+package org.apache.struts.apps.mailreader.actions;
+
+import org.apache.struts.apps.mailreader.dao.User;
+import org.apache.struts.apps.mailreader.dao.UserDatabase;
+import org.apache.struts.apps.mailreader.dao.ExpiredPasswordException;
+import org.apache.struts.apps.mailreader.forms.RegistrationForm;
+import org.apache.struts.apps.mailreader.Constants;
+
+import org.apache.struts.action.ActionMessages;
+import org.apache.struts.action.ActionMessage;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.ActionForm;
+
+import org.apache.commons.beanutils.PropertyUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletException;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * <p>
+ * Provide an Edit method for retrieving an existing user,
+ * and a Save method for updating or inserting a user.
+ * </p>
+ * <p>
+ * Both methods utilize a RegistrationForm to obtain or expose User details.
+ * If Save is used to create a user,
+ * additional validations ensure input is nominal.
+ * When a user is created,
+ * Save also handles the initial logon.
+ * </p>
+ */
+public final class RegistrationAction extends BaseAction {
+
+    // ---- Private Methods ----
+
+    final String LOG_REGISTRATION_POPULATE = "RegistrationForm.populate";
+
+    /**
+     * <p>
+     * Helper method to post error message when user already exists.
+     * </p>
+     * @param regform Our input form
+     * @param errors Our ActionMessages collection
+     */
+    private void errorUsernameUnique(RegistrationForm regform, org.apache.struts.action.ActionMessages errors) {
+        errors.add(
+            "username",
+            new org.apache.struts.action.ActionMessage("error.username.unique", regform.getUsername()));
+    }
+
+    /**
+     * <p>
+     * Verify input for creating a new user,
+     * create the user, and process the login.
+     * </p>
+     * @param regform The input form
+     * @param request The HttpRequest being served
+     * @param errors The ActionMessages collection for any errors
+     * @return A new User and empty Errors if create succeeds,
+     * or null and Errors if create fails
+     */
+    private User doCreateUser(
+         RegistrationForm regform,
+         HttpServletRequest request,
+         ActionMessages errors) {
+
+        if (log.isTraceEnabled()) {
+           log.trace(" Perform additional validations on Create");
+        }
+
+         HttpSession session = request.getSession();
+         UserDatabase database = doGetUserDatabase();
+
+         String name = regform.getUsername();
+        try {
+            if (database.findUser(name) != null) {
+                errorUsernameUnique(regform,errors);
+             }
+        }
+        catch (ExpiredPasswordException e)   {
+            errorUsernameUnique(regform,errors);
+            errors.add("errors.literal",new ActionMessage(e.getMessage()));
+        }
+
+         String password = regform.getPassword();
+         if ((password == null) || (password.length() < 1)) {
+             errors.add("password", new ActionMessage("error.password.required"));
+
+         String password2 = regform.getPassword2();
+         if ((password2 == null) || (password2.length() < 1)) {
+             errors.add(
+                 "password2",
+                 new ActionMessage("error.password2.required"));
+            }
+         }
+
+         if (!errors.isEmpty()) {
+             return null;
+         }
+
+         User user = database.createUser(regform.getUsername());
+
+         // Log the user in
+          session.setAttribute(Constants.USER_KEY, user);
+          if (log.isTraceEnabled()) {
+              log.trace(
+                  " User: '"
+                      + user.getUsername()
+                      + "' logged on in session: "
+                      + session.getId());
+             }
+
+         return user;
+     }
+
+    /**
+     * <p>
+     * Helper method to populate the input form from the User object.
+     * </p>
+     * @param regform Form with incoming values
+     * @param user User object to populate
+     * @throws ServletException On any error
+     */
+   private void doPopulate(RegistrationForm regform, User user) throws ServletException {
+
+        final String title = "Edit";
+
+        if (log.isTraceEnabled()) {
+            log.trace(Constants.LOG_POPULATE_FORM + user);
+        }
+
+       try {
+           PropertyUtils.copyProperties(regform, user);
+           regform.setAction(title);
+           regform.setPassword(null);
+           regform.setPassword2(null);
+       } catch (InvocationTargetException e) {
+           Throwable t = e.getTargetException();
+           if (t == null)
+               t = e;
+           log.error(LOG_REGISTRATION_POPULATE, t);
+           throw new ServletException(LOG_REGISTRATION_POPULATE, t);
+       } catch (Throwable t) {
+           log.error(LOG_REGISTRATION_POPULATE, t);
+           throw new ServletException(LOG_REGISTRATION_POPULATE, t);
+       }
+   }
+
+    /**
+     * <p>
+     * Helper method to populate the User object from the input form.
+     * </p>
+     * @param user User object to populate
+     * @param regform Form with incoming values
+     * @throws ServletException On any error
+     */
+    private void doPopulate(User user, RegistrationForm regform) throws ServletException {
+
+        if (log.isTraceEnabled()) {
+            log.trace(Constants.LOG_POPULATE_USER + user);
+        }
+
+        try {
+            String oldPassword = user.getPassword();
+            PropertyUtils.copyProperties(user, regform);
+            if ((regform.getPassword() == null)
+                || (regform.getPassword().length() < 1)) {
+
+                user.setPassword(oldPassword);
+            }
+
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getTargetException();
+            if (t == null) {
+                t = e;
+            }
+
+            log.error(LOG_REGISTRATION_POPULATE, t);
+            throw new ServletException(LOG_REGISTRATION_POPULATE, t);
+
+        } catch (Throwable t) {
+            log.error(LOG_REGISTRATION_POPULATE, t);
+            throw new ServletException(LOG_REGISTRATION_POPULATE, t);
+        }
+    }
+
+    /**
+     * <p>
+     * Validate and clear the transactional token,
+     * creating logging statements as needed.
+     * </p>
+     * @param request Our HttpServletRequest
+     * @param errors ActionErrors to transfer any messages
+     */
+    private void doValidateToken(HttpServletRequest request, ActionMessages errors) {
+
+        if (log.isTraceEnabled()) {
+            log.trace(Constants.LOG_TOKEN_CHECK);
+        }
+
+        if (!isTokenValid(request)) {
+            errors.add(
+                ActionMessages.GLOBAL_MESSAGE,
+                new ActionMessage(Constants.MSG_TRANSACTION_TOKEN));
+        }
+
+        resetToken(request);
+    }
+
+    // ----- Public Methods ----
+
+    /**
+     * <p>
+     * Retrieve the User object to edit or null if the User does not exist,
+     * and set an transactional token to later detect multiple Save commands.
+     * </p>
+     * @param mapping Our ActionMapping
+     * @param form Our ActionForm
+     * @param request Our HttpServletRequest
+     * @param response Our HttpServletResponse
+     * @return The "Success" result for this mapping
+     * @throws Exception on any error
+     */
+    public ActionForward Edit(
+        ActionMapping mapping,
+        ActionForm form,
+        HttpServletRequest request,
+        HttpServletResponse response)
+        throws Exception {
+
+            final String method = "Edit";
+            doLogProcess(mapping,method);
+
+            HttpSession session = request.getSession();
+            User user = doGetUser(session);
+            boolean updating = (user!=null);
+            if (updating) {
+                RegistrationForm regform = (RegistrationForm) form;
+                doPopulate(regform,user);
+            }
+
+           doSaveToken(request);
+           return doFindSuccess(mapping);
+    }
+
+    /**
+     * <p>
+     * Insert or update a User object to the persistent store.
+     * </p>
+     * <p>
+     * If a User is not logged in,
+     * then a new User is created and automatically logged in.
+     * Otherwise, the existing User is updated.
+     * </p>
+     * @param mapping Our ActionMapping
+     * @param form Our ActionForm
+     * @param request Our HttpServletRequest
+     * @param response Our HttpServletResponse
+     * @return The "Success" result for this mapping
+     * @throws Exception on any error
+     */
+     public ActionForward Save(
+        ActionMapping mapping,
+        ActionForm form,
+        HttpServletRequest request,
+        HttpServletResponse response)
+        throws Exception {
+
+        final String method = "Save";
+        doLogProcess(mapping,method);
+
+        HttpSession session = request.getSession();
+        if (isCancelled(request)) {
+            doCancel(session,method,Constants.SUBSCRIPTION_KEY);
+            return doFindSuccess(mapping);
+        }
+
+        ActionMessages errors = new ActionMessages();
+        doValidateToken(request,errors);
+
+        if (!errors.isEmpty()) {
+            return doInputForward(mapping,request,errors);
+        }
+
+        RegistrationForm regform = (RegistrationForm) form;
+        User user = doGetUser(session);
+        if (user==null) {
+            user = doCreateUser(regform,request,errors);
+            if (!errors.isEmpty()) {
+                return doInputForward(mapping,request,errors);
+            }
+        }
+
+       doPopulate(user,regform);
+       doSaveUser(user);
+
+       return doFindSuccess(mapping);
+    }
+
+}

Added: struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/SubscriptionAction.java
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/SubscriptionAction.java?rev=354803&view=auto
==============================================================================
--- struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/SubscriptionAction.java (added)
+++ struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/SubscriptionAction.java Wed Dec  7 09:01:07 2005
@@ -0,0 +1,284 @@
+package org.apache.struts.apps.mailreader.actions;
+
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.apps.mailreader.dao.User;
+import org.apache.struts.apps.mailreader.dao.Subscription;
+import org.apache.struts.apps.mailreader.Constants;
+import org.apache.struts.apps.mailreader.forms.SubscriptionForm;
+import org.apache.commons.beanutils.PropertyUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletException;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: ted_2
+ * Date: Dec 7, 2005
+ * Time: 6:33:03 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class SubscriptionAction extends BaseAction {
+
+    // ---- Private Methods ----
+
+    final String LOG_SUBSCRIPTION_POPULATE = "SubscriptionForm.populate";
+
+    private Subscription doFindSubscription(User user, String host) {
+
+        Subscription subscription;
+
+        try {
+            subscription = user.findSubscription(host);
+        }
+        catch (NullPointerException e) {
+            subscription = null;
+        }
+
+        if ((subscription == null) && (log.isTraceEnabled())) {
+            log.trace(
+                " No subscription for user "
+                + user.getUsername()
+                + " and host "
+                + host);
+        }
+
+        return subscription;
+    }
+
+    /**
+     * <p>
+     * Helper method to populate the Subscription object from the input form.
+     * </p>
+     * @param subscription User object to populate
+     * @param subform Form with incoming values
+     * @throws ServletException On any error
+     */
+    private void doPopulate(Subscription subscription, SubscriptionForm subform) throws ServletException {
+
+        if (log.isTraceEnabled()) {
+            log.trace(Constants.LOG_POPULATE_SUBSCRIPTION + subscription);
+        }
+
+        try {
+            PropertyUtils.copyProperties(subscription, subform);
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getTargetException();
+            if (t == null)
+                t = e;
+            log.error(LOG_SUBSCRIPTION_POPULATE, t);
+            throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t);
+        } catch (Throwable t) {
+            log.error(LOG_SUBSCRIPTION_POPULATE, t);
+            throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t);
+        }
+
+    }
+
+
+    /**
+     * <p>
+     * Helper method to populate the input form from the Subscription object.
+     * </p>
+     * @param subscription User object to populate
+     * @param subform Form with incoming values
+     * @throws ServletException On any error
+     */
+    private void doPopulate(SubscriptionForm subform, Subscription subscription) throws ServletException {
+
+        final String title = "Edit";
+
+        if (log.isTraceEnabled()) {
+            log.trace(Constants.LOG_POPULATE_FORM + subscription.getHost());
+        }
+
+        try {
+            PropertyUtils.copyProperties(subform, subscription);
+            subform.setAction(title);
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getTargetException();
+            if (t == null) t = e;
+            log.error(LOG_SUBSCRIPTION_POPULATE, t);
+            throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t);
+        } catch (Throwable t) {
+            log.error(LOG_SUBSCRIPTION_POPULATE, t);
+            throw new ServletException(LOG_SUBSCRIPTION_POPULATE, t);
+        }
+    }
+
+    /**
+     * Remove the given subscription for this user.
+     * @param mapping Our ActionMapping
+     * @param session Our HttpSession
+     * @param user Our User
+     * @param subscription Subscription to delete
+     * @return "Success" if delete is nominal, "Logon" if attributes are missing
+     * @throws ServletException if updates fails
+     */
+    private ActionForward doRemoveSubscription(
+       ActionMapping mapping,
+       HttpSession session,
+       User user,
+       Subscription subscription)
+       throws ServletException {
+
+            final String method = "Delete";
+            doLogProcess(mapping,method);
+
+            if (log.isTraceEnabled()) {
+                log.trace(
+                    " Deleting subscription to mail server '"
+                    + subscription.getHost()
+                    + "' for user '"
+                    + user.getUsername()
+                    + "'");
+            }
+
+            boolean missingAttributes = ((user==null) || (subscription==null));
+            if (missingAttributes) {
+                return doFindLogon(mapping,session);
+            }
+
+            user.removeSubscription(subscription);
+            session.removeAttribute(Constants.SUBSCRIPTION_KEY);
+            doSaveUser(user);
+
+            return doFindSuccess(mapping);
+    }
+
+    // ----- Public Methods ----
+
+    /**
+     * <p>
+     * Prepare for a Delete operation by populating the form
+     * and seting the action to Delete.
+     * </p>
+     * @param mapping Our ActionMapping
+     * @param form Our ActionForm
+     * @param request Our HttpServletRequest
+     * @param response Our HttpServletResponse
+     * @return The "Success" result for this mapping
+     * @throws Exception on any error
+     */
+    public ActionForward Delete(
+        ActionMapping mapping,
+        ActionForm form,
+        HttpServletRequest request,
+        HttpServletResponse response)
+        throws Exception {
+
+        final String method = "Delete";
+        doLogProcess(mapping,method);
+
+        ActionForward result = Edit(mapping,form,request,response);
+
+        SubscriptionForm subform = (SubscriptionForm) form;
+        subform.setAction(method);
+        return result;
+    }
+
+
+    /**
+     * <p>
+     * Retrieve the Subscription object to edit
+     * or null if the Subscription does not exist.
+     * </p><p>
+     * The Subscription object is bound to the User,
+     * and so if the User is not logged in,
+     * control is forwarded to the Logon result.
+     * </p>
+     * @param mapping Our ActionMapping
+     * @param form Our ActionForm
+     * @param request Our HttpServletRequest
+     * @param response Our HttpServletResponse
+     * @return The "Success" result for this mapping
+     * @throws Exception on any error
+     */
+    public ActionForward Edit(
+        ActionMapping mapping,
+        ActionForm form,
+        HttpServletRequest request,
+        HttpServletResponse response)
+        throws Exception {
+
+        final String method = "Edit";
+        doLogProcess(mapping,method);
+
+        HttpSession session = request.getSession();
+        User user = doGetUser(session);
+        if (user==null) return doFindLogon(mapping,session);
+
+        // Retrieve the subscription, if there is one
+        Subscription subscription;
+        SubscriptionForm subform = (SubscriptionForm) form;
+        String host = subform.getHost();
+        boolean updating = (host!=null);
+        if (updating) {
+            subscription = doFindSubscription(user,host);
+            if (subscription==null) return doFindFailure(mapping);
+            session.setAttribute(Constants.SUBSCRIPTION_KEY, subscription);
+            doPopulate(subform,subscription);
+            subform.setAction(method);
+        }
+
+        return doFindSuccess(mapping);
+    }
+
+    /**
+     * <p>
+     * Insert or update a Subscription object to the persistent store.
+     * </p>
+     * @param mapping Our ActionMapping
+     * @param form Our ActionForm
+     * @param request Our HttpServletRequest
+     * @param response Our HttpServletResponse
+     * @return The "Success" result for this mapping
+     * @throws Exception on any error
+     */
+     public ActionForward Save(
+        ActionMapping mapping,
+        ActionForm form,
+        HttpServletRequest request,
+        HttpServletResponse response)
+        throws Exception {
+
+        final String method = "Save";
+        doLogProcess(mapping,method);
+
+        SubscriptionForm subform = (SubscriptionForm) form;
+        HttpSession session = request.getSession();
+
+        User user = doGetUser(request);
+        if (user == null) {
+            return doFindLogon(mapping,session);
+        }
+
+        if (isCancelled(request)) {
+            doCancel(session,method,Constants.SUBSCRIPTION_KEY);
+            return doFindSuccess(mapping);
+        }
+
+        String action = subform.getAction();
+        Subscription subscription = doGetSubscription(request);
+        boolean isDelete = action.equals("Delete");
+        if (isDelete) {
+            return doRemoveSubscription(mapping,session,user,subscription);
+        }
+
+        if (subscription==null) {
+            subscription = user.createSubscription(subform.getHost());
+            session.setAttribute(Constants.SUBSCRIPTION_KEY,subscription);
+        }
+
+        doPopulate(subscription,subform);
+        doSaveUser(user);
+        session.removeAttribute(Constants.SUBSCRIPTION_KEY);
+
+        return doFindSuccess(mapping);
+    }
+
+}

Modified: struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/WelcomeAction.java
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/WelcomeAction.java?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/WelcomeAction.java (original)
+++ struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/actions/WelcomeAction.java Wed Dec  7 09:01:07 2005
@@ -67,7 +67,7 @@
         }
 
         // Confirm database loaded
-        UserDatabase userDatabase = getUserDatabase(request);
+        UserDatabase userDatabase = doGetUserDatabase();
         if (userDatabase==null) {
             messages.add(Constants.ERROR_DATABASE_NOT_LOADED);
         }
@@ -75,11 +75,11 @@
         // If there were errors, forward to our failure page
         if (messages.size()>0) {
             request.setAttribute(Constants.ERROR_KEY,messages);
-            return findFailure(mapping);
+            return doFindFailure(mapping);
         }
 
         // Forward to our success page
-        return findSuccess(mapping);
+        return doFindSuccess(mapping);
 
     }
 

Modified: struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/resources/ApplicationResources.properties
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/resources/ApplicationResources.properties?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/resources/ApplicationResources.properties (original)
+++ struts/apps/trunk/mailreader/src/java/org/apache/struts/apps/mailreader/resources/ApplicationResources.properties Wed Dec  7 09:01:07 2005
@@ -89,3 +89,4 @@
 errors.range={0} is not in the range {1} through {2}.
 errors.creditcard={0} is not a valid credit card number.
 errors.email={0} is an invalid e-mail address.
+errors.literal={0}

Modified: struts/apps/trunk/mailreader/src/webapp/MainMenu.jsp
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/webapp/MainMenu.jsp?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/webapp/MainMenu.jsp (original)
+++ struts/apps/trunk/mailreader/src/webapp/MainMenu.jsp Wed Dec  7 09:01:07 2005
@@ -11,7 +11,7 @@
 <body>
 <h3><bean:message key="mainMenu.heading"/> <bean:write name="user" property="fullName" /></h3>
 <ul>
-<li><html:link action="/EditRegistration?action=Edit"><bean:message key="mainMenu.registration"/></html:link></li>
+<li><html:link action="/EditRegistration"><bean:message key="mainMenu.registration"/></html:link></li>
 <li><html:link forward="Logoff"><bean:message key="mainMenu.logoff"/></html:link></li>
 </ul>
 </body>

Modified: struts/apps/trunk/mailreader/src/webapp/Registration.jsp
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/webapp/Registration.jsp?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/webapp/Registration.jsp (original)
+++ struts/apps/trunk/mailreader/src/webapp/Registration.jsp Wed Dec  7 09:01:07 2005
@@ -156,23 +156,25 @@
       <bean:write name="subscription" property="autoConnect"/>
     </td>
     <td align="center">
-      <app:linkSubscription page="/EditSubscription.do?action=Delete">
+      <html:link action="/DeleteSubscription"
+       paramName="subscription" paramId="host" paramProperty="host">
         <bean:message key="registration.deleteSubscription"/>
-      </app:linkSubscription>
-      <app:linkSubscription page="/EditSubscription.do?action=Edit">
+      </html:link>
+        &nbsp;
+      <html:link action="/EditSubscription"
+       paramName="subscription" paramId="host" paramProperty="host">
         <bean:message key="registration.editSubscription"/>
-      </app:linkSubscription>
+      </html:link>
     </td>
   </tr>
 </logic:iterate>
 
 </table>
 
-<html:link action="/EditSubscription?action=Create" paramId="username"
- paramName="RegistrationForm" paramProperty="username">
+<html:link action="/EditSubscription">
   <bean:message key="registration.addSubscription"/>
 </html:link>
-                     
+
 
 </logic:equal>
 

Modified: struts/apps/trunk/mailreader/src/webapp/WEB-INF/struts-config.xml
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/webapp/WEB-INF/struts-config.xml?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/webapp/WEB-INF/struts-config.xml (original)
+++ struts/apps/trunk/mailreader/src/webapp/WEB-INF/struts-config.xml Wed Dec  7 09:01:07 2005
@@ -41,7 +41,7 @@
       <form-property name="password" type="java.lang.String"/>
     </form-bean>
 
-    <!-- Registration form bean -->
+    <!-- RegistrationAction form bean -->
     <form-bean      name="RegistrationForm"
                     type="org.apache.struts.apps.mailreader.forms.RegistrationForm"/>
 
@@ -99,33 +99,42 @@
          <forward name="Success"              path="/Welcome.do"/>
        </action>
 
-      <!-- Matches all edit actions  -->
-      <action    path="/Edit*"
-                 type="org.apache.struts.apps.mailreader.actions.Edit{1}Action"
-                 name="{1}Form"
-                scope="request"
-             validate="false">
-        <forward name="Success"              path="/{1}.jsp"/>
+      <!-- "Abstract" mapping to use as base  -->
+      <action path="//BaseAction"
+             input="Input"
+              type="org.apache.struts.apps.mailreader.actions.{1}Action"
+              name="{1}Form"
+             scope="request">
+          <forward name="Success"              path="/{1}.jsp"/>
+          <forward name="Input"                path="/{1}.jsp"/>
       </action>
 
-      <!-- Matches all other Save actions -->
-      <action    path="/Save*"
-                 type="org.apache.struts.apps.mailreader.actions.Save{1}Action"
-                 name="{1}Form"
-                 scope="request"
-                 input="Input" >
-        <forward name="Success"              path="/MainMenu.do"/>
-        <forward name="Input"                path="/(1).jsp"/>
+      <action path="/Delete*"
+           extends="//BaseAction"
+           parameter="Delete"
+          validate="false">
+      </action>
+
+      <action path="/Edit*"
+           extends="//BaseAction"
+           parameter="Edit"
+          validate="false">
+      </action>
+
+      <action path="/Save*"
+           extends="//BaseAction"
+           parameter="Save"
+          validate="true">
+          <forward name="Success"              path="/MainMenu.jsp"/>
       </action>
 
       <!-- Matches SaveSubscription action -->
       <!-- If extends understood wildcards, we could specify only Success here. -->
       <action    path="/SaveSubscription"
                  extends="/Save*"
-                 type="org.apache.struts.apps.mailreader.actions.SaveSubscriptionAction"
-                 name="SubscriptionForm"
-                 input="Input" >
-        <forward name="Success"              path="/EditRegistration.do?action=Edit"/>
+                 type="org.apache.struts.apps.mailreader.actions.SubscriptionAction"
+                 name="SubscriptionForm" >
+        <forward name="Success"              path="/EditRegistration.do"/>
         <forward name="Input"                path="/Subscription.jsp"/>
       </action>
 

Modified: struts/apps/trunk/mailreader/src/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/webapp/WEB-INF/web.xml?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/webapp/WEB-INF/web.xml (original)
+++ struts/apps/trunk/mailreader/src/webapp/WEB-INF/web.xml Wed Dec  7 09:01:07 2005
@@ -5,7 +5,7 @@
 	"http://java.sun.com/dtd/web-app_2_3.dtd">
 
 <web-app>
-	<display-name>Struts Example Application</display-name>
+	<display-name>Struts MailReader Application</display-name>
 
   <!-- Action Servlet Configuration -->
   <servlet>

Modified: struts/apps/trunk/mailreader/src/webapp/WEB-INF/webtest.xml
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/webapp/WEB-INF/webtest.xml?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/webapp/WEB-INF/webtest.xml (original)
+++ struts/apps/trunk/mailreader/src/webapp/WEB-INF/webtest.xml Wed Dec  7 09:01:07 2005
@@ -158,7 +158,7 @@
                <!-- This throws an Error 500.
                     We might want to goto Logon instead.
                <invoke
-                   description="Skip Save Registration page"
+                   description="Skip Save RegistrationAction page"
                    url="SaveRegistration.do"/>
                 &logon-page;
                 -->

Modified: struts/apps/trunk/mailreader/src/webapp/Welcome.jsp
URL: http://svn.apache.org/viewcvs/struts/apps/trunk/mailreader/src/webapp/Welcome.jsp?rev=354803&r1=354802&r2=354803&view=diff
==============================================================================
--- struts/apps/trunk/mailreader/src/webapp/Welcome.jsp (original)
+++ struts/apps/trunk/mailreader/src/webapp/Welcome.jsp Wed Dec  7 09:01:07 2005
@@ -7,10 +7,10 @@
 <title><bean:message key="index.title"/></title>
 <link rel="stylesheet" type="text/css" href="base.css" />
 </head>
-
+<body>
 <h3><bean:message key="index.heading"/></h3>
 <ul>
-<li><html:link action="/EditRegistration?action=Create"><bean:message key="index.registration"/></html:link></li>
+<li><html:link action="/EditRegistration"><bean:message key="index.registration"/></html:link></li>
 <li><html:link action="/Logon"><bean:message key="index.logon"/></html:link></li>
 </ul>
 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org