View Javadoc

1   /* ===================================================================
2    * Copyright 2002-04 SRI International.
3    * Released under the MOZILLA PUBLIC LICENSE Version 1.1
4    * which can be obtained at http://www.mozilla.org/MPL/MPL-1.1.html
5    * This software is distributed on an "AS IS"
6    * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
7    * See the License for the specific language governing rights and
8    * limitations under the License.
9    * =================================================================== */
10  
11  package com.sri.emo.wizard.selection.management;
12  
13  import com.jcorporate.expresso.core.controller.*;
14  import com.jcorporate.expresso.core.db.DBConnection;
15  import com.jcorporate.expresso.core.db.DBConnectionPool;
16  import com.jcorporate.expresso.core.db.DBException;
17  import com.jcorporate.expresso.core.dbobj.DBObject;
18  import com.jcorporate.expresso.core.security.SuperUser;
19  import com.sri.common.controller.StateHandler;
20  import com.sri.emo.EmoSchema;
21  import com.sri.emo.controller.EmoAction;
22  import com.sri.emo.controller.SelectionWizardManager;
23  import com.sri.emo.dbobj.StepAttributes;
24  import com.sri.emo.dbobj.WizDecisionSet;
25  import com.sri.emo.dbobj.WizStep;
26  import com.sri.emo.wizard.expressoimpl.WizardController;
27  
28  import javax.servlet.ServletException;
29  import java.io.IOException;
30  import java.util.Iterator;
31  import java.util.List;
32  
33  /***
34   * Controller that manages Wizard Steps.  Due to the nature of the embedded
35   * state handlers, in most cases, this controller is nothing more than a <tt>Mediator</tt>
36   * of the state handlers, dispatching requests to the appropriate class.
37   * <p> A controller is a rough model of a finite state machine for a web application.
38   * Each state provides user interaction elements that can be rendered in a web
39   * page or other medium such as a command line app.</p>
40   */
41  
42  public class WizardStepController extends EmoAction {
43  
44  
45      /***
46  	 * 
47  	 */
48  	private static final long serialVersionUID = 1L;
49  
50  	/***
51       * Constant for access to state: Save Add.
52       */
53      public static final String STATE_DO_ADD = "doAdd";
54  
55      /***
56       * Constant for access to state: Delete Step.
57       */
58      public static final String STATE_DO_DELETE = "doDelete";
59  
60      /***
61       * Constant for access to state: Order Up.
62       */
63      public static final String STATE_ORDERUP = "orderUp";
64  
65      /***
66       * Constant for access to state: Order Down.
67       */
68      public static final String STATE_ORDERDOWN = "orderDown";
69  
70  
71      /***
72       * Constant for access to state: Edit Step.
73       */
74      public static final String STATE_PROMPT_EDIT = "promptEdit";
75  
76  
77      /***
78       * Constant for access to state: Save Edit.
79       */
80      public static final String STATE_DO_EDIT = "doEdit";
81  
82  
83      /***
84       * Constant for access to state: Prompt Delete.
85       */
86      public static final String STATE_PROMPT_DELETE = "promptDelete";
87  
88  
89      /***
90       * Constant for access to state: Do Select Step Type
91       */
92      public static final String STATE_DO_SELECT_STEP_TYPE = "doSelectStepType";
93  
94      /***
95       * Constant for parameter name 'model id'.
96       */
97      public static final String PARAM_MODEL_ID = "ModelId";
98  
99  
100     /***
101      * Creates an instance of WizardStepController.  The Controller constructor also defines
102      * what states and parameters are officially defined by the Controller.
103      */
104     public WizardStepController() {
105         State s;
106 
107         s = new State(STATE_DO_ADD, "Complete Adding Step");
108         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
109         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
110         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
111         addState(s);
112 
113         s = new State(STATE_PROMPT_DELETE, "Prompt Delete Step");
114         s.addParameter(WizStep.FLD_ID, true, DBObject.INT_MASK);
115 
116         s = new State(STATE_PROMPT_DELETE, "Prompt Delete Step");
117         s.addParameter(WizStep.FLD_ID, true, DBObject.INT_MASK);
118         addState(s);
119 
120         s = new State(STATE_DO_DELETE, "Delete Step");
121         s.addParameter(WizStep.FLD_ID, true, DBObject.INT_MASK);
122         addState(s);
123 
124         s = new State(STATE_ORDERUP, "Order Up");
125         s.addParameter(WizStep.FLD_ID, true, DBObject.INT_MASK);
126         addState(s);
127 
128         s = new State(STATE_ORDERDOWN, "Order Down");
129         s.addParameter(WizStep.FLD_ID, true, DBObject.INT_MASK);
130         addState(s);
131 
132         s = new State(STATE_PROMPT_EDIT, "Edit Step");
133         s.addParameter(WizStep.FLD_ID, true, DBObject.INT_MASK);
134         addState(s);
135 
136         s = new State(STATE_DO_EDIT, "Complete Editing Step");
137         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
138         s.addParameter(WizStep.FLD_WIZID, false, DBObject.INT_MASK);
139         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
140         addState(s);
141 
142         s = new State(PromptSelectModel.STATE_NAME, PromptSelectModel.STATE_DESCRIPTION);
143         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
144         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
145         s.addParameter(StepAttributes.ATTRIBUTE_MODEL, false, DBObject.INT_MASK);
146         addState(s);
147 
148         s = new State(PromptStepType.STATE_NAME, PromptStepType.STATE_DESCRIPTION);
149         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
150         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
151         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
152         addState(s);
153 
154         s = new State(STATE_DO_SELECT_STEP_TYPE, "Do Select Step Type");
155         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
156         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
157         s.addParameter(WizStep.FLD_STEP_TYPE, true, DBObject.INT_MASK);
158         addState(s);
159 
160         //Add Prompt Instructions State
161         s = new State(PromptInstructions.STATE_NAME, PromptInstructions.STATE_DESCRIPTION);
162         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
163         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
164         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
165         addState(s);
166 
167         //Add Prompt Model Field State
168         s = new State(PromptModelField.STATE_NAME, PromptModelField.STATE_DESCRIPTION);
169         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
170         s.addParameter(WizStep.FLD_WIZID, DBObject.INT_MASK);
171         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
172         s.addParameter(StepAttributes.ATTRIBUTE_MODEL, false, DBObject.INT_MASK);
173         s.addParameter(StepAttributes.ATTRIBUTE_MODEL_FIELD, false, DBObject.INT_MASK);
174         addState(s);
175 
176         //Add Prompt Text Entry Style State
177         s = new State(PromptTextEntry.STATE_NAME, PromptTextEntry.STATE_DESCRIPTION);
178         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
179         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
180         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
181         addState(s);
182 
183         //Add Prompt Node Instance State
184         s = new State(PromptNodeInstance.STATE_NAME, PromptNodeInstance.STATE_DESCRIPTION);
185         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
186         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
187         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
188         addState(s);
189 
190         //Add Prompt Per-Node Attribute Picklist State
191         s = new State(PromptNodeAttribute.STATE_NAME, PromptNodeAttribute.STATE_DESCRIPTION);
192         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
193         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
194         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
195         s.addParameter(StepAttributes.ATTRIBUTE_INSTANCE_ID, false, DBObject.INT_MASK);
196         addState(s);
197 
198         //Add Prompt Custom Picklist
199         s = new State(PromptPicklist.STATE_NAME, PromptPicklist.STATE_DESCRIPTION);
200         s.addParameter(WizStep.FLD_ID, false, DBObject.INT_MASK);
201         s.addParameter(WizStep.FLD_WIZID, true, DBObject.INT_MASK);
202         s.addParameter(WizStep.FLD_STEP_TYPE, false, DBObject.INT_MASK);
203         addState(s);
204 
205         setInitialState(PromptStepType.STATE_NAME);
206         setSchema(EmoSchema.class);
207     }
208 
209 
210     /***
211      * Runs the Commit 'Add Step' state.
212      *
213      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
214      *                 The ControllerRequest contains all the parameters such as web parameters, user
215      *                 security credentials and user locale
216      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
217      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
218      *                 for ths sytem.
219      * @throws ControllerException    upon error
220      * @throws NonHandleableException upon fatal error
221      * @throws ServletException       upon Servlet Forward error.
222      * @throws IOException            if client connection was lost.
223      */
224     protected void runDoAddState(final ServletControllerRequest request,
225                                  final ControllerResponse response)
226             throws ControllerException, NonHandleableException, ServletException, IOException {
227         try {
228 
229             StepParameterParser parser = new StepParameterParser(request);
230             ErrorCollection ec = request.getErrorCollection();
231             if (ec == null) {
232                 ec = new ErrorCollection();
233             }
234 
235             WizStep step = parser.parseAndValidate(ec);
236 
237             if (ec.getErrorCount() > 0) {
238                 if (getLogger().isDebugEnabled()) {
239                     getLogger().debug("Errors in error collection: " + ec.getErrorCount()
240                             + " errors.");
241                 }
242 
243                 response.setFormCache();
244                 response.saveErrors(ec);
245                 dispatchToEditScreen(request, response, step.getType());
246                 return;
247             }
248 
249             step.add();
250             if (getLogger().isInfoEnabled()) {
251                 getLogger().info("Step added, all decision matrix entries deleted.");
252             }
253 
254             redirectAfterSave(request, response, step);
255 
256         } catch (DBException ex) {
257             throw new ControllerException("Database Error", ex);
258         }
259 
260     }
261 
262     /***
263      * Forces a delete of the entire decision matrix.
264      *
265      * @param transaction DBConnection The current transaction.
266      * @param request     ControllerRequest the source of the wizard parameter.
267      * @throws DBException upon error.
268      */
269     private void deleteEntireDecisionMatrix(final DBConnection transaction, final ControllerRequest request) throws
270             DBException {
271         WizDecisionSet decisionMatrix = new WizDecisionSet(transaction,
272                 SuperUser.INSTANCE.getUid());
273         decisionMatrix.setWizardId(Integer.parseInt(request
274                 .getParameter(WizStep.FLD_WIZID)));
275         decisionMatrix.deleteAll();
276     }
277 
278 
279     /***
280      * Runs the Commit 'Edit Step' state.
281      *
282      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
283      *                 The ControllerRequest contains all the parameters such as web parameters, user
284      *                 security credentials and user locale
285      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
286      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
287      *                 for ths sytem.
288      * @throws ControllerException    upon error
289      * @throws NonHandleableException upon fatal error
290      * @throws ServletException       upon Servlet Forward error.
291      * @throws IOException            if client connection was lost.
292      */
293     protected void runDoEditState(final ServletControllerRequest request,
294                                   final ControllerResponse response)
295             throws ControllerException, NonHandleableException, ServletException, IOException {
296         try {
297             StepParameterParser parser = new StepParameterParser(request);
298             ErrorCollection ec = request.getErrorCollection();
299             if (ec == null) {
300                 ec = new ErrorCollection();
301             }
302             WizStep step = parser.parseAndValidate(ec);
303 
304             if (ec.getErrorCount() > 0) {
305                 if (getLogger().isDebugEnabled()) {
306                     getLogger().debug("Errors in error collection: " + ec.getErrorCount()
307                             + " errors.");
308                 }
309 
310                 response.setFormCache();
311                 response.saveErrors(ec);
312                 dispatchToEditScreen(request, response, step.getType());
313                 return;
314             }
315 
316             boolean mustDelDecisionMatrix = step.shouldUpdateDecisionMatrix();
317 
318             DBConnection transaction = DBConnectionPool.getInstance(request.getDataContext())
319                     .getConnection("Edit Wizard Step");
320             try {
321                 transaction.setAutoCommit(false);
322                 step.setConnection(transaction);
323                 step.update();
324 
325                 if (mustDelDecisionMatrix) {
326                     deleteEntireDecisionMatrix(transaction, request);
327                 }
328 
329                 if (getLogger().isInfoEnabled()) {
330                     getLogger().info("Step edited, all decision matrix entries deleted.");
331                 }
332                 transaction.commit();
333             } catch (DBException ex) {
334                 transaction.rollback();
335                 throw new ControllerException("Database Access Error", ex);
336             } finally {
337                 transaction.release();
338             }
339 
340             redirectAfterSave(request, response, step);
341         } catch (DBException ex) {
342             throw new ControllerException("Database Error", ex);
343         }
344     }
345 
346     /***
347      * Redirects to the list wizard state when a save of a step is complete.
348      *
349      * @param request  the ControllerRequest object
350      * @param response the ControllerResponse object
351      * @param step     the object that we just saved.
352      * @throws ControllerException upon transition error.
353      * @throws DBException         upon database getField() error.
354      */
355     protected void redirectAfterSave(final ControllerRequest request,
356                                      final ControllerResponse response,
357                                      final WizStep step) throws
358             ControllerException, DBException {
359         Transition complete = new Transition();
360         complete.setControllerObject(SelectionWizardManager.class);
361         complete.setState(SelectionWizardManager.STATE_PROMPT_EDIT);
362         complete.addParam(WizardController.WIZ_PARAMETER_ID, step.getWizId());
363         complete.redirectTransition(request, response);
364     }
365 
366 
367     /***
368      * Runs the Delete Step state.
369      *
370      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
371      *                 The ControllerRequest contains all the parameters such as web parameters, user
372      *                 security credentials and user locale
373      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
374      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
375      *                 for ths sytem.
376      * @throws ControllerException    upon error
377      * @throws NonHandleableException upon fatal error
378      */
379     protected void runDoDeleteState(final ControllerRequest request,
380                                     final ControllerResponse response) throws ControllerException,
381             NonHandleableException {
382         try {
383             WizStep step = retrieveWizStep(request);
384             step.delete();
385 
386             Transition redirect = new Transition("next", "next", SelectionWizardManager.class,
387                     SelectionWizardManager.STATE_PROMPT_EDIT);
388             redirect.addParam(WizardController.WIZ_PARAMETER_ID,
389                     step.getWizId());
390             redirect.redirectTransition(request, response);
391 
392         } catch (DBException ex) {
393             throw new ControllerException("Database Error retrieving step.", ex);
394         }
395 
396     }
397 
398 
399     /***
400      * Helper function to retrieve the WizStep object from the controller
401      * request.
402      *
403      * @param request the controller request object
404      * @return instantiated WizStep instance.
405      * @throws DBException         upon database retrieval error.
406      * @throws ControllerException upon controller element related error.
407      */
408     protected WizStep retrieveWizStep(final ExpressoRequest request) throws DBException, ControllerException {
409         int stepId = Integer.parseInt(request.getParameter(WizStep.FLD_ID));
410         WizStep step = new WizStep();
411         step.setId(stepId);
412         step.retrieve();
413         return step;
414     }
415 
416     /***
417      * Runs the Prompt Delete Step state.
418      *
419      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
420      *                 The ControllerRequest contains all the parameters such as web parameters, user
421      *                 security credentials and user locale
422      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
423      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
424      *                 for ths sytem.
425      * @throws ControllerException    upon error
426      * @throws NonHandleableException upon fatal error
427      */
428     protected void runPromptDeleteState(final ExpressoRequest request, final ExpressoResponse response) throws
429             ControllerException,
430             NonHandleableException {
431         try {
432             response.setTitle("Confirm Delete Step");
433             WizStep step = retrieveWizStep(request);
434             response.add(new Output("prompt", step.getTitle()));
435 
436             Transition yes = new Transition("yes", "yes", WizardStepController.class, STATE_DO_DELETE);
437             yes.addParam(WizStep.FLD_ID, request.getParameter(WizStep.FLD_ID));
438             response.add(yes);
439 
440             Transition no = new Transition("no", "no", SelectionWizardManager.class,
441                     SelectionWizardManager.STATE_PROMPT_EDIT);
442             no.addParam(WizardController.WIZ_PARAMETER_ID, step.getWizId());
443             response.add(no);
444         } catch (DBException ex) {
445             throw new ControllerException("Database Error retrieving step.", ex);
446         }
447     }
448 
449     /***
450      * Runs the Order Up state.
451      *
452      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
453      *                 The ControllerRequest contains all the parameters such as web parameters, user
454      *                 security credentials and user locale
455      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
456      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
457      *                 for ths sytem.
458      * @throws ControllerException    upon error
459      * @throws NonHandleableException upon fatal error
460      */
461     protected void runOrderUpState(final ControllerRequest request,
462                                    final ControllerResponse response) throws ControllerException,
463             NonHandleableException {
464         try {
465             String wizardId = request.getParameter(WizardController.
466                     WIZ_PARAMETER_ID);
467             String stepId = request.getParameter(WizStep.FLD_ID);
468 
469             WizStep changeStep = new WizStep();
470             changeStep.setId(stepId);
471             changeStep.retrieve();
472 
473             WizStep allSteps = new WizStep();
474             allSteps.setWizId(wizardId);
475             List result = allSteps.searchAndRetrieveList(WizStep.FLD_ORDER);
476             if (result.size() == 0) {
477                 throw new ControllerException("No Steps Found");
478             }
479 
480             if (result.size() == 1) {
481                 throw new ControllerException("Cannot change order on a single size list");
482             }
483 
484             boolean foundMatch = false;
485             WizStep previousStep = null;
486             WizStep currentStep = null;
487             for (Iterator i = result.iterator(); i.hasNext();) {
488                 WizStep oneStep = (WizStep) i.next();
489                 if (previousStep == null) {
490                     if (stepId.equals(oneStep.getId())) {
491                         throw new ControllerException("Illegal State.  Cannot move first step up.");
492                     }
493 
494                     previousStep = oneStep;
495                     continue;
496                 }
497 
498                 if (stepId.equals(oneStep.getId())) {
499                     foundMatch = true;
500                     currentStep = oneStep;
501                     String stepNum = previousStep.getOrder();
502                     previousStep.setOrder(currentStep.getOrder());
503                     currentStep.setOrder(stepNum);
504                     break;
505                 } else {
506                     previousStep = oneStep;
507                 }
508             }
509 
510             if (!foundMatch) {
511                 throw new ControllerException("Could not find matching step id: "
512                         + stepId +
513                         " for wizard id: " + wizardId);
514             }
515 
516             DBConnection connection = DBConnectionPool
517                     .getInstance(request.getDataContext())
518                     .getConnection("Reorder Up Transaction.");
519             updateAndRedirect(connection, previousStep, currentStep, wizardId, request, response);
520             return;
521         } catch (DBException ex) {
522             throw new ControllerException("Database Error Processing Request", ex);
523         }
524 
525     }
526 
527     private void updateAndRedirect(DBConnection connection, WizStep previousStep, WizStep currentStep, String wizardId,
528                                    ControllerRequest request, ControllerResponse response) throws DBException,
529             ControllerException {
530         try {
531             connection.setAutoCommit(false);
532             previousStep.setConnection(connection);
533             previousStep.update(true);
534             currentStep.setConnection(connection);
535             currentStep.update(true);
536             connection.commit();
537         } catch (Throwable t) {
538             getLogger().error(t);
539             connection.rollback();
540             throw new ControllerException("Error processing transaction.", t);
541         } finally {
542             connection.release();
543         }
544 
545         Transition redirect = new Transition("redirect", "redirect",
546                 SelectionWizardManager.class,
547                 SelectionWizardManager.STATE_PROMPT_EDIT);
548         redirect.addParam(WizardController.WIZ_PARAMETER_ID, wizardId);
549         redirect.redirectTransition(request, response);
550     }
551 
552     /***
553      * Selects the model field and etc for use in the step.
554      *
555      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
556      *                 The ControllerRequest contains all the parameters such as web parameters, user
557      *                 security credentials and user locale
558      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
559      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
560      *                 for ths sytem.
561      * @throws ControllerException    upon error
562      * @throws NonHandleableException upon fatal error
563      * @throws DBException            upon database error
564      */
565     protected void runPromptModelFieldState(final ControllerRequest request,
566                                             final ControllerResponse response) throws ControllerException,
567             NonHandleableException, DBException {
568         StateHandler handler = new PromptModelField(request.getParameter(WizStep.FLD_WIZID),
569                 request.getParameter(WizStep.FLD_ID));
570 
571         handler.handleRequest(request, response);
572     }
573 
574 
575     /***
576      * Prompts for Text entry.
577      *
578      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
579      *                 The ControllerRequest contains all the parameters such as web parameters, user
580      *                 security credentials and user locale
581      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
582      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
583      *                 for ths sytem.
584      * @throws ControllerException    upon error
585      * @throws NonHandleableException upon fatal error
586      * @throws DBException            upon database error
587      */
588     protected void runPromptTextEntryState(final ControllerRequest request,
589                                            final ControllerResponse response) throws ControllerException,
590             NonHandleableException, DBException {
591         StateHandler handler = new PromptTextEntry(request.getParameter(WizStep.FLD_WIZID),
592                 request.getParameter(WizStep.FLD_ID));
593 
594         handler.handleRequest(request, response);
595     }
596 
597     /***
598      * Selects the model instance to use in the step.
599      *
600      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
601      *                 The ControllerRequest contains all the parameters such as web parameters, user
602      *                 security credentials and user locale
603      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
604      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
605      *                 for ths sytem.
606      * @throws ControllerException    upon error
607      * @throws NonHandleableException upon fatal error
608      * @throws DBException            upon database error
609      */
610     protected void runPromptNodeInstanceState(final ControllerRequest request,
611                                               final ControllerResponse response) throws ControllerException,
612             NonHandleableException, DBException {
613         StateHandler handler = new PromptNodeInstance(request.getParameter(WizStep.FLD_WIZID),
614                 request.getParameter(WizStep.FLD_ID));
615 
616         handler.handleRequest(request, response);
617     }
618 
619     /***
620      * Selects the node attribute to use for a picklist.
621      *
622      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
623      *                 The ControllerRequest contains all the parameters such as web parameters, user
624      *                 security credentials and user locale
625      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
626      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
627      *                 for ths sytem.
628      * @throws ControllerException    upon error
629      * @throws NonHandleableException upon fatal error
630      * @throws DBException            upon database error
631      */
632     protected void runPromptNodeAttributeState(final ControllerRequest request,
633                                                final ControllerResponse response) throws ControllerException,
634             NonHandleableException, DBException {
635         StateHandler handler = new PromptNodeAttribute(request.getParameter(WizStep.FLD_WIZID),
636                 request.getParameter(WizStep.FLD_ID));
637 
638         handler.handleRequest(request, response);
639     }
640 
641     /***
642      * Selects the picklist to use.
643      *
644      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
645      *                 The ControllerRequest contains all the parameters such as web parameters, user
646      *                 security credentials and user locale
647      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
648      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
649      *                 for ths sytem.
650      * @throws ControllerException    upon error
651      * @throws NonHandleableException upon fatal error
652      * @throws DBException            upon database error
653      */
654     protected void runPromptPicklistState(final ControllerRequest request,
655                                           final ControllerResponse response) throws ControllerException,
656             NonHandleableException, DBException {
657         StateHandler handler = new PromptPicklist(request.getParameter(WizStep.FLD_WIZID),
658                 request.getParameter(WizStep.FLD_ID));
659 
660         handler.handleRequest(request, response);
661     }
662 
663 
664     /***
665      * Selects the model to use for the step.
666      *
667      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
668      *                 The ControllerRequest contains all the parameters such as web parameters, user
669      *                 security credentials and user locale
670      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
671      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
672      *                 for ths sytem.
673      * @throws ControllerException    upon error
674      * @throws NonHandleableException upon fatal error
675      * @throws DBException            upon database error
676      */
677     protected void runPromptSelectModelState(final ControllerRequest request,
678                                              final ControllerResponse response) throws ControllerException,
679             NonHandleableException, DBException {
680         StateHandler handler = new PromptSelectModel(request.getParameter(WizStep.FLD_WIZID),
681                 request.getParameter(WizStep.FLD_ID));
682 
683         handler.handleRequest(request, response);
684     }
685 
686 
687     /***
688      * Runs the Order Down state.
689      *
690      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
691      *                 The ControllerRequest contains all the parameters such as web parameters, user
692      *                 security credentials and user locale
693      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
694      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
695      *                 for ths sytem.
696      * @throws ControllerException    upon error
697      * @throws NonHandleableException upon fatal error
698      */
699     protected void runOrderDownState(final ControllerRequest request,
700                                      final ControllerResponse response) throws ControllerException,
701             NonHandleableException {
702         try {
703             //Get the step id.
704             String stepId = request.getParameter(WizStep.FLD_ID);
705 
706             //Retrieve the defined database object from the step id.
707             WizStep changeStep = new WizStep();
708             changeStep.setId(stepId);
709             changeStep.retrieve();
710 
711             //Grab all steps by taking the wizard id and finding all related
712             //steps.
713             String wizardId = changeStep.getField(WizStep.FLD_WIZID);
714 
715             assert wizardId != null && wizardId.length() > 0;
716 
717             WizStep allSteps = new WizStep();
718             allSteps.setWizId(wizardId);
719 
720             List result = allSteps.searchAndRetrieveList(WizStep.FLD_ORDER);
721             if (result.size() == 0) {
722                 throw new ControllerException("No Steps Found for wizard:" + wizardId);
723             }
724 
725             if (result.size() == 1) {
726                 throw new ControllerException("Cannot change order on a single size list");
727             }
728 
729             boolean foundMatch = false;
730             boolean swapped = false;
731             WizStep previousStep = null;
732             WizStep currentStep = null;
733             for (Iterator i = result.iterator(); i.hasNext();) {
734                 WizStep oneStep = (WizStep) i.next();
735                 if (stepId.equals(oneStep.getId())) {
736                     foundMatch = true;
737                     previousStep = oneStep;
738                     continue;
739                 }
740 
741                 if (foundMatch) {
742                     currentStep = oneStep;
743                     String stepNum = previousStep.getOrder();
744                     previousStep.setOrder(currentStep.getOrder());
745                     currentStep.setOrder(stepNum);
746                     swapped = true;
747                     break;
748                 } else {
749                     previousStep = oneStep;
750                 }
751             }
752 
753             if (foundMatch && !swapped) {
754                 throw new ControllerException("Matching id was last in list!");
755             }
756 
757             if (!foundMatch) {
758                 throw new ControllerException("Could not find matching step id: "
759                         + stepId +
760                         " for wizard id: " + wizardId);
761             }
762 
763             DBConnection connection = DBConnectionPool
764                     .getInstance(request.getDataContext())
765                     .getConnection("Reorder Down Transaction.");
766             updateAndRedirect(connection, previousStep, currentStep, wizardId, request, response);
767             return;
768         } catch (DBException ex) {
769             throw new ControllerException("Database Error Processing Request", ex);
770         }
771 
772     }
773 
774     /***
775      * Runs the Edit Step state.  The edit step state is nothing more than a mediator
776      * that dispatches to the appropriate editing page.
777      *
778      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
779      *                 The ControllerRequest contains all the parameters such as web parameters, user
780      *                 security credentials and user locale
781      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
782      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
783      *                 for ths sytem.
784      * @throws ControllerException    upon error
785      * @throws NonHandleableException upon fatal error
786      * @throws DBException            upon database error.
787      */
788     protected void runPromptEditState(final ControllerRequest request,
789                                       final ControllerResponse response) throws ControllerException,
790             NonHandleableException, DBException {
791 
792         //Load the wizard step
793         WizStep ws = new WizStep();
794         ws.setId(request.getParameter(WizStep.FLD_ID));
795         ws.retrieve();
796 
797         dispatchToEditScreen(request, response, ws.getType());
798     }
799 
800     private void dispatchToEditScreen(ControllerRequest request, ControllerResponse response,
801                                       int stepType) throws IllegalStateException, NonHandleableException,
802             ControllerException {
803         //Figure the step type and dispatch appropriately
804         switch (stepType) {
805             case PromptStepType.INSTANCE_PICKLIST:
806                 transition(PromptNodeAttribute.STATE_NAME, request, response);
807                 break;
808 
809             case PromptStepType.CUSTOM_PICKLIST:
810                 transition(PromptPicklist.STATE_NAME, request, response);
811                 break;
812 
813             case PromptStepType.INSTRUCTIONS_ONLY:
814                 transition(PromptInstructions.STATE_NAME, request, response);
815                 break;
816 
817             case PromptStepType.MODEL_PICKLIST:
818                 transition(PromptModelField.STATE_NAME, request, response);
819                 break;
820 
821             case PromptStepType.TEXT_ENTRY:
822                 transition(PromptTextEntry.STATE_NAME, request, response);
823                 break;
824 
825             default:
826                 throw new IllegalStateException("InvalidInput Value: " + WizStep.FLD_STEP_TYPE + "=" + stepType);
827         }
828     }
829 
830 
831     /***
832      * Handles the select step type state.
833      *
834      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
835      *                 The ControllerRequest contains all the parameters such as web parameters, user
836      *                 security credentials and user locale
837      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
838      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
839      *                 for ths sytem.
840      * @throws ControllerException upon error
841      * @throws DBException         upon database exception error.
842      */
843     protected void runPromptSelectStepTypeState(final ControllerRequest request,
844                                                 final ControllerResponse response) throws ControllerException,
845             DBException, NonHandleableException {
846         StateHandler handler = new PromptStepType(request.getParameter(WizStep.FLD_WIZID),
847                 request.getParameter(WizStep.FLD_ID));
848 
849         handler.handleRequest(request, response);
850     }
851 
852     /***
853      * Processes the results from the inputs generated by promptSelectStepType handler
854      * and transitions to the appropriate state based on the results.
855      *
856      * @param request  The <code>ControllerRequest</code> object handed to us by the framework.
857      *                 The ControllerRequest contains all the parameters such as web parameters, user
858      *                 security credentials and user locale
859      * @param response The <code>ControllerResponse</code> object handed to us by the framework.
860      *                 The ControllerResponse will be populated with the Inputs/Outputs/Transitions/Blocks
861      *                 for ths sytem.
862      * @throws ControllerException    upon error
863      * @throws NonHandleableException
864      */
865     protected void runDoSelectStepTypeState(final ControllerRequest request, final ControllerResponse response) throws
866             ControllerException,
867             NonHandleableException {
868         ErrorCollection ec = request.getErrorCollection();
869         if (ec != null) {
870             ec = new ErrorCollection();
871         }
872 
873         int val = Integer.parseInt(request.getParameter(WizStep.FLD_STEP_TYPE));
874         Transition redirect = new Transition();
875         redirect.setControllerObject(getClass());
876         redirect.setParams(request.getAllParameters());
877         switch (val) {
878             case PromptStepType.INSTANCE_PICKLIST:
879                 transition(PromptNodeInstance.STATE_NAME, request, response);
880                 break;
881 
882             case PromptStepType.CUSTOM_PICKLIST:
883                 transition(PromptPicklist.STATE_NAME, request, response);
884                 break;
885 
886             case PromptStepType.INSTRUCTIONS_ONLY:
887                 transition(PromptInstructions.STATE_NAME, request, response);
888                 break;
889 
890             case PromptStepType.MODEL_PICKLIST:
891                 transition(PromptSelectModel.STATE_NAME, request, response);
892                 break;
893 
894             case PromptStepType.TEXT_ENTRY:
895                 transition(PromptTextEntry.STATE_NAME, request, response);
896                 break;
897 
898             default:
899                 throw new IllegalStateException("InvalidInput Value: " + WizStep.FLD_STEP_TYPE + "=" + val);
900         }
901     }
902 
903     /***
904      * Dispatches to the PromptInstructions state handler.
905      *
906      * @param request  ControllerRequest the ControllerRequest object.
907      * @param response ControllerResponse the ControllerResponse object.
908      * @throws DBException            upon error.
909      * @throws ControllerException
910      * @throws NonHandleableException
911      */
912     protected void runPromptInstructionsState(final ControllerRequest request, final ControllerResponse response) throws
913             DBException,
914             ControllerException, NonHandleableException {
915         StateHandler handler = new PromptInstructions(request.getParameter(WizStep.FLD_WIZID),
916                 request.getParameter(WizStep.FLD_ID));
917         handler.handleRequest(request, response);
918     }
919 
920 
921     /***
922      * Override of Controller.getTitle() to provide a meaningful name to this
923      * controller.
924      *
925      * @return java.lang.String
926      */
927     public String getTitle() {
928         return "Wizard Step Manager";
929     }
930 }