Update of /cvsroot/struts/dialogs/src/net/jspcontrols/dialogs/actions/wizard In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12963/src/net/jspcontrols/dialogs/actions/wizard Added Files: IWizardManager.java WizardAction.java WizardConstants.java WizardForm.java Log Message: --- NEW FILE: IWizardManager.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.actions.wizard; import java.util.Map; /** * Wizard Manager interface. Used by web framework to manipulate wizard * rule engine. * * @author Michael Jouravlev */ public interface IWizardManager { /** * Returns errors accumulated by wizard during processing of input data. */ Map getWizardErrors(); /** * Cancels wizard. * @return string mapping describing the after-cancel View */ String wizardCancel(); /** * 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 */ String wizardBack(); /** * 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 */ String wizardNext(); /** * Disposes wizard and performs housekeeping tasks like removing messages, * event listeneres and other objects created by wizard. */ void disposeWizard(); /** * Returns true if wizard was completed or was never instantiated; * after wizard completes, it should not be accessed anymore. */ boolean isCompleted(); /** * 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. */ String getWizardView(); } --- NEW FILE: WizardAction.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.actions.wizard; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; import java.util.HashMap; import java.util.Iterator; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMessages; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionMessage; import org.apache.struts.Globals; import net.jspcontrols.dialogs.actions.DialogAction; /** * Basic wizard action. Implements back, forward and cancel method handlers. * Works in pair with action form, implementing IWizardManager interface. * * @author Michael Jouravlev */ public class WizardAction extends DialogAction { /************************************************************************** * Input events **************************************************************************/ /** * Returns the initialization key or initialization prefix. * Must start with the same prefix as dialog buttons. For example, * if dialog buttons start with "DIALOG-EVENT", then "DIALOG-EVENT-INIT" * is a good name for initilization key, while "DIALOG-INIT" is not. */ protected String getInitKey() { return "DIALOG-EVENT-INIT"; } /** * Maps submit button names to handler methods; also maps initialization * keys to initialization methods. Events, external to CRUDAction, * are considered initializing events, and therefore must start with * initialization prefix. For example, if initialization prefix * starts with "DIALOG-EVENT-INIT", then "DIALOG-EVENT-INIT-CREATE" * is a good key for "Create new business object" event, while * "DIALOG-EVENT-CREATE" is not. * <p> * If you do not want to use all CRUD handlers, and want to protect * yourself from calling unneeded handler, you can subclass this class, * and override this method. Then you define only mappings that you need. * @see WizardAction#getInitKey */ protected Map getKeyMethodMap() { Map map = new HashMap(); // Cancel viewing or editing of current item map.put("DIALOG-EVENT-CANCEL", "onCancel"); // Persist changes of current item map.put("DIALOG-EVENT-BACK", "onBack"); // Close preview mode of existing item map.put("DIALOG-EVENT-NEXT", "onNext"); return map; } /************************************************************************** * Wizard navigation methods **************************************************************************/ /** * Handles "Cancel" button on wizard panel. Commonly, ActionForward object * returned by this handler redirects outside the wizard. * * @param mapping The ActionMapping used to select this instance * @param form The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception java.lang.Exception if an exception occurs * @return ActionForward object, describing where to go next */ public ActionForward onCancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // Cancel wizard and move to after-cancel location return mapping.findForward(((IWizardManager)form).wizardCancel()); } /** * Handles "Back" button on wizard panel. ActionForward object * returned by this handler must redirect back to the wizard. * This allows to display a View corresponding to current wizard state. * * @param mapping The ActionMapping used to select this instance * @param form The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception java.lang.Exception if an exception occurs * @return ActionForward object, redirecting back to the wizard */ public ActionForward onBack(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // Try to go back one step, and move to actual location return mapping.findForward(((IWizardManager)form).wizardBack()); } /** * Handles "Back" button on wizard panel. ActionForward object * returned by this handler must redirect back to the wizard. * This allows to display a View corresponding to current wizard state. * * @param mapping The ActionMapping used to select this instance * @param form The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception java.lang.Exception if an exception occurs * @return ActionForward object, redirecting back to the wizard */ public ActionForward onNext(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // Try to go forward one step, and move to corresponding location return mapping.findForward(((IWizardManager)form).wizardNext()); } /** * Returns an <code>ActionForward</code> instance describing the View * for current dialog state, usually a forward to a JSP page. * * @param mapping The ActionMapping used to select this instance * @param form The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception java.lang.Exception if an exception occurs * @return ActionForward instance describing the View for dialog state */ public ActionForward getDialogView(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // CRUDAction works with form beans, implementing ICRUDForm IWizardManager wizardForm = (IWizardManager) form; // Store errors in the request for standard processing Map errors = wizardForm.getWizardErrors(); ActionMessages messages = getStrutsErrors(errors); request.setAttribute(Globals.ERROR_KEY, messages); // Show appropriate page String strMapping = wizardForm.getWizardView(); return mapping.findForward(strMapping); } /************************************************************************** * Helper methods **************************************************************************/ /** * Pulls errors found during wizard transition from wizard into * Struts error object. * * @param uiErrors map of errors, where key is an error message, * and value is error parameters as string array * @return errors in Struts format */ public static ActionErrors getStrutsErrors(Map uiErrors) { if (uiErrors == null || uiErrors.isEmpty()) return null; Iterator errIterator = uiErrors.keySet().iterator(); ActionErrors actionErrors = new ActionErrors(); while (errIterator.hasNext()) { String errKey = (String) errIterator.next(); String[] errMessage = (String[]) uiErrors.get(errKey); actionErrors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(errKey, errMessage)); } return actionErrors; } } --- NEW FILE: WizardConstants.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.actions.wizard; /** * Wizard constants, used by WizardAction and IWizardManager. * * @author Michael Jouravlev */ public interface WizardConstants { /************************************************************************** * First phase mappings: where to go after input data processed *************************************************************************/ /** * Canceled wizard */ String MAPPING_ON_CANCEL = "ON-CANCEL"; /** * Finished wizard. Same as MAPPING_ON_NEXT_SUCCESS, but wizard * reached its last step and was disposed. * @see WizardConstants#MAPPING_ON_NEXT_SUCCESS */ String MAPPING_ON_DONE = "ON-DONE"; /** * Successfully moved one step back */ String MAPPING_ON_BACK_SUCCESS = "ON-BACK-SUCCESS"; /** * Failed to move one step back */ String MAPPING_ON_BACK_FAILURE = "ON-BACK-FAILURE"; /** * Successfully moved one step forward, but not finished * @see WizardConstants#MAPPING_ON_DONE */ String MAPPING_ON_NEXT_SUCCESS = "ON-NEXT-SUCCESS"; /** * Failed to move to next step */ String MAPPING_ON_NEXT_FAILURE = "ON-NEXT-FAILURE"; } --- NEW FILE: WizardForm.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.actions.wizard; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import net.jspcontrols.wizard.intf.IWizard; import net.jspcontrols.dialogs.actions.wizard.IWizardManager; import net.jspcontrols.dialogs.actions.wizard.WizardConstants; import javax.servlet.http.HttpServletRequest; import java.util.Map; import java.util.HashMap; /** * Base wizard form. Custom wizard implementation can either (1) extend * basic ActionForm class and implement IWizardManager interface, * or (2) extend this predefined wizard form. */ public class WizardForm extends ActionForm implements IWizardManager { /************************************************************************** * Wizard Controller **************************************************************************/ /** * Wizard controller; must be set prior to populate phase */ protected IWizard wizard; /** * Returns errors accumulated by wizard during processing of input data. */ public Map getWizardErrors() { return wizard != null ? wizard.getWizardErrors() : new HashMap(); } /************************************************************************** * 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 net.jspcontrols.dialogs.actions.wizard.WizardConstants#MAPPING_ON_BACK_SUCCESS * @see net.jspcontrols.dialogs.actions.wizard.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 net.jspcontrols.dialogs.actions.wizard.WizardConstants#MAPPING_ON_NEXT_SUCCESS * @see net.jspcontrols.dialogs.actions.wizard.WizardConstants#MAPPING_ON_NEXT_FAILURE * @see net.jspcontrols.dialogs.actions.wizard.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; } } /** * 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; } /************************************************************************** * 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"); } // Important: clear checkboxes for POST requests only! if (wizard != null && "POST".equalsIgnoreCase(request.getMethod())) { wizard.wizardReset(); } } } |