View Javadoc

1   
2   package com.sri.emo.wizard.creation;
3   
4   import java.io.*;
5   import java.util.*;
6   
7   import com.jcorporate.expresso.core.controller.*;
8   import com.jcorporate.expresso.core.db.*;
9   import com.jcorporate.expresso.core.dbobj.*;
10  import com.sri.common.dbobj.*;
11  import com.sri.emo.controller.CreationWizardAction;
12  import com.sri.emo.dbobj.*;
13  import com.sri.emo.wizard.*;
14  import com.sri.emo.wizard.branch.*;
15  import com.sri.emo.wizard.creation.model.*;
16  import com.sri.emo.wizard.defaults.*;
17  import com.sri.emo.wizard.expressoimpl.*;
18  
19  /***
20   * Constructs Completion Wizards.
21   *
22   * @author Michael Rimov
23   * @version 1.0
24   */
25  public class EmoCreationWizardFactory extends CreationBuilder {
26  
27  
28      /***
29       * A sorted Set of special ids.
30       */
31      private SortedSet preMultiAttributeStepIds = new TreeSet();
32  
33      /***
34       * Initial prestep id must be lower than any special steps in the EmoCompletionWizard
35       */
36      private static final int INITIAL_PRESTEP_ID = -4;
37  
38  
39  
40      /***
41       * Constructs a given wizard.
42       *
43       * @param completionRepository the CompletionRepository to draw the various
44       *                             wizards from.
45       */
46      public EmoCreationWizardFactory(final CreationRepository completionRepository) {
47          super(completionRepository);
48      }
49  
50      /***
51       * Override of base class to change controller
52       *
53       * @param id int
54       * @return Transition
55       */
56      protected Transition commonTransitionConstruction(final int id) {
57          Transition t = new Transition();
58          t.setControllerObject(CreationWizardAction.class);
59          t.addParam(WizardController.WIZ_PARAMETER_ID, Integer.toString(id));
60          return t;
61      }
62  
63  
64      /***
65       * Constructs the wizard itself.
66       *
67       * @param definition the WizDefinition dbobject for this wizard.
68       * @param steps      the List of steps that were constructed previously in
69       *                   the constructSteps function.
70       * @return fully constructed Wizard instance.
71       * @throws com.jcorporate.expresso.core.db.DBException
72       *          upon database exception error.
73       */
74      protected Wizard constructWizard(final WizDefinition definition, final BranchList steps) throws DBException {
75          EmoCreationWizard cwiz = (EmoCreationWizard) super.constructWizard(definition, steps.getNodes());
76  
77          CreationBeans beans = null;
78          try {
79              beans = repository.findById(cwiz.getId());
80          } catch (ObjectNotFoundException e) {
81              throw new DBException("Could not find underlying wizard of id: "
82                      + definition.getFieldInt(WizDefinition.FLD_ID), e);
83          }
84  
85          //Set turing constitution and 'dehydration' as well.
86  //        System.out.println("CONSTRUCT WIZARD SEARCH RESULT BEANS = " + StringUtil.toString(steps.getSearchResultBeans()));
87  //        cwiz.setSearchResults(steps.getSearchResultBeans());
88          cwiz.setCompletionBeans(beans);
89  
90          return cwiz;
91      }
92  
93      /***
94       * Constructs a new wizard instance and returns it.
95       *
96       * @return Wizard instance
97       * @throws WizardException upon error building it.
98       */
99      public Wizard buildWizard() throws WizardException {
100         try {
101 
102             WizDefinition wizard = this.getWizDefinition();
103 
104             BranchList steps = constuctCompletionSteps();
105             Wizard wiz = constructWizard(wizard, steps);
106             return wiz;
107         } catch (DBException ex) {
108             throw new WizardException("Error building wizard: " + this.getWizardId(), ex);
109         }
110     }
111 
112 
113     /***
114      * Constructs the steps of the wizard.  Override to customize your
115      * step construction.
116      *
117      * @return List of Wizard Steps
118      * @throws DBException if there is an error querying the underlying data object.
119      */
120     private BranchList constuctCompletionSteps() throws DBException {
121 //        List pages = new ArrayList(getDefinition().getCompletionParts().size() + 3);
122         BranchList pages = new BranchList(50, EmoCreationWizard.DEFAULT_TRANSITION_KEY);
123 
124 //        pages.add(constructTitlePage());
125         pages.addConvergingWizardPage(constructTitlePage());
126 //        BranchNode previousNode = addDefaultPage(pages, null, constructTitlePage());
127 //        pages.add(constructInitializationPage());
128         if(getDefinition().size() == 0){
129             throw new DBException("Definition does not contain any Creation Beans, please check Creation Bean implementation");
130         }
131         CreationBean bean = getDefinition().getCreationBean(0);
132         System.out.println("bean from location 0 is " + bean.getMemLocation());
133         pages.addConvergingWizardPage(constructInitializationPage(bean.
134                 getCurrentNodeType(), EmoCreationWizard.INITIALIZATION_PAGE_ID, null));
135 //        previousNode = addDefaultPage(pages, previousNode, constructInitializationPage());
136 //        pages.addAll(constructPartsPages());
137         constructPartsPages(bean, pages);
138 //        pages.add(constructCompletionPage());
139         BranchNode summaryPage = new BranchNode(constructCompletionPage(bean), pages.getDefaultTransitionKey());
140         pages.addConverging(summaryPage);
141 //        previousNode = addDefaultPage(pages, previousNode, constructCompletionPage());
142         addCommonTransitions(pages, summaryPage);
143         return pages;
144     }
145 
146     /***
147      * addCommonTransitions
148      *
149      * @param pages BranchList
150      */
151     private void addCommonTransitions(BranchList pages, BranchNode summaryPage) {
152         Iterator iter = pages.getNodes().iterator();
153         while (iter.hasNext()) {
154             BranchNode item = (BranchNode) iter.next();
155 //            System.out.println("adding summary transition to "+item);
156             if(!item.equals(summaryPage)){
157 //                System.out.println("item isn't summary");
158                 if (!item.hasTransition(EmoCreationWizard.SUMMARY_TRANSITION)) {
159 //                    System.out.println("adding summary transition");
160                     item.addNext(EmoCreationWizard.SUMMARY_TRANSITION,
161                                  summaryPage);
162                 }
163             }
164         }
165     }
166 
167 
168 
169     //    private class CreationList extends BranchList {
170 //        List searchResultBeans;
171 //        public CreationList(int initialSize, String defaultTransitionKey){
172 //            super(initialSize, defaultTransitionKey);
173 //            searchResultBeans = new Vector(10);
174 //        }
175 //        public List getSearchResultBeans(){
176 //            return this.searchResultBeans;
177 //        }
178 //        public void addSearchResult(Serializable pageId){
179 //            SearchResultBean bean = new SearchResultBean();
180 //            bean.setPageId(pageId);
181 //            searchResultBeans.add(bean);
182 //        }
183 //    }
184 
185 
186     /***
187      * Probably the most involved portion of the builder -- go through the Parts
188      * and build the various entry pages.
189      *
190      * @return List
191      */
192     private void constructPartsPages(CreationBean bean, BranchList results) {
193 //        List results = new ArrayList();
194         for (Iterator i = bean.getCompletionParts().iterator(); i.hasNext();) {
195             CreationPartsBean partsbean = (CreationPartsBean) i.next();
196 
197             if (FieldCompletion.WIZARD.equals(partsbean.getFieldCompletion())) {
198                 try {
199                     Part stepPart = partsbean.getPart();
200                     String id = stepPart.getId();
201 //                    EmoWizardMetadata pageMetadata;
202                     CreationMetadata pageMetadata;
203 
204                     //TODO: Fix me into clean separation of logic
205                     if (stepPart.isSharedNodeAttrib()) {
206                         CreationPageMetadata relationMetadata = new CreationPageMetadata();
207                         relationMetadata.setMaxEntries(partsbean.getMaxEntries());
208                         relationMetadata.setMinEntries(partsbean.getMinEntries());
209                         relationMetadata.setNodeId(bean.getTargetId().toString());
210                         relationMetadata.setNodeType(stepPart.getPartType());
211                         relationMetadata.setPartNodeRelation(stepPart.getNodeRelation());
212                         relationMetadata.setEntry(true);
213                         relationMetadata.setEntryRequired(false);
214                         relationMetadata.setViewId("MultiCheckbox");
215 
216 //                        System.out.println("stepPart.isSharedNodeAttrib()");
217                         pageMetadata = relationMetadata;
218 
219                     } else if (stepPart.areMultipleAttributesAllowed()) {
220 //                        System.out.println("stepPart.areMultipleAttributesAllowed()");
221                         //TODO: Create MultiAttributePage.
222 //                        pageMetadata = new EmoWizardMetadata();
223                         pageMetadata = new CreationPageMetadata();
224 
225                     } else {//otherwise just a non-shared single attribute page
226 //                        System.out.println("stepPart.default()");
227 //                        pageMetadata = new EmoWizardMetadata();
228                         pageMetadata = new CreationPageMetadata();
229                     }
230 
231 
232                     ValidValue[] selectionMenu = null;
233 
234                     if (stepPart.hasPicklist()) {
235                         //
236                         //Take Parts picklist and add 'please make selection'
237                         //
238                         ValidValue[] tempSelectionMenu = stepPart.getPickListValidValues();
239                         selectionMenu = new ValidValue[tempSelectionMenu.length + 1];
240                         selectionMenu[0] = new ValidValue("", "(No Selection Made)");
241                         System.arraycopy(tempSelectionMenu, 0, selectionMenu, 1, tempSelectionMenu.length);
242 
243                         ((EmoWizardMetadata)pageMetadata).setEntryRequired(false);
244                         ((EmoWizardMetadata)pageMetadata).setEntry(true);
245                     } else if (stepPart.isHaveCustomHandler()) {
246                         // if part has custom component like 'settings', that custom component can have many embedded pages
247                         // todo use portlet display supplied by custom part handler
248 //                        IPartHandler handler = partsbean.getPart().getCustomHandler();
249 //                        handler.
250 
251                         pageMetadata = this.constructCustomHandlerPageMetadata(partsbean, id);
252                     } else if (stepPart.areMultipleAttributesAllowed() && !stepPart.isSharedNodeAttrib()) {
253                         //If min != max
254                         pageMetadata = this.constructMultiAttributePageMetadata(partsbean, id);
255 
256                         //If the following isn't true, then we don't have a how many
257                         //parts page.
258                         if (!minEqualsMax(partsbean)) {
259 
260                             //Multiple attributes.  There are two options here.  1 for related nodes
261                             //another for multiple attribute nodes.
262 
263                             //Construct the multiple entry.  This requires a two step process:
264                             //The first is 'how many entries are you going to make'
265                             //The second is 'ok, enter the data'
266 
267                             //We have a multi-text entry attribute page.  Create a new 'how many are you going to enter' page.
268                             Integer howmanyPartsId = generatePreMultiAttributePageId();
269                             EmoWizardMetadata howManyEntriesMetadata = constructHowManyEntriesPageMetadata(partsbean,
270                                     howmanyPartsId.toString());
271 
272                             //Construct the 'how many entries' page.
273                             EmoWizardPage preMultiEntryPage = new EmoWizardPage(howmanyPartsId, howManyEntriesMetadata,
274                                     null);
275 
276                             //Set the default value to how many entries are in the target definition.
277                             /***
278                              * @todo RICHARD: since we are now only dealing with node_types we do not
279                              * have any entries predefines so we skip this step.  Make sure
280                              * it is allowed
281                              */
282                             if(!bean.getCurrentNode().getNodeId().equals("-1")){
283                                 //if this is not a new node, then fill in the correct number of attributes
284                                 Attribute[] currentNumberAttributes = bean.getCurrentNode().getAttributes(
285                                         partsbean.getPart().getPartType());
286                                 preMultiEntryPage.setData(Integer.toString(currentNumberAttributes.length));
287                             }
288                             results.addConvergingWizardPage(preMultiEntryPage);
289 //                            previousNode = addDefaultPage(results, previousNode, preMultiEntryPage);
290                         }
291 
292                     } else {
293                         //Standard textbox.
294                         ((EmoWizardMetadata)pageMetadata).setEntryRequired(false);
295                     }
296 
297                     setCommonPartsParameters(partsbean, id, (EmoWizardMetadata)pageMetadata);
298                     pageMetadata.setCreate(partsbean.isCreate());
299                     pageMetadata.setBrowse(partsbean.isBrowse());
300                     pageMetadata.setSearch(partsbean.isSearch());
301                     pageMetadata.setRequired(partsbean.isRequired());
302 
303                     pageMetadata.setCreateText(partsbean.getCreateText());
304                     pageMetadata.setBrowseText(partsbean.getBrowseText());
305                     pageMetadata.setSearchText(partsbean.getSearchText());
306 
307 
308                     EmoWizardPage wizardPage = null;
309 
310 //                    previousNode = addDefaultPage(results, previousNode, wizardPage);
311 //                    results.add(wizardPage);
312 
313                     if(partsbean.isSearch() || partsbean.isBrowse() || partsbean.isCreate()){
314                         wizardPage = constructSearchBrowsePage(results, partsbean, id, pageMetadata);
315                     }else{
316                         wizardPage = constructWizardPage(bean, partsbean, id, (EmoWizardMetadata)pageMetadata, selectionMenu);
317                         results.addConvergingWizardPage(wizardPage);
318                     }
319 
320                 } catch (Exception e) {
321                     e.printStackTrace();
322                     throw new RuntimeException(e);
323                 }
324             }
325         }
326 
327 //        return previousNode;
328     }
329 
330     /***
331      * constructCreatePage
332      *
333      * @param results BranchList
334      * @param partsbean CreationPartsBean
335      * @param id String
336      * @param pageMetadata CreationMetadata
337      * @return EmoWizardPage
338      */
339     private BranchList constructCreatePage(String defaultTransitionKey, CreationPartsBean partsbean,
340                                               String id,
341                                               CreationMetadata pageMetadata) throws
342             DBException {
343         CreationBean bean = getDefinition().getCreationBeanByPartId(partsbean.getPart().getId());
344         System.out.println("constructingCreatePage");
345         Integer newId = generatePreMultiAttributePageId();
346 
347         MinMaxPageMetadata resultsMetaData = new MinMaxPageMetadata();
348            resultsMetaData.setMaxEntries(partsbean.getMaxEntries());
349            resultsMetaData.setMinEntries(partsbean.getMinEntries());
350            resultsMetaData.setEntry(true);
351            resultsMetaData.setEntryRequired(false);
352            resultsMetaData.setViewId("SearchResult");
353 
354            //copy basics over
355            resultsMetaData.setBrowse(pageMetadata.isBrowse());
356            resultsMetaData.setBrowseText(pageMetadata.getBrowseText());
357            resultsMetaData.setSearch(pageMetadata.isSearch());
358            resultsMetaData.setSearchText(pageMetadata.getSearchText());
359            resultsMetaData.setCreate(pageMetadata.isCreate());
360            resultsMetaData.setCreateText(pageMetadata.getCreateText());
361            resultsMetaData.setRequired(pageMetadata.isRequired());
362 
363            String newIdStr = Integer.toString(newId.intValue());
364            setCommonPartsParameters(partsbean, newIdStr, (EmoWizardMetadata)resultsMetaData);
365 
366            Part stepPart = partsbean.getPart();
367            NodeType nodeType = NodeType.getFromTypeString(stepPart.getPartType());
368            EmoWizardPage initPage = null;
369 
370            if(nodeType != null){
371                Integer newId2 = generatePreMultiAttributePageId();
372                initPage = constructInitializationPage(nodeType, newId2.toString(), partsbean.getPart().getId());
373                System.out.println("generated initialization page "+newId2+" for the create button");
374            }
375 //        EmoWizardPage wizardPage = constructWizardPage(partsbean, newIdStr, (EmoWizardMetadata)resultsMetaData, null);
376 //           SearchListPage wizardPage = new SearchListPage(newId, resultsMetaData, null);
377 //           wizardPage.setNodeType(partsbean.getPart().getPartType());
378 //           wizardPage.setSourcePageId(new Integer(id));
379 
380            BranchNode node = new BranchNode(initPage, EmoCreationWizard.CREATE_TRANSITION);
381 //           BranchNode node = results.addConvergingWizardPage(wizardPage);
382            //loop back to itself
383            node.addDefault(initPage);
384            BranchList newBranch = new BranchList(4, defaultTransitionKey);
385            newBranch.addBranch(node);
386            constructPartsPages(bean, newBranch);
387            return newBranch;
388     }
389 
390     /***
391      * constructSearchBrowsePage
392      *
393      * @param results List
394      * @param partsbean TemplatePartsBean
395      * @param id String
396      * @param pageMetadata TemplateMetadata
397      */
398     private SearchListPage constructSearchBrowsePage(BranchList results,
399 //                                           BranchNode splittingNode,
400                                            CreationPartsBean partsbean,
401                                            String id,
402                                            CreationMetadata pageMetadata) throws
403             DBException, Exception {
404             System.out.println("constructingSearchBrowsePage");
405 //            Integer newId = generatePreMultiAttributePageId();
406 
407             MinMaxPageMetadata resultsMetaData = new MinMaxPageMetadata();
408             resultsMetaData.setMaxEntries(partsbean.getMaxEntries());
409             resultsMetaData.setMinEntries(partsbean.getMinEntries());
410             resultsMetaData.setEntry(true);
411             resultsMetaData.setEntryRequired(false);
412             resultsMetaData.setViewId("SearchResult");
413 
414             //copy basics over
415             resultsMetaData.setBrowse(pageMetadata.isBrowse());
416             resultsMetaData.setBrowseText(pageMetadata.getBrowseText());
417             resultsMetaData.setSearch(pageMetadata.isSearch());
418             resultsMetaData.setSearchText(pageMetadata.getSearchText());
419             resultsMetaData.setCreate(pageMetadata.isCreate());
420             resultsMetaData.setCreateText(pageMetadata.getCreateText());
421             resultsMetaData.setRequired(pageMetadata.isRequired());
422 
423 //            String newIdStr = Integer.toString(newId.intValue());
424             setCommonPartsParameters(partsbean, id,
425                                      (EmoWizardMetadata) resultsMetaData);
426 
427 //        EmoWizardPage wizardPage = constructWizardPage(partsbean, newIdStr, (EmoWizardMetadata)resultsMetaData, null);
428             SearchListPage wizardPage = new SearchListPage(new Integer(id),
429                     resultsMetaData, null);
430             wizardPage.setNodeType(partsbean.getPart().getPartType());
431             wizardPage.setSourcePageId(new Integer(id));
432 
433 //           BranchNode node = new BranchNode(wizardPage, "Search");
434             BranchNode node = results.addConvergingWizardPage(wizardPage);
435             //loop back to itself
436             node.addNext(EmoCreationWizard.SEARCH_TRANSITION,
437                          EmoCreationWizard.DEFAULT_TRANSITION_KEY,
438                          wizardPage);
439             node.addNext(EmoCreationWizard.BROWSE_TRANSITION,
440                          EmoCreationWizard.DEFAULT_TRANSITION_KEY,
441                          wizardPage);
442             if(partsbean.isCreate()){
443                 CreationBean bean = getDefinition().getCreationBeanByPartId(partsbean.getPart().getId());
444                 bean.setSearchPage(wizardPage);
445                 results.addBranch(node, EmoCreationWizard.CREATE_TRANSITION,
446                                   constructCreatePage(results.getDefaultTransitionKey(), partsbean, id, pageMetadata));
447 //                node.addNext(EmoCreationWizard.CREATE_TRANSITION,
448 //                             constructCreatePage(results, partsbean, id,
449 //                                                 pageMetadata));
450             }
451 //           results.addBranch(node);
452 //           results.addBranch(node);
453            return wizardPage;
454     }
455 
456     /***
457      * Probably the most involved portion of the builder -- go through the Parts
458      * and build the various entry pages.
459      *
460      * @return List
461      */
462 //    private List constructPartsPagesOld() {
463 //        List results = new ArrayList();
464 //        for (Iterator i = getDefinition().getCompletionParts().iterator(); i.hasNext();) {
465 //            CreationPartsBean partsbean = (CreationPartsBean) i.next();
466 //
467 //            if (FieldCompletion.WIZARD.equals(partsbean.getFieldCompletion())) {
468 //                try {
469 //                    Part stepPart = partsbean.getPart();
470 //                    String id = stepPart.getId();
471 //
472 //                    EmoWizardMetadata pageMetadata;
473 //
474 //                    //TODO: Fix me into clean separation of logic
475 //                    if (stepPart.isSharedNodeAttrib()) {
476 //                        CreationPageMetadata relationMetadata = new CreationPageMetadata();
477 //                        relationMetadata.setMaxEntries(partsbean.getMaxEntries());
478 //                        relationMetadata.setMinEntries(partsbean.getMinEntries());
479 //                        relationMetadata.setNodeId(getDefinition().getTargetId().toString());
480 //                        relationMetadata.setNodeType(stepPart.getPartType());
481 //                        relationMetadata.setPartNodeRelation(stepPart.getNodeRelation());
482 //                        relationMetadata.setEntry(true);
483 //                        relationMetadata.setEntryRequired(false);
484 //                        relationMetadata.setViewId("MultiCheckbox");
485 //
486 //                        pageMetadata = relationMetadata;
487 //
488 //                    } else if (stepPart.areMultipleAttributesAllowed()) {
489 //                        pageMetadata = new EmoWizardMetadata();
490 //                    } else {//otherwise just a non-shared single attribute page
491 //                        pageMetadata = new EmoWizardMetadata();
492 //                    }
493 //
494 //
495 //                    ValidValue[] selectionMenu = null;
496 //
497 //                    if (stepPart.hasPicklist()) {
498 //                        //
499 //                        //Take Parts picklist and add 'please make selection'
500 //                        //
501 //                        ValidValue[] tempSelectionMenu = stepPart.getPickListValidValues();
502 //                        selectionMenu = new ValidValue[tempSelectionMenu.length + 1];
503 //                        selectionMenu[0] = new ValidValue("", "(No Selection Made)");
504 //                        System.arraycopy(tempSelectionMenu, 0, selectionMenu, 1, tempSelectionMenu.length);
505 //
506 //                        pageMetadata.setEntryRequired(false);
507 //                        pageMetadata.setEntry(true);
508 //                    } else if (stepPart.isHaveCustomHandler()) {
509 //                        // if part has custom component like 'settings', that custom component can have many embedded pages
510 //                        // todo use portlet display supplied by custom part handler
511 //                        pageMetadata = (EmoWizardMetadata)this.constructCustomHandlerPageMetadata(partsbean, id);
512 //                    } else if (stepPart.areMultipleAttributesAllowed() && !stepPart.isSharedNodeAttrib()) {
513 //                        //If min != max
514 //                        pageMetadata = (EmoWizardMetadata)this.constructMultiAttributePageMetadata(partsbean, id);
515 //
516 //                        //If the following isn't true, then we don't have a how many
517 //                        //parts page.
518 //                        if (!minEqualsMax(partsbean)) {
519 //
520 //                            //Multiple attributes.  There are two options here.  1 for related nodes
521 //                            //another for multiple attribute nodes.
522 //
523 //                            //Construct the multiple entry.  This requires a two step process:
524 //                            //The first is 'how many entries are you going to make'
525 //                            //The second is 'ok, enter the data'
526 //
527 //                            //We have a multi-text entry attribute page.  Create a new 'how many are you going to enter' page.
528 //                            Integer howmanyPartsId = generatePreMultiAttributePageId();
529 //                            EmoWizardMetadata howManyEntriesMetadata = constructHowManyEntriesPageMetadata(partsbean,
530 //                                    howmanyPartsId.toString());
531 //
532 //                            //Construct the 'how many entries' page.
533 //                            EmoWizardPage preMultiEntryPage = new EmoWizardPage(howmanyPartsId, howManyEntriesMetadata,
534 //                                    null);
535 //
536 //                            //Set the default value to how many entries are in the target definition.
537 //                            /***
538 //                             * @todo RICHARD: since we are now only dealing with node_types we do not
539 //                             * have any entries predefines so we skip this step.  Make sure
540 //                             * it is allowed
541 //                             */
542 //                            preMultiEntryPage.setData(Integer.toString(1));
543 //                            results.add(preMultiEntryPage);
544 //                        }
545 //
546 //
547 //                    } else {
548 //                        //Standard textbox.
549 //                        pageMetadata.setEntryRequired(false);
550 //                    }
551 //
552 //                    setCommonPartsParameters(partsbean, id, pageMetadata);
553 //
554 //
555 //                    EmoWizardPage wizardPage = constructWizardPage(partsbean, id, pageMetadata, selectionMenu);
556 //
557 //                    results.add(wizardPage);
558 //                } catch (Exception e) {
559 //                    e.printStackTrace();
560 //                    throw new RuntimeException(e);
561 //                }
562 //            }
563 //        }
564 //
565 //        return results;
566 //    }
567 
568     /***
569      * Constructs the actual wizard page.
570      *
571      * @param partsbean     CompletionPartsBean the current part for the page.
572      * @param id            finalString the page id.
573      * @param pageMetadata  EmoWizardMetadata the wizard metadata that has been
574      *                      constructed earlier in the process.
575      * @param selectionMenu ValidValue[] the selection menu (may be null)
576      * @return EmoWizardPage or derivative.
577      * @throws DBException upon database query error.
578      * @throws Exception   upon custom part handler error.
579      */
580     private EmoWizardPage constructWizardPage(final CreationBean bean,
581             final CreationPartsBean partsbean,
582                                               final String id,
583                                               final EmoWizardMetadata pageMetadata,
584                                               final ValidValue[] selectionMenu) throws DBException, Exception {
585         EmoWizardPage wizardPage;
586         Part stepPart = partsbean.getPart();
587         Node wizardTarget = bean.getCurrentNode();
588 
589         Attribute[] attributes = wizardTarget.getAttributes(stepPart.getPartType());
590 
591         //TODO: Extract clean logic here.
592         if (stepPart.isHaveCustomHandler()) {
593             System.out.println("EmoCreationWizardFactory.constructWizardPage() isHaveCustomHandler");
594             wizardPage = constructCustomHandlerPage(bean, id, pageMetadata);
595         } else if (stepPart.isSharedNodeAttrib()) {
596             System.out.println("EmoCreationWizardFactory.constructWizardPage() isSharedNodeAttrib");
597             wizardPage = new RelationWizardPage(new Integer(id), pageMetadata);
598 //            Node[] relatedNodes = wizardTarget.getRelatedNodes(stepPart.getNodeRelation(),stepPart.getPartType());
599 //            HashMap dataToPut = new HashMap(relatedNodes.length);
600 //            for (int i = 0; i < relatedNodes.length; i++) {
601 //                dataToPut.put(RelationWizardPage.PARAM_PREFIX + "_" + i, relatedNodes[i].getNodeId());
602 //            }
603 
604 //            if (dataToPut.size() > 0) {
605 //                wizardPage.setData(dataToPut);
606 //            }
607         } else if (stepPart.areMultipleAttributesAllowed()) {
608             System.out.println("EmoCreationWizardFactory.constructWizardPage() areMultipleAttributesAllowed");
609 
610             wizardPage = new MultiEntryWizardPage(new Integer(id), pageMetadata);
611             if (minEqualsMax(partsbean)) {
612                 ((MultiEntryWizardPage) wizardPage).setNumEntries(partsbean.getMinEntries().intValue());
613             }
614 
615             List dataToSet = new ArrayList(attributes.length);
616             for (int i = 0; i < attributes.length; i++) {
617 //                dataToSet.add(attributes[i].getAttribValueRaw());
618             }
619 
620             if (dataToSet.size() > 0) {
621                 // todo we will still get errors from empty boxes if this data set is incomplete
622                 wizardPage.setData((Serializable) dataToSet);
623             }
624         } else {
625             System.out.println("EmoCreationWizardFactory.constructWizardPage() default");
626 
627             wizardPage = new EmoWizardPage(new Integer(id), pageMetadata, selectionMenu);
628             if (attributes.length == 0) {
629                 wizardPage.setData(null);
630             } else {
631 //                assert attributes.length == 0 || attributes.length == 1:
632 //                        "Expected only zero or one attributes returned for single attribute";
633 //                wizardPage.setData(attributes[0].getAttribValueRaw());
634                 wizardPage.setData(null);
635             }
636         }
637         return wizardPage;
638     }
639 
640 
641     /***
642      * Special case. If min equals max values in multi-entry pages.
643      *
644      * @param partsbean CompletionPartsBean the current part.
645      * @return boolean true if min equals max.
646      */
647     private boolean minEqualsMax(final CreationPartsBean partsbean) {
648         if (partsbean.getMinEntries() != null && partsbean.getMaxEntries() != null) {
649             if (partsbean.getMinEntries().intValue() == partsbean.getMaxEntries().intValue()) {
650                 return true;
651             }
652         }
653         return false;
654     }
655 
656 
657     private void setCommonPartsParameters(final CreationPartsBean partsbean, final String id,
658                                           final EmoWizardMetadata pageMetadata) throws DBException {
659 
660         pageMetadata.setCancelLink(cloneTransition(cancel, id));
661         pageMetadata.setNextLink(cloneTransition(next, id));
662 //        pageMetadata.setSummaryLink(cloneTransition(summary, id));
663         pageMetadata.setPreviousLink(cloneTransition(back, id));
664         pageMetadata.setTitle(partsbean.getPart().getParentEntity().getDisplayName() + "->"+ partsbean.getPart().getPartLabel());
665         pageMetadata.setDirective(partsbean.getDirective());
666         pageMetadata.setHelpText(partsbean.getHelpText());
667 
668         //The Wizard has metadata entry.
669         pageMetadata.setEntry(true);
670 
671     }
672 
673     /***
674      * Constructs 'how many entries' page metadata.  This is coupled with the
675      * multi-attribute pages and is ordered prior to those pages.
676      *
677      * @param partsbean CompletionPartsBean the current part bean.
678      * @param id        String page id.
679      * @return EmoWizardMetadata the emo wizard metadata previously constructed
680      * @throws DBException upon error.
681      */
682     private EmoWizardMetadata constructHowManyEntriesPageMetadata(final CreationPartsBean partsbean,
683                                                                   final String id) throws DBException {
684 
685         EmoWizardMetadata pageMetadata = new EmoWizardMetadata();
686         pageMetadata.setEntryRequired(false);
687         pageMetadata.setEntry(true);
688         pageMetadata.setCancelLink(cloneTransition(cancel, id));
689 
690         pageMetadata.setNextLink(cloneTransition(next, id));
691 //        pageMetadata.setSummaryLink(cloneTransition(summary, id));
692         pageMetadata.setPreviousLink(cloneTransition(back, id));
693         pageMetadata.setTitle("How many " + partsbean.getPart().getPartLabel());
694         pageMetadata.setDirective(buildMultiAttributeIntroDirective(partsbean));
695         pageMetadata.setViewId("HowManyAttributes");
696         return pageMetadata;
697     }
698 
699 
700     /***
701      * Custructs metadata based on custom handlers.
702      *
703      * @param partsbean CompletionPartsBean
704      * @param pageId    String
705      * @return EmoWizardMetadata
706      * @throws DBException
707      */
708     private CreationMetadata constructCustomHandlerPageMetadata(CreationPartsBean partsbean, String pageId) throws
709             DBException {
710         CustomPartHandlerMetadata pageMetadata = new CustomPartHandlerMetadata();
711         pageMetadata.setCancelLink(cloneTransition(cancel, pageId));
712 //        pageMetadata.setSummaryLink(cloneTransition(summary, pageId));
713         pageMetadata.setNextLink(cloneTransition(next, pageId));
714         pageMetadata.setPreviousLink(cloneTransition(back, pageId));
715         pageMetadata.setTitle(partsbean.getPart().getPartLabel());
716 
717         String directive = "Please enter settings. To learn more about the " +
718                 "choices, click on the label of a setting, and after reading more," +
719                 " navigate back to here with the browser's 'back' button. ";
720 
721         pageMetadata.setHelpText(directive);
722         pageMetadata.setDirective(directive);
723         partsbean.setDirective(directive);
724 
725 //      partsbean has access to the part, so use it to retrieve and remember custom handler class
726         String handlerClass = partsbean.getPart().getField(Part.SPECIAL_HANDLER);
727         pageMetadata.setCustomHandlerClassName(handlerClass);
728 
729         return pageMetadata;
730     }
731 
732     /***
733      * Construct a custom handler page.
734      *
735      * @param id           String id of page in wizard
736      * @param pageMetadata EmoWizardMetadata
737      * @return EmoWizardPage
738      * @throws Exception upon error.
739      * @todo Finish Me.
740      */
741     private EmoWizardPage constructCustomHandlerPage(CreationBean bean, String id,
742                                                      EmoWizardMetadata pageMetadata) throws Exception {
743 
744         /***
745          * @todo populate default page from custom handler.
746          */
747 
748         // store menus in metadata, default values in page
749         CustomPartHandlerMetadata customHandlerMetadata = (CustomPartHandlerMetadata) pageMetadata;
750         IPartHandler handler = customHandlerMetadata.getCustomHandler();
751         Integer templateId = bean.getTargetId();
752 
753         if (handler instanceof AbstractSettingHandler) {
754             if (customHandlerMetadata.getInputList() == null) {
755                 AbstractSettingHandler settingHandler = (AbstractSettingHandler) handler;
756                 List list = settingHandler.getInputs(templateId.toString());
757                 customHandlerMetadata.setInputList(list);
758                 customHandlerMetadata.setSettingPrototype(settingHandler.getSettingPrototype());
759             }
760         } else {
761             throw new Exception("unimplemented custom part: " + handler.getClass().getName());
762         }
763 
764         return (EmoWizardPage) new CustomPartHandlerPage(new Integer(id), pageMetadata);
765     }
766 
767 
768     private CreationMetadata constructMultiAttributePageMetadata(CreationPartsBean partsbean, String id) throws
769             DBException {
770         MultiEntryMetadata pageMetadata = new MultiEntryMetadata();
771         pageMetadata.setEntryRequired(false);
772         pageMetadata.setEntry(true);
773         pageMetadata.setCancelLink(cloneTransition(cancel, id));
774         pageMetadata.setNextLink(cloneTransition(next, id));
775 //        pageMetadata.setSummaryLink(cloneTransition(summary, id));
776         pageMetadata.setPreviousLink(cloneTransition(back, id));
777         pageMetadata.setTitle(partsbean.getPart().getPartLabel());
778         pageMetadata.setDirective(buildMultiAttributeIntroDirective(partsbean));
779         pageMetadata.setViewId("HowManyAttributes");
780         pageMetadata.setMinEntries(partsbean.getMinEntries());
781         pageMetadata.setMaxEntries(partsbean.getMaxEntries());
782 
783         //Now tweak the final page.
784         if (partsbean.getHelpText() == null || partsbean.getHelpText().length() == 0) {
785             pageMetadata.setHelpText("Page 2 of 2: Please enter values.");
786         } else {
787             pageMetadata.setHelpText("Page 2 of 2: " + partsbean.getHelpText());
788         }
789 
790         pageMetadata.setViewId("MultiAttributeWizardEntry");
791 
792         return pageMetadata;
793 
794     }
795 
796     /***
797      * Generates a unique page id that differentiates it from the parts pages.
798      *
799      * @return Integer
800      */
801     private Integer generatePreMultiAttributePageId() {
802         if (preMultiAttributeStepIds.size() == 0) {
803             Integer returnValue = new Integer(INITIAL_PRESTEP_ID);
804             preMultiAttributeStepIds.add(returnValue);
805             return returnValue;
806         } else {
807             Integer lowestInt = (Integer) preMultiAttributeStepIds.first();
808             Integer nextLowest = new Integer(lowestInt.intValue() - 1);
809             preMultiAttributeStepIds.add(nextLowest);
810             return nextLowest;
811         }
812     }
813 
814     /***
815      * Builds the directive for the 'multiple attribute' selection intro screens.
816      * The text creation logic is a little convoluted so since it depends on whether
817      * min or max is defined.
818      *
819      * @param partsbean CompletionPartsBean
820      * @return String the resulting string.
821      * @throws DBException upon Part query error.
822      */
823     private String buildMultiAttributeIntroDirective(CreationPartsBean partsbean) throws DBException {
824         StringBuffer buffer = new StringBuffer(128);
825         // @todo move layout to view tier
826         buffer.append("Page 1 of 2: How many ");
827         buffer.append(partsbean.getPart().getPartLabel());
828         buffer.append(" would you like to enter?");
829         boolean addedMin = false;
830         if (partsbean.getMinEntries() != null) {
831             addedMin = true;
832             buffer.append(" You must enter a minimum value of ");
833             buffer.append(partsbean.getMinEntries());
834         }
835 
836         boolean addedMax = false;
837         if (partsbean.getMaxEntries() != null) {
838             addedMax = true;
839             if (addedMin) {
840                 buffer.append(" and a maximum value of ");
841             } else {
842                 buffer.append("  You must enter a maximum value of");
843             }
844             buffer.append(partsbean.getMaxEntries());
845         }
846 
847         if (addedMin || addedMax) {
848             buffer.append(".");
849         }
850 
851         return buffer.toString();
852     }
853 
854     private EmoWizardPage constructInitializationPage(NodeType nodeType, String pageId, String partId){
855         InitializationPageMetadata pageMetadata = new InitializationPageMetadata();
856         pageMetadata.setCancelLink(cloneTransition(cancel, pageId));
857         pageMetadata.setNextLink(cloneTransition(next, pageId));
858 //        pageMetadata.setSummaryLink(cloneTransition(summary, pageId));
859         pageMetadata.setPreviousLink(cloneTransition(back, pageId));
860         pageMetadata.setPartId(partId);
861 //        pageMetadata.
862         pageMetadata.setViewId("Initialize");
863         if(partId==null){
864             //always make sure that the first object needs to be checked
865             //by the finalization step
866             pageMetadata.setFilled(true);
867         }
868 
869         String displayName = "";
870         try {
871             displayName = nodeType.getDisplayName();
872         } catch (DBException ex) {
873             displayName = "Node";
874         }
875         pageMetadata.setHelpText("Enter a <b>title</b> and <b>summary</b> for the new "+displayName);
876         pageMetadata.setTitle("Edit " + displayName);
877 //        pageMetadata.setDirective(getDefinition().getSummaryNonRaw());
878 //        pageMetadata.setEntry(false);
879 //        pageMetadata.setEntryRequired(true);
880         EmoWizardPage wizard = new EmoWizardPage(new Integer(pageId), pageMetadata,
881                 null);
882         return wizard;
883     }
884 
885     /***
886      * Construct the introduction page that is the first thing the user sees
887      * when the wizard is run.
888      *
889      * @return EmoWizardPage
890      */
891     private EmoWizardPage constructTitlePage() {
892         EmoWizardMetadata pageMetadata = new EmoWizardMetadata();
893         pageMetadata.setCancelLink(cloneTransition(cancel, EmoCreationWizard.TITLE_PAGE_ID));
894         pageMetadata.setNextLink(cloneTransition(next, EmoCreationWizard.TITLE_PAGE_ID));
895 //        pageMetadata.setSummaryLink(cloneTransition(summary, EmoCreationWizard.TITLE_PAGE_ID));
896         pageMetadata.setTitle(getDefinition().getWizardTitle());
897         pageMetadata.setDirective(getDefinition().getSummaryNonRaw());
898         pageMetadata.setEntry(false);
899 
900         return new EmoWizardPage(new Integer(EmoCreationWizard.TITLE_PAGE_ID), pageMetadata,
901                 null);
902     }
903 
904     /***
905      * Construct the final page for the wizard that is displayed before the user
906      * clicks the finish button.
907      *
908      * @return EmoWizardPage
909      * @throws DBException upon error querying the underlying data objects.
910      */
911     private EmoWizardPage constructCompletionPage(CreationBean bean) throws DBException {
912 
913         CreationBean cb = bean;
914         EmoWizardMetadata pageMetadata = new EmoWizardMetadata();
915         pageMetadata.setCancelLink(cloneTransition(cancel, EmoCreationWizard.FINAL_PAGE_ID));
916         pageMetadata.setFinishLink(cloneTransition(finish, EmoCreationWizard.FINAL_PAGE_ID));
917         pageMetadata.setPreviousLink(cloneTransition(back, EmoCreationWizard.FINAL_PAGE_ID));
918 
919         // @todo move layout to view tier
920         String nodeTitleId = " <strong>&quot;" + cb.getCurrentNodeType().getDisplayName()
921                 + "&quot;</strong> Template (" + cb.getCurrentNodeType().getId() + ") ";
922 
923         pageMetadata.setTitle("Finishing creation wizard for " + cb.getCurrentNodeType().getDisplayName());
924         pageMetadata.setHelpText(nodeTitleId);
925         pageMetadata.setDirective(
926                 "The values you entered are summarized below. Click 'next' to save those values into" + nodeTitleId + "and finish the wizard.");
927         pageMetadata.setEntry(false);
928         pageMetadata.setViewId("Confirm");
929         return new EmoWizardPage(new Integer(EmoCreationWizard.FINAL_PAGE_ID), pageMetadata,
930                 null);
931     }
932 
933 }