Author: craigmcc Date: Mon Apr 18 13:15:16 2005 New Revision: 161794 URL: http://svn.apache.org/viewcvs?view=rev&rev=161794 Log: Initial checkin of a version of the logon and edit profile dialogs that uses the new dialog support, instead of DialogController. This has not been tested yet (or even hooked in to the menus), but I needed to check it in to make the code accessible from my laptop on an upcoming trip.
The dialog flows themselves are defined in "use-cases/src/web/WEB-INF/dialog-config.xml". Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileActions.java struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileState.java struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/LogonActions.java struts/shale/trunk/use-cases/src/web/WEB-INF/dialog-config.xml struts/shale/trunk/use-cases/src/web/profile/ struts/shale/trunk/use-cases/src/web/profile/logon.jsp struts/shale/trunk/use-cases/src/web/profile/profile1.jsp struts/shale/trunk/use-cases/src/web/profile/profile2.jsp struts/shale/trunk/use-cases/src/web/profile/profile3.jsp Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/BaseViewController.java struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties struts/shale/trunk/use-cases/src/web/WEB-INF/applicationContext.xml struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileActions.java URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileActions.java?view=auto&rev=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileActions.java (added) +++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileActions.java Mon Apr 18 13:15:16 2005 @@ -0,0 +1,265 @@ +/* + * Copyright 2004-2005 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.shale.usecases.profile; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.shale.usecases.logic.LogonLogic; +import org.apache.shale.usecases.model.User; +import org.apache.shale.util.Messages; +import org.apache.shale.view.AbstractFacesBean; + +/** + * <p>Action methods for the Edit Profile dialog.</p> + * + * $Id$ + */ +public class EditProfileActions extends AbstractFacesBean { + + + // -------------------------------------------------------- Static Variables + + + /** + * <p>Log instance for this class.</p> + */ + private static final Log log = LogFactory.getLog(EditProfileActions.class); + + + /** + * <p>Message resources for this application.</p> + */ + private static final Messages messages = + new Messages("org.apache.shale.usecases.view.Bundle"); + + + // ------------------------------------------------------ Manifest Constants + + + /** + * <p>Managed bean name under which the business logic bean instance + * for this dialog is stored.</p> + */ + static final String LOGIC_BEAN = "profile$logic"; // FIXME - shared name + + + /** + * <p>Logical outcome indicating a problem with the password field.</p> + */ + static final String PASSWORD = "password"; + + + /** + * <p>Logical outcome indicating successful completion.</p> + */ + static final String SUCCESS = "success"; + + + /** + * <p>Logical outcome indicating a problem with the username field.</p> + */ + static final String USERNAME = "username"; + + + + // --------------------------------------------------- Configured Properties + + + /** + * <p>Flag indicating that a confirmation email is required before a new + * profile may be activated.</p> + */ + private boolean confirmation = false; + public boolean isConfirmation() { return this.confirmation; } + public void setConfirmation(boolean confirmation) { this.confirmation = confirmation; } + + + /** + * <p>Session scope attribute under which a [EMAIL PROTECTED] User} instance for the + * currently logged in user is stored.</p> + */ + private String userKey = "user"; + public String getUserKey() { return this.userKey; } + public void setUserKey(String userKey) { this.userKey = userKey; } + + + // ----------------------------------------------------------------- Actions + + + /** + * <p>Perform any processing necessary to cancel an edit profile dialog.</p> + * + * <p>The following logical outcome values are returned:</p> + * <ul> + * <li><code>SUCCESS</code> - Proceed to the next state normally.</li> + * </ul> + */ + public String cancel() { + + return SUCCESS; + + } + + + /** + * <p>Finish processing by creating or updating the appropriate user + * profile.</p> + * + * <p>The following logical outcome values are returned:</p> + * <ul> + * <li><code>PASSWORD</code> - One or both password values were entered, + * but they do not match (or neither were entered on a create)</li> + * <li><code>SUCCESS</code> - Creation or update succeeded, proceed to + * the next state normally.</li> + * <li><code>USERNAME</code> - Missing or dupicate username on + * a create.</li> + * </ul> + */ + public String finish() { + + // Acquire our state information + EditProfileState state = (EditProfileState) getValue("#{dialog.data}"); + boolean okUsername = true; + boolean okPassword = true; + + // Validate password match if both specified + if ((state.getPassword() != null) && (state.getPassword().length() > 0) && + (state.getPassword2() != null) && (state.getPassword2().length() > 0)) { + if (!state.getPassword().equals(state.getPassword2())) { + error(messages.getMessage("profile.mismatch")); + okPassword = false; + } + } + + // Validate required fields if creating + if (state.isCreating()) { + if ((state.getUsername() == null) || (state.getUsername().length() < 1)) { + error(messages.getMessage("profile.username")); + okUsername = false; + } + if ((state.getPassword() == null) || (state.getPassword().length() < 1)) { + error(messages.getMessage("profile.password")); + okPassword = false; + } + } + + // Validate duplicate username if creating + LogonLogic logic = (LogonLogic) getBean(LOGIC_BEAN); + if (state.isCreating() && (logic.findUser(state.getUsername()) != null)) { + error(messages.getMessage("profile.duplicate")); + okUsername = false; + } + + // Return appropriate outcome on validation failures + if (!okUsername) { + return USERNAME; + } else if (!okPassword) { + return PASSWORD; + } + + // Create or acquire our User instance + User user = null; + if (state.isCreating()) { + user = logic.createUser(); + } else { + user = (User) getBean(getUserKey()); + } + + // Update to reflect changes during this dialog + user.setCategories(state.getCategories()); + if (state.isCreating()) { + user.setConfirmed(!isConfirmation()); + } + user.setEmailAddress(state.getEmailAddress()); + user.setFullName(state.getFullName()); + if ((state.getPassword() != null) && (state.getPassword().length() > 0)) { + user.setPassword(state.getPassword()); + } + user.setUsername(state.getUsername()); + + // Persist the changes made during this dialog + if (state.isCreating()) { + logic.insertUser(user); + } else { + logic.updateUser(user); + } + + // Log in a new user if already confirmed + // Otherwise, send the confirmation email + if (state.isCreating()) { + if (user.isConfirmed()) { + getSessionMap().put(getUserKey(),user); + } else { + info(messages.getMessage("profile.confirm")); + // FIXME - send confirmation email + } + } + + // Return a success outcome + return SUCCESS; + + + } + + + /** + * <p>Register an instance of [EMAIL PROTECTED] EditProfileState} as the data object + * for our dialog. If there is an existing logged on user, we are editing + * the existing profile; otherwise, we are creating a new one.</p> + * + * <p>The following logical outcome values are returned:</p> + * <ul> + * <li><code>SUCCESS</code> - Proceed to the next state.</li> + * </ul> + */ + public String setup() { + + // Acquire a reference to the currently logged on user, if there is one + User user = (User) getBean(getUserKey()); + + // Configure a state object based on the currently logged on user, + // or set up for a newly created profile + EditProfileState state = new EditProfileState(); + if (user == null) { + state.setCreating(true); + } else { + state.setCreating(false); + int oldCategories[] = user.getCategories(); + int categories[] = null; + if (oldCategories != null) { + categories = new int[oldCategories.length]; + System.arraycopy + (oldCategories, 0, categories, 0, oldCategories.length); + } else { + categories = new int[0]; + } + state.setCategories(categories); + state.setEmailAddress(user.getEmailAddress()); + state.setFullName(user.getFullName()); + state.setPassword(null); + state.setPassword2(null); + state.setUsername(user.getUsername()); + } + + // Register our state as the data object for this dialog, and continue + setValue("#{dialog.data}", state); + return SUCCESS; + + } + + +} Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileState.java URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileState.java?view=auto&rev=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileState.java (added) +++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/EditProfileState.java Mon Apr 18 13:15:16 2005 @@ -0,0 +1,90 @@ +/* + * Copyright 2004-2005 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.shale.usecases.profile; + +/** + * <p>Dialog state information for the Edit Profile dialog.</p> + * + * $Id$ + */ +public class EditProfileState { + + + // ------------------------------------------------ Configuration Properties + + + /** + * <p>Flag indicating that we are creating a new profile, versus editing + * an existing one.</p> + */ + private boolean creating = true; + public boolean isCreating() { return this.creating; } + public void setCreating(boolean creating) { this.creating = creating; } + + + // -------------------------------------------------- Input Field Properties + + + /** + * <p>Category identifiers for the categories selected by this user + */ + private int categories[] = new int[0]; + public int[] getCategories() { return this.categories; } + public void setCategories(int categories[]) { this.categories = categories; } + + + /** + * <p>Email address for this user.</p> + */ + private String emailAddress = null; + public String getEmailAddress() { return this.emailAddress; } + public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; } + + + /** + * <p>Full name for this user.</p> + */ + private String fullName = null; + public String getFullName() { return this.fullName; } + public void setFullName(String fullName) { this.fullName = fullName; } + + + /** + * <p>Password entered by the user.</p> + */ + private String password = null; + public String getPassword() { return this.password; } + public void setPassword(String password) { this.password = password; } + + + /** + * <p>Confirmation password entered by the user.</p> + */ + private String password2 = null; + public String getPassword2() { return this.password2; } + public void setPassword2(String password2) { this.password2 = password2; } + + + /** + * <p>Username entered by the user.</p> + */ + private String username = null; + public String getUsername() { return this.username; } + public void setUsername(String username) { this.username = username; } + + +} Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/LogonActions.java URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/LogonActions.java?view=auto&rev=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/LogonActions.java (added) +++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/profile/LogonActions.java Mon Apr 18 13:15:16 2005 @@ -0,0 +1,331 @@ +/* + * Copyright 2004-2005 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.shale.usecases.profile; + +import java.util.Map; +import javax.faces.context.FacesContext; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.shale.usecases.logic.LogonLogic; +import org.apache.shale.usecases.model.User; +import org.apache.shale.util.Messages; +import org.apache.shale.view.AbstractViewController; + +/** + * <p><code>ViewController</code> and action methods for the Logon dialog.</p> + * + * <p><strong>WARNING</strong> - The format of the cookie used to store + * "remember me" credentials is <strong>NOT</strong> secure, and should + * be considered demo quality. The architecture of a production quality + * version of this function would be identical; more effort would need + * to be invested in improving security around the cookie values.</p> + * + * $Id$ + */ +public class LogonActions extends AbstractViewController { + + + // -------------------------------------------------------- Static Variables + + + /** + * <p>Log instance for this class.</p> + */ + private static final Log log = LogFactory.getLog(LogonActions.class); + + + /** + * <p>Message resources for this application.</p> + */ + private static final Messages messages = + new Messages("org.apache.shale.usecases.view.Bundle"); + + + // ------------------------------------------------------ Manifest Constants + + + + /** + * <p>Logical outcome indicating an authenticated user.</p> + */ + static final String AUTHENTICATED = "authenticated"; + + + /** + * <p>Logical outcome indicating the user wishes to create a new + * user profile.</p> + */ + static final String CREATE = "create"; + + + /** + * <p>Managed bean name under which the business logic bean instance + * for this dialog is stored.</p> + */ + static final String LOGIC_BEAN = "profile$logic"; // FIXME - shared name + + + /** + * <p>Name of the HTTP cookie in which we store "remember me" credentials.</p> + */ + static final String COOKIE_NAME = "remember_me"; + + + /** + * <p>Logical outcome indicating an unauthenticated user.</p> + */ + static final String UNAUTHENTICATED = "unauthenticated"; + + + // --------------------------------------------------- Configured Properties + + + /** + * <p>Flag indicating that "remember me" cookies are enabled.</p> + */ + private boolean rememberMe = false; + public boolean isRememberMe() { return this.rememberMe; } + public void setRememberMe(boolean rememberMe) { this.rememberMe = rememberMe; } + + + /** + * <p>Session scope attribute under which a [EMAIL PROTECTED] User} instance for the + * currently logged in user is stored.</p> + */ + private String userKey = "user"; // FIXME - shared + public String getUserKey() { return this.userKey; } + public void setUserKey(String userKey) { this.userKey = userKey; } + + + // -------------------------------------------------- Input Field Properties + + + /** + * <p>Password entered by the user.</p> + */ + private String password = null; + public String getPassword() { return this.password; } + public void setPassword(String password) { this.password = password; } + + + /** + * <p>Flag indicating that the user wishes to have a "remember me" + * cookie created this time.</p> + */ + private boolean remember = false; + public boolean isRemember() { return this.remember; } + public void setRemember(boolean remember) { this.remember = remember; } + + + /** + * <p>Username entered by the user.</p> + */ + private String username = null; + public String getUsername() { return this.username; } + public void setUsername(String username) { this.username = username; } + + + // ----------------------------------------------------------------- Actions + + + /** + * <p>Perform any processing necessary to cancel an edit profile dialog.</p> + * + * <p>The following logical outcome values are returned:</p> + * <ul> + * <li><code>AUTHENTICATED</code> - User has been authenticated.</li> + * <li><code>UNAUTHENTICATED</code> - User has not been authenticated + * (no cookie, "remember me" not supported).</li> + * </ul> + */ + public String check() { + + // Is "remember me" functionality enabled? + if (!isRememberMe()) { + return UNAUTHENTICATED; + } + + // Locate the "remember me" cookie (if any) + FacesContext context = getFacesContext(); + Map map = context.getExternalContext().getRequestCookieMap(); + Cookie cookie = (Cookie) map.get(COOKIE_NAME); + if (cookie == null) { + return UNAUTHENTICATED; + } + + // Extract the user identifier of the logged-on user (if any) + int id = 0; + try { + id = Integer.parseInt(cookie.getValue()); + } catch (NumberFormatException e) { + return UNAUTHENTICATED; + } + + // Locate the corresponding valid user (if any) and return it + LogonLogic logic = (LogonLogic) getBean(LOGIC_BEAN); + User user = logic.findUser(id); + if (user == null) { + return UNAUTHENTICATED; + } + + // Register the newly authenticated user and return that outcome + register(user); + return AUTHENTICATED; + + } + + + /** + * <p>Request creation of a new user profile.</p> + */ + public String create() { + + // At this point, there is no special behavior needed + // prior to executing the subdialog. If there is, it + // should likely be defined as an action in EditProfileActions + // instead of here. + return CREATE; + + } + + + /** + * <p>Alternate exit action for this dialog. Remove the currently + * logged on user (if any), remove this instance from session scope, + * and return outcome <code>unauthenticated</code>.</p> + */ + public String logoff() { + + unregister(); + return UNAUTHENTICATED; + + } + + + /** + * <p>Authenticate the entered username and password.</p> + */ + public String logon() { + + // Attempt a successful authentication + LogonLogic logic = (LogonLogic) getBean(LOGIC_BEAN); + User user = logic.authenticate(username, password); + if (user != null) { + if (user.isConfirmed()) { + // Confirmed user, log him/her on + register(user); + if (isRememberMe()) { + if (isRemember()) { + remember(user); + } else { + forget(user); + } + } + return AUTHENTICATED; + } else { + // Unconfirmed user, tell him/her to reply to the email + error(messages.getMessage("profile.unconfirmed")); + return UNAUTHENTICATED; + } + } + + // On unsuccessful authentication, tell the user to try again + error(messages.getMessage("profile.incorrect")); + return UNAUTHENTICATED; + + } + + + // --------------------------------------------------------- Private Methods + + + /** + * <p>Remove any existing "remember me" cookie that was included.</p> + * + * @param user [EMAIL PROTECTED] User} to be forgotten + */ + private void forget(User user) { + + FacesContext context = getFacesContext(); + HttpServletRequest request = + (HttpServletRequest) context.getExternalContext().getRequest(); + Cookie cookie = + new Cookie(COOKIE_NAME, ""); + cookie.setDomain(request.getServerName()); + cookie.setMaxAge(0); // Delete immediately + cookie.setPath(request.getContextPath()); + HttpServletResponse response = + (HttpServletResponse) context.getExternalContext().getResponse(); + response.addCookie(cookie); + + } + + + /** + * <p>Store the specified [EMAIL PROTECTED] User} in session scope, and take whatever + * other actions are necessary to mark the user as being logged on.</p> + * + * @param user [EMAIL PROTECTED] User} who is to be logged on + */ + private void register(User user) { + + // Store the user instance in session scope + FacesContext context = getFacesContext(); + context.getExternalContext().getSessionMap(). + put(getUserKey(), user); + + } + + + /** + * <p>Add a "remember me" cookie to the current response.</p> + * + * @param user [EMAIL PROTECTED] User} whose identity is to be persisted + */ + private void remember(User user) { + + FacesContext context = getFacesContext(); + HttpServletRequest request = + (HttpServletRequest) context.getExternalContext().getRequest(); + Cookie cookie = + new Cookie(COOKIE_NAME, "" + user.getId()); // FIXME - more secure mechanism needed + // cookie.setDomain(request.getServerName()); + cookie.setMaxAge(60 * 60 * 24 * 365); // One year + cookie.setPath(request.getContextPath()); + HttpServletResponse response = + (HttpServletResponse) context.getExternalContext().getResponse(); + response.addCookie(cookie); + + } + + + /** + * <p>Remove registration of the currently logged in user, as needed.</p> + */ + private void unregister() { + + // Remove user instance from session scope + getFacesContext().getExternalContext().getSessionMap(). + remove(getUserKey()); + + } + + +} Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/BaseViewController.java URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/BaseViewController.java?view=diff&r1=161793&r2=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/BaseViewController.java (original) +++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/BaseViewController.java Mon Apr 18 13:15:16 2005 @@ -25,6 +25,9 @@ * for the use cases example application.</p> * * $Id$ + * + * @deprecated Extend AbstractViewController directly now that it provides + * all of the useful convenience methods */ public abstract class BaseViewController extends AbstractViewController { @@ -40,33 +43,6 @@ // ------------------------------------------------------- Protected Methods - - - /** - * <p>Return the named bean from request, session, or application scope. - * If this is a managed bean, it might also get created as a side effect. - * Return <code>null</code> if no such bean can be found or created.</p> - * - * @param name Name of the desired bean - */ - protected Object getBean(String name) { - - FacesContext context = getFacesContext(); - return context.getApplication().getVariableResolver(). - resolveVariable(context, name); - - } - - - /** - * <p>Return the <code>FacesContext</code> instance for the - * current request.</p> - */ - protected FacesContext getFacesContext() { - - return FacesContext.getCurrentInstance(); - - } } Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties?view=diff&r1=161793&r2=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties (original) +++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties Mon Apr 18 13:15:16 2005 @@ -29,6 +29,7 @@ # Miscellaneous Labels label.cancel=Cancel +label.create=Create New User Profile label.finish=Finish label.first=First label.go=Go @@ -54,6 +55,23 @@ logon.unconfirmed=The username you specified has not been confirmed yet. \ To confirm it, please reply to the email message that was sent to your \ specified email address. + +# Edit Profile Labels and Messages +profile.confirm=The username you specified has not been confirmed yet. \ + To confirm it, please reply to the email message that was sent to your \ + specified email address. +profile.duplicate=That username is aready in use, please try again +profile.incorrect=Invalid username or password specified, please try again +profile.mismatch=Password values do not match, please try again +profile.password=Password is required when creating a profile +profile.title=Log On To Use Cases Example Application +profile.title.1=User Profile (Page 1 of 3) +profile.title.2=User Profile (Page 2 of 3) +profile.title.3=User Profile (Page 3 of 3) +logon.unconfirmed=The username you specified has not been confirmed yet. \ + To confirm it, please reply to the email message that was sent to your \ + specified email address. +profile.username=Username is required when creating a profile # Miscellaneous Prompts prompt.categories=Message Categories: Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/applicationContext.xml URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/applicationContext.xml?view=diff&r1=161793&r2=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/web/WEB-INF/applicationContext.xml (original) +++ struts/shale/trunk/use-cases/src/web/WEB-INF/applicationContext.xml Mon Apr 18 13:15:16 2005 @@ -24,6 +24,7 @@ <beans> + <!-- FIXME - deprecated, use next entry after migration is complete --> <!-- Business logic used to manipulate registered user profile information, and authenticate logons --> <bean name="logon$logic" @@ -33,6 +34,23 @@ <ref bean="logon$users"/> </property> </bean> + + + <!-- Business logic used to manipulate registered user profile + information, and authenticate logons --> + <bean name="profile$logic" + class="org.apache.shale.usecases.logic.LogonLogic" + singleton="false"> + <property name="dao"> + <ref bean="profile$users"/> + </property> + </bean> + + + <!-- DAO implementation for users database --> + <bean name="profile$users" + class="org.apache.shale.usecases.model.minimal.MinimalUsersDAO" + singleton="true"/> </beans> Added: struts/shale/trunk/use-cases/src/web/WEB-INF/dialog-config.xml URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/dialog-config.xml?view=auto&rev=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/web/WEB-INF/dialog-config.xml (added) +++ struts/shale/trunk/use-cases/src/web/WEB-INF/dialog-config.xml Mon Apr 18 13:15:16 2005 @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + + Copyright 2004-2005 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. + + $Id$ + +--> + +<!-- + + Dialog definitions for Shale Use Cases Example Web Application + +--> + +<!DOCTYPE dialogs PUBLIC + "-//Apache Software Foundation//DTD Shale Dialog Configuration 1.0//EN" + "http://struts.apache.org/dtds/shale-dialog-config-1_0.dtd"> + +<dialogs> + + + <!-- Log On / Create Profile Dialog --> + <dialog name="Log On" + start="Check Cookie"> + + <action name="Check Cookie" + method="#{profile$logon.check}"> + <transition outcome="authenticated" + target="Exit"/> + <transition outcome="unauthenticated" + target="Logon Form"/> + </action> + + <view name="Logon Form" + viewId="/profile/logon.jsp"> + <transition outcome="authenticated" + target="Exit"/> + <transition outcome="create" + target="Create Profile"/> + </view> + + <subdialog name="Create Profile" + dialogName="Edit Profile"> + <transition outcome="next" + target="Exit"/> + </subdialog> + + <end name="Exit"/> + + </dialog> + + + <!-- Edit Profile Dialog --> + <dialog name="Edit Profile" + start="Setup"> + + <action name="Setup" + method="#{profile$edit.setup}"> + <transition outcome="next" + target="Page 1"/> + </action> + + <view name="Page 1" + viewId="/profile/page1.jsp"> + <transition outcome="cancel" + target="Cancel"/> + <transition outcome="finish" + target="Finish"/> + <transition outcome="next" + target="Page 2"/> + </view> + + <view name="Page 2" + viewId="/profile/page2.jsp"> + <transition outcome="cancel" + target="Cancel"/> + <transition outcome="finish" + target="Finish"/> + <transition outcome="next" + target="Page 3"/> + <transition outcome="previous" + target="Page 1"/> + </view> + + <view name="Page 3" + viewId="/profile/page3.jsp"> + <transition outcome="cancel" + target="Cancel"/> + <transition outcome="finish" + target="Finish"/> + <transition outcome="next" + target="Exit"/> + <transition outcome="previous" + target="Page 2"/> + </view> + + <action name="Cancel" + method="#{profile$edit.cancel}"> + <transition outcome="success" + target="Exit"/> + </action> + + <action name="Finish" + method="#{profile$edit.finish}"> + <transition outcome="password" + target="Page 1"/> + <transition outcome="success" + target="Exit"/> + <transition outcome="username" + target="Page 1"/> + </action> + + <end name="Exit"/> + + </dialog> + + +</dialogs> Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml?view=diff&r1=161793&r2=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml (original) +++ struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml Mon Apr 18 13:15:16 2005 @@ -207,6 +207,73 @@ </navigation-rule> + <!-- ======================= Logon and Profile Edit Dialog =============== --> + + + <!-- ViewController Beans --> + + <!-- Because the logon form and the dialog actions share logic, they + are combined into the "profile$logon" bean defined below. --> + + <!-- Dialog Actions Beans --> + + <managed-bean> + <managed-bean-name>profile$edit</managed-bean-name> + <managed-bean-class> + org.apache.shale.usecases.profile.EditProfileActions + </managed-bean-class> + <managed-bean-scope>request</managed-bean-scope> + <managed-property> + <description> + Flag indicating that email confirmation must be sent and received + before a newly created username is activated. + </description> + <display-name>Confirmation Flag</display-name> + <property-name>confirmation</property-name> + <property-class>boolean</property-class> + <value>false</value> + </managed-property> + <managed-property> + <description> + Session scope attribute key under which the User instance for a + logged on user is stored. + </description> + <display-name>User Key</display-name> + <property-name>userKey</property-name> + <property-class>java.lang.String</property-class> + <value>user</value> + </managed-property> + </managed-bean> + + <managed-beans> + <managed-bean-name>profile$logon</managed-bean-name> + <managed-bean-class> + org.apache.shale.usecases.profile.LogonActions + </managed-bean-class> + <managed-bean-scope>request</managed-bean-scope> + <managed-property> + <description> + Flag indicating that "remember me" cookie support + is enabled. + </description> + <display-name>Remember Me</display-name> + <property-name>rememberMe</property-name> + <property-class>boolean</property-class> + <value>false</value> + </managed-property> + <managed-property> + <description> + Session scope attribute key under which the User instance for a + logged on user is stored. + </description> + <display-name>User Key</display-name> + <property-name>userKey</property-name> + <property-class>java.lang.String</property-class> + <value>user</value> + </managed-property> + </managed-beans> + + <!-- ========================= Remote Lookup Support ===================== --> @@ -340,6 +407,7 @@ </managed-bean> +<!-- DEPRECATED - see profile$logic below --> <!-- Comment out to use Spring BeanFactory for instantiation <managed-bean> <description> @@ -360,6 +428,7 @@ --> +<!-- DEPRECATED - see profile$users below --> <!-- Comment out to use Spring BeanFactory for instantiation <managed-bean> <description> @@ -367,6 +436,41 @@ information. </description> <managed-bean-name>logon$users</managed-bean-name> + <managed-bean-class> + org.apache.shale.usecases.model.minimal.MinimalUsersDAO + </managed-bean-class> + <managed-bean-scope>application</managed-bean-scope> + </managed-bean> +--> + + +<!-- Comment out to use Spring BeanFactory for instantiation + <managed-bean> + <description> + Business logic used to manipulate registered user profile + information, and authenticate logons. + </description> + <managed-bean-name>profile$logic</managed-bean-name> + <managed-bean-class> + org.apache.shale.usecases.logic.LogonLogic + </managed-bean-class> + <managed-bean-scope>request</managed-bean-scope> + <managed-property> + <property-name>dao</property-name> + <property-class>org.apache.shale.usecases.model.UsersDAO</property-class> + <value>#{profile$users}</value> + </managed-property> + </managed-bean> +--> + + +<!-- Comment out to use Spring BeanFactory for instantiation + <managed-bean> + <description> + Data Access Object (DAO) used to manipulate registered user profile + information. + </description> + <managed-bean-name>profile$users</managed-bean-name> <managed-bean-class> org.apache.shale.usecases.model.minimal.MinimalUsersDAO </managed-bean-class> Added: struts/shale/trunk/use-cases/src/web/profile/logon.jsp URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/profile/logon.jsp?view=auto&rev=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/web/profile/logon.jsp (added) +++ struts/shale/trunk/use-cases/src/web/profile/logon.jsp Mon Apr 18 13:15:16 2005 @@ -0,0 +1,107 @@ +<[EMAIL PROTECTED] contentType="text/html;charset=UTF-8"%> +<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %> +<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> +<%@ taglib prefix="s" uri="http://struts.apache.org/shale/core" %> + +<%-- + + Copyright 2004-2005 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. + +--%> + +<f:view> +<[EMAIL PROTECTED] file="../messages.jspf"%> +<html> +<head> +<title> + <h:outputText value="#{messages['profile.title']}"/> +</title> +</head> +<body> + + <h:form id="logonForm"> + + <h:panelGrid columns="3"> + + <f:facet name="header"> + <h:messages + globalOnly="true"/> + </f:facet> + + <%-- "remember" --%> + + <h:outputText value="" + rendered="#{profile$logon.rememberMe}"/> + + <h:panelGroup rendered="#{profile$logon.rememberMe}"> + <h:selectBooleanCheckbox + id="remember" + value="#{profile$logon.remember}"/> + <h:outputLabel for="remember"> + <h:outputText value="#{messages['prompt.remember']}"/> + </h:outputLabel> + </h:panelGroup> + + <h:outputText value="" + rendered="#{profile$logon.rememberMe}"/> + + <%-- username --%> + + <h:outputLabel for="username"> + <h:outputText value="#{messages['prompt.username']}"/> + </h:outputLabel> + + <h:inputText id="username" + required="true" + value="#{profile$logon.username}"/> + + <h:message for="username"/> + + <%-- password --%> + + <h:outputLabel for="password"> + <h:outputText value="#{messages['prompt.password']}"/> + </h:outputLabel> + + <h:inputSecret id="password" + required="true" + value="#{profile$logon.password}"/> + + <h:message for="password"/> + + <%-- actions --%> + + <s:token id="token"/> + + <h:panelGroup> + <h:commandButton id="logon" + action="#{profile$logon.logon}" + value="#{messages['label.logon']}"/> + <h:commandLink id="create" + action="#{profile$logon.create}" + immediate="true"> + <h:outputText value="#{messages['label.create']}"/> + </h:commandLink> + </h:panelGroup> + + <h:message for="token"/> + + </h:panelGrid> + + </h:form> + +</body> +</html> +</f:view> Added: struts/shale/trunk/use-cases/src/web/profile/profile1.jsp URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/profile/profile1.jsp?view=auto&rev=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/web/profile/profile1.jsp (added) +++ struts/shale/trunk/use-cases/src/web/profile/profile1.jsp Mon Apr 18 13:15:16 2005 @@ -0,0 +1,108 @@ +<[EMAIL PROTECTED] contentType="text/html;charset=UTF-8"%> +<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %> +<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> +<%@ taglib prefix="s" uri="http://struts.apache.org/shale/core" %> + +<%-- + + Copyright 2004-2005 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. + +--%> + +<f:view> +<[EMAIL PROTECTED] file="../messages.jspf"%> +<html> +<head> +<title> + <h:outputText value="#{messages['profile.title.1']}"/> +</title> +</head> +<body> + + <h:form id="profile1Form"> + + <h:panelGrid columns="3"> + + <f:facet name="header"> + <h:messages + globalOnly="true"/> + </f:facet> + + <%-- username --%> + + <h:outputLabel for="username"> + <h:outputText value="#{messages['prompt.username']}"/> + </h:outputLabel> + + <h:inputText id="username" + required="true" + value="#{dialog.data.username}"/> + + <h:message for="username"/> + + <%-- password --%> + + <h:outputLabel for="password"> + <h:outputText value="#{messages['prompt.password']}"/> + </h:outputLabel> + + <h:inputSecret id="password" + required="#{dialog.data.creating}" + value="#{dialog.data.password}"/> + + <h:message for="password"/> + + <%-- password2 --%> + + <h:outputLabel for="password2"> + <h:outputText value="#{messages['prompt.password2']}"/> + </h:outputLabel> + + <h:inputSecret id="password2" + required="#{dialog.data.creating}" + value="#{dialog.data.password2}"/> + + <h:message for="password2"/> + + <%-- actions --%> + + <s:token id="token"/> + + <h:panelGroup> + <h:commandButton id="next" + action="next" + value="#{messages['label.next']}"/> + <h:commandButton id="previous" + action="previous" + disabled="true" + value="#{messages['label.previous']}"/> + <h:commandButton id="finish" + action="finish" + value="#{messages['label.finish']}"/> + <h:commandButton id="cancel" + action="cancel" + immediate="true" + value="#{messages['label.cancel']}"/> + </h:panelGroup> + + <h:message for="token"/> + + </h:panelGrid> + + </h:form> + +</body> +</html> +</f:view> Added: struts/shale/trunk/use-cases/src/web/profile/profile2.jsp URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/profile/profile2.jsp?view=auto&rev=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/web/profile/profile2.jsp (added) +++ struts/shale/trunk/use-cases/src/web/profile/profile2.jsp Mon Apr 18 13:15:16 2005 @@ -0,0 +1,97 @@ +<[EMAIL PROTECTED] contentType="text/html;charset=UTF-8"%> +<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %> +<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> +<%@ taglib prefix="s" uri="http://struts.apache.org/shale/core" %> + +<%-- + + Copyright 2004-2005 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. + +--%> + +<f:view> +<[EMAIL PROTECTED] file="../messages.jspf"%> +<html> +<head> +<title> + <h:outputText value="#{messages['profile.title.2']}"/> +</title> +</head> +<body> + + <h:messages globalOnly="true"/> + + <h:form id="profile2Form"> + + <h:panelGrid columns="3"> + + <f:facet name="header"> + <h:messages + globalOnly="true"/> + </f:facet> + + <%-- fullName --%> + + <h:outputLabel for="fullName"> + <h:outputText value="#{messages['prompt.fullName']}"/> + </h:outputLabel> + + <h:inputText id="fullName" + required="true" + value="#{dialog.data.fullName}"/> + + <h:message for="fullName"/> + + <%-- emailAddress --%> + + <h:outputLabel for="emailAddress"> + <h:outputText value="#{messages['prompt.emailAddress']}"/> + </h:outputLabel> + + <h:inputText id="emailAddress" + required="true" + value="dialog.data.emailAddress}"/> + + <h:message for="emailAddress"/> + + <%-- actions --%> + + <s:token id="token"/> + + <h:panelGroup> + <h:commandButton id="next" + action="next" + value="#{messages['label.next']}"/> + <h:commandButton id="previous" + action="previous" + value="#{messages['label.previous']}"/> + <h:commandButton id="finish" + action="finish" + value="#{messages['label.finish']}"/> + <h:commandButton id="cancel" + action="cancel" + immediate="true" + value="#{messages['label.cancel']}"/> + </h:panelGroup> + + <h:message for="token"/> + + </h:panelGrid> + + </h:form> + +</body> +</html> +</f:view> Added: struts/shale/trunk/use-cases/src/web/profile/profile3.jsp URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/profile/profile3.jsp?view=auto&rev=161794 ============================================================================== --- struts/shale/trunk/use-cases/src/web/profile/profile3.jsp (added) +++ struts/shale/trunk/use-cases/src/web/profile/profile3.jsp Mon Apr 18 13:15:16 2005 @@ -0,0 +1,87 @@ +<[EMAIL PROTECTED] contentType="text/html;charset=UTF-8"%> +<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %> +<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %> +<%@ taglib prefix="s" uri="http://struts.apache.org/shale/core" %> + +<%-- + + Copyright 2004-2005 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. + +--%> + +<f:view> +<[EMAIL PROTECTED] file="../messages.jspf"%> +<html> +<head> +<title> + <h:outputText value="#{messages['profile.title.3']}"/> +</title> +</head> +<body> + + <h:form id="profile3Form"> + + <h:panelGrid columns="3"> + + <f:facet name="header"> + <h:messages + globalOnly="true"/> + </f:facet> + + <%-- categories --%> + + <h:outputLabel for="categories"> + <h:outputText value="#{messages['prompt.categories']}"/> + </h:outputLabel> + + <h:selectManyCheckbox + id="categories" + layout="pageDirection" + value="#{dialog.data.categories}"> + <f:selectItems value="#{domains.supportedCategories}"/> + </h:selectManyCheckbox> + + <h:message for="categories"/> + + <%-- actions --%> + + <s:token id="token"/> + + <h:panelGroup> + <h:commandButton id="next" + action="next" + disabled="true" + value="#{messages['label.next']}"/> + <h:commandButton id="previous" + action="previous" + value="#{messages['label.previous']}"/> + <h:commandButton id="finish" + action="finish" + value="#{messages['label.finish']}"/> + <h:commandButton id="cancel" + action="cancel" + immediate="true" + value="#{messages['label.cancel']}"/> + </h:panelGroup> + + <h:message for="token"/> + + </h:panelGrid> + + </h:form> + +</body> +</html> +</f:view> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]