View Javadoc

1   
2   
3   
4   package com.sri.emo.wizard.creation;
5   
6   import java.io.*;
7   import java.util.*;
8   
9   import com.jcorporate.expresso.core.controller.*;
10  import com.jcorporate.expresso.core.dataobjects.*;
11  import com.jcorporate.expresso.core.db.*;
12  import com.jcorporate.expresso.core.db.exception.*;
13  import com.jcorporate.expresso.core.registry.*;
14  import com.sri.common.util.*;
15  import com.sri.emo.dbobj.*;
16  import com.sri.emo.wizard.*;
17  import com.sri.emo.wizard.branch.*;
18  import com.sri.emo.wizard.creation.model.*;
19  import com.sri.emo.wizard.expressoimpl.*;
20  
21  /***
22   * A completion wizard.
23   * For the completion wizard pages, ids are java.lang.Integer types with values
24   * <= 0 are special pages.  Any values >0 represent a corresponding Part.
25   * Developers should use isPartsPage() for interpretation of this, however.
26   *
27   * @author Michael Rimov
28   */
29  public class EmoCreationWizard extends BranchingWizard {
30  
31  
32      /***
33       * Constant for the title page id.
34       */
35      public static final String TITLE_PAGE_ID = "-2";
36  
37      /***
38       * Constant for the initialization page id
39       */
40      public static final String INITIALIZATION_PAGE_ID = "-3";
41  
42      /***
43       * Constant for the last page (where 'finish' appears) id.
44       */
45      public static final String FINAL_PAGE_ID = "-1";
46  
47      public static final String DEFAULT_TRANSITION_KEY = "button_Next";
48  
49      public static final String SEARCH_TRANSITION = "Search";
50      public static final String BROWSE_TRANSITION = "Browse";
51      public static final String CREATE_TRANSITION = "Create";
52  
53      public static final String SUMMARY_TRANSITION = "Summary";
54  
55      /***
56       * Underlying completion data bean. This object is not serialized due
57       * to space considerations since it is stateless for the given wizard.
58       * However, for saving state and reconsistuting it via the <tt>Memento</tt>
59       * pattern, then it is set/reset during that phase.
60       */
61      private transient CreationBeans completionBeans;
62  
63      /***
64       * Constructs an emo completion wizard.
65       *
66       * @param wizMonitor WizardMonitor
67       * @param steps      WizardPage[]
68       */
69      public EmoCreationWizard(final WizardMonitor wizMonitor, final BranchNode[] steps) {
70          super(wizMonitor, steps);
71          System.out.println("new EmoCreationWizard generated!");
72      }
73  
74      public SearchResultBean getCurrentSearchBean(){
75          return getSearchResult(getCurrentPage().getId());
76      }
77  
78  
79      public SearchResultBean addSearchResult(Serializable pageId) {
80          SearchResultBean bean = new SearchResultBean();
81          bean.setPageId(pageId);
82          ((SearchListPage)this.getPageById(pageId)).setSearchBean(bean);
83          return bean;
84      }
85  
86      public SearchListPage getSearchListPage(Serializable pageId){
87          return (SearchListPage)this.getPageById(pageId);
88      }
89      public SearchResultBean getSearchResult(Serializable pageId) {
90          return ((SearchListPage)this.getPageById(pageId)).getSearchBean();
91      }
92  
93      /***
94       * Override of Sequential's onNextPage to allow for validation of values
95       * as they're entered.
96       *
97       * @param previousPage     WizardPage
98       * @param nextPage         The next page that will be invoked.  A 'lookahead' so
99       *                         to speak.
100      * @param previousPageData Serializable
101      * @return boolean true if the wizard can proceed, false if the previous
102      *         page needs to be displayed with validation errors.
103      * @throws WizardException upon error.
104      * @throws AssertionError  if the previouspage id is the final page.
105      */
106     protected boolean onNextPage(final WizardPage previousPage, final WizardPage nextPage,
107                                  final Serializable previousPageData) throws WizardException, AssertionError {
108 
109         Integer previousPageId = (Integer) previousPage.getId();
110         assert previousPageId != null;
111         System.out.println("onNextPage()");
112         System.out.println("PREVIOUS: " + previousPage);
113         System.out.println("NEXT PG:  " + nextPage);
114         System.out.println("previousPageData: " + previousPageData);
115 //        try {
116 //            System.out.println("title = " +
117 //                               getCompletionBean().getCurrentNode().getNodeTitle());
118 //        } catch (DBException ex) {
119 //            ex.printStackTrace();
120 //        }
121         if(isInitializationPage(previousPage, previousPageId)){
122             InitializationPageMetadata metaData = (InitializationPageMetadata)previousPage.getMetadata();
123             metaData.setFilled(true);
124             CreationBean bean = getCompletionBean().getCreationBeanByPartId(metaData.getPartId());
125 //            bean.setNewBean(true);
126             System.out.println("Setting bean: " + bean.getTargetId() + " as new");
127             System.out.println("INITIALIZATION PAGE CLEARING = " + bean.toString());
128             System.out.println("search page = " + bean.getSearchPage());
129             if(bean.getSearchPage() != null){
130                 bean.getSearchPage().getSearchBean().setSearched(false);
131                 bean.getSearchPage().getSearchBean().clearSelectedSearchResults();
132             }
133             return validateInitializationPageData(previousPage, previousPageData);
134         }
135         else if(isSearchPage(previousPageData)){
136             return performSearch(previousPage, nextPage, previousPageData);
137         }
138         else if(isBrowsePage(previousPageData)){
139             return performBrowse(previousPage, nextPage, previousPageData);
140         }
141         else if(isSearchResultPage(previousPage)){
142 //            getCompletionBean().getCurrentBean().setNewBean(false);
143             InitializationPageMetadata page = getInitPage(getCompletionBean().getCurrentBean().getPartId());
144             if(getCompletionBean().getCurrentBean().getCurrentNodeType().equals(((SearchListPage)previousPage).getNodeType())){
145                 page.setFilled(false);
146             }
147             return saveSearchParams(previousPage, previousPageData);
148         }
149         //If we have a part page
150         else if (isPartsPage(previousPageId)) {
151             //validate part entry.
152             return validatePartPageData(previousPage, previousPageData);
153             //Or if we have a title page.
154         } else if (TITLE_PAGE_ID.equals(previousPageId.toString())) {
155             //Then return true/
156             return true;
157 
158             //Or if we have the final page.
159         } else if (FINAL_PAGE_ID.equals(previousPageId.toString())) {
160             assert false:"Final page should not have gotten 'onNext' event";
161             throw new WizardException("Internal Error: received 'next' where the previous page "
162                     + "was the final page.  Wizard is incorrectly constructed.");
163         } else {
164 
165             //Consider if the next page is a multi attribute page, then the current
166             //date must be the number of steps.
167             if (nextPage.getMetadata() instanceof MultiEntryMetadata) {
168                 boolean returnValue = validatePreMultiAttributesPage(previousPage, nextPage, previousPageData);
169                 returnValue &= super.onNextPage(previousPage, nextPage, previousPageData);
170                 return returnValue;
171 //                if (returnValue && ((MultiEntryWizardPage)nextPage).getNumEntries() == 0) {
172 //                    return returnValue
173 //                }
174             }
175 
176             //
177             //We don't have to do anything to make everything work.
178             //
179         }
180 
181         //
182         //Super class will return false if the page itself has errors.
183         //
184         return super.onNextPage(previousPage, nextPage, previousPageData);
185     }
186 
187     private InitializationPageMetadata getInitPage(Serializable partId){
188         String partIdStr = null;
189         if(partId != null){
190             partIdStr = partId.toString();
191         }
192         System.out.println("getInitPage("+partIdStr+")");
193         for (int i = 0; i < getAllSteps().length; i++) {
194             WizardPage oneStep = getAllSteps()[i].getPage();
195             System.out.println("checking " + oneStep.getId());
196             if(oneStep.getMetadata() instanceof InitializationPageMetadata){
197                 InitializationPageMetadata metadata = (InitializationPageMetadata)oneStep.getMetadata();
198                 if(partIdStr == null && metadata.getPartId() == null){
199                     System.out.println("filled = " + metadata.isFilled());
200                     return metadata;
201                 }
202                 else if(metadata.getPartId() != null && metadata.getPartId().equals(partIdStr)){
203                     System.out.println("filled = " + metadata.isFilled());
204                     return metadata;
205                 }
206             }
207         }
208         return null;
209     }
210 
211     /***
212      * saveSearchParams
213      *
214      * @param previousPage WizardPage
215      * @param previousPageData Serializable
216      * @return boolean
217      */
218     private boolean saveSearchParams(WizardPage previousPage,
219                                      Serializable previousPageData) {
220         System.out.println("previousPageData = " + previousPageData);
221         System.out.println("previous = " + previousPage.getData());
222         if(previousPageData != null){
223             System.out.println("saveSearchParams = " +
224                                previousPageData.getClass());
225         }
226         SearchListPage resultsPage = (SearchListPage)previousPage;
227 //        WizardPage sourcePage = getPageById(resultsPage.getSourcePageId());
228 //        sourcePage.setData(previousPageData);
229         try {
230             if (previousPageData instanceof String) {
231                 System.out.println("previousPageData was String");
232                 int i = Integer.parseInt((String) previousPageData);
233                 System.out.println("node " + i + " selected");
234                 getSearchResult(previousPage.getId()).setSelectedNode(i);
235             }
236             else if (previousPageData instanceof List) {
237                 List list = (List) previousPageData;
238                 Iterator iter = list.iterator();
239                 System.out.println("previousPageData was List");
240                 while (iter.hasNext()) {
241                     String item = iter.next().toString();
242                     int i = Integer.parseInt(item);
243                     System.out.println("node " + i + " selected");
244                     getSearchResult(previousPage.getId()).setSelectedNode(i);
245                 }
246             }else{
247                 System.out.println("previousPageData not matching!!!");
248             }
249         } catch (DBException ex) {
250             ex.printStackTrace();
251             previousPage.addError("Error accessing database");
252             return false;
253         } catch (NumberFormatException ex) {
254             ex.printStackTrace();
255             previousPage.addError("Invalid node entered");
256             return false;
257         }
258         return true;
259     }
260 
261 
262     /***
263      * isSearchResultPage
264      *
265      * @param previousPage WizardPage
266      * @return boolean
267      */
268     private boolean isSearchResultPage(WizardPage previousPage) {
269         return previousPage instanceof SearchListPage;
270 //        return getSearchResult(previousPage.getId()) != null;
271     }
272 
273     private boolean performBrowse(final WizardPage previousPage, final WizardPage nextPage,
274                                   final Serializable previousPageData) {
275         return performSearch(previousPage, nextPage, previousPageData, true);
276     }
277 
278     private boolean performSearch(final WizardPage previousPage, final WizardPage nextPage,
279                                  final Serializable previousPageData) {
280         return performSearch(previousPage, nextPage, previousPageData, false);
281     }
282 
283     /***
284      * performSearch
285      *
286      * @param previousPageData Serializable
287      * @param nextPage WizardPage
288      * @return boolean
289      */
290     private boolean performSearch(final WizardPage previousPage, final WizardPage nextPage,
291                                  final Serializable previousPageData, boolean browse) {
292         if(!(previousPageData instanceof Map)){
293             throw new IllegalArgumentException(
294                     "previousPageData was expected to be of type java.util.Map, instead found " +
295                     previousPageData.getClass());
296         }
297         Map data = (Map)previousPageData;
298         String keywords = (String) data.get("Keywords");
299         if(!browse){
300             if (keywords == null || keywords.trim().length() == 0) {
301                 previousPage.addError(
302                         "Please enter a value for the keywords to search");
303                 return false;
304             }
305         }
306         System.out.println("keywords = " + keywords);
307         keywords = keywords.toLowerCase();
308 
309         Node searchParam = null;
310         try {
311             searchParam = new Node();
312 //            previousPage.getMetadata()
313 //            searchParam.setNodeType(this.getCompletionBean().getCurrentNode().getNodeType());
314             searchParam.setNodeType(((SearchListPage)previousPage).getNodeType());
315 //            searchParam.setCustomWhereClause("NODE_TYPE="NODE_TITLE LIKE '%"+keywords+"%' OR NODE_ANNOTATION LIKE '%"+keywords+"%' OR NODE_COMMENT LIKE '%"+keywords+"%'");
316             System.out.println("node type set as '"+searchParam.getNodeType()+"'");
317 //            if(!browse){
318 //                searchParam.setNodeOwner(keywords);
319 //            }
320             searchParam.search();
321             Object keys[] = searchParam.getFoundKeysArray();
322             System.out.println("found " + keys.length + " keys");
323             System.out.println(StringUtil.toString(keys));
324             List list = searchParam.searchAndRetrieveList();
325             List trimmedList = list;
326 //            searchParam.retrieve();
327             Iterator it = null;
328             if(!browse){
329                 trimmedList = new Vector(20);
330                 it = list.iterator();
331                 while(it.hasNext()){
332                     Node n = (Node)it.next();
333                     if(hasKeyword(n, keywords)){
334                         trimmedList.add(n);
335                     }
336                 }
337             }
338 
339             it = trimmedList.iterator();
340             List nodes = new ArrayList(list.size());
341 //            Map dataToSet = new HashMap();
342             while(it.hasNext()){
343                 Node n = (Node)it.next();
344 //                System.out.println("retrieved " + n);
345                 SearchNode node = new SearchNode();
346                 node.setNode(n);
347                 nodes.add(node);
348             }
349             /***
350              * @todo figure out how to add the retrieved list as input to the
351              * next page
352              */
353 //            PageMetadata metaData = nextPage.getMetadata();
354             SearchResultBean searchBean = ((SearchListPage)nextPage).getSearchBean();
355 //            if(searchBean == null){
356 //                searchBean = addSearchResult(nextPage.getId());
357 //            }
358 //            System.out.println("searchBean.nodes set to " + nodes);
359 //            System.out.println("values = " + StringUtil.toString(nodes));
360             searchBean.setSearched(true);
361             searchBean.setNodes(nodes);
362 
363         } catch (DBException ex) {
364             previousPage.addError(ex.getMessage());
365             return false;
366         }
367 
368         return true;
369     }
370 
371     /***
372      * hasKeyword
373      *
374      * @param n Node
375      * @param keywords String
376      * @return boolean
377      */
378     private boolean hasKeyword(Node n, String keywords) throws DBException {
379         if(n.getNodeTitle().toLowerCase().indexOf(keywords) >= 0){
380             return true;
381         }
382         if(n.getNodeCommentRaw().toLowerCase().indexOf(keywords) >= 0){
383             return true;
384         }
385         if(n.getNodeAnnotationRaw().toLowerCase().indexOf(keywords) >= 0){
386             return true;
387         }
388         //temporarily adding in focal KSAs for design pattern
389 //        if(n.getNodeType().equals("PARADIGM_TYPE")){
390 //            Part[] p = n.getParts();
391 //            for(int i = 0; i < p.length; i++){
392 //                p[i].get
393 //            }
394 //        }
395         return false;
396     }
397 
398     /***
399      * isSearchPage
400      *
401      * @param previousPage WizardPage
402      * @return boolean
403      */
404     private boolean isSearchPage(Serializable pageData) {
405         if(!(pageData instanceof Map)){
406             return false;
407         }
408         Map map = (Map) pageData;
409         String transition = (String) map.get(DEFAULT_TRANSITION_KEY);
410         System.out.println(DEFAULT_TRANSITION_KEY + " transition is " + map.get(DEFAULT_TRANSITION_KEY));
411         return SEARCH_TRANSITION.equals(transition);
412     }
413 
414 
415     private boolean isBrowsePage(Serializable pageData) {
416         if(!(pageData instanceof Map)){
417             return false;
418         }
419         Map map = (Map) pageData;
420         String transition = (String) map.get(DEFAULT_TRANSITION_KEY);
421         return BROWSE_TRANSITION.equals(transition);
422     }
423     /***
424      * validateInitializationPageData
425      *
426      * @param previousPage WizardPage
427      * @param previousPageData Serializable
428      * @return boolean
429      */
430     private boolean validateInitializationPageData(WizardPage src,
431             Serializable previousPageData) {
432         System.out.println("page data = " + previousPageData.getClass());
433         System.out.println("is = " + previousPageData);
434         List list = (List)previousPageData;
435 //        Map map = (Map)previousPageData;
436 //        String title = (String)map.get(WizardController.WIZ_DATA_ID);
437         String title  = (String) list.get(0);
438         if(title == null || title.length() == 0){
439             src.addError("Please enter a title.");
440             return false;
441         }
442             try {
443                 Node testNode = new Node(RequestRegistry.getUser());
444                 testNode.setNodeTitle(title);
445                 System.out.println("node type = " + testNode.getNodeType());
446                 if (testNode.find()) {
447                     src.addError(
448                             "Title is already in use; please choose another.");
449                     return false;
450                 }
451             } catch (DBException ex1) {
452                 src.addError(ex1.getMessage());
453                 return false;
454             }
455         try {
456             /***
457              * @todo rich: make sure this still works
458              */
459             completionBeans.getCurrentBean().getCurrentNode().set(Node.NODE_TITLE, title);
460         } catch (DataException ex) {
461             src.addError(ex.getMessage());
462             return false;
463         }
464         return true;
465     }
466 
467     /***
468      * isInitializationPage
469      *
470      * @param previousPageId Integer
471      * @return boolean
472      */
473     private boolean isInitializationPage(WizardPage previousPage, Integer previousPageId) {
474         return previousPage.getMetadata() instanceof InitializationPageMetadata;
475 //        Integer i = new Integer(INITIALIZATION_PAGE_ID);
476 //        return i.equals(previousPageId);
477     }
478 
479 
480     private boolean validatePreMultiAttributesPage(final WizardPage previousPage, final WizardPage nextPage,
481                                                    final Serializable previousPageData) {
482 //        if (previousPageData == null) {
483 //            previousPage.addError("You must enter a value for this page");
484 //            return false;
485 //        }
486 
487         MultiEntryWizardPage multiNextPage = (MultiEntryWizardPage) nextPage;
488         MultiEntryMetadata nextPageMetadata = (MultiEntryMetadata) nextPage.getMetadata();
489 
490         int numEntries = 0;
491         try {
492 
493             if (previousPageData == null || ((String) previousPageData).trim().length() == 0) {
494                 numEntries = 0;
495             } else {
496                 numEntries = Integer.parseInt((String) previousPageData);
497             }
498         } catch (NumberFormatException ex) {
499             previousPage.addError("You must enter a valid number for this page");
500             return false;
501         }
502 
503         boolean hadError = false;
504 //        if (nextPageMetadata.getMinEntries() != null
505 //                && numEntries < nextPageMetadata.getMinEntries().intValue()) {
506 //            previousPage.addError(
507 //                "Too few. You must enter a value greater than or equal to the minimum number of entries: "
508 //                + nextPageMetadata.getMinEntries());
509 //            hadError = true;
510 //        }
511 
512         if (nextPageMetadata.getMaxEntries() != null
513                 && numEntries > nextPageMetadata.getMaxEntries().intValue()) {
514             previousPage.addError(
515                     "Too many. You must enter a value less than or equal to the maximum number of entries: "
516                             + nextPageMetadata.getMaxEntries());
517             hadError = true;
518         }
519 
520         if (hadError) {
521             return false;
522         }
523 
524         multiNextPage.setNumEntries(numEntries);
525         return true;
526     }
527 
528     /***
529      * Constant for the minimum possible part number.  Anything else is a
530      * 'special page' of some sort.
531      */
532     private static final int MIN_PARTS_NUMBER = 0;
533 
534     /***
535      * Overridden target node id.  This must be explicitly set by the
536      * wizard controller. Otherwise we use the completion bean.
537      */
538 //    private String targetNodeId;
539 
540     /***
541      * Checks if the given page Id indicates it is a
542      * 'Parts' page.
543      *
544      * @param pageId Integer
545      * @return boolean
546      */
547     protected boolean isPartsPage(final Integer pageId) {
548         assert pageId != null;
549 
550         return pageId.intValue() >= MIN_PARTS_NUMBER;
551     }
552 
553     /***
554      * @param src         WizardPage
555      * @param enteredData Serializable
556      * @return boolean true if the data was validated.
557      * @throws WizardException upon error.
558      */
559     private boolean validatePartPageData(final WizardPage src, final Serializable enteredData) throws WizardException {
560         int partId = ((Integer) src.getId()).intValue();
561 
562         try {
563             Part onePart = new Part();
564             onePart.setPartId(partId);
565             onePart.retrieve();
566             //If single valued, then validate it.
567 //            * @todo Finish here when Part has custom handler.
568             if (onePart.isSingleValued()) {
569                 if (enteredData == null) {
570                     src.addError("Please enter a value for this page.");
571                     return false;
572                 }
573             }
574         } catch (DBRecordNotFoundException ex) {
575             throw new WizardException("Could not find part of id: " + partId
576                     + " perhaps it was deleted by someone else?", ex);
577         } catch (Throwable ex) {
578             throw new WizardException("Error processing page for part id: " + partId, ex);
579         }
580 
581         return true;
582     }
583 
584     protected boolean includeInMainStep(BranchNode node){
585         CreationBean bean = getCompletionBean().getCreationBeanByPartId(node.getPage().getId().toString());
586 
587 
588 //        if(bean != null){
589 //           return bean.isNewBean();
590 //        }
591 //        node.getPage().
592 //        System.out.println("EmoCreationWizard.includeInMainStep() " + node.getPage().getId());
593 //        System.out.println("page data = " + node.getPage().getData());
594 //        if(isSearchResultPage(node.getPage())){
595 //            System.out.println("false");
596 //            return false;
597 //        }
598 //        System.out.println("false");
599         return true;
600     }
601     /***
602      * This version returns a <tt>Node<tt> instance if one has
603      * been successfully created.
604      * <p>{@inheritDoc}</p>
605      *
606      * @param src             WizardPage the source of the event.
607      * @param data            This class expects a string for the data.
608      * @param additonalParams anything that the underlying wizard needs. The
609      *                        values are set by the Application Controller.
610      * @return An instance of a {@link com.sri.emo.dbobj.Node} object
611      *         that represents the node the Decision Matrix returned or null if
612      *         there was no equivilant data found.
613      * @throws WizardException upon error.
614      */
615     public Object processFinish(final WizardPage src, final Serializable data,
616                                 final Map additonalParams) throws WizardException {
617         super.processFinish(src, data, additonalParams);
618 
619         assert src != null;
620 
621         /***
622          * @todo rich: process finish for all of the nodes, not just the main one
623          */
624         Node node = getCompletionBean().getCreationBean(0).getCurrentNode();
625         System.out.println("processFinish : " + node.toDebugString());
626         try {
627             if(!verifyRequiredAttributes(src)){
628                 return null;
629             }
630             copyReqDataIntoTargetNode(node, EmoCreationWizard.INITIALIZATION_PAGE_ID);
631             node.add();
632             copyDataIntoTargetNode(node);
633         } catch (DBException ex) {
634             src.addError(ex.getMessage());
635             throw new WizardException(ex);
636         } catch (Exception e) {
637             src.addError(e.getMessage());
638 
639             if (e instanceof RuntimeException) {
640                 throw (RuntimeException) e;
641             } else {
642                 throw new WizardException(e);
643             }
644         }
645         // only save data if we have 'dynamic target', i.e., specified by param at beginning of
646         // web call, as opposed to 'model' target ID, which was used to design this wizard
647 //        if (this.isDynamicTarget()) {
648 //            try {
649 //                node = new Node();
650 //                node.setNodeId(getTargetNodeId());
651 //                node.retrieve();
652 //
653 //                copyDataIntoTargetNode(node);
654 //
655 //            } catch (DBRecordNotFoundException ex) {
656 //                String message = "Could not find node of id: " + getTargetNodeId();
657 //                src.addError(message + " with error: " + ex.getMessage());
658 //                throw new WizardException(message, ex);
659 //            } catch (Exception e) {
660 //                src.addError(e.getMessage());
661 //
662 //                if (e instanceof RuntimeException) {
663 //                    throw (RuntimeException) e;
664 //                } else {
665 //                    throw new WizardException(e);
666 //                }
667 //            }
668 //        } else {
669 //            src.addError("Cannot save to source of wizard design; expected a different (cloned?) destination");
670 //        }
671 
672         return node;
673     }
674 
675     /***
676      * verifyRequiredAttributes
677      */
678     private boolean verifyRequiredAttributes(WizardPage src) throws DBException,
679             NumberFormatException, WizardException {
680         Iterator keyIterator = this.getAllData().keySet().iterator();
681         boolean requiredFilled = true;
682 
683 //        while(keyIterator.hasNext()){
684 //            Integer key = (Integer)keyIterator.next();
685 //            Object wizardData = this.getAllData().get(key);
686 //            PageMetadata metadata = getPageById(key).getMetadata();
687 //            boolean required = metadata.isEntryRequired();
688 //            if(required){
689 //                if(wizardData == null){
690 //                    src.addError(metadata.getTitle() + " was marked as a required field, but has not been set, please fix.");
691 //                    requiredFilled = false;
692 //                }
693 //                else if(wizardData instanceof Collection &&
694 //                   ((Collection)wizardData).size() == 0){
695 //                    src.addError(metadata.getTitle() + " was marked as a required field, but has not been set, please fix.");
696 //                    requiredFilled = false;
697 //                    }
698 //            }
699 //        }
700 
701 
702         CreationBeans completionBeans = this.getCompletionBean();
703 
704 
705         Iterator iter = completionBeans.iterator();
706         while (iter.hasNext()) {
707             CreationBean completionBean = (CreationBean) iter.next();
708             System.out.println("Verifying filled attributes for " + completionBean.getTargetId());
709             InitializationPageMetadata page = getInitPage(completionBean.getPartId());
710             System.out.println("page is filled = " + page.isFilled());
711             if(page.isFilled()){
712                 for (Iterator partsIterator = completionBean.getCompletionParts().
713                                               iterator(); partsIterator.hasNext(); ) {
714                     CreationPartsBean onePartBean = (CreationPartsBean)
715                             partsIterator.next();
716                     //Skip parts beans that have no data.
717                     if (onePartBean.getFieldCompletion() ==
718                         FieldCompletion.NOT_INCLUDED) {
719                         continue;
720                     }
721 
722                     Part currentPart = onePartBean.getPart();
723                     System.out.println("working on part type " +
724                                        currentPart.getPartType());
725                     System.out.println("part id = " + currentPart.getId());
726                     System.out.println("all data = " +
727                                        StringUtil.toString(getAllData().
728                             entrySet()));
729                     //Retrieves the data value for that part.
730                     Object wizardData = this.getAllData().get(new Integer(
731                             currentPart.getId()));
732                     if (onePartBean.isRequired()) {
733                         System.out.println(currentPart.getPartType() +
734                                            " is required");
735                         if (wizardData != null) {
736                             System.out.println("data = '" + wizardData +
737                                                "' class:" +
738                                                wizardData.getClass());
739                         }
740                         InitializationPageMetadata otherPage = getInitPage(currentPart.getId());
741                         if(otherPage != null && otherPage.isFilled()){
742                             System.out.println("found a bean and it is marked as having it's parts filled");
743                             System.out.println("bean: " + otherPage.getPartId());
744                             continue;
745                         }
746 
747                         if (wizardData == null) {
748                             src.addError(currentPart.getPartLabel() +
749                                     " was marked as a required field, but has not been set, please fix.");
750                             requiredFilled = false;
751                         } else if (wizardData instanceof Collection &&
752                                    ((Collection) wizardData).size() == 0) {
753                             src.addError(currentPart.getPartLabel() +
754                                     " was marked as a required field, but has not been set, please fix.");
755                             requiredFilled = false;
756                         }
757                     }
758                 }
759             }
760         }
761         return requiredFilled;
762     }
763 
764     /***
765      * copyReqDataIntoTargetNode
766      *
767      * @param node Node
768      */
769     private void copyReqDataIntoTargetNode(Node node, String initializationPageId) throws DataException {
770         Map allData = this.getAllData();
771         System.out.println("All Data = " +
772                            StringUtil.toString(allData.keySet().iterator()));
773 //        System.out.println("init page class = " + allData.get(new Integer(EmoTemplateWizard.
774 //                INITIALIZATION_PAGE_ID)).getClass());
775         List list = (List)allData.get(new Integer(initializationPageId));
776         String title  = (String) list.get(0);
777         String summary = (String) list.get(1);
778         String comment = (String) list.get(2);
779         System.out.println("found title as '" + title + "'");
780         node.set(Node.NODE_TITLE, title);
781         node.set(Node.NODE_ANNOTATION, summary);
782         node.set(Node.NODE_COMMENT, comment);
783     }
784 
785 
786     /***
787      * Returns true if the dynamic target has been specified.
788      *
789      * @return boolean
790      */
791     protected boolean isDynamicTarget() {
792         //changed by rich
793         //always dynamic target?
794         return true;
795 //        if (this.getCompletionBean().getTargetId().intValue() == Integer.parseInt(this.getTargetNodeId())) {
796 //            return false;
797 //        } else {
798 //            return true;
799 //        }
800     }
801 
802     /***
803      * Copies the wizard data into the given node.
804      *
805      * @param target Node The node that is set to receive all the data.
806      * @throws Exception upon consturction error, and database errors.
807      */
808     private void copyDataIntoTargetNode(final Node target) throws Exception {
809         CreationBeans completionBeas = this.getCompletionBean();
810         Iterator iter = completionBeans.iterator();
811         while (iter.hasNext()) {
812             CreationBean completionBean = (CreationBean) iter.next();
813             for (Iterator partsIterator = completionBean.getCompletionParts().
814                                           iterator();
815                                           partsIterator.hasNext(); ) {
816                 CreationPartsBean onePartBean = (CreationPartsBean) partsIterator.
817                                                 next();
818                 //Skip parts beans that have no data.
819                 if (onePartBean.getFieldCompletion() ==
820                     FieldCompletion.NOT_INCLUDED) {
821                     continue;
822                 }
823 
824                 Part currentPart = onePartBean.getPart();
825                 System.out.println("working on part type " +
826                                    currentPart.getPartType());
827 
828                 //Retrieves the data value for that part.
829                 Object wizardData = this.getAllData().get(new Integer(currentPart.
830                         getId()));
831 
832                 if (currentPart.isHaveCustomHandler()) {
833 
834                     CustomPartHandlerMetadata meta = (CustomPartHandlerMetadata)
835                                                      getCurrentPage().getMetadata();
836                     IPartHandler handler = meta.getCustomHandler();
837                     List inputs = meta.getInputList();
838 
839                     for (Iterator iterator = inputs.iterator(); iterator.hasNext(); ) {
840                         Input input = (Input) iterator.next();
841                         handler.saveInput(input);
842                     }
843 
844                 } else if (currentPart.isOwnedAttribute()) {
845                     //TODO Transaction Me
846                     if (currentPart.isMultipleAllowed()) {
847                         List valueList = (List) wizardData;
848     //                    assert valueList != null:"Got null values from wizard page: " + onePartBean.toString();
849                         if (valueList == null) {
850                             valueList = new ArrayList(0);
851                         }
852 
853                         Attribute[] attributes = target.getAttributes(currentPart.
854                                 getPartType());
855                         //Don't worry about existing attributes since the wizard ones replace
856                         //whatever is there, so we go from there.
857                         for (int attributeIndex = 0;
858                                                   attributeIndex < attributes.length;
859                                                   attributeIndex++) {
860                             attributes[attributeIndex].delete(true);
861                         }
862 
863                         for (Iterator pageValuesIterator = valueList.iterator();
864                                 pageValuesIterator.hasNext(); ) {
865                             String onePageValue = (String) pageValuesIterator.next();
866                             System.out.println("adding attribute " +
867                                                currentPart.getPartType() + " as " +
868                                                onePageValue);
869                             target.addAttribute(currentPart.getPartType(),
870                                                 onePageValue,
871                                                 "");
872                         }
873 
874                     } else {
875     //                    System.out.println("
876                         Attribute[] attributes = target.getAttributes(currentPart.
877                                 getPartType());
878                         System.out.println("attribute.length = " +
879                                            attributes.length);
880                         for (int i = 0; i < attributes.length; i++) {
881                             System.out.println(attributes[i].getAttribValue());
882                         }
883     //                    System.out.println(StringUtil.toString(attributes));
884                         assert attributes.length == 0 || attributes.length == 1:
885                                 "Expected only zero or one attributes returned for single attribute";
886 
887                         if (attributes.length == 0) {
888                             if (wizardData != null) {
889                                 target.addAttribute(currentPart.getPartType(),
890                                                     wizardData.toString(), "");
891                             }
892                         } else {
893                             if (wizardData == null) {
894                                 target.removeAttribute(attributes[0].getAttribId());
895                             } else {
896                                 target.updateAttribute(attributes[0].getAttribId(),
897                                         wizardData.toString(), "");
898                             }
899                         }
900                     }
901 
902                 } else if (currentPart.isSharedNodeAttrib()) {
903                     //TODO Transaction Me
904                     System.out.println("current part = " + currentPart.getId());
905                     System.out.println("part label = " + currentPart.getPartLabel() + ", type = " + currentPart.getPartType());
906                     if(wizardData != null){
907                         System.out.println("wizardData is of class : " +
908                                            wizardData.getClass());
909                     }
910                     assert wizardData instanceof Set;
911 
912                     Set allRelationsParameterMap = (Set) wizardData;
913                     if (allRelationsParameterMap == null) {
914                         allRelationsParameterMap = new HashSet(0);
915                     }
916                     String[] allRelationIds = (String[]) allRelationsParameterMap.
917                                               toArray(
918                                                       new String[
919                                                       allRelationsParameterMap.size()]);
920 
921                     target.updateNodeRelations(currentPart.getPartType(),
922                                                currentPart.getNodeRelation(),
923                                                allRelationIds);
924                 }
925 
926             }
927         }
928     }
929 
930 // commented out by rich, we use the node within the templatebean instead
931 //of a target node within the DB
932 //    public String getTargetNodeId() {
933 //        assert completionBean != null;
934 //
935 //        if (targetNodeId == null) {
936 //            return this.completionBean.getTargetId().toString();
937 //        } else {
938 //            return targetNodeId;
939 //        }
940 //    }
941 
942 //    public Node getTargetNode() throws WizardException {
943 //        try {
944 //            Node n = new Node();
945 //            n.setNodeId(this.getTargetNodeId());
946 //            n.retrieve();
947 //            return n;
948 //        } catch (DBRecordNotFoundException ex) {
949 //            throw new WizardException("Could no longer find template of id: " + getTargetNodeId()
950 //                    + " perhaps someone else deleted it?");
951 //        } catch (DBException ex) {
952 //            throw new WizardException("Error querying database", ex);
953 //        }
954 //    }
955 
956     /***
957      * Sets the underlying completion bean.
958      *
959      * @param completionBean CompletionBean
960      */
961     public void setCompletionBeans(final CreationBeans completionBeans) {
962         this.completionBeans = completionBeans;
963     }
964 
965 //    public void setTargetNodeId(final String targetNodeId) {
966 //        this.targetNodeId = targetNodeId;
967 //    }
968 
969     public CreationBeans getCompletionBean() {
970         return completionBeans;
971     }
972 
973     public WizardPage getInitPage(){
974         return getPageById(new Integer(INITIALIZATION_PAGE_ID));
975     }
976 
977 }