Return-Path: Delivered-To: apmail-struts-dev-archive@www.apache.org Received: (qmail 40361 invoked from network); 6 Apr 2006 22:33:04 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 6 Apr 2006 22:33:04 -0000 Received: (qmail 97696 invoked by uid 500); 6 Apr 2006 22:32:59 -0000 Delivered-To: apmail-struts-dev-archive@struts.apache.org Received: (qmail 97659 invoked by uid 500); 6 Apr 2006 22:32:59 -0000 Mailing-List: contact dev-help@struts.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "Struts Developers List" Reply-To: "Struts Developers List" Delivered-To: mailing list dev@struts.apache.org Received: (qmail 97647 invoked by uid 500); 6 Apr 2006 22:32:58 -0000 Received: (qmail 97642 invoked by uid 99); 6 Apr 2006 22:32:58 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Apr 2006 15:32:58 -0700 X-ASF-Spam-Status: No, hits=-8.6 required=10.0 tests=ALL_TRUSTED,INFO_TLD,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Thu, 06 Apr 2006 15:32:54 -0700 Received: (qmail 39932 invoked by uid 65534); 6 Apr 2006 22:32:33 -0000 Message-ID: <20060406223233.39927.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r392100 [4/4] - in /struts/action/trunk/apps: faces-example1/src/main/java/ faces-example1/src/main/java/org/ faces-example1/src/main/java/org/apache/ faces-example1/src/main/java/org/apache/struts/ faces-example1/src/main/java/org/apache/s... Date: Thu, 06 Apr 2006 22:31:41 -0000 To: commits@struts.apache.org From: mrdon@apache.org X-Mailer: svnmailer-1.0.7 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/RegistrationForm.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/RegistrationForm.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/RegistrationForm.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/RegistrationForm.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,308 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2; + + +import javax.servlet.http.HttpServletRequest; +import org.apache.struts.action.ActionError; +import org.apache.struts.action.ActionErrors; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.validator.ValidatorForm; + + +/** + * Form bean for the user registration page. This form has the following + * fields, with default values in square brackets: + *
    + *
  • action - The maintenance action we are performing (Create, + * Delete, or Edit). + *
  • fromAddress - The EMAIL address of the sender, to be included + * on sent messages. [REQUIRED] + *
  • fullName - The full name of the sender, to be included on + * sent messages. [REQUIRED] + *
  • password - The password used by this user to log on. + *
  • password2 - The confirmation password, which must match + * the password when changing or setting. + *
  • replyToAddress - The "Reply-To" address to be included on + * sent messages. [Same as from address] + *
  • username - The registered username, which must be unique. + * [REQUIRED] + *
+ * + * @author Craig R. McClanahan + * @version $Rev: 54936 $ $Date: 2004-10-16 10:57:09 -0700 (Sat, 16 Oct 2004) $ + */ + +public final class RegistrationForm extends ValidatorForm { + + + // ----------------------------------------------------- Instance Variables + + + /** + * The maintenance action we are performing (Create or Edit). + */ + private String action = "Create"; + + + /** + * The from address. + */ + private String fromAddress = null; + + + /** + * The full name. + */ + private String fullName = null; + + + /** + * The password. + */ + private String password = null; + + + /** + * The confirmation password. + */ + private String password2 = null; + + + /** + * The reply to address. + */ + private String replyToAddress = null; + + + + /** + * The username. + */ + private String username = null; + + + // ----------------------------------------------------------- Properties + + + /** + * Return the maintenance action. + */ + public String getAction() { + + return (this.action); + + } + + + /** + * Set the maintenance action. + * + * @param action The new maintenance action. + */ + public void setAction(String action) { + + this.action = action; + + } + + + /** + * Return the from address. + */ + public String getFromAddress() { + + return (this.fromAddress); + + } + + + /** + * Set the from address. + * + * @param fromAddress The new from address + */ + public void setFromAddress(String fromAddress) { + + this.fromAddress = fromAddress; + + } + + + /** + * Return the full name. + */ + public String getFullName() { + + return (this.fullName); + + } + + + /** + * Set the full name. + * + * @param fullName The new full name + */ + public void setFullName(String fullName) { + + this.fullName = fullName; + + } + + + /** + * Return the password. + */ + public String getPassword() { + + return (this.password); + + } + + + /** + * Set the password. + * + * @param password The new password + */ + public void setPassword(String password) { + + this.password = password; + + } + + + /** + * Return the confirmation password. + */ + public String getPassword2() { + + return (this.password2); + + } + + + /** + * Set the confirmation password. + * + * @param password2 The new confirmation password + */ + public void setPassword2(String password2) { + + this.password2 = password2; + + } + + + /** + * Return the reply to address. + */ + public String getReplyToAddress() { + + return (this.replyToAddress); + + } + + + /** + * Set the reply to address. + * + * @param replyToAddress The new reply to address + */ + public void setReplyToAddress(String replyToAddress) { + + this.replyToAddress = replyToAddress; + + } + + + /** + * Return the username. + */ + public String getUsername() { + + return (this.username); + + } + + + /** + * Set the username. + * + * @param username The new username + */ + public void setUsername(String username) { + + this.username = username; + + } + + + // --------------------------------------------------------- Public Methods + + + /** + * Reset all properties to their default values. + * + * @param mapping The mapping used to select this instance + * @param request The servlet request we are processing + */ + public void reset(ActionMapping mapping, HttpServletRequest request) { + + this.action = "Create"; + this.fromAddress = null; + this.fullName = null; + this.password = null; + this.password2 = null; + this.replyToAddress = null; + this.username = null; + + } + + + /** + * Validate the properties that have been set from this HTTP request, + * and return an ActionErrors object that encapsulates any + * validation errors that have been found. If no errors are found, return + * null or an ActionErrors object with no + * recorded error messages. + * + * @param mapping The mapping used to select this instance + * @param request The servlet request we are processing + */ + public ActionErrors validate(ActionMapping mapping, + HttpServletRequest request) { + + // Perform validator framework validations + ActionErrors errors = super.validate(mapping, request); + + // Only need crossfield validations here + if (((password == null) && (password2 != null)) || + ((password != null) && (password2 == null)) || + ((password != null) && (password2 != null) && + !password.equals(password2))) { + errors.add("password2", + new ActionError("error.password.match")); + } + return errors; + + } + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SaveRegistrationAction.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SaveRegistrationAction.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SaveRegistrationAction.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SaveRegistrationAction.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,219 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2; + + +import java.lang.reflect.InvocationTargetException; +import java.util.Locale; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionError; +import org.apache.struts.action.ActionErrors; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.util.MessageResources; + + +/** + * Implementation of Action that validates and creates or + * updates the user registration information entered by the user. If a new + * registration is created, the user is also implicitly logged on. + * + * @author Craig R. McClanahan + * @version $Rev: 55303 $ $Date: 2004-10-21 19:56:53 -0700 (Thu, 21 Oct 2004) $ + */ + +public final class SaveRegistrationAction extends Action { + + + // ----------------------------------------------------- Instance Variables + + + /** + * The Log instance for this application. + */ + private Log log = + LogFactory.getLog("org.apache.struts.webapp.Example"); + + + // --------------------------------------------------------- Public Methods + + + /** + * Process the specified HTTP request, and create the corresponding HTTP + * response (or forward to another web component that will create it). + * Return an ActionForward instance describing where and how + * control should be forwarded, or null if the response has + * already been completed. + * + * @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 + * + * @exception Exception if the application business logic throws + * an exception + */ + public ActionForward execute(ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response) + throws Exception { + + // Extract attributes and parameters we will need + Locale locale = getLocale(request); + MessageResources messages = getResources(request); + HttpSession session = request.getSession(); + RegistrationForm regform = (RegistrationForm) form; + String action = regform.getAction(); + if (action == null) { + action = "Create"; + } + UserDatabase database = (UserDatabase) + servlet.getServletContext().getAttribute(Constants.DATABASE_KEY); + if (log.isDebugEnabled()) { + log.debug("SaveRegistrationAction: Processing " + action + + " action"); + } + + // Is there a currently logged on user (unless creating)? + User user = (User) session.getAttribute(Constants.USER_KEY); + if (!"Create".equals(action) && (user == null)) { + if (log.isTraceEnabled()) { + log.trace(" User is not logged on in session " + + session.getId()); + } + return (mapping.findForward("logon")); + } + + // Was this transaction cancelled? + if (isCancelled(request)) { + if (log.isTraceEnabled()) { + log.trace(" Transaction '" + action + + "' was cancelled"); + } + session.removeAttribute(Constants.SUBSCRIPTION_KEY); + return (mapping.findForward("failure")); + } + + // Validate the transactional control token + ActionErrors errors = new ActionErrors(); + if (log.isTraceEnabled()) { + log.trace(" Checking transactional control token"); + } + if (!isTokenValid(request)) { + errors.add(ActionErrors.GLOBAL_ERROR, + new ActionError("error.transaction.token")); + } + resetToken(request); + + // Validate the request parameters specified by the user + if (log.isTraceEnabled()) { + log.trace(" Performing extra validations"); + } + String value = null; + value = regform.getUsername(); + if (("Create".equals(action)) && + (database.findUser(value) != null)) { + errors.add("username", + new ActionError("error.username.unique", + regform.getUsername())); + } + if ("Create".equals(action)) { + value = regform.getPassword(); + if ((value == null) || (value.length() <1)) { + errors.add("password", + new ActionError("error.password.required")); + } + value = regform.getPassword2(); + if ((value == null) || (value.length() < 1)) { + errors.add("password2", + new ActionError("error.password2.required")); + } + } + + // Report any errors we have discovered back to the original form + if (!errors.isEmpty()) { + saveErrors(request, errors); + saveToken(request); + return (mapping.getInputForward()); + } + + // Update the user's persistent profile information + try { + if ("Create".equals(action)) { + user = database.createUser(regform.getUsername()); + } + 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("Registration.populate", t); + throw new ServletException("Registration.populate", t); + } catch (Throwable t) { + log.error("Registration.populate", t); + throw new ServletException("Subscription.populate", t); + } + + try { + database.save(); + } catch (Exception e) { + log.error("Database save", e); + } + + // Log the user in if appropriate + if ("Create".equals(action)) { + session.setAttribute(Constants.USER_KEY, user); + if (log.isTraceEnabled()) { + log.trace(" User '" + user.getUsername() + + "' logged on in session " + session.getId()); + } + } + + // Remove the obsolete form bean + if (mapping.getAttribute() != null) { + if ("request".equals(mapping.getScope())) + request.removeAttribute(mapping.getAttribute()); + else + session.removeAttribute(mapping.getAttribute()); + } + + // Forward control to the specified success URI + if (log.isTraceEnabled()) { + log.trace(" Forwarding to success page"); + } + return (mapping.findForward("success")); + + } + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SaveSubscriptionAction.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SaveSubscriptionAction.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SaveSubscriptionAction.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SaveSubscriptionAction.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,203 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2; + + +import java.lang.reflect.InvocationTargetException; +import java.util.Locale; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts.action.Action; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.util.MessageResources; + + +/** + * Implementation of Action that validates and creates or + * updates the mail subscription entered by the user. + * + * @author Craig R. McClanahan + * @version $Rev: 54936 $ $Date: 2004-10-16 10:57:09 -0700 (Sat, 16 Oct 2004) $ + */ + +public final class SaveSubscriptionAction extends Action { + + + // ----------------------------------------------------- Instance Variables + + + /** + * The Log instance for this application. + */ + private Log log = + LogFactory.getLog("org.apache.struts.webapp.Example"); + + + // --------------------------------------------------------- Public Methods + + + /** + * Process the specified HTTP request, and create the corresponding HTTP + * response (or forward to another web component that will create it). + * Return an ActionForward instance describing where and how + * control should be forwarded, or null if the response has + * already been completed. + * + * @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 + * + * @exception Exception if the application business logic throws + * an exception + */ + public ActionForward execute(ActionMapping mapping, + ActionForm form, + HttpServletRequest request, + HttpServletResponse response) + throws Exception { + + // Extract attributes and parameters we will need + Locale locale = getLocale(request); + MessageResources messages = getResources(request); + HttpSession session = request.getSession(); + SubscriptionForm subform = (SubscriptionForm) form; + String action = subform.getAction(); + if (action == null) { + action = "?"; + } + if (log.isDebugEnabled()) { + log.debug("SaveSubscriptionAction: Processing " + action + + " action"); + } + + // Is there a currently logged on user? + User user = (User) session.getAttribute(Constants.USER_KEY); + if (user == null) { + if (log.isTraceEnabled()) { + log.trace(" User is not logged on in session " + + session.getId()); + } + return (mapping.findForward("logon")); + } + + // Was this transaction cancelled? + if (isCancelled(request)) { + if (log.isTraceEnabled()) { + log.trace(" Transaction '" + action + + "' was cancelled"); + } + session.removeAttribute(Constants.SUBSCRIPTION_KEY); + return (mapping.findForward("success")); + } + + // Is there a related Subscription object? + Subscription subscription = + (Subscription) session.getAttribute(Constants.SUBSCRIPTION_KEY); + if ("Create".equals(action)) { + if (log.isTraceEnabled()) { + log.trace(" Creating subscription for mail server '" + + subform.getHost() + "'"); + } + subscription = + user.createSubscription(subform.getHost()); + } + if (subscription == null) { + if (log.isTraceEnabled()) { + log.trace(" Missing subscription for user '" + + user.getUsername() + "'"); + } + response.sendError(HttpServletResponse.SC_BAD_REQUEST, + messages.getMessage("error.noSubscription")); + return (null); + } + + // Was this transaction a Delete? + if (action.equals("Delete")) { + if (log.isTraceEnabled()) { + log.trace(" Deleting mail server '" + + subscription.getHost() + "' for user '" + + user.getUsername() + "'"); + } + user.removeSubscription(subscription); + session.removeAttribute(Constants.SUBSCRIPTION_KEY); + try { + UserDatabase database = (UserDatabase) + servlet.getServletContext(). + getAttribute(Constants.DATABASE_KEY); + database.save(); + } catch (Exception e) { + log.error("Database save", e); + } + return (mapping.findForward("success")); + } + + // All required validations were done by the form itself + + // Update the persistent subscription information + if (log.isTraceEnabled()) { + log.trace(" Populating database from form bean"); + } + try { + PropertyUtils.copyProperties(subscription, subform); + } catch (InvocationTargetException e) { + Throwable t = e.getTargetException(); + if (t == null) + t = e; + log.error("Subscription.populate", t); + throw new ServletException("Subscription.populate", t); + } catch (Throwable t) { + log.error("Subscription.populate", t); + throw new ServletException("Subscription.populate", t); + } + + try { + UserDatabase database = (UserDatabase) + servlet.getServletContext(). + getAttribute(Constants.DATABASE_KEY); + database.save(); + } catch (Exception e) { + log.error("Database save", e); + } + + // Remove the obsolete form bean and current subscription + if (mapping.getAttribute() != null) { + if ("request".equals(mapping.getScope())) + request.removeAttribute(mapping.getAttribute()); + else + session.removeAttribute(mapping.getAttribute()); + } + session.removeAttribute(Constants.SUBSCRIPTION_KEY); + + // Forward control to the specified success URI + if (log.isTraceEnabled()) { + log.trace(" Forwarding to success page"); + } + return (mapping.findForward("success")); + + } + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/Subscription.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/Subscription.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/Subscription.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/Subscription.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,103 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2; + + +/** + *

A Subscription which is stored, along with the + * associated {@link User}, in a {@link UserDatabase}.

+ * + * @author Craig R. McClanahan + * @version $Rev: 54934 $ $Date: 2004-10-16 10:07:50 -0700 (Sat, 16 Oct 2004) $ + */ + +public interface Subscription { + + + // ------------------------------------------------------------- Properties + + + /** + * Return the auto-connect flag. + */ + public boolean getAutoConnect(); + + + /** + * Set the auto-connect flag. + * + * @param autoConnect The new auto-connect flag + */ + public void setAutoConnect(boolean autoConnect); + + + /** + * Return the host name. + */ + public String getHost(); + + + /** + * Return the password. + */ + public String getPassword(); + + + /** + * Set the password. + * + * @param password The new password + */ + public void setPassword(String password); + + + /** + * Return the subscription type. + */ + public String getType(); + + + /** + * Set the subscription type. + * + * @param type The new subscription type + */ + public void setType(String type); + + + /** + * Return the {@link User} owning this Subscription. + */ + public User getUser(); + + + /** + * Return the username. + */ + public String getUsername(); + + + /** + * Set the username. + * + * @param username The new username + */ + public void setUsername(String username); + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SubscriptionForm.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SubscriptionForm.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SubscriptionForm.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/SubscriptionForm.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,279 @@ +/* + * Copyright 1999-2001,2004 The 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.webapp.example2; + + +import javax.servlet.http.HttpServletRequest; +import org.apache.struts.action.ActionError; +import org.apache.struts.action.ActionErrors; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionMapping; + + +/** + * Form bean for the user profile page. This form has the following fields, + * with default values in square brackets: + *
    + *
  • action - The maintenance action we are performing (Create, Delete, + * or Edit). + *
  • host - The mail host for this subscription. [REQUIRED] + *
  • password - The password for this subscription. [REQUIRED] + *
  • type - The subscription type (imap,pop3) + for this subscription. [REQUIRED] + *
  • username - The username of this subscription. [REQUIRED] + *
+ * + * @author Craig R. McClanahan + * @version $Rev: 54934 $ $Date: 2004-10-16 10:07:50 -0700 (Sat, 16 Oct 2004) $ + */ + +public final class SubscriptionForm extends ActionForm { + + + // --------------------------------------------------- Instance Variables + + + /** + * The maintenance action we are performing (Create or Edit). + */ + private String action = "Create"; + + + /** + * Should we auto-connect at startup time? + */ + private boolean autoConnect = false; + + + /** + * The host name. + */ + private String host = null; + + + /** + * The password. + */ + private String password = null; + + + /** + * The subscription type. + */ + private String type = null; + + + /** + * The username. + */ + private String username = null; + + + // ----------------------------------------------------------- Properties + + + /** + * Return the maintenance action. + */ + public String getAction() { + + return (this.action); + + } + + + /** + * Set the maintenance action. + * + * @param action The new maintenance action. + */ + public void setAction(String action) { + + this.action = action; + + } + + + /** + * Return the auto-connect flag. + */ + public boolean getAutoConnect() { + + return (this.autoConnect); + + } + + + /** + * Set the auto-connect flag. + * + * @param autoConnect The new auto-connect flag + */ + public void setAutoConnect(boolean autoConnect) { + + this.autoConnect = autoConnect; + } + + + /** + * Return the host name. + */ + public String getHost() { + + return (this.host); + + } + + + /** + * Set the host name. + * + * @param host The host name + */ + public void setHost(String host) { + + this.host = host; + + } + + + /** + * Return the password. + */ + public String getPassword() { + + return (this.password); + + } + + + /** + * Set the password. + * + * @param password The new password + */ + public void setPassword(String password) { + + this.password = password; + + } + + + /** + * Return the subscription type. + */ + public String getType() { + + return (this.type); + + } + + + /** + * Set the subscription type. + * + * @param type The subscription type + */ + public void setType(String type) { + + this.type = type; + + } + + + /** + * Return the username. + */ + public String getUsername() { + + return (this.username); + + } + + + /** + * Set the username. + * + * @param username The new username + */ + public void setUsername(String username) { + + this.username = username; + + } + + + // --------------------------------------------------------- Public Methods + + + /** + * Reset all properties to their default values. + * + * @param mapping The mapping used to select this instance + * @param request The servlet request we are processing + */ + public void reset(ActionMapping mapping, HttpServletRequest request) { + + this.action = "Create"; + this.autoConnect = false; + this.host = null; + this.password = null; + this.type = null; + this.username = null; + + } + + + /** + * Validate the properties that have been set from this HTTP request, + * and return an ActionErrors object that encapsulates any + * validation errors that have been found. If no errors are found, return + * null or an ActionErrors object with no + * recorded error messages. + * + * @param mapping The mapping used to select this instance + * @param request The servlet request we are processing + */ + public ActionErrors validate(ActionMapping mapping, + HttpServletRequest request) { + + ActionErrors errors = new ActionErrors(); + + if ((host == null) || (host.length() < 1)) + errors.add("host", + new ActionError("error.host.required")); + if ((username == null) || (username.length() < 1)) + errors.add("username", + new ActionError("error.username.required")); + if ((password == null) || (password.length() < 1)) + errors.add("password", + new ActionError("error.password.required")); + if ((type == null) || (type.length() < 1)) + errors.add("type", + new ActionError("error.type.required")); + else if (!"imap".equals(type) && !"pop3".equals(type)) + errors.add("type", + new ActionError("error.type.invalid", type)); + + return (errors); + + } + + +} + Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/User.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/User.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/User.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/User.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,147 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2; + + +/** + *

A User which is stored, along with his or her + * associated {@link Subscription}s, in a {@link UserDatabase}.

+ * + * @author Craig R. McClanahan + * @version $Rev: 54934 $ $Date: 2004-10-16 10:07:50 -0700 (Sat, 16 Oct 2004) $ + * @since Struts 1.1 + */ + +public interface User { + + + // ------------------------------------------------------------- Properties + + + /** + * Return the {@link UserDatabase} with which we are associated. + */ + public UserDatabase getDatabase(); + + + /** + * Return the from address. + */ + public String getFromAddress(); + + + /** + * Set the from address. + * + * @param fromAddress The new from address + */ + public void setFromAddress(String fromAddress); + + + /** + * Return the full name. + */ + public String getFullName(); + + + /** + * Set the full name. + * + * @param fullName The new full name + */ + public void setFullName(String fullName); + + + /** + * Return the password. + */ + public String getPassword(); + + + /** + * Set the password. + * + * @param password The new password + */ + public void setPassword(String password); + + + /** + * Return the reply-to address. + */ + public String getReplyToAddress(); + + + /** + * Set the reply-to address. + * + * @param replyToAddress The new reply-to address + */ + public void setReplyToAddress(String replyToAddress); + + + /** + * Find and return all {@link Subscription}s associated with this user. + * If there are none, a zero-length array is returned. + */ + public Subscription[] getSubscriptions(); + + + /** + * Return the username. + */ + public String getUsername(); + + + // --------------------------------------------------------- Public Methods + + + /** + * Create and return a new {@link Subscription} associated with this + * User, for the specified host name. + * + * @param host Host name for which to create a subscription + * + * @exception IllegalArgumentException if the host name is not unique + * for this user + */ + public Subscription createSubscription(String host); + + + /** + * Find and return the {@link Subscription} associated with the specified + * host. If none is found, return null. + * + * @param host Host name to look up + */ + public Subscription findSubscription(String host); + + + /** + * Remove the specified {@link Subscription} from being associated + * with this User. + * + * @param subscription Subscription to be removed + * + * @exception IllegalArgumentException if the specified subscription is not + * associated with this User + */ + public void removeSubscription(Subscription subscription); + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/UserDatabase.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/UserDatabase.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/UserDatabase.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/UserDatabase.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,101 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2; + + +/** + *

A Data Access Object (DAO) interface describing + * the available operations for retrieving and storing {@link User}s + * (and their associated {@link Subscription}s) in some persistence layer + * whose characteristics are not specified here. One or more implementations + * will be created to perform the actual I/O that is required.

+ * + * @author Craig R. McClanahan + * @version $Rev: 54934 $ $Date: 2004-10-16 10:07:50 -0700 (Sat, 16 Oct 2004) $ + * @since Struts 1.1 + */ + +public interface UserDatabase { + + + // --------------------------------------------------------- Public Methods + + + /** + *

Create and return a new {@link User} defined in this user database. + *

+ * + * @param username Username of the new user + * + * @exception IllegalArgumentExceptionif the specified username + * is not unique + */ + public User createUser(String username); + + + /** + *

Finalize access to the underlying persistence layer.

+ * + * @exception Exception if a database access error occurs + */ + public void close() throws Exception; + + + /** + *

Return the existing {@link User} with the specified username, + * if any; otherwise return null.

+ * + * @param username Username of the user to retrieve + */ + public User findUser(String username); + + + /** + *

Return the set of {@link User}s defined in this user database.

+ */ + public User[] findUsers(); + + + /** + *

Initiate access to the underlying persistence layer.

+ * + * @exception Exception if a database access error occurs + */ + public void open() throws Exception; + + + /** + * Remove the specified {@link User} from this database. + * + * @param user User to be removed + * + * @exception IllegalArgumentException if the specified user is not + * associated with this database + */ + public void removeUser(User user); + + + /** + *

Save any pending changes to the underlying persistence layer.

+ * + * @exception Exception if a database access error occurs + */ + public void save() throws Exception; + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryDatabasePlugIn.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryDatabasePlugIn.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryDatabasePlugIn.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryDatabasePlugIn.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,247 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2.memory; + + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import javax.servlet.ServletException; +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.config.ModuleConfig; +import org.apache.struts.util.LabelValueBean; +import org.apache.struts.webapp.example2.Constants; + +/** + *

MemoryDatabasePlugIn 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.

+ * + *

IMPLEMENTATION WARNING - 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 + * NOT assume that files written here will survive a restart + * of your servlet container.

+ * + * @author Craig R. McClanahan + * @version $Rev: 54934 $ $Date: 2004-10-16 10:07:50 -0700 (Sat, 16 Oct 2004) $ + */ + +public final class MemoryDatabasePlugIn implements PlugIn { + + + // ----------------------------------------------------- Instance Variables + + + /** + * The application configuration for our owning module. + */ + private ModuleConfig config = null; + + + /** + * The {@link 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 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; + config = 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 + * + * @exception 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.config = config; + 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); + + // Setup and cache other required data + setupCache(servlet, config); + + } + + + // --------------------------------------------------------- Public Methods + + + // ------------------------------------------------------ Protected Methods + + + /** + *

Cache commonly required data as servlet context attributes.

+ * + * @param servlet The ActionServlet instance running + * this webapp + * @param config The ModuleConfig for this application module + */ + protected void setupCache(ActionServlet servlet, ModuleConfig config) { + + // Set up list of server types under "serverTypes" + ArrayList serverTypes = new ArrayList(); + serverTypes.add(new LabelValueBean("IMAP Protocol", "imap")); + serverTypes.add(new LabelValueBean("POP3 Protocol", "pop3")); + servlet.getServletContext().setAttribute("serverTypes", serverTypes); + + } + + + + + // -------------------------------------------------------- Private Methods + + + /** + * Calculate and return an absolute pathname to the XML file to contain + * our persistent storage information. + * + * @exception 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()); + + } + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemorySubscription.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemorySubscription.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemorySubscription.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemorySubscription.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,180 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2.memory; + + +import org.apache.struts.webapp.example2.Subscription; +import org.apache.struts.webapp.example2.User; + + +/** + *

Concrete implementation of {@link Subscription} for an in-memory + * database backed by an XML data file.

+ * + * @author Craig R. McClanahan + * @version $Rev: 54934 $ $Date: 2004-10-16 10:07:50 -0700 (Sat, 16 Oct 2004) $ + * @since Struts 1.1 + */ + +public final class MemorySubscription implements Subscription { + + + // ----------------------------------------------------------- Constructors + + + /** + *

Construct a new Subscription associated with the specified + * {@link User}. + * + * @param user The user with which we are associated + * @param host The mail host for this subscription + */ + public MemorySubscription(MemoryUser user, String host) { + + super(); + this.user = user; + this.host = host; + + } + + + // ----------------------------------------------------- Instance Variables + + + /** + * The mail host for this subscription. + */ + private String host = null; + + + /** + * The {@link User} with which we are associated. + */ + private MemoryUser user = null; + + + // ------------------------------------------------------------- Properties + + + /** + * Should we auto-connect at startup time? + */ + private boolean autoConnect = false; + + public boolean getAutoConnect() { + return (this.autoConnect); + } + + public void setAutoConnect(boolean autoConnect) { + this.autoConnect = autoConnect; + } + + + /** + * The mail host for this subscription. + */ + public String getHost() { + return (this.host); + } + + + /** + * The password (in clear text) for this subscription. + */ + private String password = null; + + public String getPassword() { + return (this.password); + } + + public void setPassword(String password) { + this.password = password; + } + + + /** + * The subscription type ("imap" or "pop3"). + */ + private String type = "imap"; + + public String getType() { + return (this.type); + } + + public void setType(String type) { + this.type = type; + } + + + /** + * The User owning this Subscription. + */ + public User getUser() { + return (this.user); + } + + + /** + * The username for this subscription. + */ + private String username = null; + + public String getUsername() { + return (this.username); + } + + public void setUsername(String username) { + this.username = username; + } + + + // --------------------------------------------------------- Public Methods + + + /** + * Return a String representation of this object. + */ + public String toString() { + + StringBuffer sb = new StringBuffer(""); + return (sb.toString()); + + } + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryUser.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryUser.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryUser.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryUser.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,270 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2.memory; + + +import java.util.HashMap; +import org.apache.struts.webapp.example2.Subscription; +import org.apache.struts.webapp.example2.User; +import org.apache.struts.webapp.example2.UserDatabase; + + +/** + *

Concrete implementation of {@link User} for an in-memory + * database backed by an XML data file.

+ * + * @author Craig R. McClanahan + * @version $Rev: 54934 $ $Date: 2004-10-16 10:07:50 -0700 (Sat, 16 Oct 2004) $ + * @since Struts 1.1 + */ + +public final class MemoryUser implements User { + + + // ----------------------------------------------------------- Constructors + + + /** + *

Construct a new User associated with the specified + * {@link UserDatabase}. + * + * @param database The user database with which we are associated + * @param username The username of this user + */ + public MemoryUser(MemoryUserDatabase database, String username) { + + super(); + this.database = database; + this.username = username; + + } + + + // ----------------------------------------------------- Instance Variables + + + /** + * The {@link UserDatabase} with which we are associated. + */ + private MemoryUserDatabase database = null; + + + /** + * The {@link Subscription}s for this User, keyed by hostname. + */ + private HashMap subscriptions = new HashMap(); + + + /** + * The username for this user. + */ + private String username = null; + + + // ------------------------------------------------------------- Properties + + + /** + * The {@link UserDatabase} with which we are associated. + */ + public UserDatabase getDatabase() { + return (this.database); + } + + + /** + * The email address from which messages are sent. + */ + private String fromAddress = null; + + public String getFromAddress() { + return (this.fromAddress); + } + + public void setFromAddress(String fromAddress) { + this.fromAddress = fromAddress; + } + + + /** + * The full name of this user, included in from addresses. + */ + private String fullName = null; + + public String getFullName() { + return (this.fullName); + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + + /** + * The password (in clear text). + */ + private String password = null; + + public String getPassword() { + return (this.password); + } + + public void setPassword(String password) { + this.password = password; + } + + + /** + * The EMAIL address to which replies should be sent. + */ + private String replyToAddress = null; + + public String getReplyToAddress() { + return (this.replyToAddress); + } + + public void setReplyToAddress(String replyToAddress) { + this.replyToAddress = replyToAddress; + } + + + /** + * Find and return all {@link Subscription}s associated with this user. + * If there are none, a zero-length array is returned. + */ + public Subscription[] getSubscriptions() { + + synchronized (subscriptions) { + Subscription results[] = new Subscription[subscriptions.size()]; + return ((Subscription[]) subscriptions.values().toArray(results)); + } + + } + + + /** + * The username (must be unique). + */ + public String getUsername() { + return (this.username); + } + + + // --------------------------------------------------------- Public Methods + + + /** + * Create and return a new {@link Subscription} associated with this + * User, for the specified host name. + * + * @param host Host name for which to create a subscription + * + * @exception IllegalArgumentException if the host name is not unique + * for this user + */ + public Subscription createSubscription(String host) { + + synchronized (subscriptions) { + if (subscriptions.get(host) != null) { + throw new IllegalArgumentException("Duplicate host '" + host + + "' for user '" + + username + "'"); + } + MemorySubscription subscription = + new MemorySubscription(this, host); + synchronized (subscriptions) { + subscriptions.put(host, subscription); + } + return (subscription); + } + + } + + + /** + * Find and return the {@link Subscription} associated with the specified + * host. If none is found, return null. + * + * @param host Host name to look up + */ + public Subscription findSubscription(String host) { + + synchronized (subscriptions) { + return ((Subscription) subscriptions.get(host)); + } + + } + + + /** + * Remove the specified {@link Subscription} from being associated + * with this User. + * + * @param subscription Subscription to be removed + * + * @exception IllegalArgumentException if the specified subscription is not + * associated with this User + */ + public void removeSubscription(Subscription subscription) { + + if (!(this == subscription.getUser())) { + throw new IllegalArgumentException + ("Subscription not associated with this user"); + } + synchronized (subscriptions) { + subscriptions.remove(subscription.getHost()); + } + + } + + + /** + * Return a String representation of this object. + */ + public String toString() { + + StringBuffer sb = new StringBuffer(""); + return (sb.toString()); + + } + + +} Added: struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryUserDatabase.java URL: http://svn.apache.org/viewcvs/struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryUserDatabase.java?rev=392100&view=auto ============================================================================== --- struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryUserDatabase.java (added) +++ struts/action/trunk/apps/faces-example2/src/main/java/org/apache/struts/webapp/example2/memory/MemoryUserDatabase.java Thu Apr 6 15:31:36 2006 @@ -0,0 +1,412 @@ +/* + * Copyright 1999-2002,2004 The 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.webapp.example2.memory; + + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.HashMap; +import org.apache.commons.digester.Digester; +import org.apache.commons.digester.ObjectCreationFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts.webapp.example2.Subscription; +import org.apache.struts.webapp.example2.User; +import org.apache.struts.webapp.example2.UserDatabase; +import org.xml.sax.Attributes; + + +/** + *

Concrete implementation of {@link UserDatabase} for an in-memory + * database backed by an XML data file.

+ * + * @author Craig R. McClanahan + * @version $Rev: 54934 $ $Date: 2004-10-16 10:07:50 -0700 (Sat, 16 Oct 2004) $ + * @since Struts 1.1 + */ + +public final class MemoryUserDatabase implements UserDatabase { + + + // ----------------------------------------------------------- Constructors + + + // ----------------------------------------------------- Instance Variables + + + /** + * Logging output for this user database instance. + */ + private Log log = LogFactory.getLog(this.getClass()); + + + /** + * The {@link User}s associated with this UserDatabase, keyed by username. + */ + private HashMap users = new HashMap(); + + + // ------------------------------------------------------------- Properties + + + /** + * Absolute pathname to the persistent file we use for loading and storing + * persistent data. + */ + private String pathname = null; + + private String pathnameOld = null; + + private String pathnameNew = null; + + public String getPathname() { + return (this.pathname); + } + + public void setPathname(String pathname) { + this.pathname = pathname; + pathnameOld = pathname + ".old"; + pathnameNew = pathname + ".new"; + } + + + // --------------------------------------------------------- Public Methods + + + /** + *

Finalize access to the underlying persistence layer.

+ * + * @exception Exception if a database access error occurs + */ + public void close() throws Exception { + + save(); + + } + + + /** + *

Create and return a new {@link User} defined in this user database. + *

+ * + * @param username Username of the new user + * + * @exception IllegalArgumentExceptionif the specified username + * is not unique + */ + public User createUser(String username) { + + synchronized (users) { + if (users.get(username) != null) { + throw new IllegalArgumentException("Duplicate user '" + + username + "'"); + } + if (log.isTraceEnabled()) { + log.trace("Creating user '" + username + "'"); + } + MemoryUser user = new MemoryUser(this, username); + synchronized (users) { + users.put(username, user); + } + return (user); + } + + } + + + /** + *

Return the existing {@link User} with the specified username, + * if any; otherwise return null.

+ * + * @param username Username of the user to retrieve + */ + public User findUser(String username) { + + synchronized (users) { + return ((User) users.get(username)); + } + + } + + + /** + *

Return the set of {@link User}s defined in this user database.

+ */ + public User[] findUsers() { + + synchronized (users) { + User results[] = new User[users.size()]; + return ((User[]) users.values().toArray(results)); + } + + } + + + /** + *

Initiate access to the underlying persistence layer.

+ * + * @exception Exception if a database access error occurs + */ + public void open() throws Exception { + + FileInputStream fis = null; + BufferedInputStream bis = null; + + try { + + // Acquire an input stream to our database file + if (log.isDebugEnabled()) { + log.debug("Loading database from '" + pathname + "'"); + } + fis = new FileInputStream(pathname); + bis = new BufferedInputStream(fis); + + // Construct a digester to use for parsing + Digester digester = new Digester(); + digester.push(this); + digester.setValidating(false); + digester.addFactoryCreate + ("database/user", + new MemoryUserCreationFactory(this)); + digester.addFactoryCreate + ("database/user/subscription", + new MemorySubscriptionCreationFactory(this)); + + // Parse the input stream to initialize our database + digester.parse(bis); + bis.close(); + bis = null; + fis = null; + + } catch (Exception e) { + + log.error("Loading database from '" + pathname + "':", e); + throw e; + + } finally { + + if (bis != null) { + try { + bis.close(); + } catch (Throwable t) { + ; + } + bis = null; + fis = null; + } + + } + + } + + + /** + * Remove the specified {@link User} from this database. + * + * @param user User to be removed + * + * @exception IllegalArgumentException if the specified user is not + * associated with this database + */ + public void removeUser(User user) { + + if (!(this == user.getDatabase())) { + throw new IllegalArgumentException + ("User not associated with this database"); + } + if (log.isTraceEnabled()) { + log.trace("Removing user '" + user.getUsername() + "'"); + } + synchronized (users) { + users.remove(user.getUsername()); + } + + } + + + /** + *

Save any pending changes to the underlying persistence layer.

+ * + * @exception Exception if a database access error occurs + */ + public void save() throws Exception { + + if (log.isDebugEnabled()) { + log.debug("Saving database to '" + pathname + "'"); + } + File fileNew = new File(pathnameNew); + PrintWriter writer = null; + + try { + + // Configure our PrintWriter + FileOutputStream fos = new FileOutputStream(fileNew); + OutputStreamWriter osw = new OutputStreamWriter(fos); + writer = new PrintWriter(osw); + + // Print the file prolog + writer.println(""); + writer.println(""); + + // Print entries for each defined user and associated subscriptions + User users[] = findUsers(); + for (int i = 0; i < users.length; i++) { + writer.print(" "); + writer.println(users[i]); + Subscription subscriptions[] = + users[i].getSubscriptions(); + for (int j = 0; j < subscriptions.length; j++) { + writer.print(" "); + writer.println(subscriptions[j]); + writer.print(" "); + writer.println(""); + } + writer.print(" "); + writer.println(""); + } + + // Print the file epilog + writer.println(""); + + // Check for errors that occurred while printing + if (writer.checkError()) { + writer.close(); + fileNew.delete(); + throw new IOException + ("Saving database to '" + pathname + "'"); + } + writer.close(); + writer = null; + + } catch (IOException e) { + + if (writer != null) { + writer.close(); + } + fileNew.delete(); + throw e; + + } + + + // Perform the required renames to permanently save this file + File fileOrig = new File(pathname); + File fileOld = new File(pathnameOld); + if (fileOrig.exists()) { + fileOld.delete(); + if (!fileOrig.renameTo(fileOld)) { + throw new IOException + ("Renaming '" + pathname + "' to '" + pathnameOld + "'"); + } + } + if (!fileNew.renameTo(fileOrig)) { + if (fileOld.exists()) { + fileOld.renameTo(fileOrig); + } + throw new IOException + ("Renaming '" + pathnameNew + "' to '" + pathname + "'"); + } + fileOld.delete(); + + } + + +} + + +/** + * Digester object creation factory for subscription instances. + */ +class MemorySubscriptionCreationFactory implements ObjectCreationFactory { + + public MemorySubscriptionCreationFactory(MemoryUserDatabase database) { + this.database = database; + } + + private MemoryUserDatabase database = null; + + private Digester digester = null; + + public Digester getDigester() { + return (this.digester); + } + + public void setDigester(Digester digester) { + this.digester = digester; + } + + public Object createObject(Attributes attributes) { + String host = attributes.getValue("host"); + User user = (User) digester.peek(); + Subscription subscription = user.createSubscription(host); + String autoConnect = attributes.getValue("autoConnect"); + if (autoConnect == null) { + autoConnect = "false"; + } + if ("true".equalsIgnoreCase(autoConnect) || + "yes".equalsIgnoreCase(autoConnect)) { + subscription.setAutoConnect(true); + } else { + subscription.setAutoConnect(false); + } + subscription.setPassword(attributes.getValue("password")); + subscription.setType(attributes.getValue("type")); + subscription.setUsername(attributes.getValue("username")); + return (subscription); + } + +} + + +/** + * Digester object creation factory for user instances. + */ +class MemoryUserCreationFactory implements ObjectCreationFactory { + + public MemoryUserCreationFactory(MemoryUserDatabase database) { + this.database = database; + } + + private MemoryUserDatabase database = null; + + private Digester digester = null; + + public Digester getDigester() { + return (this.digester); + } + + public void setDigester(Digester digester) { + this.digester = digester; + } + + public Object createObject(Attributes attributes) { + String username = attributes.getValue("username"); + User user = database.createUser(username); + user.setFromAddress(attributes.getValue("fromAddress")); + user.setFullName(attributes.getValue("fullName")); + user.setPassword(attributes.getValue("password")); + user.setReplyToAddress(attributes.getValue("replyToAddress")); + return (user); + } + +} --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org For additional commands, e-mail: dev-help@struts.apache.org