You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(16) |
Sep
(10) |
Oct
(1) |
Nov
(2) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(148) |
Feb
(80) |
Mar
(41) |
Apr
(85) |
May
(247) |
Jun
(345) |
Jul
(237) |
Aug
(241) |
Sep
(439) |
Oct
(321) |
Nov
(413) |
Dec
(302) |
2004 |
Jan
(143) |
Feb
(147) |
Mar
(200) |
Apr
(107) |
May
(15) |
Jun
(36) |
Jul
(11) |
Aug
(1) |
Sep
(36) |
Oct
|
Nov
(6) |
Dec
|
2005 |
Jan
|
Feb
|
Mar
|
Apr
(115) |
May
(74) |
Jun
(215) |
Jul
(82) |
Aug
(47) |
Sep
(32) |
Oct
(8) |
Nov
(70) |
Dec
(24) |
2006 |
Jan
|
Feb
(1) |
Mar
(4) |
Apr
(2) |
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2007 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <jm...@us...> - 2005-09-23 06:38:11
|
Update of /cvsroot/struts/dialogs/war/sample-logincontrol/tomcat In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/war/sample-logincontrol/tomcat Modified Files: masterpage.jsp Log Message: Added MailReader Demo; Added component RuleSet Index: masterpage.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-logincontrol/tomcat/masterpage.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** masterpage.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- masterpage.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,5 **** <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <html:html locale="true"> --- 1,11 ---- + <!-- + Struts Dialogs Example + Author: Michael Jouravlev, 2004-2005 + --> + <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <html:html locale="true"> |
From: <jm...@us...> - 2005-09-23 06:38:11
|
Update of /cvsroot/struts/dialogs/src/net/jspcontrols/mailreader/business In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/src/net/jspcontrols/mailreader/business Added Files: Subscription.java User.java Log Message: Added MailReader Demo; Added component RuleSet --- NEW FILE: Subscription.java --- /* * $Id: Subscription.java,v 1.1 2005/09/23 06:37:57 jmikus Exp $ * * Copyright 1999-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 net.jspcontrols.mailreader.business; /** * <p>A <strong>Subscription</strong> which is stored, along with the * associated {@link net.jspcontrols.mailreader.business.User}, in a {@link net.jspcontrols.mailreader.memory.UserDatabase}.</p> * * @version $Rev: 54929 $ $Date: 2005/09/23 06:37:57 $ */ 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(); /** * Sets the host name. */ public void setHost(String host); /** * 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 net.jspcontrols.mailreader.business.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); } --- NEW FILE: User.java --- /* * $Id: User.java,v 1.1 2005/09/23 06:37:57 jmikus Exp $ * * Copyright 1999-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 net.jspcontrols.mailreader.business; import net.jspcontrols.mailreader.business.Subscription; import net.jspcontrols.mailreader.memory.UserDatabase; import java.util.Collection; /** * <p>A <strong>User</strong> which is stored, along with his or her * associated {@link net.jspcontrols.mailreader.business.Subscription}s, in a {@link net.jspcontrols.mailreader.memory.UserDatabase}.</p> * * @version $Rev: 54929 $ $Date: 2005/09/23 06:37:57 $ * @since Struts 1.1 */ public interface User { // ------------------------------------------------------------- Properties /** * Return the {@link net.jspcontrols.mailreader.memory.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 net.jspcontrols.mailreader.business.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(); /** * Setus username */ public void setUsername(String username); // --------------------------------------------------------- Public Methods /** * Create and return a new {@link net.jspcontrols.mailreader.business.Subscription} associated with this * User, for the specified host name. * * @param host Host name for which to create a subscription * * @exception java.lang.IllegalArgumentException if the host name is not unique * for this user */ public Subscription createSubscription(String host); /** * Find and return the {@link net.jspcontrols.mailreader.business.Subscription} associated with the specified * host. If none is found, return <code>null</code>. * * @param host Host name to look up */ public Subscription findSubscription(String host); /** * Remove the specified {@link net.jspcontrols.mailreader.business.Subscription} from being associated * with this User. * * @param subscription Subscription to be removed * * @exception java.lang.IllegalArgumentException if the specified subscription is not * associated with this User */ public void removeSubscription(Subscription subscription); public Collection getSubscriptionCollection(); } |
From: <jm...@us...> - 2005-09-23 06:38:11
|
Update of /cvsroot/struts/dialogs/war/sample-logincontrol/resin In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/war/sample-logincontrol/resin Modified Files: embedded-child-login.jsp embedded-child-logout.jsp masterpage.jsp Log Message: Added MailReader Demo; Added component RuleSet Index: embedded-child-login.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-logincontrol/resin/embedded-child-login.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** embedded-child-login.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- embedded-child-login.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,12 **** <!-- ! Struts Dialogs, Login Control example Author: Michael Jouravlev, 2004-2005 - - This is "Login Page" view for login child control --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> ! <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <table width=100% border=0 celpadding=0 cellspacing=2> --- 1,11 ---- <!-- ! Struts Dialogs Example Author: Michael Jouravlev, 2004-2005 --> + <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <table width=100% border=0 celpadding=0 cellspacing=2> Index: embedded-child-logout.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-logincontrol/resin/embedded-child-logout.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** embedded-child-logout.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- embedded-child-logout.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,12 **** <!-- ! Struts Dialogs, Login Control example Author: Michael Jouravlev, 2004-2005 - - This is "Current User Info" view for login child control --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> ! <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <table width=100% border=0 celpadding=0 cellspacing=2> --- 1,11 ---- <!-- ! Struts Dialogs Example Author: Michael Jouravlev, 2004-2005 --> + <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <table width=100% border=0 celpadding=0 cellspacing=2> Index: masterpage.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-logincontrol/resin/masterpage.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** masterpage.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- masterpage.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,5 **** <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <html:html locale="true"> --- 1,11 ---- + <!-- + Struts Dialogs Example + Author: Michael Jouravlev, 2004-2005 + --> + <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <html:html locale="true"> |
Update of /cvsroot/struts/dialogs/war/sample-wizardaction In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/war/sample-wizardaction Modified Files: wizard-error.jsp wizard-signupconfirm.jsp wizard-signupdetails.jsp wizard-signupstart.jsp wizard-userpage.jsp Log Message: Added MailReader Demo; Added component RuleSet Index: wizard-error.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-wizardaction/wizard-error.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** wizard-error.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- wizard-error.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 5,11 **** <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> ! <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> --- 5,11 ---- <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> Index: wizard-signupconfirm.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-wizardaction/wizard-signupconfirm.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** wizard-signupconfirm.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- wizard-signupconfirm.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,10 **** <!-- ! Easy Wizard example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> ! <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html:html locale="true"> --- 1,11 ---- <!-- ! Struts Dialogs Example Author: Michael Jouravlev, 2004-2005 --> + <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <html:html locale="true"> Index: wizard-signupdetails.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-wizardaction/wizard-signupdetails.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** wizard-signupdetails.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- wizard-signupdetails.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,10 **** <!-- ! Easy Wizard example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <html:html locale="true"> --- 1,11 ---- <!-- ! Struts Dialogs Example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <html:html locale="true"> Index: wizard-signupstart.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-wizardaction/wizard-signupstart.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** wizard-signupstart.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- wizard-signupstart.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,10 **** <!-- ! Easy Wizard example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <html:html> --- 1,11 ---- <!-- ! Struts Dialogs Example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <html:html> Index: wizard-userpage.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-wizardaction/wizard-userpage.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** wizard-userpage.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- wizard-userpage.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,10 **** <!-- ! Easy Wizard example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <% --- 1,11 ---- <!-- ! Struts Dialogs Example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <% |
From: <jm...@us...> - 2005-09-23 06:38:11
|
Update of /cvsroot/struts/dialogs/war/mailreader-css In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/war/mailreader-css Added Files: base.css screen.css Log Message: Added MailReader Demo; Added component RuleSet --- NEW FILE: base.css --- body{ background-color: #fff; padding:0 0 0 0; margin:2 8 2 8; } body, input, select, td, textarea{ font-family:Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 0.9em; } h1, h2, h3, h4, h5, h6, p, strong, div, form, acronym, label, table, td, th, span, a, hr, code, pre, hr { margin:0; padding:0; background-repeat:no-repeat; list-style-type:none; } table { border: 1px solid #666; width: 80%; margin: 20px 0 20px 0; } th, td { padding: 2px 4px 2px 4px; vertical-align: top; } thead tr { background-color: #FF9966; } td.itemdescr { background-color: #FF9966; } --- NEW FILE: screen.css --- body{ background-color: #fff; padding:0 0 0 0; margin:2 8 2 8; } body, input, select, td, textarea{ font-family:Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 0.9em; } h1, h2, h3, h4, h5, h6, p, strong, div, form, acronym, label, table, td, th, span, a, hr, code, pre, hr { margin:0; padding:0; background-repeat:no-repeat; list-style-type:none; } td.itemdescr { background-color: #FF9966; } a, a:visited, a:hover { color:#666; text-decoration:none; } a:hover { text-decoration: underline; } img{ border:none; } hr { height: 1px; color: #000; clear:both; } textarea { width:80%; height:200px; } dt { font-weight: bold; } .clear { clear: both; } h1 { font-size: 2em; } h1 a{ color: #000; } div#header { background-color: #fea; border-top: 1px solid #000; border-bottom: 1px solid #000; padding: 20px 10px 30px 15px; margin: 10px 5% 20px 5%; } div#header ul{ margin: 10px 0 0 0; } div#header ul li{ list-style-type: none; float: left; padding: 0 10px 0 0; font-weight: bold; } div#header ul li a{ display: block; color: #f00; border-left: 1px solid red; padding-left: 5px; } div#header ul li a:hover{ border-left: 1px solid #000; } h2 { font-size: 1.2em; margin: 10px 0 10px 0; } h2 { font-size: 1.1em; margin: 10px 0 5px 0; } p { margin: 0 0 10px 0; } acronym { border-bottom: 1px dashed #000; cursor: help; } div#body { margin: 0 5% 20px 5%; padding: 20px 20px 20px 20px; border: 1px dashed #666; } div#validxhtml { float: right; background-color: #eee; border: 1px dotted #999; padding: 2px; margin: 5px; width:100px; text-align: center; } div#footer { border-top: 1px solid #666; padding: 5px 5px 5px 5px; text-align:right; } div#footer span { float: left; } /*.changed { background-color: #ee0; border: 1px solid #ccc; padding: 10px; margin: 10px; }*/ ul#stylelist { margin:0 0 30px 0; } ul#stylelist li { list-style-type: none; float:left; width:100px; border: 1px solid #ccc; background-color: #eee; padding:2px; margin-right: 2px; } table { border: 1px solid #666; width: 80%; margin: 20px 0 20px 0; } th, td { padding: 2px 4px 2px 4px; text-align: left; vertical-align: top; } thead tr { background-color: #FF9966; } th.sorted { background-color: orange; } th a, th a:visited { color: black; } th a:hover { text-decoration: underline; color: black; } th.sorted a, th.sortable a { background-position: right; display: block; width: 100%; } th.sortable a { background-image: url(../img/arrow_off.png); } th.order1 a { background-image: url(../img/arrow_down.png); } th.order2 a { background-image: url(../img/arrow_up.png); } tr.odd { background-color: #fff } tr.tableRowEven, tr.even { background-color: #fea } ul#showsource { float: right; background-color: #eee; border: 1px dotted #999; padding: 2px 4px 2px 4px; margin: 5px; width:100px; list-style-type: none; } /* test styles */ table.its thead tr { background-color: #69c; } table.its tr.even { background-color: #def; } table.mars thead tr { background-color: #9c9; } table.mars tr.even { background-color: #ccb; } table.mars tr.odd { background-color: #eec; } table.simple thead tr { background-color: #eee; } table.simple tr.even { background-color: #fff; } table.simple { border: 1px solid #ccc; border-collapse: collapse; } table.simple td,table.simple th{ border: 1px solid #ccc; } table.nocol tbody td,table.nocol tbody th{ border-left: none; border-right: none; } table.report td, table.report th{ font: menu; } table.report th{ background: buttonface; border-width: 1px; border-style: solid; border-color: threedhighlight threedshadow threedshadow threedhighlight; cursor: hand; } table.report idcol { background: buttonface; } table.report tr.even{ background-color: #399; } table.report tbody { height: 100px; overflow: auto; } table.report { height: 120px; overflow: auto; } table.report tbody tr{ height: 10px; } table.mark td.tableCellError { background-color: #d00; color: #fff; } table.sublist { margin: 0 0 0 0; width: 100%; } table.sublist td, table.sublist th { width: 50%; } div.exportlinks { background-color: #eee; border: 1px dotted #999; padding: 2px 4px 2px 4px; margin: -10px 0 10px 0; width: 79%; } span.export { padding: 0 4px 1px 20px; display:inline; display:inline-block; cursor: pointer; } span.excel { background-image: url(../img/ico_file_excel.png); } span.csv { background-image: url(../img/ico_file_csv.png); } span.xml { background-image: url(../img/ico_file_xml.png); } span.pdf { background-image: url(../img/ico_file_pdf.png); } span.pagebanner { background-color: #eee; border: 1px dotted #999; padding: 2px 4px 2px 4px; width: 79%; margin-top: 10px; display:block; border-bottom: none; } span.pagelinks { background-color: #eee; border: 1px dotted #999; padding: 2px 4px 2px 4px; width: 79%; display:block; border-top: none; margin-bottom: -5px; } table.simple td.textRed {color: #b11;} |
Update of /cvsroot/struts/dialogs/war/images In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/war/images Added Files: crudaction.gif crudaction_transitions.gif dialogaction.gif mailreader-home-mainmenu.gif mailreader-home-welcome.gif mailreader-login.gif mailreader-logout.gif mailreader-matrix.gif mailreader-subscription-create.gif mailreader-subscription-update.gif mailreader-subscriptions.gif selectaction.gif struts-dialog-action.gif struts-pre-post-action.gif wizard_arch_struts.gif Log Message: Added MailReader Demo; Added component RuleSet --- NEW FILE: crudaction.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: crudaction_transitions.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: dialogaction.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: mailreader-home-mainmenu.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: mailreader-home-welcome.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: mailreader-login.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: mailreader-logout.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: mailreader-matrix.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: mailreader-subscription-create.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: mailreader-subscription-update.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: mailreader-subscriptions.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: selectaction.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: struts-dialog-action.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: struts-pre-post-action.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: wizard_arch_struts.gif --- (This appears to be a binary file; contents omitted.) |
From: <jm...@us...> - 2005-09-23 06:38:11
|
Update of /cvsroot/struts/dialogs/war/sample-logindialog In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/war/sample-logindialog Modified Files: login.jsp userpage.jsp Log Message: Added MailReader Demo; Added component RuleSet Index: login.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-logindialog/login.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** login.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- login.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,11 **** <!-- ! Struts Dialogs Examples, Login Dialog Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> ! <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html:html> --- 1,11 ---- <!-- ! Struts Dialogs Example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <html:html> Index: userpage.jsp =================================================================== RCS file: /cvsroot/struts/dialogs/war/sample-logindialog/userpage.jsp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** userpage.jsp 4 Aug 2005 07:39:56 -0000 1.1 --- userpage.jsp 23 Sep 2005 06:37:57 -0000 1.2 *************** *** 1,9 **** <!-- ! Struts Dialogs Examples, Login Dialog Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <!-- If user is not logged in, redirect to login page --> --- 1,11 ---- <!-- ! Struts Dialogs Example Author: Michael Jouravlev, 2004-2005 --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ! <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> ! <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> ! <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <!-- If user is not logged in, redirect to login page --> |
From: <jm...@us...> - 2005-09-23 06:38:10
|
Update of /cvsroot/struts/dialogs/war In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/war Added Files: error.html filelist.txt index.jsp strutsdialogs-power.gif tour.html Log Message: Added MailReader Demo; Added component RuleSet --- NEW FILE: error.html --- <html> <p>ACCESS DENIED</p> </html> --- NEW FILE: filelist.txt --- Struts Dialogs samples: ----------------------- index.html - contains links to all samples MailReader Demo Application: ---------------------------- index.jsp - redirects to Home.do error.html - displays "ACCESS DENIED" if JSP page accessed directly tour.html - displays tour documentation Common files: ------------- strutsdialogs-power.gif - "Powered by Struts Dialogs" logo --- NEW FILE: index.jsp --- <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <%@ page session="false" %> <%-- Redirect default requests to Welcome action. By using a redirect, the user-agent will change address to match the path of our Welcome action. --%> <logic:redirect action="/Home"/> --- NEW FILE: strutsdialogs-power.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tour.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Struts Dialogs: Mail Reader</title> <link type="text/css" href="../skin/page.css" rel="stylesheet"> </head> <body text="#000000" bgcolor="#FFFFFF"> <h1>Struts Dialogs: Mail Reader</h1> <a name="N1000C"></a><a name="overview"></a> <h3>Overview</h3> <div style="margin-left: 0 ; border: 2px"> <p>This document is based on Ted Husted's documentation for original MailReader application. For the sake of readability the modifications of the original text are not shown. The non-relevant portions of original document like plugins, database, Commons Validator are removed, please refer to original MailReader documentation.</p> <p>The premise of the MailReader is that it is the first iteration of a portal application. This version allows users to register themselves and to create and maintain a set of accounts with various mail servers. When completed, the application would let users read mail from their accounts. This sample application does not allow sending and receiving of real emails, it collects user information and mail addresses only.</p> <p>The MailReader application demonstrates registering with an application, logging into an application, maintaining a master record, and maintaining child records. This document walks through the JSP pages, Struts Java classes, and Struts configuration elements needed to do these things.</p> <p>The walkthrough starts with how the initial page is displayed, and then steps through logging in, adding and editing subscriptions, and creating a new registration.</p> </div> <a name="N1001F"></a><a name="actions"></a> <h3>Actions</h3> <div style="margin-left: 0 ; border: 2px"> <p>The goal of Struts is to simplify development of web applications. It is facilitated by means of custom requests handlers called <em>actions</em>. You may think of action as of mini-servlet.</p> <p>An action performs the following functions:</p> <ul> <li>receives a request from browser;</li> <li>interprets request parameters;</li> <li>updates domain objects if needed;</li> <li>generates dynamic output;</li> </ul> <p>The actions are listed in a configuration file and identify <em>web resources</em>. Actions can generate different output depending on state of web resource and on request parameters.</p> <p>An accepted practice in Struts is to never link directly to server pages, but only to the actions. In Struts, the role of server page is reduced to data-aware HTML, used exclusively as presentation technology.</p> <p> <strong>"Link actions not pages."</strong> </p> <p>By linking to actions, developers can "rewire" an application without editing the server pages.</p> <p>The picture below shows the structure of MailReader application, developed with Struts Dialogs. It is slightly changed from original MailReader for simplicity and clarity. Notice, that different pages are not linked to each other, making up a "flow". Instead, pages are organized as a table, where rows correspond to web resources, and columns correspond to state of these web resources.</p> <div align="center"> <img class="figure" alt="MailReader Matrix" src="images/mailreader-matrix.gif"></div> <p>MailReader has four distinct web resources: <strong>Home</strong>, <strong>Accounts</strong>, <strong>Login</strong> and <strong>Subscriptions</strong>. Each resource behaves differently depending on state. Theare are two application-wide states: "Not Logged In" and "Logged In" that indicate whether a user is logged in or not.</p> <p> <strong>Home</strong>, <strong>Accounts</strong> and <strong>Login</strong> resources exist in both states, while <strong>Subscriptions</strong> resource has meaningful output only for "Logged In" state, because Subscriptions resorce displays email subscriptions for currently logged-in user.</p> <p>Each web resource is defined with one Struts action class and one or more JSP pages. For example, Home resource defines only one JSP page, which is modified at runtime, while Login resource defines two distinct pages, each for one state.</p> <p>Nice thing about stateful resources is that they produce valid output whenever they are navigated to. There is no need to establish a strict flow between resources or their pages.</p> </div> <a name="N10078"></a><a name="indexpage"></a> <h3>Index Page</h3> <div style="margin-left: 0 ; border: 2px"> <p>Struts allows developers to manage an application through "virtual pages" called actions. A web application, like any other web site, can specify a list of welcome pages. When you open a web application without specifying a particular page, a welcome page is used by default. Unfortunately, actions cannot be specified as a welcome page. So, in the case of a welcome page, how do we follow the Struts best practice of navigating through actions rather than pages?</p> <p>One solution is to use a server page to "bootstrap" a Struts action. A Java web application recognizes the idea of "forwarding" from one action (or page) to another action (or page). We can register the usual <span class="codefrag">index.jsp</span> as the welcome page and have it forward redirect to a "Home" action. Here's the MailReader's <span class="codefrag">index.jsp</span>:</p> <pre class="code"> <%@ taglib uri="/tags/struts-logic" prefix="logic" %> <%@ page session="false"> <logic:redirect action="/Home"/> </pre> <p>At the top of the page, we import the "struts-logic" JSP tag library. (Again, see the <a href="http://jakarta.apache.org/struts/userGuide/preface.html">Preface to the Struts User Guide</a> for more about the technologies underlying Struts.) We also tell the server to wait creating a session. The page itself consists of a single tag that redirects to the "Welcome" action. The tag inserts the actual web address for the redirect when the page is rendered. But, where does the tag find the actual address to insert?</p> <p>The actions, along with other Struts components, are registered through one or more Struts configuration files. The configuration files are written as XML documents and processed when the application starts.</p> </div> <!-- ********************** --> <h2>Home component</h2> <a name="N1000C"></a><a name="overview"></a> <h3>Overview</h3> <div style="margin-left: 0 ; border: 2px"> <p> <strong>Home</strong> component carries out three functions:</p> <ul> <li>Startup menu</li> <li>Main menu</li> <li>Language selection</li> </ul> <p>Home component is controlled by one action (HomeAction) and has one view (home.jsp). The <span class="codefrag">home.jsp</span> page displays either startup menu or main menu depending on user's logged-in status.</p> <p>Startup menu is shown to a non-logged-in user and allows either to log in or to create a new user account.</p> <div align="center"> <img class="figure" alt="MailReader Startup Menu" src="images/mailreader-home-welcome.gif"></div> <p></p> <p>Main menu is shown to a logged-in user and allows to review and update user account information, to manage email subscriptions and to log off the application.</p> <div align="center"> <img class="figure" alt="MailReader Main Menu" src="images/mailreader-home-mainmenu.gif"></div> </div> <a name="N1003A"></a><a name="home-jsp"></a> <h3>home.jsp</h3> <div style="margin-left: 0 ; border: 2px"> <p>Let us first design the <span class="codefrag">home.jsp</span> page, then we will define action class and wire events to event handles. The <span class="codefrag">home.jsp</span> page displays different menu options depending on user's status.</p> <pre class="code"> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html> <head> <title><bean:message key="index.title"/></title> <link rel="stylesheet" type="text/css" href="base.css" /> </head> <body> <h3><bean:message key="index.heading"/></h3> <!-- Signup and login options for not logged-in user --> <logic:notPresent name="user" scope="session"> <ul> <li> <html:link action="<strong>/Home?DIALOG-EVENT-SIGNUP</strong>"> <bean:message key="index.registration"/></html:link> </li> <li> <html:link action="<strong>/Home?DIALOG-EVENT-LOGON</strong>"> <bean:message key="index.logon"/> </html:link> </li> </ul> </logic:notPresent> <!-- Account modification and subscription list for logged-in user --> <logic:present name="user" scope="session"> <ul> <li> <html:link action="<strong>/Home?DIALOG-EVENT-ACCUPDATE</strong>"> <bean:message key="index.updateaccount"/> </html:link> </li> <li> <html:link action="<strong>/Home?DIALOG-EVENT-SUBSCRIPTIONS</strong>"> <bean:message key="index.managesubscriptions"/> </html:link> </li> <li> <html:link action="<strong>/Logon</strong>"> <bean:message key="index.showuserinfo"/> </html:link> </li> <li> <html:link action="<strong>/Logon?DIALOG-EVENT-LOGOFF</strong>"> <bean:message key="index.logoff"/> </html:link> </li> </ul> </logic:present> <!-- Language selection --> <h3><bean:message key="index.langopts"/></h3> <ul> <li> <html:link action="<strong>/Home?DIALOG-EVENT-LOCALE&language=en</strong>"> <bean:message key="index.langenglish"/> </html:link> </li> <li> <html:link action="<strong>/Home?DIALOG-EVENT-LOCALE&language=ru</strong>" useLocalEncoding="true"> <bean:message key="index.langrussian"/> </html:link> </li> </ul> <hr/> <p><html:img bundle="alternate" pageKey="strutsdialogs.logo.path" altKey="strutsdialogs.logo.alt"/></p> </body> </html> </pre> <p>The <span class="codefrag">home.jsp</span> page has three sections. The language selection section is always displayed. The startup menu is displayed when a user is not logged in; it is wrapped into <span class="codefrag"><logic:notPresent name="user" scope="session"></span> element. The main menu is displayed to logged in user; it is wrapped into <span class="codefrag"><logic:present name="user" scope="session"></span> element. This works because when a user logs in, the "user" bean with user's account information is saved in the session.</p> </div> <a name="N10073"></a><a name="events"></a> <h3>Login state and events</h3> <div style="margin-left: 0 ; border: 2px"> <p>The links in each section of <span class="codefrag">home.jsp</span> page generate events. An event is a HTTP request identified with dialog event parameter. By default, dialog event parameter name should start with "DIALOG-EVENT", as seen in the code above. Of course, it is possible to pass additional request parameters along, for example to change interface language to Russian: <span class="codefrag">/Home?DIALOG-EVENT-LOCALE&language=ru</span> </p> <p>The recommended practice is to send all events to a parent action, in case of <span class="codefrag">home.jsp</span> page this would be HomeAction class. For example, <span class="codefrag">/Home?DIALOG-EVENT-LOGON</span> generates logon event, while <span class="codefrag">/Home?DIALOG-EVENT-SIGNUP</span> generates signup event. The benefit of sending all page events to a parent action is centralized processing and cleaner application structure.</p> <p>On the other hand, nothing prevents from sending an event to a different action class, like you see in the case of logging user off: <span class="codefrag">/Logon?DIALOG-EVENT-LOGOFF</span>. Here the logoff event is sent directly to Logon action.</p> </div> <a name="N10094"></a><a name="homeaction"></a> <h3>Home action</h3> <div style="margin-left: 0 ; border: 2px"> <p>To properly handle input events and output page rendering, the home action must subclass a <a href="dialogaction.html">DialogAction</a> class. Then request events are mapped to method handlers, <span class="codefrag">getInitKey</span> returns "DIALOG-EVENT" by default:</p> <pre class="code"> public final class HomeAction extends DialogAction { ... protected Map getKeyMethodMap() { Map methodMap = new HashMap(); methodMap.put(getInitKey()+"-LOGON", "onLogon"); methodMap.put(getInitKey()+"-SIGNUP", "onAccountSignup"); methodMap.put(getInitKey()+"-ACCUPDATE", "onAccountUpdate"); methodMap.put(getInitKey()+"-LOCALE", "onLocale"); methodMap.put(getInitKey()+"-SUBSCRIPTIONS", "onSubscriptions"); return methodMap; } ... } </pre> <p>Then event handlers are implemented. They must have the same signature as <span class="codefrag">Action.execute</span> method. For example, this is how account update handler is coded:</p> <pre class="code"> public ActionForward onAccountUpdate(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return mapping.findForward("accupdate"); } </pre> <p>Method <span class="codefrag">onAccountUpdate</span> does not do much. It simply forwards the request to another resource called "accupdate".</p> <p>The hanlder of language-change event is more elaborate. It obtains the desired language either from request parameter or from request header, sets the "locale" key in the session and redisplays <span class="codefrag">home.jsp</span> page:</p> <pre class="code"> public ActionForward onLocale(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String language = request.getParameter("language"); String country = request.getParameter("country"); Locale locale = getLocale(request); if ((!isBlank(language)) && (!isBlank(country))) { locale = new Locale(language, country); } else if (!isBlank(language)) { locale = new Locale(language, ""); } // Set current locale HttpSession session = request.getSession(); session.setAttribute(Globals.LOCALE_KEY, locale); // Redisplay home page return EventForward.DIALOG_RELOAD; } </pre> <p>See the description for <a href="dialogaction.html">DialogAction</a> class for in-depth explanation of how Struts Dialogs components process input events and generate output.</p> </div> <a name="N100CD"></a><a name="config"></a> <h3>Configuration of Home component</h3> <div style="margin-left: 0 ; border: 2px"> <p>Follows the configuration of Home component in <span class="codefrag">struts-config.xml</span> file. The example below uses new <strong>component</strong>, <strong>event</strong> and <strong>render</strong> elements, introduced in Struts Dialogs 1.23:</p> <pre class="code"> <action-mappings> ... <!-- Home page. Handles welcome menu, main menu and language selection --> <component path = "/Home" view = "/home.jsp" type = "net.jspcontrols.mailreader.HomeAction"> <event name = "logon" path = "/Logon.do?DIALOG-EVENT-INIT"/> <event name = "signup" path = "/Registration.do?DIALOG-EVENT-CREATE"/> <event name = "accupdate" path = "/Registration.do?DIALOG-EVENT-UPDATE"/> <event name = "subscriptions" path = "/Subscriptions.do?DIALOG-EVENT-INIT"/> <render name = "failure" path = "/error.jsp" /> </component> ... </action-mappings> </pre> <p>The same component can be configured using standard Struts <strong>action</strong> and <strong>forward</strong> elements, though with less clarity:</p> <pre class="code"> <action-mappings> ... <action path = "/Home" scope = "session" validate = "false" type = "net.jspcontrols.mailreader.HomeAction"> <forward name = "logon" path = "/Logon.do?DIALOG-EVENT-INIT" redirect = "true"/> <forward name = "signup" path = "/Registration.do?DIALOG-EVENT-CREATE" redirect = "true"/> <forward name = "accupdate" path = "/Registration.do?DIALOG-EVENT-UPDATE" redirect = "true"/> <forward name = "subscriptions" path = "/Subscriptions.do?DIALOG-EVENT-INIT" redirect = "true"/> <forward name = "DIALOG-VIEW" path = "/home.jsp"/> <forward name = "failure" path = "/error.jsp"/> </action> ... </action-mappings> </pre> <p>HomeAction has only one corresponding view, <span class="codefrag">home.jsp</span>, therefore HomeAction takes advantage of "view" attribute of "component" element, which defines the view for a component. If traditional syntax for action configuration is used, the view should be defined as result of a forward element with "DIALOG-VIEW" name. This is one of the default view mapping names, that is used by <a href="dialogaction.html">DialogAction</a>.</p> <p>Similarly, <span class="codefrag"><event></span> element is just the same as <span class="codefrag"><forward ... redirect = "true"></span>, while <span class="codefrag"><render></span> element is the same as <span class="codefrag"><forward ... redirect = "false"></span>. Also, <span class="codefrag"><component></span> element has different defaults, like turned off validation and session scope for form beans.</p> <p>To use new syntax in <span class="codefrag">struts-config.xml</span>, you need to use Struts Dialogs 1.23 and to add new RuleSet object to <span class="codefrag">web.xml</span> file:</p> <pre class="code"> <init-param> <param-name>rulesets</param-name> <param-value>net.jspcontrols.dialogs.actions.DialogRuleSet</param-value> </init-param> </pre> <p>If you have config validation turned on, then you need to have a proper DTD file <span class="codefrag">struts-config_1_2_dialog.dtd</span> for updated <span class="codefrag">struts-config.xml</span> file. If you place DTD file in WEB-INF directory, then you can refer to it using the following doctype in the struts-config.xml file:</p> <pre class="code"> <!DOCTYPE struts-config SYSTEM "struts-config_1_2_dialog.dtd"> </pre> <p>The MailReader application retains a list of users along with their email accounts. The application stores this information in a database. If the application can't connect to the database, the application can't do its job. So before displaying the home page, the class checks to see if the database is available. The MailReader is also an internationalized application. So, the WelcomeAction checks to see if the message resources are available too. If both resources are available, the class displays home page. Otherwise, it forwards to the "failure" path so that the appropriate error messages can be displayed:</p> <pre class="code"> public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // Setup message array in case there are errors ArrayList messages = new ArrayList(); // Confirm message resources loaded MessageResources resources = getResources(request); if (resources == null) { messages.add(Constants.ERROR_MESSAGES_NOT_LOADED); } // Confirm database loaded UserDatabase userDatabase = getUserDatabase(request); if (userDatabase == null) { messages.add(Constants.ERROR_DATABASE_NOT_LOADED); } // If there were errors, queue plain error messages to the request, // and forward to boot failure page. Notice: no redirection here. if (messages.size() > 0) { request.setAttribute(Constants.ERROR_KEY,messages); mapping.findForward(Constants.FAILURE); } // Messages and database initialized successfully, let DialogAction // handle input and output. return super.execute(mapping, form, request, response); } </pre> </div> <!-- <section id="database"> <title>MemoryDatabasePlugIn.java</title> <p>The database is exposed to the application as an object stored in application scope. The database object is based on an interface. Different implementations of the database could be loaded without changing the rest of the application. But how is the database object loaded in the first place?</p> <p>One section of the Struts configuration is devoted to "PlugIns". When a Struts application loads, it also loads whatever PlugIns are specified in its configuration. The PlugIn interface is quite simple, and you can use PlugIns to do anything that might need to be done when your application loads. The PlugIn is also notified when the application shuts down, so you can release any allocated resources.</p> <source> <plug-in className="org.apache.struts.webapp.example.memory.MemoryDatabasePlugIn"> <set-property property="pathname" value="/WEB-INF/database.xml"/> </plug-in> </source> <p>By default, the MailReader application loads a "MemoryDatabase" implementation of the UserDatabase. MemoryDatabase stores the database contents as a XML document, which is parsed by the Digester and loaded as a set of nested hashtables. The outer table is the list of user objects, each of which has its own inner hashtable of subscriptions. When you register, a user object is stored in this hashtable ... and when you login, the user object is stored within the session context.</p> <p>The database comes seeded with a sample user. If you check the database.xml file under WEB-INF, you'll see the sample user described as:</p> <source> <user username="user" fromAddress="Joh...@so..." fullName="John Q. User" password="pass"> <subscription host="mail.hotmail.com" autoConnect="false" password="bar" type="pop3" username="user1234"> </subscription> <subscription host="mail.yahoo.com" autoConnect="false" password="foo" type="imap" username="jquser"> </subscription> </user> </source> <p>This creates a registration record for "John Q. User", with the detail for his hotmail account (or "subscription").</p> </section> <section id="messageresources"> <title>MessageResources.properties</title> <p>Another section of the Struts configuration loads the message resources for the application. If you change a message in the resource, and then reload the application, the change will appear throughout the application. If you provide message resources for additional locales, you can internationalize your application.</p> <source> <message-resources parameter="org.apache.struts.webapp.example.MessageResources" /> </source> <p>This is a standard properties text file. Here are the entries used by the welcome page:</p> <source> index.heading=MailReader Demonstration Application Options index.logon=Log on to the MailReader Demonstration Application index.registration=Register with the MailReader Demonstration Application index.title=MailReader Demonstration Application (Struts Dialogs) index.tour=A Walking Tour of the MailReader Demonstration Application </source> <p>The MailReader application uses a second set of message resources for non-text elements. The "key" element can be used to access this resource bundle rather than the default bundle.</p> <source> <message-resources parameter="org.apache.struts.webapp.example.AlternateMessageResources" key="alternate" /> </source> </section> --> <!-- ************************** --> <h2>Logon component</h2> <p>Login component is controlled by one action (LoginAction) and has two views: <span class="codefrag">login.jsp</span> and <span class="codefrag">logout.jsp</span>.</p> <p> <span class="codefrag">login.jsp</span> is shown to a non-logged-in user and allows either to log in using existing user account.</p> <div align="center"> <img class="figure" alt="MailReader Login" src="images/mailreader-login.gif"></div> <p></p> <p> <span class="codefrag">logout.jsp</span> is shown to a logged-in user and allows to check current user's name and to log off the applicaiton.</p> <div align="center"> <img class="figure" alt="MailReader Logout" src="images/mailreader-logout.gif"></div> </div> <a name="N10041"></a><a name="loginaction"></a> <h3>Logon action</h3> <div style="margin-left: 0 ; border: 2px"> <p>MailReader's <span class="codefrag">LoginAction</span> class does not differ much from standard <a href="dialogaction-logincomponentsample.html">Login Component</a>. The only difference that instead of saving a name of logged-in user in the session, it saves the whole User object, which contains additional account information. Another difference is that <span class="codefrag">LoginAction</span> uses dynabean to store user's name and password, and Commons Validator to check input values.</p> <pre class="code"> public ActionForward onLogon (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // Validate user credentials, use Commons Validator ActionMessages errors = form.validate(mapping, request); // Local variables UserDatabase database = getUserDatabase(request); String username = (String) PropertyUtils.getSimpleProperty(form, "username"); String password = (String) PropertyUtils.getSimpleProperty(form, "password"); // Retrieve user from database if (errors.isEmpty()) { // Load user; if not found, errors will be set User user = getUser(database, username, password, errors); // If user not found, this effectively logs out current user SaveUser(request, user); } // Errors found; reload dialog and display errors if (!errors.isEmpty()) { this.saveDialogErrors(request.getSession(), errors); return EventForward.DIALOG_RELOAD; // Successfully logged in; navigate to home page } else { return mapping.findForward("success"); } } </pre> </div> <a name="N1005A"></a><a name="loginpages"></a> <h3>Logon pages</h3> <div style="margin-left: 0 ; border: 2px"> <p>Logon component has two pages. <span class="codefrag">login.jsp</span> is shown to a non-logged-in user and allows either to log in using existing user account. <span class="codefrag">logout.jsp</span> is shown to a logged-in user and allows to check current user's name and to log off the application. The following code selects the appropriate page depending on application state:</p> <pre class="code"> public ActionForward getDialogView(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // Mark response as non-cachable setNoCache(response); // Display page, corresponding to login state. HttpSession session = request.getSession(); if (session.getAttribute(Constants.USER_KEY) == null) { return mapping.findForward("notloggedin"); } else { return mapping.findForward("loggedin"); } } </pre> </div> <!- ^^^^^^^^^^^^^^ --> <h2>Subscriptions component</h2> <p>Subscriptions component is controlled by one action (SubscriptionAction.java) and has two views: <span class="codefrag">subscriptions.jsp</span> and <span class="codefrag">subscription.jsp</span>.</p> <p> <span class="codefrag">subscriptions.jsp</span> displays a list of email subscriptions. It is shown to a logged-in user, if there is no <em>current</em> subscription.</p> <div align="center"> <img class="figure" alt="MailReader Subscriptions" src="images/mailreader-subscriptions.gif"></div> <p></p> <p>If current subscription exists, <span class="codefrag">subscription.jsp</span> displays it to a logged-in user. It can be either a new subscription...</p> <div align="center"> <img class="figure" alt="MailReader Create Subscription" src="images/mailreader-subscription-create.gif"></div> <p>...or an existing subscription:</p> <div align="center"> <img class="figure" alt="MailReader Update Subscription" src="images/mailreader-subscription-update.gif"></div> </div> <a name="N1004C"></a><a name="subscriptionaction"></a> <h3>SubscriptionAction.java</h3> <div style="margin-left: 0 ; border: 2px"> <p> <span class="codefrag">SubscriptionAction</span> class does not differ much from standard all-in-one <a href="crudaction.html">CRUD Component</a>. The major difference is that Subscription action first verifies if a user is logged in. If not, it redirects to Login action. If user is logged in, then Subscription action handles input events in standard way for DialogAction class. In real application this code should be placed in an interceptor or servlet filter. Struts Chains, introduced in Struts 1.3, should allow easy implementation of generic interceptors like login interceptor.</p> <pre class="code"> public class SubscriptionAction extends CRUDAction { ... public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // If user not found, redirect to login action HttpSession session = request.getSession(); if (session.getAttribute(Constants.USER_KEY) == null) { return mapping.findForward("logon"); } // User is valid, perform standard event processing return super.execute(mapping, form, request, response); } ... } </pre> </div> <a name="N10061"></a><a name="subscriptionslist"></a> <h3>Subscriptions list</h3> <div style="margin-left: 0 ; border: 2px"> <p>If <em>current</em> subscription does not exist, Subscrpiptions action displays subscrpiption list. This list can be split into pages. Default page size is four rows. Struts-EL is used to access actionform data.</p> <pre class="code"> <table> <thead> <tr> <th>Host</th> <th>Username</th> <th>Server Type</th> <th >Auto</th> <th>Operation</th> </tr> </thead> <logic:present name="user" scope="session"> <!-- Show subscription list --> <logic-el:iterate id="subscription" collection="${SubscriptionForm.subscriptions}" offset="${SubscriptionForm.offset}" length="${SubscriptionForm.pagesize}" type="net.jspcontrols.mailreader.business.Subscription"> <tr> <td><c:out value="${subscription.host}"/></td> <td><c:out value="${subscription.username}"/></td> <td><c:out value="${subscription.type}"/></td> <td><c:out value="${subscription.autoConnect}"/></td> <td> <html-el:link href="Subscriptions.do?DIALOG-EVENT-UPDATE&host=${subscription.host}"> Edit </html-el:link> <html-el:link href="Subscriptions.do?DIALOG-EVENT-DELETE&host=${subscription.host}"> Delete </html-el:link> </td> </tr> </logic-el:iterate> </logic:present> </table> <html:form action="/Subscriptions.do"> <html:submit property="DIALOG-EVENT-CREATE" value="New Subscription"/> <html-el:submit property="DIALOG-EVENT-PREVPAGE" value="Previous Page" disabled="${SubscriptionForm.firstpage}"/> <html-el:submit property="DIALOG-EVENT-NEXTPAGE" value="Next Page" disabled="${SubscriptionForm.lastpage}"/> <html:submit property="DIALOG-EVENT-BACKHOME" value="Cancel"/> </html:form> </pre> </div> <a name="N10073"></a><a name="subscription"></a> <h3>Creating and updating subscriptions</h3> <div style="margin-left: 0 ; border: 2px"> <p>The major difference of this version of MailReader application from original Ted Husted's version is that action form has session scope and current subscription is nested within the action form. Fortunately, Subscrption business object (BO) has only String and boolean fields, so no conversion is needed and it is easy to retain invalid values in the form.</p> <p>When a user creates new subscription, a new <span class="codefrag">Subscription</span> object is created and nested in the <span class="codefrag">SubscriptionForm.java</span> class. If a user wants to update existing subscription, then it is cloned into a detached object, which in turn, is nested within <span class="codefrag">SubscriptionForm.java</span> class. Therefore, changes to nested subscription do not affect persistent data. If the user cancels the update process, then detached subscription is simply deleted from memory.</p> <p>Subscription action creates new or updates existing subscription based on input event generated by button on <span class="codefrag">subscriptions.jsp</span> page. DIALOG-EVENT-CREATE creates new subscription, DIALOG-EVENT-UPDATE selects a subscription as current and updates it.</p> </div> </body> </html> |
From: <jm...@us...> - 2005-09-23 06:38:10
|
Update of /cvsroot/struts/dialogs/war/WEB-INF/classes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17798/war/WEB-INF/classes Added Files: MailReader-AlternateApplicationResources.properties MailReader-ApplicationResources.properties MailReader-ApplicationResources_ru.properties Samples-ApplicationResources.properties log4j.properties Removed Files: ApplicationResources.properties Log Message: Added MailReader Demo; Added component RuleSet --- NEW FILE: MailReader-AlternateApplicationResources.properties --- prompt.password=Enter your Password here ==> strutsdialogs.logo.path=/strutsdialogs-power.gif strutsdialogs.logo.alt=Powered by Struts Dialogs --- NEW FILE: MailReader-ApplicationResources.properties --- button.cancel=Cancel button.confirm=Confirm button.reset=Reset button.save=Save button.logoff=Log Off change.message=Your password has expired. Please ask the system administrator to change it. change.try=Try Again change.title=Password Has Expired database.load=Cannot load database from {0} error.database.missing=User database is missing, cannot validate logon credentials error.fromAddress.format=Invalid format for From Address error.fromAddress.required=From Address is required error.fullName.required=Full Name is required error.host.required=Mail Server is required error.noSubscription=No Subscription bean in user session error.password.expired=Your password has expired for username {0} error.password.required=Password is required error.password2.required=Confirmation password is required error.password.match=Password and confirmation password must match error.password.mismatch=Invalid username and/or password, please try again error.replyToAddress.format=Invalid format for Reply To Address error.transaction.token=Cannot submit this form out of order error.type.invalid=Server Type must be 'imap' or 'pop3' error.type.required=Server Type is required error.username.required=Username is required error.username.unique=That username is already in use, please select another error.subscription.unique=That mail server is already in use, please select another errors.footer=</ul><hr> errors.header=<h3><font color="red">Validation Error</font></h3><p>You must correct the following error(s) before proceeding:</p><ul> errors.prefix=<li> errors.suffix=</li> errors.ioException=I/O exception rendering error messages: {0} expired.password=User Password has expired for {0} heading.autoConnect=Auto heading.subscriptions=Current Subscriptions heading.host=Host Name heading.user=User Name heading.type=Server Type heading.action=Action index.heading=MailReader Demonstration Application Options index.logon=Log on to the MailReader Demonstration Application index.registration=Register with the MailReader Demonstration Application index.updateaccount=Update Account Information index.showuserinfo=Show Current User Information index.logoff=Log Off index.langopts=Language Options index.langenglish=English (\u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439) index.langrussian=Russian (\u0420\u0443\u0441\u0441\u043a\u0438\u0439) index.managesubscriptions=Manage Subscriptions index.title=MailReader Demonstration Application (Struts Dialogs) index.tour=A Walking Tour of the MailReader Demonstration Application linkSubscription.io=I/O Error: {0} linkSubscription.noSubscription=No subscription under attribute {0} linkUser.io=I/O Error: {0} linkUser.noUser=No user under attribute {0} logon.title=MailReader Demonstration Application - Logon logon.heading=Enter your username and password logoff.title=MailReader Demonstration Application - Logoff logoff.heading=User Information mainMenu.heading=Main Menu Options for mainMenu.logoff=Log off MailReader Demonstration Application mainMenu.registration=Edit your user registration profile mainMenu.title=MailReader Demonstration Application - Main Menu option.imap=IMAP Protocol option.pop3=POP3 Protocol prompt.autoConnect=Auto Connect prompt.fromAddress=From Address prompt.fullName=Full Name prompt.mailHostname=Mail Server prompt.mailPassword=Mail Password prompt.mailServerType=Server Type prompt.mailUsername=Mail Username prompt.password=Password prompt.password2=(Repeat) Password prompt.replyToAddress=Reply To Address prompt.username=Username registration.addSubscription=Add registration.deleteSubscription=Delete registration.editSubscription=Edit registration.title.create=Register for the MailReader Demonstration Application registration.title.edit=Edit Registration for the MailReader Demonstration Application registration.heading.create=Register a new user registration.heading.edit=Update account information subscription.title.create=Create New Mail Subscription subscription.title.delete=Delete Existing Mail Subscription subscription.title.edit=Edit Existing Mail Subscription subscriptions.headingfor=Subscriptions for user: subscriptions.title=MailReader Demonstration Application - Subscriptions subscriptions.prevpage=Previous Page subscriptions.nextpage=Next Page # Standard error messages for validator framework checks errors.required={0} is required. errors.minlength={0} cannot be less than {1} characters. errors.maxlength={0} cannot be greater than {2} characters. errors.invalid={0} is invalid. errors.byte={0} must be an byte. errors.short={0} must be an short. errors.integer={0} must be an integer. errors.long={0} must be an long. errors.float={0} must be an float. errors.double={0} must be an double. errors.date={0} is not a date. errors.range={0} is not in the range {1} through {2}. errors.creditcard={0} is not a valid credit card number. errors.email={0} is an invalid e-mail address. errors.notimplemented=Feature not implemented errors.notloggedin=User is not logged in --- NEW FILE: MailReader-ApplicationResources_ru.properties --- button.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c button.confirm=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c button.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c button.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c button.logoff=\u0412\u044b\u0445\u043e\u0434 change.message=\u041f\u0430\u0440\u043e\u043b\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u0435\u043d. change.try=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c change.title=\u041f\u0430\u0440\u043e\u043b\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u0435\u043d database.load=\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u0430 \u0438\u0437 {0} error.database.missing=\u041d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f - \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e. error.fromAddress.format=\u0412 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:' \u0443\u043a\u0430\u0437\u0430\u043d \u0430\u0434\u0440\u0435\u0441 \u0432 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435. error.fromAddress.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0432 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:'. error.fullName.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f. error.host.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440. error.noSubscription=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0432 \u0441\u0435\u0441\u0441\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f error.password.expired=\u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f {0} \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u0435\u043d. error.password.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c. error.password2.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u043e\u043b\u044f. error.password.match=\u041f\u0430\u0440\u043e\u043b\u044c \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u043e\u043b\u044f \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442. error.password.mismatch=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u044f \u0438/\u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c - \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u043d\u043e\u0432\u0430. error.replyToAddress.format=\u0412 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430:' \u0443\u043a\u0430\u0437\u0430\u043d \u0430\u0434\u0440\u0435\u0441 \u0432 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435. error.transaction.token=\u042d\u0442\u0430 \u0444\u043e\u0440\u043c\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 - \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0437\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445. error.type.invalid=\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0438\u043f\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043b\u0438\u0448\u044c 'imap' \u0438\u043b\u0438 'pop3' error.type.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 error.username.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f error.username.unique=\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f - \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f. error.subscription.unique=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0430 \u044d\u0442\u043e\u043c \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\u002c \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0439\u002e errors.footer=</ul><hr> errors.header=<h3><font color="red">\u041e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0437\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445</font></h3><p>\u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043d\u0438\u0436\u0435 \u043e\u0448\u0438\u0431\u043a\u0438:</p><ul> errors.prefix=<li> errors.suffix=</li> errors.ioException=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445: {0} expired.password=\u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f {0} \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u0435\u043d heading.autoConnect=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 heading.subscriptions=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 heading.host=\u0421\u0435\u0440\u0432\u0435\u0440 heading.user=\u0418\u043c\u044f heading.type=\u0422\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 heading.action=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 index.heading=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b' index.logon=\u0412\u043e\u0439\u0442\u0438 \u043a\u0430\u043a \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c index.registration=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f index.updateaccount=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c index.showuserinfo=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 index.logoff=\u0417\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u0441\u0435\u0430\u043d\u0441 index.langopts=\u0412\u044b\u0431\u043e\u0440 \u044f\u0437\u044b\u043a\u0430 (Language Options) index.langenglish=\u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439 (English) index.langrussian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russian) index.managesubscriptions=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 index.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b' (Struts Dialogs) index.tour=\u041e\u0431\u0437\u043e\u0440 \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b' linkSubscription.io=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 (\u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438): {0} linkSubscription.noSubscription=\u0410\u0442\u0440\u0438\u0431\u0443\u0442 {0} \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. linkUser.io=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 (\u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f): {0} linkUser.noUser=\u0410\u0442\u0440\u0438\u0431\u0443\u0442 {0} \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. logon.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b - \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u043c\u0435\u043d\u0438 \u0438 \u043f\u0430\u0440\u043e\u043b\u044f. logon.heading=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0438\u043c\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c logoff.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b \u002d \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435. logoff.heading=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 mainMenu.heading=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044e \u0434\u043b\u044f mainMenu.logoff=\u0412\u044b\u0439\u0442\u0438 mainMenu.registration=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 mainMenu.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b' - \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e option.imap=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b IMAP option.pop3=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b POP3 prompt.autoConnect=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 prompt.fromAddress=\u0410\u0434\u0440\u0435\u0441 \u041e\u0442 prompt.fullName=\u041f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f prompt.mailHostname=\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 prompt.mailPassword=\u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 prompt.mailServerType=\u0422\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 prompt.mailUsername=\u0418\u043c\u044f \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 prompt.password=\u041f\u0430\u0440\u043e\u043b\u044c prompt.password2=(\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435) \u041f\u0430\u0440\u043e\u043b\u044c prompt.replyToAddress=\u0410\u0434\u0440\u0435\u0441 \u041e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430 prompt.username=\u0418\u043c\u044f registration.addSubscription=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c registration.deleteSubscription=\u0423\u0434\u0430\u043b\u0438\u0442\u044c registration.editSubscription=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c registration.title.create=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f registration.title.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 registration.heading.create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c registration.heading.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c subscription.title.create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 subscription.title.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 subscription.title.edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 subscriptions.headingfor=\u0421\u043f\u0438\u0441\u043e\u043a \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u003a subscriptions.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b \u002d \u0421\u043f\u0438\u0441\u043e\u043a \u0430\u0434\u0440\u0435\u0441\u043e\u0432 subscriptions.prevpage=\u041b\u0438\u0441\u0442\u0430\u0442\u044c \u043d\u0430\u0437\u0430\u0434 subscriptions.nextpage=\u041b\u0438\u0441\u0442\u0430\u0442\u044c \u0432\u043f\u0435\u0440\u0435\u0434 # Standard error messages for validator framework checks errors.required=\u041f\u043e\u043b\u0435 {0} \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c. errors.minlength={0} \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u043e\u0440\u043e\u0447\u0435 {1} \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. errors.maxlength={0} \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u043b\u0438\u043d\u043d\u0435\u0435 {2} \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. errors.invalid=\u041f\u043e\u043b\u0435 {0} \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0435\u0432\u0435\u0440\u043d\u043e. errors.byte=\u041f\u043e\u043b\u0435 {0} \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0431\u0430\u0439\u0442\u043e\u043c. errors.short=\u041f\u043e\u043b\u0435 {0} \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u043c \u0446\u0435\u043b\u044b\u043c. errors.integer=\u041f\u043e\u043b\u0435 {0} \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0446\u0435\u043b\u044b\u043c. errors.long=\u041f\u043e\u043b\u0435 {0} \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0434\u043b\u0438\u043d\u043d\u044b\u043c \u0446\u0435\u043b\u044b\u043c. errors.float=\u041f\u043e\u043b\u0435 {0} \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439. errors.double=\u041f\u043e\u043b\u0435 {0} \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439. errors.date=\u041f\u043e\u043b\u0435 {0} \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0430\u0442\u043e\u0439. errors.range=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f {0} \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0432 \u0433\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u043e\u0442 {1} \u043f\u043e {2}. errors.creditcard={0} \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u043c\u0435\u0440\u043e\u043c \u043a\u0440\u0435\u0434\u0438\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b. errors.email={0} \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u043c e\u002dmail \u0430\u0434\u0440\u0435\u0441\u043e\u043c. --- NEW FILE: Samples-ApplicationResources.properties --- # InputLoginAction login.badpassword=Login name and password combination is not found. # CRUDAction crudData.stringisnull=String Value must not be null crudData.numbernotint=Num Value must contain an integer value crudData.storevaluetoolow=Could not persist data; increase intValue over 150 crudData.badmode=Cannot perform this operation now crudData.storageunavailable=Persistent storage unavailable crudData.itemnotfound=Item {0} could not be found in storage crudData.internalstorageerror=Storage Error loginsignupcontrol.invalidnamepass=User name and password must be longer than 5 characters. loginsignupcontrol.usernametooshort=User name must be at least 3 characters long. loginsignupcontrol.passwordtooshort=Password must be at least 5 characters long. loginsignupcontrol.passwordnotequal=Repeated password must be equal to password. loginsignupcontrol.cannotlogin=Login name and password combination is not found. loginsignupcontrol.loginexists=Login name already exists, please choose another name. loginsignupcontrol.nopersonalinfo=Both book name and movie name must be entered. loginsignupcontrol.accountsexhausted=User account storage is full, cannot register. loginsignupcontrol.nosecurityinfo=Please, answer the security question. --- NEW FILE: log4j.properties --- # # Root logger # log4j.rootLogger=WARN, stdout # # MailReader appender and layout # log4j.appender.MailReaderAppender=org.apache.log4j.RollingFileAppender log4j.appender.MailReaderAppender.File=logs/mailreader.log log4j.appender.MailReaderAppender.MaxFileSize=200KB log4j.appender.MailReaderAppender.MaxBackupIndex=3 log4j.appender.MailReaderAppender.layout=org.apache.log4j.PatternLayout log4j.appender.MailReaderAppender.layout.ConversionPattern=%m%n # # stdout appender and layout # log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%-5p [%t]: %m%n # # MailReader logger uses log instance initialized by DispatchAction # #log4j.logger.org.apache.struts.actions=DEBUG, MailReaderAppender log4j.logger.org.apache.struts.actions.DispatchAction=DEBUG, MailReaderAppender log4j.logger.org.apache.struts.actions=DEBUG, MailReaderAppender --- ApplicationResources.properties DELETED --- |
From: <jm...@us...> - 2005-09-23 06:35:28
|
Update of /cvsroot/struts/dialogs/war/images In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17425/images Log Message: Directory /cvsroot/struts/dialogs/war/images added to the repository |
From: <jm...@us...> - 2005-09-23 06:35:27
|
Update of /cvsroot/struts/dialogs/war/mailreaderpages In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17425/mailreaderpages Log Message: Directory /cvsroot/struts/dialogs/war/mailreaderpages added to the repository |
From: <jm...@us...> - 2005-09-23 06:35:26
|
Update of /cvsroot/struts/dialogs/war/logs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17425/logs Log Message: Directory /cvsroot/struts/dialogs/war/logs added to the repository |
From: <jm...@us...> - 2005-09-23 06:35:26
|
Update of /cvsroot/struts/dialogs/war/mailreader-css In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17425/mailreader-css Log Message: Directory /cvsroot/struts/dialogs/war/mailreader-css added to the repository |
From: <jm...@us...> - 2005-09-23 06:27:32
|
Update of /cvsroot/struts/dialogs/src/net/jspcontrols/mailreader/business In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15810/business Log Message: Directory /cvsroot/struts/dialogs/src/net/jspcontrols/mailreader/business added to the repository |
From: <jm...@us...> - 2005-09-23 06:27:32
|
Update of /cvsroot/struts/dialogs/src/net/jspcontrols/mailreader/memory In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15810/memory Log Message: Directory /cvsroot/struts/dialogs/src/net/jspcontrols/mailreader/memory added to the repository |
From: <jm...@us...> - 2005-09-23 06:27:30
|
Update of /cvsroot/struts/dialogs/src/net/jspcontrols/mailreader In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15724/mailreader Log Message: Directory /cvsroot/struts/dialogs/src/net/jspcontrols/mailreader added to the repository |
From: <jm...@us...> - 2005-09-11 02:06:39
|
Update of /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14567/src/documentation/content/xdocs/strutsdialogs Modified Files: index.xml Log Message: Index: index.xml =================================================================== RCS file: /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs/index.xml,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** index.xml 11 Sep 2005 01:46:38 -0000 1.12 --- index.xml 11 Sep 2005 02:06:31 -0000 1.13 *************** *** 89,93 **** one action class only, which is called <em>parent action</em>. Data, submitted from a page, is handled by the parent action. If submitted data changed resource state, the action may render a different page the next time resource ! is accessed. Read more on input submission in <strong>Event Handling section</strong>.</p> </section> </section> --- 89,93 ---- one action class only, which is called <em>parent action</em>. Data, submitted from a page, is handled by the parent action. If submitted data changed resource state, the action may render a different page the next time resource ! is accessed.</p> </section> </section> *************** *** 110,116 **** which resource to navigate to next. This approach allows to define all navigation targets in the <code>struts-config.xml</code> file, thus having a clear representation of web application structure.</p> - - <p>Event handling is implemented by DialogAction, the extension of venerable DispatchAction. - DialogAction provides other services as well, like <strong>two-phase request processing</strong>.</p> </section> --- 110,113 ---- *************** *** 205,209 **** <section id="dialogaction"> ! <title>DialogAction: the Jack of all trades</title> <p><link href="dialogaction.html">DialogAction</link> is the main asset of Struts Dialogs library.</p> --- 202,206 ---- <section id="dialogaction"> ! <title>DialogAction: Jack of all trades</title> <p><link href="dialogaction.html">DialogAction</link> is the main asset of Struts Dialogs library.</p> |
From: <jm...@us...> - 2005-09-11 01:46:46
|
Update of /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11633/src/documentation/content/xdocs/strutsdialogs Modified Files: index.xml Log Message: Index: index.xml =================================================================== RCS file: /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs/index.xml,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** index.xml 4 Aug 2005 08:18:47 -0000 1.11 --- index.xml 11 Sep 2005 01:46:38 -0000 1.12 *************** *** 7,12 **** <body> ! <section id="overview"> <title>Overview</title> <p>Struts Dialogs library allows building <em>web components</em> using Struts and JSP.</p> --- 7,146 ---- <body> ! ! <section id="overview_new"> <title>Overview</title> + <p><strong>Struts Dialogs</strong> combines Front Controller pattern of classic Struts with Page Controller features + of ASP.NET and JSP. It implements event handling, basic state management, provides simplified control flow and facilitates + component development.</p> + + <ul> + <li><strong>Simplified control flow</strong> - concerns between actions, action forms and JSP pages are cleanly separated.</li> + <li><strong>Event handling</strong> - command links and form submissions are processed + by an action, which a JSP page corresponds to.</li> + <li><strong>State management</strong> - session-scoped ActionForm is elevated from simple request buffer to stateful + input/output object.</li> + <li><strong>Component development</strong> - It is possible to create standalone and embedded components without portal + engine and portlet API.</li> + <li><strong>Web Wizards</strong> - create web wizards, similar to traditional desktop wizard dialogs.</li> + </ul> + </section> + + <section id="controlflow"> + <title>Simplified control flow</title> + <p>Struts is a controller framework that adheres closely to the principles of Front Controller Pattern + (<link href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html">J2EE Front Controller pattern</link>, + <link href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpatterns/html/DesFrontController.asp">.NET Front Controller pattern</link>):</p> + + <ul> + <li><strong>ActionServlet</strong>, <strong>RequestProcessor</strong>: Controller (J2EE); Handler (.NET)</li> + <li><strong>Action</strong>: Dispatcher (J2EE); part of Command (.NET)</li> + <li><strong>ActionForm</strong>: part of Command (.NET)</li> + <li><strong>JSP</strong>: view</li> + </ul> + + <p>The Front Controller pattern does not specify how the state should be managed, or where a request should be directed + after a view is rendered. Out-of-the-box Struts does not provide much help on these subjects. Quite contrary, + official Struts documentation suggest practices that may complicate the matters.</p> + + <section id="traditionalflow"> + <title>Traditional Struts approach</title> + + <p>ActionForm was initially designed as convenience object for input data. Struts guidelines recommend using + ActionForm with request scope, which prevents from storing state information in it. It is up to + the developer to decide where to queue output data, and where to store information between requests.</p> + + <p>Struts documentation does not specify how exactly JSP preparation and form submission should + be handled. Struts users came up with idea of pre-Action (output Action, setup Action) and post-Action + (input Action) dispatchers, so actions and JSP pages are interlaced:</p> + + <figure src="images/struts-pre-post-action.gif" alt="Pre- and Post- actions"/> + + <p>The problem here is that one JSP can relate to several actions, and the only way to determine + the action (or actions) that handle the submission of the page, is to look through the JSP code. + Because of many-to-many relationships between actions and JSP pages, web application becomes + hard to maintain right from the start.</p> + </section> + + <section id="codebehind"> + <title>Code-behind for Struts</title> + + <p>Struts Dialogs employs code-behind pattern similar to one used in .NET framework, + while keeping your investments into Struts.</p> + + <p>One of the .NET concepts is a unity of page markup (ASP) and business-related code (C# or VB). + A page layout and widgets are defined in the markup, while corresponding code-behind class handles + page lifecycle and incoming events. This concept is especially easy to grasp for desktop applications + programmers: before page is displayed, the code behind it initializes page data. After page is rendered, + activating a widget in the browser window generates event, which is dispatched to a handler.</p> + + <p>This pattern can be implemented in Struts with no change to core classes or tag libraries. It even can + be improved, because Struts allows to define several markup pages corresponding to one action.</p> + + <p>First you need to change your mindset. Forget about traditional Struts pre-actions and post-actions. + Do not think in terms of pages either. Think in terms of web resources. Recall that internet is about + web resources, not about mere pages. A page is just a visualization of resource in its current state at + a given time. An address identifies a resource, not a particular representaion of it. Resource can be rendered + differently depending on its state.</p> + + <figure src="images/struts-dialog-action.gif" alt="Dialog action"/> + + <p>In Struts Dialogs each resource is serviced by one action class. Depending on resource state, + the action class can render different views,defined in JSP pages. Each JSP page belongs to + one action class only, which is called <em>parent action</em>. Data, submitted from a page, is handled by the parent + action. If submitted data changed resource state, the action may render a different page the next time resource + is accessed. Read more on input submission in <strong>Event Handling section</strong>.</p> + </section> + </section> + + <section id="eventhandling"> + <title>Event handling</title> + + <p>Official Struts documentation does not specify, how exactly form input should be handled. + It is common practice to prepare content for JSP page with one action, and to collect input data + in another action. This wide-spread net of single-task actions makes development more complicated + than it could be.</p> + + <p>Struts Dialogs offers a different approach, which is used by frameworks like .NET and JSF. + Form submission generates input event, which is handled in action class. Action class defines + handler methods for every input event. Input events can be generated not only by submitting a form, + but also by clicking on a command link.</p> + + <p>Direct linking from JSP page to another resource is discouraged. Instead, a command link should + generate an event, which would be handled by parent action class. Only action class should decide + which resource to navigate to next. This approach allows to define all navigation targets in the <code>struts-config.xml</code> + file, thus having a clear representation of web application structure.</p> + + <p>Event handling is implemented by DialogAction, the extension of venerable DispatchAction. + DialogAction provides other services as well, like <strong>two-phase request processing</strong>.</p> + </section> + + + <section id="state_management"> + <title>State management</title> + + <p>Struts Dialogs does not introduce new classes to manage application state. Instead, it uses + the class which already exists in the Struts core, ActionForm. Official Struts guidelines recommend + using ActionForm with request scope, only to collect input data. This decision entails developers + to use custom objects to queue output data and to store information between requests.</p> + + <p>Struts Dialogs suggests to use session scope for ActionForm. One simple change in the config file + promotes ActionForm from simple request buffer to stateful input/output object. In JSF terms, + ActionForm now acts as a backing bean for JSP page. There is nothing groundbreaking in using + session scope for ActionForm, or in storing output data in it. Online poll shows that about 60% of + respondents use ActionForm for queueing output data.</p> + + <p>With changing ActionForm scope to session, it is possible now to initialize form bean only once, + and to reuse data between requests. This is convenient for form resubmissions, for page reloading + or for navigating back to previous resource. Having all resource data + in a single ActionForm simplifies JSP page. Struts automatically populates ActionForm + with submitted data, now you can use this data to render a page without any + additional efforts. Session scope justifies the usage of nested properties within ActionForm, + which allows to use business objects or DTOs directly without copying their data to ActionForm + and from ActionForm.</p> + + </section> + + <section id="components"> + <title>Component Development</title> <p>Struts Dialogs library allows building <em>web components</em> using Struts and JSP.</p> *************** *** 50,58 **** </section> <section id="selectaction"> <title>SelectAction: dispatches submit events</title> <p><link href="selectaction.html">SelectAction</link> is an enhancement of standard DispatchAction. ! It handles submit events and provides improved dispatching functionality. ! SelectAction has the following features:</p> <ul> <li>works uniformly with pushbuttons, image buttons and regular links;</li> --- 184,201 ---- </section> + <section id="actions"> + <title>Actions</title> + + <p>Most features of the Struts Dialogs library are available through use of different action + classes. Most often you will be using DialogAction class, extending your specific action class + from it.</p> + + <section id="selectaction"> <title>SelectAction: dispatches submit events</title> <p><link href="selectaction.html">SelectAction</link> is an enhancement of standard DispatchAction. ! It handles submit events and provides improved dispatching functionality. You can use this action ! class if you do not need full power of DialogAction, and all you want is just to dispatch submit ! events to handler methods. SelectAction has the following features:</p> <ul> <li>works uniformly with pushbuttons, image buttons and regular links;</li> *************** *** 62,66 **** <section id="dialogaction"> ! <title>DialogAction: handles component state and renders a view</title> <p><link href="dialogaction.html">DialogAction</link> is the main asset of Struts Dialogs library.</p> --- 205,209 ---- <section id="dialogaction"> ! <title>DialogAction: the Jack of all trades</title> <p><link href="dialogaction.html">DialogAction</link> is the main asset of Struts Dialogs library.</p> *************** *** 83,90 **** <section id="crudaction"> <title>CRUDAction: simplifies CrUD operations</title> ! <p><link href="crudaction.html">CRUDAction</link> is a more specific kind of action class, ! which implements all operations needed to manipulate business data, nested business object (BO), or nested value object (VO) also called an <code>item</code>. This action allows to create new item, duplicate existing item, edit, view, clear and delete item.</p> --- 226,240 ---- + <section id="wizardaction"> + <title>WizardAction: creates robust page flows</title> + <p><link href="wizardaction.html">WizardAction</link> allows to create <em>web wizards</em>, + similar to traditional desktop wizard dialogs. A wizard has predefined sequence of states, + and is rendered with HTML forms, containing Back, Forward, Cancel and Done pushbuttons.</p> + </section> + <section id="crudaction"> <title>CRUDAction: simplifies CrUD operations</title> ! <p><link href="crudaction.html">CRUDAction</link> implements all operations needed ! to manipulate business data, nested business object (BO), or nested value object (VO) also called an <code>item</code>. This action allows to create new item, duplicate existing item, edit, view, clear and delete item.</p> *************** *** 94,104 **** implement handling of both item list and CRUD operations as one web component.</p> </section> ! ! <section id="wizardaction"> ! <title>WizardAction: creates robust page flows</title> ! <p><link href="wizardaction.html">WizardAction</link> allows to create <em>web wizards</em>, ! similar to traditional desktop wizard dialogs. A wizard has predefined sequence of states, ! and is rendered with HTML forms, containing Back, Forward, Cancel and Done pushbuttons.</p> ! </section> <section id="demos"> --- 244,248 ---- implement handling of both item list and CRUD operations as one web component.</p> </section> ! </section> <section id="demos"> *************** *** 114,116 **** </body> ! </document> --- 258,260 ---- </body> ! </document> \ No newline at end of file |
From: <jm...@us...> - 2005-09-11 01:46:46
|
Update of /cvsroot/struts/struts-site/src/documentation/resources/images In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11633/src/documentation/resources/images Added Files: struts-dialog-action.gif struts-pre-post-action.gif Log Message: --- NEW FILE: struts-dialog-action.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: struts-pre-post-action.gif --- (This appears to be a binary file; contents omitted.) |
From: <jm...@us...> - 2005-09-11 01:46:46
|
Update of /cvsroot/struts/struts-site/src/documentation/content/xdocs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11633/src/documentation/content/xdocs Modified Files: index.xml Log Message: Index: index.xml =================================================================== RCS file: /cvsroot/struts/struts-site/src/documentation/content/xdocs/index.xml,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** index.xml 22 Jul 2005 01:37:59 -0000 1.13 --- index.xml 11 Sep 2005 01:46:38 -0000 1.14 *************** *** 41,45 **** </li> <li> ! <em>Struts Dialogs</em> - Provides robust user interface for interactive input/output forms, and event-based programming model. </li> <li> --- 41,45 ---- </li> <li> ! <em>Struts Dialogs</em> - Implements event handling paradigm, state management, provides simplified control flow and facilitates component development. </li> <li> |
From: <jm...@us...> - 2005-08-04 08:19:29
|
Update of /cvsroot/struts/struts-site In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27290 Modified Files: b.cmd Log Message: Index: b.cmd =================================================================== RCS file: /cvsroot/struts/struts-site/b.cmd,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** b.cmd 22 Jul 2005 01:37:59 -0000 1.2 --- b.cmd 4 Aug 2005 08:18:47 -0000 1.3 *************** *** 1 **** ! call C:\Dev\apache-forrest-0-5\bin\forrest.bat site \ No newline at end of file --- 1 ---- ! call C:\Dev\apache-forrest-0-5-1\bin\forrest.bat site \ No newline at end of file |
Update of /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27290/src/documentation/content/xdocs/strutsdialogs Modified Files: dialogaction-logincomponentsample.xml dialogaction-logincontrolsample.xml index.xml Log Message: Index: dialogaction-logincomponentsample.xml =================================================================== RCS file: /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs/dialogaction-logincomponentsample.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dialogaction-logincomponentsample.xml 11 Jul 2005 07:42:30 -0000 1.3 --- dialogaction-logincomponentsample.xml 4 Aug 2005 08:18:47 -0000 1.4 *************** *** 104,108 **** <source> <action path="/logincomponent" ! type = "package net.jspcontrols.dialogs.samples.dialogloginaction.DialogLoginActionComponent" name = "dialogloginform" scope = "session" --- 104,108 ---- <source> <action path="/logincomponent" ! type = "package net.jspcontrols.dialogs.samples.login.DialogLoginActionComponent" name = "dialogloginform" scope = "session" Index: dialogaction-logincontrolsample.xml =================================================================== RCS file: /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs/dialogaction-logincontrolsample.xml,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** dialogaction-logincontrolsample.xml 11 Jul 2005 07:42:30 -0000 1.5 --- dialogaction-logincontrolsample.xml 4 Aug 2005 08:18:47 -0000 1.6 *************** *** 97,101 **** <action path="/embeddedmasterpage" forward="/embedded-masterpage.jsp"/> <action path="/embeddedchild" ! type = "net.jspcontrols.dialogs.samples.childaction.EmbeddedAction name = "dialogloginform" scope = "session" --- 97,101 ---- <action path="/embeddedmasterpage" forward="/embedded-masterpage.jsp"/> <action path="/embeddedchild" ! type = "net.jspcontrols.dialogs.samples.embedded.EmbeddedControl name = "dialogloginform" scope = "session" Index: index.xml =================================================================== RCS file: /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs/index.xml,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** index.xml 3 Aug 2005 23:59:01 -0000 1.10 --- index.xml 4 Aug 2005 08:18:47 -0000 1.11 *************** *** 110,115 **** <section id="download"> <title>Download</title> ! <p>Download Struts Dialogs version 1.21 from ! <link href="http://sourceforge.net/project/showfiles.php?group_id=49385&release_id=341239">SourceForge website</link>.</p> </section> --- 110,114 ---- <section id="download"> <title>Download</title> ! <p><link href="https://sourceforge.net/project/showfiles.php?group_id=49385&package_id=154597">Download Struts Dialogs</link>.</p> </section> |
Update of /cvsroot/struts/dialogs/src/net/jspcontrols/dialogs/samples/wizard/rules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20952/src/net/jspcontrols/dialogs/samples/wizard/rules Added Files: SignupWizard.java StepConfirm.java StepDetails.java StepSignup.java Log Message: --- NEW FILE: SignupWizard.java --- /* * Copyright 2004-2005 Michael Jouravlev. * * 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 net.jspcontrols.dialogs.samples.wizard.rules; import net.jspcontrols.wizard.impl.Wizard; import net.jspcontrols.wizard.intf.IWizardStep; import net.jspcontrols.wizard.intf.IWizardTransition; import net.jspcontrols.wizard.impl.WizardTransition; import java.util.Map; /** * This class defines a simple signup wizard. The wizard has three steps * with the second step being optional. * <p> * The first step asks a new user for a login name and a password he would * like to use. Also the first step asks if a user wants to supply additional * information about himself. If yes, the second step is made available, it * allows to input the favorite book and the favorite movie of the user. * The third step simply shows user's selections. * <p> * This class stores some UI-related information like error messages, but * efforts were made to design it agnostic of particular web framework. * * @author Michael Jouravlev */ public class SignupWizard extends Wizard { /************************************************************************** * New User Signup wizard nodes **************************************************************************/ /** * The first step accepts and stores new user name and password. * It also allows for a client to choose to provide additional personal * information. */ final StepSignup stepSignup; /** * Returns first node of Signup wizard: the Signup node * @return the Signup node */ public StepSignup getStepSignup() {return stepSignup;} /** * Details step stores favorite book and movie name. These * values are not required if this step is not selected in the signup * node (not quite how UI-agnostic validation should work, but this * is a demo for a wizard, not for MVC concepts). */ final StepDetails stepDetails; /** * Returns second node of Signup wizard: the Personalization node * @return the Personalization node */ public StepDetails getStepDetails() {return stepDetails;} /** * Confirmation step displays user information and stores it in * application domain accounts. After this step the wizard can be * disposed. */ final IWizardStep stepConfirm; /** * Returns third node of Signup wizard: the Confirmation node * @return the Confirmation node */ public IWizardStep getStepConfirm() {return stepConfirm;} /************************************************************************** * Wizard constructor **************************************************************************/ /** * Constructs a signup wizard. */ public SignupWizard (Map errors) { /** * Wizard controller can either use built-in error message map, * or use an external one. */ if (errors != null) { this.errors = errors; } /******** * Nodes ********/ /* * Nodes do not need to be exposed or to have a separate * identifier. But to use wizard accounts data as javabean properties * in the UI, it is easier to define getters and setters for * references to nodes, instead of looking up nodes by name. */ stepSignup = new StepSignup(this, "Signup Node"); stepDetails = new StepDetails(this, "Details Node"); stepConfirm = new StepConfirm(this, "Confirmation Node"); /* * Starting off the Signup node */ sourceState = stepSignup; /* * Set the current node to source node */ currentState = sourceState; /******** * Edges ********/ /* * Path from identification node to personalization node. * Will be chosen if name and password are valid and a user * elected to enter personal information. */ stepSignup.addOutgoingTransition( new WizardTransition(this, "Signup To Detail", stepDetails) { public boolean validate() { return stepSignup.getPersonalize() && stepSignup.validateNameAndPassword(); } } ); /* * Path from identification node to confirmation node. Will be chosen * if name and password are valid and a user did not elect to enter * personal information. */ stepSignup.addOutgoingTransition( new WizardTransition(this, "Signup To Confirmation", stepConfirm) { public boolean validate() { return stepSignup.validateNameAndPassword(); } } ); /* * Path from personalization node to confirmation node * Will be chosen if both book and movie are non null values. */ stepDetails.addOutgoingTransition( new WizardTransition(this, "Detail To Confirmation", stepConfirm) { public boolean validate() { if ( stepDetails.getSecurityAnswerId() > -1 && stepDetails.getSecurityAnswer() != null && stepDetails.getSecurityAnswer().trim().length() > 0) { return true; } else { wizard.getWizardErrors().put( "loginsignupcontrol.nosecurityinfo", null); return false; } } } ); } /** * This is a simple test of this wizard. The wizard itself does not need * UI interaction. * * @param args command-line params, unused */ public static void main(String[] args) { /* * Create wizard controller */ SignupWizard wiz = new SignupWizard(null); /* * Traverse wizard and display all edges */ System.out.println("Traversing the signup wizard"); wiz.traverse(wiz.getSourceStep()); /* * User name and password not set, try to move forward. * Should stay on the Signup Node */ IWizardStep curNode = null; boolean flag = false; do { System.out.println("\nGo forward"); wiz.forward(); curNode = wiz.getCurrentStep(); System.out.println("Current node: " + curNode.getStateName()); if (curNode instanceof StepSignup) { StepSignup nodeSignup = (StepSignup) wiz.getCurrentStep(); nodeSignup.setName("sysdba"); nodeSignup.setPassword("masterkey"); nodeSignup.setPersonalize(true); } else if (curNode instanceof StepDetails) { StepDetails nodePersonal = (StepDetails) wiz.getCurrentStep(); /* * First time do not enter book and movie, enter on second pass */ if (flag) { nodePersonal.setSecurityAnswerId(1); nodePersonal.setSecurityAnswer("Moscow"); } else { flag = !flag; } } } while (!"Confirmation Node".equals(curNode.getStateName())); do { System.out.println("\nGo back"); wiz.back(); curNode = wiz.getCurrentStep(); System.out.println("Current node: " + curNode.getStateName()); } while (!"Signup Node".equals(curNode.getStateName())); curNode = wiz.getStepByName("Non-existing node"); if (curNode != null) { System.out.println("\nFound node: " + curNode.getStateName()); } else { System.out.println("\nNot Found node: " + "Non-existing node"); } curNode = wiz.getStepByName("Details Node"); if (curNode != null) { System.out.println("Found node: " + curNode.getStateName()); } else { System.out.println("Not Found node: " + "Details node"); } curNode = wiz.getStepByName("Signup Node"); if (curNode != null) { System.out.println("Found node: " + curNode.getStateName()); } else { System.out.println("Not Found node: " + "Signup node"); } } /** * Traverses the wizard from the beginning to the end. Used for testing. * @param node node from which to start traversal */ public static void traverse(IWizardStep node) { IWizardTransition[] srcEdges = node.getOutgoingTransitions(); if (srcEdges == null || srcEdges.length ==0) { } else { for (int i = 0; i < srcEdges.length; i++) { System.out.println( "Edge Name: " + srcEdges[i].getName() + "\n\tSource node: " + srcEdges[i].getSource().getStateName() + "\n\tTarget node: " + srcEdges[i].getTarget().getStateName()); traverse(srcEdges[i].getTarget()); if (srcEdges[i].getSource() != node) { System.out.println("Edge " + srcEdges[i].getName() + " is incorrect"); } } } } } --- NEW FILE: StepConfirm.java --- /* * Copyright 2004-2005 Michael Jouravlev. * * 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 net.jspcontrols.dialogs.samples.wizard.rules; import net.jspcontrols.wizard.impl.WizardStep; import net.jspcontrols.dialogs.samples.wizard.accounts.UserAccounts; import net.jspcontrols.dialogs.samples.wizard.rules.SignupWizard; import java.util.Map; /** * Confirmation node of Signup wizard. Being the last node of the wizard, * it submits wizard data to user accounts storage. * * @version 0.1 * @author Michael Jouravlev */ public class StepConfirm extends WizardStep { /** * Creates Confirmation node * * @param value owner wizard object, used to reference wizard-wide * objects like error messages * @param name name of this node. Used to locate node by name, and * as mapping for JSP page */ public StepConfirm(SignupWizard value, String name) { super(value, name); } /** * Instructs the node to clear boolean values. Usually called * before the properties are about to be updated. */ public void resetBooleans() { /* no-op */ } } --- NEW FILE: StepDetails.java --- /* * Copyright 2004-2005 Michael Jouravlev. * * 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 net.jspcontrols.dialogs.samples.wizard.rules; import net.jspcontrols.wizard.impl.WizardStep; import net.jspcontrols.dialogs.samples.wizard.rules.SignupWizard; /** * Personalization node of Signup wizard. This is the second and optional node * of the wizard, allows a user to provide additional information like * favorite book and favorite movie * * @version 0.1 * @author Michael Jouravlev */ public class StepDetails extends WizardStep { /************************************************************************** * Business properties: favorite book and movie **************************************************************************/ private String[] securityQuestions = new String[] { "What is your favorite color?", "What is your home city?", "What is your pet's name?", "Who was your childhood hero?" }; public String[] getSecurityQuestions() {return securityQuestions;} /** * Returns security question as string */ public String getSecurityQuestion() { return isStateInPath() && securityAnswerId > -1 ? securityQuestions[securityAnswerId] : null; } /** * Id of security question, this is stored in database */ private int securityAnswerId = -1; /** * Returns id of security question */ public int getSecurityAnswerId() {return securityAnswerId;} /** * Sets security answer id * @param securityAnswerId security answer id */ public void setSecurityAnswerId(int securityAnswerId) { this.securityAnswerId = securityAnswerId; } /** * Additional user info: favorite book */ private String securityAnswer; /** * Returns user favorite book as part of personalization information, * only if the Personalization node is included in the actual path * of the wizard. * * @return favorite book */ public String getSecurityAnswer() {return isStateInPath() ? securityAnswer : null;} /** * Sets the favorite book as part of personalization information. * This method is not to be called by client. * * @param securityAnswer favorite user book */ public void setSecurityAnswer(String securityAnswer) {this.securityAnswer = securityAnswer;} /************************************************************************** * Constructor **************************************************************************/ /** * Creates Personalization node * * @param value owner wizard object, used to reference wizard-wide * objects, like error messages * @param name name of this node */ public StepDetails(SignupWizard value, String name) { super(value, name); } /** * Instructs the node to clear boolean values. Usually called * before the properties are about to be updated. */ public void resetBooleans() { /* no-op */ } } --- NEW FILE: StepSignup.java --- /* * Copyright 2004-2005 Michael Jouravlev. * * 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 net.jspcontrols.dialogs.samples.wizard.rules; import net.jspcontrols.wizard.impl.WizardStep; import net.jspcontrols.dialogs.samples.wizard.rules.SignupWizard; /** * Identification node of Signup wizard, the first node of the wizard. * it allows to enter name and password of a new user, and also to choose * an option to provide additional information (the information itself would * be provided on the second step: Personalization) * * @version 0.1 * @author Michael Jouravlev */ public class StepSignup extends WizardStep { /************************************************************************** * Business properties: name and password **************************************************************************/ /** * User name */ private String name; /** * Returns user name stored in the wizard * @return user name */ public String getName() {return name;} /** * Sets user name in the wizard * @param name user name to set in the wizard */ public void setName(String name) {this.name = name;} /** * User password */ private String password; /** * Returns user password stored in the wizard as cleartext. It is * up to the UI layer how to display it. */ public String getPassword() {return password;} /** * Sets user password in the wizard * @param password user password to set in the wizard */ public void setPassword(String password) { this.password = password; } /** * Repeated user password */ private String confirmPassword; /** * Returns repeated user password */ public String getConfirmPassword() {return confirmPassword;} /** * Sets repeated user password in the wizard * @param confirmPassword user password to set in the wizard */ public void setConfirmPassword(String confirmPassword) { this.confirmPassword = confirmPassword; } /************************************************************************** * Wizard flow control property **************************************************************************/ /** * Flag that user wants to supply additional information about himself */ private boolean personalize; /** * Returns true if personalization flag is set. This flag is used * to determine if wizard should display Personalization step. * @return true if a user selected to provide additional information * about himself. */ public boolean getPersonalize() {return personalize;} /** * Sets personalization flag. * @param personalize true if user wants to provide additional * information about himself. */ public void setPersonalize(boolean personalize) {this.personalize = personalize;} /************************************************************************** * Common validation method, called from outgoing edges **************************************************************************/ /** * Validates name and password. Validation is normally performed * in an outgoing edge, but this common functionality is used by * both outgoing edges. * * @return true if name and password conform to basic * name/password requirements */ public boolean validateNameAndPassword() { boolean valid = true; /* * User name should have length of at least three characters. * * We can also verify that login already exists, but this wizard * does it only when wizard is about to be finished, so if a user * cancels it in the middle, the persistent storage is not called. * * Notice typecast to SignupWizard, which defines getErrors() * method. */ if ( name == null || name.length() < 3 ) { valid = false; getWizard().getWizardErrors().put( "loginsignupcontrol.usernametooshort", new String[] {name} ); } /* * User password should have length of at least five characters */ if ( password == null || password.length() < 5 ) { valid = false; getWizard().getWizardErrors().put( "loginsignupcontrol.passwordtooshort", null ); /* * Repeated password should be equal to password */ } else if ( !password.equals(confirmPassword) ) { valid = false; getWizard().getWizardErrors().put( "loginsignupcontrol.passwordnotequal", null ); } return valid; } /************************************************************************** * Constructor **************************************************************************/ /** * Creates Signup node * * @param value owner wizard object, used to reference wizard-wide * objects like error messages * @param name name of this node */ public StepSignup(SignupWizard value, String name) { super(value, name); } /** * Instructs the node to clear boolean values. Usually called * before the properties are about to be updated. */ public void resetBooleans() { setPersonalize(false); } } |
From: <jm...@us...> - 2005-08-04 07:45:29
|
Update of /cvsroot/struts/dialogs/src/net/jspcontrols/dialogs/samples/wizard/signupsimple In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20952/src/net/jspcontrols/dialogs/samples/wizard/signupsimple Added Files: SignupFormSimple.java Log Message: --- NEW FILE: SignupFormSimple.java --- /* * Copyright 2004-2005 Michael Jouravlev * * 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 net.jspcontrols.dialogs.samples.wizard.signupsimple; import org.apache.struts.action.ActionMapping; import org.apache.struts.util.LabelValueBean; import net.jspcontrols.wizard.intf.IWizardListener; import net.jspcontrols.dialogs.samples.wizard.rules.SignupWizard; import net.jspcontrols.dialogs.samples.wizard.accounts.UserAccounts; import net.jspcontrols.dialogs.actions.wizard.WizardForm; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.ArrayList; /** * Wizard Manager for New User Signup wizard. Very compact, because uses * base WizardForm class. Uses standard WizardAction as dispatching action. * * @author Michael Jouravlev */ public class SignupFormSimple extends WizardForm implements IWizardListener { /************************************************************************** * Wizard Controller **************************************************************************/ /** * Returns aggregated wizard controller, typecast to concrete type. * Used to access properties of this from JSP page. */ public SignupWizard getSignupWizard() { return (SignupWizard) wizard; } /************************************************************************** * Session object is used as login storage and to access user accounts **************************************************************************/ /** * This demo uses session to store login info and to access user accounts. */ HttpSession session; /** * Returns current session. Used to access user accounts. */ public HttpSession getSession() { return session; } /************************************************************************** * Wizard lifecycle **************************************************************************/ /** * Disposes wizard and performs housekeeping tasks like removing messages, * event listeneres and other objects created by wizard. */ public void disposeWizard() { // Cleanup wizard super.disposeWizard(); // Remove combobox values session.removeAttribute("simple-signup-questions"); } /************************************************************************** * Implementing IWizardListener **************************************************************************/ /** * Fires event when wizard is about to move forward from current step. * * @param event IWizardListener.STEP_REGULAR if about to leave "middle" step, * IWizardListener.STEP_LAST if about to leave the final wizard * step, effectively finishing the wizard. * @return true if it is allowed to move to the next step, false if step * must not be changed. * @see IWizardListener#STEP_REGULAR * @see IWizardListener#STEP_LAST */ public boolean onTransition(int event) { // Not finishing wizard ==> not interested if (event != IWizardListener.STEP_LAST) return true; // Wizard is about to complete ==> store new user account if (UserAccounts.addUser( session, getSignupWizard().getStepSignup().getName(), getSignupWizard().getStepSignup().getPassword(), getSignupWizard().getStepDetails().getSecurityAnswerId(), getSignupWizard().getStepDetails().getSecurityAnswer(), true) ) return true; // Account was not stored ==> generate error, do not dispose wizard getWizardErrors().put("loginsignupcontrol.loginexists", new String[] {getSignupWizard().getStepSignup().getName()}); return false; } /************************************************************************** * ActionForm methods **************************************************************************/ /** * Resets action form. This method is called each time request is received. * Initialize wizard here if needed, and clear checkboxes. * * @param mapping The ActionMapping used to select this instance * @param request The HTTP request we are processing */ public void reset(ActionMapping mapping, HttpServletRequest request) { super.reset(mapping, request); // Session is used to store login name session = request.getSession(); // This wizard is not a control, it does not have stub pages. // So, initialize wizard each time user navigates to this action // and wizard controller does not exist yet. if (wizard == null) { // Create new Wizard Controller instance; // Use internal to Rule Engine object for error messages. wizard = new SignupWizard(null); // Use this action form as wizard event listener; // it stores account info in the account database when // wizard is about to finish. wizard.addListener(this); // Build combobox data fro wizard array data; // rule engine does not deal with types specific to Struts, // it returns a simple string array. ArrayList questions = new ArrayList(); String[] wizardQuestions = getSignupWizard().getStepDetails().getSecurityQuestions(); for (int i = 0; i < wizardQuestions.length; i++) { questions.add(new LabelValueBean(wizardQuestions[i], Integer.toString(i))); } // This is a combobox object for security question on second step. session.setAttribute( "simple-signup-questions", questions ); } } } |
From: <jm...@us...> - 2005-08-04 07:45:29
|
Update of /cvsroot/struts/dialogs/src/net/jspcontrols/dialogs/samples/wizard/signupfull In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20952/src/net/jspcontrols/dialogs/samples/wizard/signupfull Added Files: SignupForm.java Log Message: --- NEW FILE: SignupForm.java --- /* * Copyright 2004-2005 Michael Jouravlev * * 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 net.jspcontrols.dialogs.samples.wizard.signupfull; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.util.LabelValueBean; import net.jspcontrols.wizard.intf.IWizard; import net.jspcontrols.wizard.intf.IWizardListener; import net.jspcontrols.dialogs.actions.wizard.IWizardManager; import net.jspcontrols.dialogs.actions.wizard.WizardConstants; import net.jspcontrols.dialogs.samples.wizard.rules.SignupWizard; import net.jspcontrols.dialogs.samples.wizard.accounts.UserAccounts; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Map; import java.util.HashMap; import java.util.ArrayList; /** * Wizard Manager for New User Signup wizard. For simplicity, this action form * does not use base WizardForm. Uses standard WizardAction as dispatching action. * * @author Michael Jouravlev */ public class SignupForm extends ActionForm implements IWizardManager, IWizardListener { /************************************************************************** * Wizard Controller **************************************************************************/ /** * Aggregated wizard ontroller; must be set prior to populate phase */ private IWizard wizard; /** * Returns aggregated wizard controller, typecast to concrete type. * Used to access properties of this from JSP page. */ public SignupWizard getSignupWizard() { return (SignupWizard) wizard; } /** * Returns aggregated wizard controller as generic wizard. This method * is not used in this simple action form, it comes handy when * base WizardForm class is utilized. */ public IWizard getWizard() { return wizard; } /** * Returns errors accumulated by wizard during processing of input data. */ public Map getWizardErrors() { return wizard != null ? wizard.getWizardErrors() : new HashMap(); } /************************************************************************** * Session object is used as login storage and to access user accounts **************************************************************************/ /** * This demo uses session to store login info and to access user accounts. */ HttpSession session; /** * Returns current session. Used to access user accounts. */ public HttpSession getSession() { return session; } /************************************************************************** * Wizard Navigation **************************************************************************/ /** * Cancels wizard. * @return string mapping describing the after-cancel View */ public String wizardCancel() { disposeWizard(); return WizardConstants.MAPPING_ON_CANCEL; } /** * Tries to go one step back. Wizard does not allow to move past first * step. * @return string mapping describing the after-back View. * If successfully moved one step back, MAPPING_ON_BACK_SUCCESS * is returned. Otherwise, MAPPING_ON_BACK_FAILURE is returned. * @see WizardConstants#MAPPING_ON_BACK_SUCCESS * @see WizardConstants#MAPPING_ON_BACK_FAILURE */ public String wizardBack() { return wizard != null && wizard.back() ? WizardConstants.MAPPING_ON_BACK_SUCCESS : WizardConstants.MAPPING_ON_BACK_FAILURE; } /** * Tries to go one step forward. * @return string mapping describing the after-forward View * If successfully moved one step forward, and wizard is not finished * yet, MAPPING_ON_NEXT_SUCCESS is returned. If wizard was finished, * MAPPING_ON_DONE is returned. Otherwise, MAPPING_ON_NEXT_FAILURE * is returned. * @see WizardConstants#MAPPING_ON_NEXT_SUCCESS * @see WizardConstants#MAPPING_ON_NEXT_FAILURE * @see WizardConstants#MAPPING_ON_DONE */ public String wizardNext() { if (wizard != null && wizard.forward()) { if (wizard.isCompleted()) { disposeWizard(); return WizardConstants.MAPPING_ON_DONE; } else { return WizardConstants.MAPPING_ON_NEXT_SUCCESS; } } return WizardConstants.MAPPING_ON_NEXT_FAILURE; } /** * Disposes wizard and performs housekeeping tasks like removing messages, * event listeneres and other objects created by wizard. */ public void disposeWizard() { // Cleanup wizard if (wizard != null) { wizard.removeAllListeners(); wizard = null; } // Remove combobox values session.removeAttribute("simple-signup-questions"); } /** * Returns true if wizard was completed or was never instantiated; * after wizard completes, it should not be accessed anymore. */ public boolean isCompleted() { return wizard != null ? wizard.isCompleted() : true; } /** * Returns string mapping of the wizard page, corresponding to * current wizard state. By convention, uses the name of wizard step. * Always use unique names for wizard steps. */ public String getWizardView() { return wizard != null ? wizard.getCurrentStepName() : null; } /************************************************************************** * Implementing IWizardListener **************************************************************************/ /** * Fires event when wizard is about to move forward from current step. * * @param event IWizardListener.STEP_REGULAR if about to leave "middle" step, * IWizardListener.STEP_LAST if about to leave the final wizard * step, effectively finishing the wizard. * @return true if it is allowed to move to the next step, false if step * must not be changed. * @see IWizardListener#STEP_REGULAR * @see IWizardListener#STEP_LAST */ public boolean onTransition(int event) { // Not finishing wizard ==> not interested if (event != IWizardListener.STEP_LAST) return true; // Wizard is about to complete ==> store new user account if (UserAccounts.addUser( session, getSignupWizard().getStepSignup().getName(), getSignupWizard().getStepSignup().getPassword(), getSignupWizard().getStepDetails().getSecurityAnswerId(), getSignupWizard().getStepDetails().getSecurityAnswer(), true) ) return true; // Account was not stored ==> generate error, do not dispose wizard getWizardErrors().put("loginsignupcontrol.loginexists", new String[] {getSignupWizard().getStepSignup().getName()}); return false; } /************************************************************************** * ActionForm methods **************************************************************************/ /** * Resets action form. This method is called each time request is received. * Initialize wizard here if needed, and clear checkboxes. * * @param mapping The ActionMapping used to select this instance * @param request The HTTP request we are processing */ public void reset(ActionMapping mapping, HttpServletRequest request) { super.reset(mapping, request); // This form must have session scope to store CRUD data if (!"session".equalsIgnoreCase(mapping.getScope())) { throw new IllegalStateException("Action " + mapping.getPath() + "should have session scope"); } // Session is used to store login name session = request.getSession(); // This wizard is not a control, it does not have stub pages. // So, initialize wizard each time user navigates to this action // and wizard controller does not exist yet. if (wizard == null) { // Create new Wizard Controller instance; // Use internal to Rule Engine object for error messages. wizard = new SignupWizard(null); // Use this action form as wizard event listener; // it stores account info in the account database when // wizard is about to finish. wizard.addListener(this); // Build combobox data fro wizard array data; // rule engine does not deal with types specific to Struts, // it returns a simple string array. ArrayList questions = new ArrayList(); String[] wizardQuestions = getSignupWizard().getStepDetails().getSecurityQuestions(); for (int i = 0; i < wizardQuestions.length; i++) { questions.add(new LabelValueBean(wizardQuestions[i], Integer.toString(i))); } // This is a combobox object for security question on second step. session.setAttribute( "simple-signup-questions", questions ); } // Important: clear checkboxes for POST requests only! if ("POST".equalsIgnoreCase(request.getMethod())) { wizard.wizardReset(); } } } |