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 2006/01/09 14:32:20 UTC

svn commit: r367292 [1/3] - in /struts/sandbox/trunk/mailreader-course/lab-2-1-src: ./ META-INF/ WEB-INF/ java/ java/org/ java/org/apache/ java/org/apache/struts/ java/org/apache/struts/apps/ java/org/apache/struts/apps/mailreader/ java/org/apache/stru...

Author: husted
Date: Mon Jan  9 05:32:07 2006
New Revision: 367292

URL: http://svn.apache.org/viewcvs?rev=367292&view=rev
Log:
MailReader Training Course 
* Add workshop code for session 2-1

Added:
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/META-INF/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/META-INF/context.xml   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/WEB-INF/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/WEB-INF/web.xml   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/Constants.java   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/LogonAction.java   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/MemoryDatabasePlugIn.java   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/RegisterAction.java   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/test/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/LogonForm.jsp   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/MainMenu.jsp   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/RegisterForm.jsp   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-configure.xml   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-validate.xml   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-configure.xml   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-validate.xml   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/database.xml   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/struts-config.xml   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/struts-html.tld   (with props)
    struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/web.xml   (with props)

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/META-INF/context.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/META-INF/context.xml?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/META-INF/context.xml (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/META-INF/context.xml Mon Jan  9 05:32:07 2006
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context path="/">
+</Context>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/META-INF/context.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/WEB-INF/web.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/WEB-INF/web.xml?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/WEB-INF/web.xml (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/WEB-INF/web.xml Mon Jan  9 05:32:07 2006
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+</web-app>
\ No newline at end of file

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/WEB-INF/web.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/Constants.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/Constants.java?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/Constants.java (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/Constants.java Mon Jan  9 05:32:07 2006
@@ -0,0 +1,207 @@
+package org.apache.struts.apps.mailreader.course;
+
+/**
+ * <p/>
+ * Manifest constants for the MailReader application.
+ * </p>
+ */
+public class Constants {
+
+    // --- Tokens ----
+
+    /**
+     * <p/>
+     * The token representing a "create" task.
+     * </p>
+     */
+    public static final String CREATE = "Create";
+
+    /**
+     * <p/>
+     * The application scope attribute under which our user database
+     * is stored.
+     * </p>
+     */
+    public static final String DATABASE_KEY = "database";
+
+    /**
+     * <p/>
+     * The token representing a "edit" task.
+     * </p>
+     */
+    public static final String DELETE = "Delete";
+
+    /**
+     * <p/>
+     * The token representing a "edit" task.
+     * </p>
+     */
+    public static final String EDIT = "Edit";
+
+    /**
+     * <p/>
+     * The request attributes key under the WelcomeAction stores an ArrayList
+     * of error messages, if required resources are missing.
+     * </p>
+     */
+    public static final String ERROR_KEY = "ERROR";
+
+    /**
+     * <p/>
+     * The token representing a "failure" result for this application.
+     * </p>
+     */
+    public static final String FAILURE = "Failure";
+
+    /**
+     * <p/>
+     * The token representing a "logon" result for this application.
+     * </p>
+     */
+    public static final String LOGON = "Logon";
+
+    /**
+     * <p/>
+     * The package name for this application.
+     * </p>
+     */
+    public static final String PACKAGE = "org.apache.struts.apps.mailreader";
+
+    /**
+     * <p/>
+     * The token representing a "save" task.
+     * </p>
+     */
+    public static final String SAVE = "Save";
+
+    /**
+     * <p/>
+     * The session scope attribute under which the Subscription object
+     * currently selected by our logged-in User is stored.
+     * </p>
+     */
+    public static final String SUBSCRIPTION_KEY = "subscription";
+
+    /**
+     * <p/>
+     * The token representing a "success" result for this application.
+     * </p>
+     */
+    public static final String SUCCESS = "Success";
+
+    /**
+     * <p/>
+     * The session scope attribute under which the User object
+     * for the currently logged in user is stored.
+     * </p>
+     */
+    public static final String USER_KEY = "user";
+
+    // ---- Error Messages ----
+
+    /**
+     * <p/>
+     * A static message in case database resource is not loaded.
+     * <p/>
+     */
+    public static final String ERROR_DATABASE_NOT_LOADED =
+            "ERROR:  User database not loaded -- check servlet container logs for error messages.";
+
+    /**
+     * <p/>
+     * A static message in case message resource is not loaded.
+     * </p>
+     */
+    public static final String ERROR_MESSAGES_NOT_LOADED =
+            "ERROR:  Message resources not loaded -- check servlet container logs for error messages.";
+
+    // ---- Error Tokens ----
+
+    /**
+     * <p/>
+     * The resource key for an error with the transactional token.
+     * </p>
+     */
+    public static final String MSG_TRANSACTION_TOKEN = "error.transaction.token";
+
+    // ---- Log Messages ----
+
+    /**
+     * <p/>
+     * The message to log when cancelling a transaction.
+     * </p>
+     */
+    public static final String LOG_CANCEL = " Transaction cancelled: ";
+
+    /**
+     * <p/>
+     * The message to log when forwarding to a result.
+     * </p>
+     */
+    public static final String LOG_RESULT = " Forwarding to result: ";
+
+    /**
+     * <p/>
+     * The message to log when forwarding to a 'failure' result.
+     * <p/>
+     */
+    public static final String LOG_FAILURE = LOG_RESULT + FAILURE;
+
+    /**
+     * <p/>
+     * The message to log when forwarding to a 'logon' result.
+     * </p>
+     */
+    public static final String LOG_LOGON = LOG_RESULT + LOGON;
+
+    /**
+     * <p/>
+     * The message to log when populating a form.
+     * </p>
+     */
+    public static final String LOG_POPULATE_FORM = " Populating form from: ";
+
+    /**
+     * <p/>
+     * The message to log when populating a subscription.
+     * </p>
+     */
+    public static final String LOG_POPULATE_SUBSCRIPTION = " Populating subscription: ";
+
+    /**
+     * <p/>
+     * The message to log when populating a user.
+     * </p>
+     */
+    public static final String LOG_POPULATE_USER = " Populating user: ";
+
+    /**
+     * <p/>
+     * The message to log when forwarding to a 'success' result.
+     * </p>
+     */
+    public static final String LOG_PROCESSING = " Processing: ";
+
+    /**
+     * <p/>
+     * The message to log when forwarding to a 'success' result.
+     * </p>
+     */
+    public static final String LOG_SUCCESS = LOG_RESULT + SUCCESS;
+
+    /**
+     * <p/>
+     * The message to log when setting a transactional token.
+     * </p>
+     */
+    public static final String LOG_TOKEN = " Setting transactional control token";
+
+    /**
+     * <p/>
+     * The message to log when checking a transactional token.
+     * </p>
+     */
+    public static final String LOG_TOKEN_CHECK = " Checking transactional control token";
+
+
+}

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/Constants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/LogonAction.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/LogonAction.java?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/LogonAction.java (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/LogonAction.java Mon Jan  9 05:32:07 2006
@@ -0,0 +1,95 @@
+/*
+ * $Id: LogonAction.java 360442 2005-12-31 20:10:04Z husted $
+ *
+ * Copyright 2000-2004 Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.apps.mailreader.course;
+
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.ActionMessages;
+import org.apache.struts.apps.mailreader.dao.User;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+/**
+ * <p/>
+ * Validate a user logon.
+ * </p>
+ *
+ * @version $Rev: 360442 $ $Date: 2005-12-31 15:10:04 -0500 (Sat, 31 Dec 2005) $
+ */
+public final class LogonAction extends RegisterAction {
+
+
+    /**
+     * <p/>
+     * Store User object in client session.
+     * If user object is null, any existing user object is removed.
+     * </p>
+     *
+     * @param request The request we are processing
+     * @param user    The user object returned from the database
+     */
+    protected void doCacheUser(HttpServletRequest request, User user) {
+
+        HttpSession session = request.getSession();
+        session.setAttribute(USER_KEY, user);
+    }
+
+    /**
+     * <p/>
+     * Use "username" and "password" fields from ActionForm to retrieve a User
+     * object from the database. If credentials are not valid, or database
+     * has disappeared, post error messages and forward to input.
+     * </p>
+     *
+     * @param mapping  The ActionMapping used to select this instance
+     * @param form     The optional ActionForm bean for this request (if any)
+     * @param request  The HTTP request we are processing
+     * @param response The HTTP response we are creating
+     * @throws Exception if the application business logic throws
+     *                   an exception
+     */
+    public ActionForward execute(
+            ActionMapping mapping,
+            ActionForm form,
+            HttpServletRequest request,
+            HttpServletResponse response)
+            throws Exception {
+
+        // Retrieve user
+        String username = doGet(form, USERNAME);
+        String password = doGet(form, PASSWORD);
+        ActionMessages errors = new ActionMessages();
+        User user = doGetUser(username, password, errors);
+
+        // Report back any errors, and exit if any
+        if (!errors.isEmpty()) {
+            return doInputForward(mapping, request, errors);
+        }
+
+        // Cache user object in session to signify logon
+        doCacheUser(request, user);
+
+        // Done
+        return doFindSuccess(mapping);
+
+    }
+
+}

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/LogonAction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/MemoryDatabasePlugIn.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/MemoryDatabasePlugIn.java?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/MemoryDatabasePlugIn.java (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/MemoryDatabasePlugIn.java Mon Jan  9 05:32:07 2006
@@ -0,0 +1,174 @@
+package org.apache.struts.apps.mailreader.course;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.ActionServlet;
+import org.apache.struts.action.PlugIn;
+import org.apache.struts.apps.mailreader.dao.impl.memory.MemoryUserDatabase;
+import org.apache.struts.config.ModuleConfig;
+
+import javax.servlet.ServletException;
+import java.io.*;
+
+/**
+ * <p><strong>MemoryDatabasePlugIn</strong> initializes and finalizes the
+ * persistent storage of User and Subscription information for the Struts
+ * Demonstration Application, using an in-memory database backed by an
+ * XML file.</p>
+ * <p/>
+ * <p><strong>IMPLEMENTATION WARNING</strong> - If this web application is run
+ * from a WAR file, or in another environment where reading and writing of the
+ * web application resource is impossible, the initial contents will be copied
+ * to a file in the web application temporary directory provided by the
+ * container.  This is for demonstration purposes only - you should
+ * <strong>NOT</strong> assume that files written here will survive a restart
+ * of your servlet container.</p>
+ *
+ * @version $Rev: 360442 $ $Date: 2005-12-31 15:10:04 -0500 (Sat, 31 Dec 2005) $
+ */
+public class MemoryDatabasePlugIn implements PlugIn {
+
+    // ---- Instance Variables ----
+
+    /**
+     * The {@link org.apache.struts.apps.mailreader.dao.impl.memory.MemoryUserDatabase} object we construct and make available.
+     */
+    private MemoryUserDatabase database = null;
+
+
+    /**
+     * Logging output for this plug in instance.
+     */
+    private Log log = LogFactory.getLog(this.getClass());
+
+
+    /**
+     * The {@link org.apache.struts.action.ActionServlet} owning this application.
+     */
+    private ActionServlet servlet = null;
+
+    // ---- Properties ----
+
+    /**
+     * The web application resource path of our persistent database
+     * storage file.
+     */
+    private String pathname = "/WEB-INF/database.xml";
+
+    public String getPathname() {
+        return (this.pathname);
+    }
+
+    public void setPathname(String pathname) {
+        this.pathname = pathname;
+    }
+
+    // ---- PlugIn Methods ----
+
+
+    /**
+     * Gracefully shut down this database, releasing any resources
+     * that were allocated at initialization.
+     */
+    public void destroy() {
+
+        log.info("Finalizing memory database plug in");
+
+        if (database != null) {
+            try {
+                database.close();
+            } catch (Exception e) {
+                log.error("Closing memory database", e);
+            }
+        }
+
+        servlet.getServletContext().removeAttribute(Constants.DATABASE_KEY);
+        database = null;
+        servlet = null;
+        database = null;
+    }
+
+
+    /**
+     * Initialize and load our initial database from persistent storage.
+     *
+     * @param servlet The ActionServlet for this web application
+     * @param config  The ApplicationConfig for our owning module
+     * @throws ServletException if we cannot configure ourselves correctly
+     */
+    public void init(ActionServlet servlet, ModuleConfig config)
+            throws ServletException {
+
+        log.info("Initializing memory database plug in from '" +
+                pathname + "'");
+
+        // Remember our associated configuration and servlet
+        this.servlet = servlet;
+
+        // Construct a new database and make it available
+        database = new MemoryUserDatabase();
+        try {
+            String path = calculatePath();
+            if (log.isDebugEnabled()) {
+                log.debug(" Loading database from '" + path + "'");
+            }
+            database.setPathname(path);
+            database.open();
+        } catch (Exception e) {
+            log.error("Opening memory database", e);
+            throw new ServletException("Cannot load database from '" +
+                    pathname + "'", e);
+        }
+
+        // Make the initialized database available
+        servlet.getServletContext().setAttribute(Constants.DATABASE_KEY,
+                database);
+
+    }
+
+    // ---- Private Methods ----
+
+    /**
+     * Calculate and return an absolute pathname to the XML file to contain
+     * our persistent storage information.
+     *
+     * @throws Exception if an input/output error occurs
+     */
+    private String calculatePath() throws Exception {
+
+        // Can we access the database via file I/O?
+        String path = servlet.getServletContext().getRealPath(pathname);
+        if (path != null) {
+            return (path);
+        }
+
+        // Does a copy of this file already exist in our temporary directory
+        File dir = (File)
+                servlet.getServletContext().getAttribute
+                        ("javax.servlet.context.tempdir");
+        File file = new File(dir, "struts-example-database.xml");
+        if (file.exists()) {
+            return (file.getAbsolutePath());
+        }
+
+        // Copy the static resource to a temporary file and return its path
+        InputStream is =
+                servlet.getServletContext().getResourceAsStream(pathname);
+        BufferedInputStream bis = new BufferedInputStream(is, 1024);
+        FileOutputStream os =
+                new FileOutputStream(file);
+        BufferedOutputStream bos = new BufferedOutputStream(os, 1024);
+        byte buffer[] = new byte[1024];
+        while (true) {
+            int n = bis.read(buffer);
+            if (n <= 0) {
+                break;
+            }
+            bos.write(buffer, 0, n);
+        }
+        bos.close();
+        bis.close();
+        return (file.getAbsolutePath());
+
+    }
+}
\ No newline at end of file

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/MemoryDatabasePlugIn.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/RegisterAction.java
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/RegisterAction.java?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/RegisterAction.java (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/RegisterAction.java Mon Jan  9 05:32:07 2006
@@ -0,0 +1,628 @@
+package org.apache.struts.apps.mailreader.course;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.*;
+import org.apache.struts.actions.MappingDispatchAction;
+import org.apache.struts.apps.mailreader.dao.ExpiredPasswordException;
+import org.apache.struts.apps.mailreader.dao.User;
+import org.apache.struts.apps.mailreader.dao.UserDatabase;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+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 class RegisterAction extends MappingDispatchAction {
+
+    // ---- Constants ----
+
+    /**
+     * <p/>
+     * The application scope attribute under which our user database
+     * is stored.
+     * </p>
+     */
+    public static final String DATABASE_KEY = "database";
+
+    /**
+     * <p/>
+     * Name of fromAddress field ["fromAddress"].
+     * </p>
+     */
+    public final static String FROM_ADDRESS = "fromAddress";
+
+    /**
+     * <p/>
+     * Name of fullName field ["fullName"].
+     * </p>
+     */
+    public final static String FULL_NAME = "fullName";
+
+    /**
+     * <p/>
+     * Name of password field ["password"].
+     * </p>
+     */
+    public static String PASSWORD = "password";
+
+    /**
+     * <p/>
+     * Name of password confirmation field ["password2"].
+     * </p>
+     */
+    public final static String PASSWORD2 = "password2";
+
+    /**
+     * <p/>
+     * Name of replyToAddress field ["replyToAddress"].
+     * </p>
+     */
+    public final static String REPLY_TO_ADDRESS = "replyToAddress";
+
+    /**
+     * <p/>
+     * The token representing a "success" result for this application.
+     * </p>
+     */
+    public static final String SUCCESS = "Success";
+
+    /**
+     * <p/>
+     * The session scope attribute under which the User object
+     * for the currently logged in user is stored.
+     * </p>
+     */
+    public static final String USER_KEY = "user";
+
+    /**
+     * <p/>
+     * Name of username field ["username"].
+     * </p>
+     */
+    public static String USERNAME = "username";
+
+    /**
+     * <p/>
+     * Name of task field ["task"].
+     * </p>
+     */
+    public final static String TASK = "task";
+
+    // ---- Private Methods ----
+
+    /**
+     * <p/>
+     * The <code>Log</code> instance for this application.
+     * </p>
+     */
+    private Log log = LogFactory.getLog(Constants.PACKAGE);
+
+    /**
+     * <p/>
+     * The message prefix to use when populating a Registration Form.
+     * </p>
+     */
+    final String LOG_REGISTRATION_POPULATE = "RegistrationForm.populate";
+
+    /**
+     * <p/>
+     * Helper method to post error message when user already exists.
+     * </p>
+     *
+     * @param username Existing username
+     * @param errors   Our ActionMessages collection
+     */
+    private void errorUsernameUnique(String username,
+                                     ActionMessages errors) {
+        errors.add(
+                USERNAME,
+                new org.apache.struts.action.ActionMessage(
+                        "error.username.unique", username));
+    }
+
+
+    /**
+     * <p/>
+     * Helper method to log event and cancel transaction.
+     * </p>
+     *
+     * @param session Our HttpSession
+     * @param method  Method being processed
+     * @param key     Attrkibute to remove from session, if any
+     */
+    private 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);
+        }
+    }
+
+    /**
+     * <p/>
+     * Verify input for creating a new user,
+     * create the user, and process the login.
+     * </p>
+     *
+     * @param form    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(
+            ActionForm form,
+            HttpServletRequest request,
+            ActionMessages errors) {
+
+        if (log.isTraceEnabled()) {
+            log.trace(" Perform additional validations on Create");
+        }
+
+        UserDatabase database = doGetUserDatabase();
+        String username = doGet(form, USERNAME);
+        try {
+            if (database.findUser(username) != null) {
+                errorUsernameUnique(username, errors);
+            }
+        }
+        catch (ExpiredPasswordException e) {
+            errorUsernameUnique(username, errors);
+            errors.add("errors.literal", new ActionMessage(e.getMessage()));
+        }
+
+        String password = doGet(form, PASSWORD);
+        if ((password == null) || (password.length() < 1)) {
+            errors.add(PASSWORD, new ActionMessage("error.password.required"));
+
+            String password2 = doGet(form, PASSWORD2);
+            if ((password2 == null) || (password2.length() < 1)) {
+                errors.add(
+                        PASSWORD2,
+                        new ActionMessage("error.password2.required"));
+            }
+        }
+
+        if (!errors.isEmpty()) {
+            return null;
+        }
+
+        User user = database.createUser(username);
+
+        // Log the user in
+        HttpSession session = request.getSession();
+        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 obtain User form session (if any).
+     * </p>
+     *
+     * @param session Our HttpSession
+     * @return User object, or null if there is no user.
+     */
+    private User doGetUser(HttpSession session) {
+        return (User) session.getAttribute(Constants.USER_KEY);
+    }
+
+    /**
+     * <p/>
+     * Confirm user credentials. Post any errors and return User object
+     * (or null).
+     * </p>
+     *
+     * @param database Database in which to look up the user
+     * @param username Username specified on the logon form
+     * @param password Password specified on the logon form
+     * @param errors   ActionMessages queue to passback errors
+     * @return Validated User object or null
+     * @throws org.apache.struts.apps.mailreader.dao.ExpiredPasswordException
+     *          to be handled by Struts exception
+     *          processor via the action-mapping
+     */
+    private User doGetUser(UserDatabase database, String username,
+                           String password, ActionMessages errors)
+            throws ExpiredPasswordException {
+
+        User user = null;
+        if (database == null) {
+            errors.add(
+                    ActionMessages.GLOBAL_MESSAGE,
+                    new ActionMessage("error.database.missing"));
+        } else {
+
+            if (username.equals("Hermes")) {
+                throw new ExpiredPasswordException("Hermes");
+            }
+
+            user = database.findUser(username);
+            if ((user != null) && !user.getPassword().equals(password)) {
+                user = null;
+            }
+            if (user == null) {
+                errors.add(
+                        ActionMessages.GLOBAL_MESSAGE,
+                        new ActionMessage("error.password.mismatch"));
+            }
+        }
+
+        return user;
+    }
+
+    /**
+     * <p/>
+     * Return a reference to the UserDatabase
+     * or null if the database is not available.
+     * </p>
+     *
+     * @return a reference to the UserDatabase or null if the database is not
+     *         available
+     */
+    private UserDatabase doGetUserDatabase() {
+        return (UserDatabase) servlet.getServletContext().getAttribute(
+                DATABASE_KEY);
+    }
+
+    /**
+     * <p/>
+     * Log a "processing" message for an Action.
+     * </p>
+     *
+     * @param mapping Our ActionMapping
+     * @param method  Name of method being processed
+     */
+    private 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());
+        }
+    }
+
+    /**
+     * <p/>
+     * Helper method to populate the input form from the User object.
+     * </p>
+     *
+     * @param form Form with incoming values
+     * @param user User object to populate
+     * @throws ServletException On any error
+     */
+    private void doPopulate(ActionForm form, User user)
+            throws ServletException {
+
+        final String title = Constants.EDIT;
+
+        if (log.isTraceEnabled()) {
+            log.trace(Constants.LOG_POPULATE_FORM + user);
+        }
+
+        try {
+            PropertyUtils.copyProperties(form, user);
+            DynaActionForm dyna = (DynaActionForm) form;
+            dyna.set(TASK, title);
+            dyna.set(PASSWORD, null);
+            dyna.set(PASSWORD2, 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 form Form with incoming values
+     * @throws ServletException On any error
+     */
+    private void doPopulate(User user, ActionForm form)
+            throws ServletException {
+
+        if (log.isTraceEnabled()) {
+            log.trace(Constants.LOG_POPULATE_USER + user);
+        }
+
+        try {
+            String oldPassword = user.getPassword();
+            PropertyUtils.copyProperties(user, form);
+            String password = doGet(form, PASSWORD);
+            if ((password == null)
+                    || (password.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/>
+     * Helper method to log event and save token.
+     * </p>
+     *
+     * @param request Our HttpServletRequest
+     */
+    private 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
+     */
+    private 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);
+        }
+    }
+
+    /**
+     * <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);
+    }
+
+    // ---- Protected methods ----
+
+    /**
+     * <p/>
+     * Return the mapping labeled "success"
+     * or null if there is no such mapping.
+     * </p>
+     *
+     * @param mapping Our ActionMapping
+     * @return Return the mapping named "success" or null if there is no such
+     *         mapping.
+     */
+    protected ActionForward doFindSuccess(ActionMapping mapping) {
+        return mapping.findForward(SUCCESS);
+    }
+
+
+    /**
+     * <p/>
+     * Helper method to fetch a String property from a DynaActionForm.
+     * </p>
+     * <p/>
+     * Values are returned trimmed of leading and trailing whitespace.
+     * Zero-length strings are returned as null.
+     * </p>
+     *
+     * @param form     Our DynaActionForm
+     * @param property The name of the property
+     * @return The value or null if an error occurs
+     */
+    protected String doGet(ActionForm form, String property) {
+        String initial;
+        try {
+            initial = (String) PropertyUtils.getSimpleProperty(form, property);
+        } catch (Throwable t) {
+            initial = null;
+        }
+        String value = null;
+        if ((initial != null) && (initial.length() > 0)) {
+            value = initial.trim();
+            if (value.length() == 0) {
+                value = null;
+            }
+        }
+        return value;
+    }
+
+    /**
+     * <p/>
+     * Confirm user credentials. Post any errors and return User object
+     * (or null).
+     * </p>
+     *
+     * @param username Username specified on the logon form
+     * @param password Password specified on the logon form
+     * @param errors   ActionMessages queue to passback errors
+     * @return Validated User object or null
+     * @throws org.apache.struts.apps.mailreader.dao.ExpiredPasswordException
+     *          to be handled by Struts exception
+     *          processor via the action-mapping
+     */
+    protected User doGetUser(String username,
+                             String password, ActionMessages errors)
+            throws ExpiredPasswordException {
+
+        return doGetUser(doGetUserDatabase(), username, password, errors);
+    }
+
+    /**
+     * <p/>
+     * Save any errors and forward to the Input result.
+     * </p>
+     *
+     * @param mapping Our ActionMapping
+     * @param request Our HttpServletRequest
+     * @param errors  Our ActionMessages collectoin
+     * @return The InputForward for this mappintg
+     */
+    protected ActionForward doInputForward(ActionMapping mapping,
+                                           HttpServletRequest request,
+                                           ActionMessages errors) {
+        this.saveErrors(request, errors);
+        return (mapping.getInputForward());
+    }
+
+    // ----- 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 = Constants.EDIT;
+        doLogProcess(mapping, method);
+
+        HttpSession session = request.getSession();
+        User user = doGetUser(session);
+        boolean updating = (user != null);
+        if (updating) {
+            doPopulate(form, 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 = Constants.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);
+        }
+
+        User user = doGetUser(session);
+        if (user == null) {
+            user = doCreateUser(form, request, errors);
+            if (!errors.isEmpty()) {
+                return doInputForward(mapping, request, errors);
+            }
+        }
+
+        doPopulate(user, form);
+        doSaveUser(user);
+
+        return doFindSuccess(mapping);
+    }
+}

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/java/org/apache/struts/apps/mailreader/course/RegisterAction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/LogonForm.jsp
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/LogonForm.jsp?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/LogonForm.jsp (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/LogonForm.jsp Mon Jan  9 05:32:07 2006
@@ -0,0 +1,54 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
+<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
+
+<html:xhtml/>
+<html>
+<head>
+    <title><bean:message key="Logon.title"/></title>
+</head>
+
+<body>
+<html:errors/>
+
+<html:form action="/LogonPost">
+    <table border="0" width="100%">
+
+        <tr>
+            <th align="right">
+                <bean:message key="username.label"/>:
+            </th>
+            <td align="left">
+                <html:text property="username" size="16" maxlength="18"/>
+            </td>
+        </tr>
+
+        <tr>
+            <th align="right">
+                <bean:message key="password.label"/>:
+            </th>
+            <td align="left">
+                <html:password property="password" size="16" maxlength="18"
+                               redisplay="false"/>
+            </td>
+        </tr>
+
+        <tr>
+            <td align="right">
+                <html:submit property="DO_SUBMIT">
+                    <bean:message key="button.submit"/>
+                </html:submit>
+            </td>
+            <td align="left">
+                <html:reset property="DO_RESET">
+                    <bean:message key="button.reset"/>
+                </html:reset>
+            </td>
+        </tr>
+
+    </table>
+
+</html:form>
+
+</body>
+</html>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/LogonForm.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/MainMenu.jsp
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/MainMenu.jsp?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/MainMenu.jsp (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/MainMenu.jsp Mon Jan  9 05:32:07 2006
@@ -0,0 +1,16 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean" %>
+<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
+<html>
+<head>
+    <title><bean:message key="MainMenu.title"/></title>
+</head>
+
+<body>
+<h3>Main Menu Options for <c:out value="${user.map.fullName}"/></h3>
+<ul>
+    <li><html:link action="/RegisterEdit">Edit Profile</html:link></li>
+    <li>[TODO] Logout</li>
+</ul>
+</body>
+</html>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/MainMenu.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/RegisterForm.jsp
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/RegisterForm.jsp?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/RegisterForm.jsp (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/RegisterForm.jsp Mon Jan  9 05:32:07 2006
@@ -0,0 +1,164 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
+<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean" %>
+<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
+
+<html:html>
+<head>
+    <!-- Lab 2-1: When task is Edit, change title -->
+    <title>
+        <c:if test="${RegisterForm.map.task == 'Create'}">
+            <bean:message key="registration.title.create"/>
+        </c:if>
+        <c:if test="${RegisterForm.map.task == 'Edit'}">
+            <bean:message key="registration.title.edit"/>
+        </c:if>
+    </title>
+</head>
+
+<body>
+
+<html:errors/>
+
+<html:form action="/RegisterSave">
+    <html:hidden property="task"/>
+    <table border="0" width="100%">
+
+        <tr>
+            <th align="right">
+                Username:
+            </th>
+            <td align="left">
+                <!-- Lab 2-1: When task is Edit, change username to readonly -->
+                <c:if test="${RegisterForm.map.task == 'Create'}">
+                    <html:text property="username" size="16" maxlength="16"/>
+                </c:if>
+                <c:if test="${RegisterForm.map.task == 'Edit'}">
+                    <c:out value="${RegisterForm.map.username}"/>
+                    <html:hidden property="username"/>
+                </c:if>
+            </td>
+        </tr>
+
+        <tr>
+            <th align="right">
+                Password:
+            </th>
+            <td align="left">
+                <html:password property="password" size="16"
+                               maxlength="16"/>
+            </td>
+        </tr>
+
+        <tr>
+            <th align="right">
+                Confirm Password:
+            </th>
+            <td align="left">
+                <html:password property="password2" size="16"
+                               maxlength="16"/>
+            </td>
+        </tr>
+        <tr>
+            <th align="right">
+                Fullname:
+            </th>
+            <td align="left">
+                <html:text property="fullName" size="50"/>
+            </td>
+        </tr>
+
+        <tr>
+            <th align="right">
+                From Address:
+            </th>
+            <td align="left">
+                <html:text property="fromAddress" size="50"/>
+            </td>
+        </tr>
+
+        <tr>
+            <th align="right">
+                Reply To Address:
+            </th>
+            <td align="left">
+                <html:text property="replyToAddress" size="50"/>
+            </td>
+        </tr>
+
+        <tr>
+            <td align="right">
+                <html:submit property="DO_SUBMIT">
+                    <bean:message key="button.submit"/>
+                </html:submit>
+            </td>
+            <td align="left">
+                <html:reset property="DO_RESET">
+                    <bean:message key="button.reset"/>
+                </html:reset>
+                &nbsp;
+                <html:cancel/>
+            </td>
+        </tr>
+
+    </table>
+</html:form>
+
+<!-- Lab 2-1: When task is Edit, display Subscriptions -->
+<c:if test="${RegisterForm.map.task == 'Edit'}">
+<div align="center">
+    <h3><bean:message key="heading.subscriptions"/></h3>
+</div>
+
+<table border="1" width="100%">
+
+    <tr>
+        <th align="center" width="30%">
+            <bean:message key="heading.host"/>
+        </th>
+        <th align="center" width="25%">
+            <bean:message key="heading.user"/>
+        </th>
+        <th align="center" width="10%">
+            <bean:message key="heading.type"/>
+        </th>
+        <th align="center" width="10%">
+            <bean:message key="heading.autoConnect"/>
+        </th>
+        <th align="center" width="15%">
+            <bean:message key="heading.action"/>
+        </th>
+    </tr>
+
+    <c:forEach var="subscription" items="${user.subscriptions}">
+    <tr>
+        <td align="left">
+            <bean:write name="subscription" property="host"/>
+        </td>
+        <td align="left">
+            <bean:write name="subscription" property="username"/>
+        </td>
+        <td align="center">
+            <bean:write name="subscription" property="type"/>
+        </td>
+        <td align="center">
+            <bean:write name="subscription" property="autoConnect"/>
+        </td>
+        <td align="center">
+            <html:link action="/DeleteSubscription"
+                       paramName="subscription" paramId="host"
+                       paramProperty="host">
+                <bean:message key="registration.deleteSubscription"/>
+            </html:link>
+            &nbsp;
+            <html:link action="/EditSubscription"
+                       paramName="subscription" paramId="host"
+                       paramProperty="host">
+                <bean:message key="registration.editSubscription"/>
+            </html:link>
+        </td>
+    </tr>
+    </c:forEach>
+    </c:if>
+</body>
+</html:html>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/RegisterForm.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-configure.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-configure.xml?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-configure.xml (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-configure.xml Mon Jan  9 05:32:07 2006
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE struts-config PUBLIC
+        "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
+        "http://struts.apache.org/dtds/struts-config_1_3.dtd">
+
+<struts-config>
+
+    <form-beans>
+        <form-bean
+                name="LogonForm"
+                extends="BaseForm"/>
+    </form-beans>
+
+    <action-mappings
+            type="org.apache.struts.action.RequestActionMapping">
+
+        <action path="/Logon"
+                name="LogonForm"
+                forward="/LogonForm.jsp"
+                validate="false"/>
+
+        <action
+                path="/LogonPost"
+                type="org.apache.struts.apps.mailreader.course.LogonAction"
+                name="LogonForm"
+                scope="request"
+                validate="true"
+                input="Input">
+            <forward
+                    name="Input"
+                    path="/Logon.do"/>
+            <forward
+                    name="Success"
+                    redirect="true"
+                    path="/MainMenu.do"/>
+        </action>
+
+    </action-mappings>
+
+</struts-config>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-configure.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-validate.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-validate.xml?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-validate.xml (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-validate.xml Mon Jan  9 05:32:07 2006
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE form-validation PUBLIC
+        "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.2.0//EN"
+        "http://jakarta.apache.org/commons/dtds/validator_1_2_0.dtd">
+
+<form-validation>
+    <formset>
+        <form name="LogonForm">
+
+            <field property="username"
+                   depends="required">
+                <arg key="username.label"/>
+            </field>
+
+            <field property="password"
+                   depends="required, minlength,maxlength">
+                <arg key="password.label"/>
+                <arg key="${var:minlength}"
+                     name="minlength"
+                     resource="false"/>
+                <arg key="${var:maxlength}"
+                     name="maxlength"
+                     resource="false"/>
+
+                <var>
+                    <var-name>
+                        maxlength
+                    </var-name>
+                    <var-value>
+                        16
+                    </var-value>
+                </var>
+                <var>
+                    <var-name>
+                        minlength
+                    </var-name>
+                    <var-value>
+                        3
+                    </var-value>
+                </var>
+            </field>
+        </form>
+    </formset>
+</form-validation>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Logon-validate.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-configure.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-configure.xml?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-configure.xml (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-configure.xml Mon Jan  9 05:32:07 2006
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE struts-config PUBLIC
+        "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
+        "http://struts.apache.org/dtds/struts-config_1_3.dtd">
+
+<struts-config>
+
+    <form-beans>
+        <form-bean
+                name="RegisterForm"
+                extends="BaseForm">
+            <form-property
+                    name="password2"
+                    type="java.lang.String"/>
+            <form-property
+                    name="fullName"
+                    type="java.lang.String"/>
+            <form-property
+                    name="fromAddress"
+                    type="java.lang.String"/>
+            <form-property
+                    name="replyToAddress"
+                    type="java.lang.String"/>
+        </form-bean>
+    </form-beans>
+
+    <action-mappings
+            type="org.apache.struts.action.RequestActionMapping">
+
+        <action path="RegisterAction"
+                input="Input"
+                type="org.apache.struts.apps.mailreader.course.RegisterAction"
+                name="RegisterForm"
+                scope="request">
+            <forward
+                    name="Input"
+                    path="/RegisterForm.jsp"/>
+            <forward
+                    name="Success"
+                    redirect="true"
+                    path="/MainMenu.do"/>
+        </action>
+
+        <action path="/Register"
+                extends="RegisterAction"
+                forward="/RegisterForm.jsp"
+                validate="false"/>
+
+        <action path="/RegisterEdit"
+                extends="RegisterAction"
+                parameter="Edit"
+                validate="false">
+            <forward
+                    name="Success"
+                    path="/RegisterForm.jsp"/>
+        </action>
+
+
+        <action path="/RegisterSave"
+                extends="RegisterAction"
+                parameter="Save">
+        </action>
+
+    </action-mappings>
+
+</struts-config>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-configure.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-validate.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-validate.xml?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-validate.xml (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-validate.xml Mon Jan  9 05:32:07 2006
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE form-validation PUBLIC
+        "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.2.0//EN"
+        "http://jakarta.apache.org/commons/dtds/validator_1_2_0.dtd">
+
+<form-validation>
+
+    <formset>
+        <form name="RegisterForm">
+
+            <field property="username" depends="required">
+                <arg position="0" key="username.label"/>
+            </field>
+
+            <field property="password" depends="required">
+                <arg position="0" key="password.label"/>
+            </field>
+
+            <field property="password2" depends="required,validwhen">
+                <arg position="0" key="password2.label"/>
+                <var>
+                    <var-name>test</var-name>
+                    <var-value>(*this* == password)</var-value>
+                </var>
+            </field>
+
+            <!-- Lab 1-2: Insert remaining fields from use case -->
+
+            <field property="fullName"
+                   depends="required">
+                <arg key="fullName.label"/>
+            </field>
+
+            <field property="fromAddress"
+                   depends="required,email">
+                <arg key="fromAddress.label"/>
+            </field>
+
+            <field property="replyToAddress"
+                   depends="email">
+                <arg key="replyToAddress.label"/>
+            </field>
+
+        </form>
+    </formset>
+</form-validation>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/Register-validate.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/database.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/database.xml?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/database.xml (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/database.xml Mon Jan  9 05:32:07 2006
@@ -0,0 +1,22 @@
+<?xml version='1.0'?>
+<database>
+    <user username="user"
+          password="pass"
+          fullName="John Q. User"
+          fromAddress="John.User@somewhere.com">
+        <subscription
+                host="mail.hotmail.com"
+                type="pop3"
+                autoConnect="false"
+                username="user1234"
+                password="bar">
+        </subscription>
+        <subscription
+                host="mail.yahoo.com"
+                type="imap"
+                autoConnect="false"
+                username="jquser"
+                password="foo">
+        </subscription>
+    </user>
+</database>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/database.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/struts-config.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/struts-config.xml?rev=367292&view=auto
==============================================================================
--- struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/struts-config.xml (added)
+++ struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/struts-config.xml Mon Jan  9 05:32:07 2006
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE struts-config PUBLIC
+        "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
+        "http://struts.apache.org/dtds/struts-config_1_3.dtd">
+
+<struts-config>
+
+    <form-beans>
+        <form-bean
+                name="BaseForm"
+                type="org.apache.struts.validator.DynaValidatorForm">
+            <form-property
+                    name="username"
+                    type="java.lang.String"/>
+            <form-property
+                    name="password"
+                    type="java.lang.String"/>
+            <!-- Lab 2-1: Add task property -->
+            <form-property
+                    name="task"
+                    type="java.lang.String"
+                    initial="Create"/>
+        </form-bean>
+    </form-beans>
+
+    <action-mappings
+            type="org.apache.struts.action.RequestActionMapping">
+
+        <action path="/MainMenu"
+                forward="/MainMenu.jsp"
+                validate="false"/>
+
+    </action-mappings>
+
+    <controller
+            inputForward="true"/>
+
+    <message-resources
+            parameter="MessageResources"/>
+
+    <plug-in
+            className="org.apache.struts.apps.mailreader.course.MemoryDatabasePlugIn">
+        <set-property
+                property="pathname"
+                value="/WEB-INF/database.xml"/>
+    </plug-in>
+
+    <plug-in
+            className="org.apache.struts.validator.ValidatorPlugIn">
+        <set-property
+                property="pathnames"
+                value="/org/apache/struts/validator/validator-rules.xml,
+                /WEB-INF/Logon-validate.xml,/WEB-INF/Register-validate.xml"
+                />
+    </plug-in>
+
+</struts-config>

Propchange: struts/sandbox/trunk/mailreader-course/lab-2-1-src/webapp/WEB-INF/struts-config.xml
------------------------------------------------------------------------------
    svn:eol-style = native



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