From: <jm...@us...> - 2005-07-11 06:07:50
|
Update of /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12571/src/documentation/content/xdocs/strutsdialogs Modified Files: index.xml Added Files: wizardaction.xml Log Message: --- NEW FILE: wizardaction.xml --- <?xml version="1.0"?> <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd"> <document> <header> <title>Struts Dialogs: WizardAction</title> </header> <body> <section id="overview"> <title>Overview</title> <p>WizardAction and a corresponding WizardForm provide integration of <link href="https://easywizard.dev.java.net">Easy Wizard</link> flow engine with Struts. Easy Wizard allows to create robust sequences of web pages, known as <em>wizards</em>.</p> <p>See this <link href="http://www.superinterface.com/strutsdialog/wizardaction.do">online demo</link>, which simulates a signup for a new user accout. Play with the wizard, try to refresh any page, to use browser navigation buttons, to go back and forward; leave the wizard, navigate somewhere else, then return back and check its state; try to cancel wizard, to start it again, to use invalid values, just try to break it. If you like what you see, read on.</p> <p>Easy Wizard has modular architecture and consists of two components: <em>Rule Engine</em> and <em>Wizard Manager</em>.</p> <ul> <li>Rule Engine has no user interface, and is portable across different presentation environments.</li> <li>Wizard Manager integrates Rule Engine with particular web framework.</li> </ul> <section id="ruleengine"> <title>Rule Engine</title> <p>Rule Engine is the core wizard component, which does not depend on a particular presentation framework. It can be built and tested in headless mode, using only standard Java SE classes.</p> <p>Rule Engine contains definitions of wizard steps and transitions, and is customized for every specific flow. Rule Engine interacts with Wizard Manager by means of <em>Wizard Controller</em> object.</p> </section> <section id="wizardmanager"> <title>Wizard Manager</title> <p>Wizard Manager is the component, which adapts Rule Engine to a particular web framework. Easy Wizard provides a custom Wizard Manager for every framework it supports. The task of Wizard Manager is to accept input from a user and to render wizard pages.</p> </section> <figure src="images/wizard_arch_struts.gif" alt="Easy Wizard architecture"/> <section id="integration"> <title>Integration with Struts</title> <p>WizardAction and WizardForm classes provide functionality of a Wizard Manager. They handle requests and responses, accept user input, dispatch input event and data to the Rule Engine, collects error messages and display a page, appropriate to current wizard state.</p> <p>WizardAction channels user commands to Wizard Controller. If Forward transition was requested, Wizard Controller validates all outgoing transitions for current step, and chooses a valid one. Wizard Controller changes the state of Rule Engine and returns back error messages if any.</p> <p>After receiving result from Wizard Controller, WizardAction selects a proper page to display according to current state of Rule Engine.</p> </section> </section> <section id="creating"> <title>Creating a wizard</title> <p>To create a wizard you need to peform two steps:</p> <ul> <li>Define wizard rules by customizing Rule Engine</li> <li>Define interaction with a user by creating custom Wizard Manager</li> </ul> <p>To accomplish first task, please consult <link href="http://wiki.java.net/bin/view/Projects/EasyWizard">Easy Wizard project</link> and <link href="http://wiki.java.net/bin/view/Projects/EasyWizardDocumentation">Easy Wizard documentation</link>.</p> <p>You do not need to download Easy Wizard separately. You will find all source code in Struts Dialogs distribution. Easy Wizard source code in src\org\superinterface\wizard directory, WizardAction and WizardForm in src\net\sf\dialogs\actions\wizard directory, and Signup Wizard sample code in src\net\sf\dialogs\samples\wizardaction directory.</p> <p>The rest of this document describes how to create a Wizard Manager using WizardAction and WizardForm, and how to integrate it with Rule Engine that you should have developed beforehand.</p> </section> <section id="accessing"> <title>Accessing Rule Engine from Struts</title> <p>Considering, that you have already created a custom Rule Engine for Signup Wizard, we will now integrate it with Struts.</p> <p>To store and access Rule Engine you need to use an action form, which implements <code>IWizardManager</code> interface. This interface has the following methods:</p> <ul> <li><code>Map getWizardErrors();</code> - returns errors, accumulated by wizard during processing of input data.</li> <li><code>String wizardCancel();</code> - cancels wizard.</li> <li><code>String wizardBack();</code> - moves one step back if possible.</li> <li><code>String wizardNext();</code> - moves one step forward if possible.</li> <li><code>void disposeWizard();</code> - disposes wizard and performs housekeeping tasks.</li> <li><code>boolean isCompleted();</code> - returns true if wizard was completed or was never instantiated.</li> <li><code>String getWizardView();</code> - returns string mapping of a wizard page, corresponding to current wizard state. By convention, a wizard step is used as page mapping.</li> </ul> <p>The easiest way to use <code>IWizardManager</code> is to employ predefined <code>WizardForm</code> class, which already implements this interface.</p> </section> <section id="wizardform"> <title>Using WizardForm</title> <p>First thing you need to do is to decide how you are going to instantiate and initialize the Wizard Controller. The easiest way is to do it in the <code>reset()</code> method. The following code uses protected field <code>wizard</code>, defined in WizardForm. Direct access to this field seems easier than using method like <code>getWizard</code>.</p> <source> public void reset(ActionMapping mapping, HttpServletRequest request) { // Do not forget to call superclass super.reset(mapping, request); // This wizard does not have stub pages, thus initialize it every time // a user navigates to this action and wizard controller does not exist. 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); } } </source> <p>To provide access to fields of your wizard you need to define a getter for a concrete Wizard Controller:</p> <source> public SignupWizard getSignupWizard() { return (SignupWizard) wizard; } </source> <p>Another thing you are likely to do is to define a listener for wizard forward/back operations by implementing IWizardListener interface. This allows you to catch the event when wizard is about to change state, so you can to prevent the state change if needed. For example, the following code saves new user name and password into user accout table, when wizard is about to finish. If username and password cannot be persisted, error message is generated and wizard is not allowed to finish.</p> <source> public boolean onTransition(int event) { // Not finishing wizard yet ==> 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.persisterror", new String[] {getSignupWizard().getStepSignup().getName()}); return false; } </source> <p>That is all for integrating Wizard Controller. All is left is to define an action mapping for the wizard in <code>struts-config.xml</code> file.</p> </section> <section id="keysandmappings"> <title>Wizard events and return mappings</title> <p>WizardAction defines the following user event keys and method handler names:</p> <p>"DIALOG-EVENT-CANCEL" --> <code>onCancel</code><br/> Cancel wizard; assigned to "Cancel" button.</p> <p>"DIALOG-EVENT-BACK" --> <code>onBack</code><br/> Tries to move one step back; assigned to "Back" or "Previous" button.</p> <p>"DIALOG-EVENT-NEXT" --> <code>onNext</code><br/> Tries to move one step forward or to finish a wizard, if current page is the last page of the wizard; assigned to "Back" or "Forward" or "Done" button.</p> <p>WizardConstants class defines the following view mappings used to select destination after a user event was processed, and wizard state was updated:</p> <p>String MAPPING_ON_CANCEL = "ON-CANCEL";<br/> Wizard was canceled by user.</p> <p>String MAPPING_ON_DONE = "ON-DONE";<br/> Wizard successfully finished.</p> <p>String MAPPING_ON_BACK_SUCCESS = "ON-BACK-SUCCESS";<br/> Wizard moved one step back.</p> <p>String MAPPING_ON_BACK_FAILURE = "ON-BACK-FAILURE";<br/> Failed to move one step back.</p> <p>String MAPPING_ON_NEXT_SUCCESS = "ON-NEXT-SUCCESS";<br/> Successfully moved one step forward, but not finished yet.</p> <p>String MAPPING_ON_NEXT_FAILURE = "ON-NEXT-FAILURE";<br/> Failed to move to next step.</p> <p>Below is the definition of wizard action mapping.</p> <source> <action path="/wizardaction" type = "net.sf.dialogs.actions.wizard.WizardAction" name = "wizardform" scope = "session" validate = "false" parameter = "DIALOG-EVENT"> <!-- Where to hand control over after input phase (POST) --> <forward name="MAPPING_ON_BACK_SUCCESS" path="/wizardaction.do" redirect="true"/> <forward name="MAPPING_ON_BACK_FAILURE" path="/wizardaction.do" redirect="true"/> <forward name="MAPPING_ON_NEXT_SUCCESS" path="/wizardaction.do" redirect="true"/> <forward name="MAPPING_ON_NEXT_FAILURE" path="/wizarderroraction.do" redirect="true"/> <forward name="ON-CANCEL" path="/allsamples.html" redirect="true"/> <forward name="ON-DONE" path="/wizard-userpage.jsp" redirect="true"/> <!-- Which page to load on the output phase or on refresh (GET) --> <forward name="Signup Node" path="/wizard-signupstart.jsp"/> <forward name="Details Node" path="/wizard-signupdetails.jsp"/> <forward name="Confirmation Node" path="/wizard-signupconfirm.jsp"/> </action> <action path="/wizarderroraction" forward="/wizard-error.jsp"/> </source> </section> <section id="samplecode"> <title>Sample code</title> <p>See full source code of user signup wizard in src\net\sf\dialogs\samples\wizardaction\wizardsubclassed directory of the downloaded code.</p> </section> <section id="livedemo"> <title>Live Demo</title> <p>See <link href="http://www.superinterface.com/strutsdialog/wizardaction.do">live demo of signup wizard</link>.</p> </section> </body> </document> Index: index.xml =================================================================== RCS file: /cvsroot/struts/struts-site/src/documentation/content/xdocs/strutsdialogs/index.xml,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** index.xml 29 Jun 2005 22:51:33 -0000 1.6 --- index.xml 11 Jul 2005 06:07:37 -0000 1.7 *************** *** 89,114 **** 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>WizardAction allows to create web wizards, 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> ! <p>WizardAction is built on top of <link href="https://easywizard.dev.java.net">Easy Wizard</link>. ! To create your own wizard you need to peform two steps. ! First is to ! <link href="http://today.java.net/pub/a/today/2005/03/15/webwizard1.htm">define wizard rules</link>. ! Then you will need to create Wizard UI Manager, see description of WizardAction for details.</p> ! </section> ! --> ! <section id="actions"> ! <title>Links to action classes</title> ! <ul> ! <li><link href="selectaction.html">SelectAction</link></li> ! <li><link href="dialogaction.html">DialogAction</link></li> ! <li><link href="crudaction.html">CRUDAction</link></li> ! </ul> </section> </body> </document> --- 89,112 ---- 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"> ! <title>Live Demos</title> ! <p>Each action class from Struts Dialogs library is illustrated with sample code and ! <link href="http://www.superinterface.com/strutsdialog">live demos</link>.</p> ! </section> ! ! <section id="download"> ! <title>Download</title> ! <p>Download Struts Dialogs 1.2 version from ! <link href="http://sourceforge.net/project/showfiles.php?group_id=49385&release_id=338164">SourceForge website</link>.</p> </section> + </body> </document> |