KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > component > tree > Tree


1 /*
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * "The contents of this file are subject to the Mozilla Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11  * License for the specific language governing rights and limitations under
12  * the License.
13  *
14  * The Original Code is ICEfaces 1.5 open source software code, released
15  * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
16  * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
17  * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
18  *
19  * Contributor(s): _____________________.
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
23  * License), in which case the provisions of the LGPL License are
24  * applicable instead of those above. If you wish to allow use of your
25  * version of this file only under the terms of the LGPL License and not to
26  * allow others to use your version of this file under the MPL, indicate
27  * your decision by deleting the provisions above and replace them with
28  * the notice and other provisions required by the LGPL License. If you do
29  * not delete the provisions above, a recipient may use your version of
30  * this file under either the MPL or the LGPL License."
31  *
32  */

33
34 package com.icesoft.faces.component.tree;
35
36 import com.icesoft.faces.component.CSS_DEFAULT;
37 import com.icesoft.faces.component.ext.taglib.Util;
38 import com.icesoft.faces.util.CoreUtils;
39
40 import javax.faces.component.EditableValueHolder;
41 import javax.faces.component.NamingContainer;
42 import javax.faces.component.UICommand;
43 import javax.faces.component.UIComponent;
44 import javax.faces.context.FacesContext;
45 import javax.faces.el.ValueBinding;
46 import javax.faces.event.AbortProcessingException;
47 import javax.faces.event.FacesEvent;
48 import javax.faces.event.FacesListener;
49 import javax.faces.event.PhaseId;
50 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
51 import javax.swing.tree.TreeModel JavaDoc;
52 import java.io.Serializable JavaDoc;
53 import java.util.HashMap JavaDoc;
54 import java.util.Iterator JavaDoc;
55 import java.util.Map JavaDoc;
56
57 /**
58  * Tree is a JSF component class that represent an ICEfaces tree.
59  * <p/>
60  * The tree component displays hierarchical data as a "tree" of branches and
61  * leaf nodes. Optionally, the tree may also display navigation controls for the
62  * dynamic expansion and collapse of branch nodes. Nodes may also support an
63  * action event when clicked that can be used to respond to user click events.
64  * <p/>
65  * This component extends the JSF UICommand component and implemnents the JSF
66  * NamingContainer interface.
67  * <p/>
68  * By default this component is rendered by the "com.icesoft.faces.View"
69  * renderer type.
70  *
71  * @author Chris Brown
72  * @author gmccleary
73  * @version 1.1
74  */

75 public class Tree extends UICommand implements NamingContainer {
76
77     // default style classes
78
private static final String JavaDoc DEFAULT_CSSIMAGEDIR =
79             "/xmlhttp/css/xp/css-images/";
80
81     private static final String JavaDoc DEFAULT_NAV_OPEN_TOP_GIF =
82             "tree_nav_top_open.gif";
83
84     private static final String JavaDoc DEFAULT_NAV_CLOSE_TOP_GIF =
85             "tree_nav_top_close.gif";
86
87     private static final String JavaDoc DEFAULT_NAV_OPEN_TOP_NO_SIBLINGS_GIF =
88             "tree_nav_top_open_no_siblings.gif";
89
90     private static final String JavaDoc DEFAULT_NAV_CLOSE_TOP_NO_SIBLINGS_GIF =
91             "tree_nav_top_close_no_siblings.gif";
92
93     private static final String JavaDoc DEFAULT_NAV_OPEN_MIDDLE_GIF =
94             "tree_nav_middle_open.gif";
95
96     private static final String JavaDoc DEFAULT_NAV_CLOSE_MIDDLE_GIF =
97             "tree_nav_middle_close.gif";
98
99     private static final String JavaDoc DEFAULT_NAV_CLOSE_BOTTOM_GIF =
100             "tree_nav_bottom_close.gif";
101
102     private static final String JavaDoc DEFAULT_NAV_OPEN_BOTTOM_GIF =
103             "tree_nav_bottom_open.gif";
104
105     private static final String JavaDoc DEFAULT_LINE_MIDDLE_NODE_GIF =
106             "tree_line_middle_node.gif";
107
108     private static final String JavaDoc DEFAULT_LINE_VERTICAL_GIF =
109             "tree_line_vertical.gif";
110
111     private static final String JavaDoc DEFAULT_LINE_BLANK_GIF = "tree_line_blank.gif";
112
113     private static final String JavaDoc DEFAULT_LINE_BOTTOM_NODE_GIF =
114             "tree_line_last_node.gif";
115
116     private static final String JavaDoc DEFAULT_DOCUMENT_GIF = "tree_document.gif";
117
118     private static final String JavaDoc DEFAULT_FOLDER_GIF = "tree_folder_close.gif";
119
120     private static final String JavaDoc DEFAULT_FOLDER_OPEN_GIF =
121             "tree_folder_open.gif";
122
123     /**
124      * String constant for tree node collapse event.
125      */

126     public static final String JavaDoc NAVIGATION_EVENT_COLLAPSE = "collapse";
127
128     /**
129      * String constant for tree node expand event.
130      */

131     public static final String JavaDoc NAVIGATION_EVENT_EXPAND = "expand";
132
133     /**
134      * String constant for tree node id prefix.
135      */

136     public static final String JavaDoc ID_PREFIX = "n-";
137
138     // private attributes
139
private DefaultMutableTreeNode JavaDoc navigatedNode;
140     private String JavaDoc navigationEventType;
141     // images
142
private String JavaDoc imageDir;
143     private String JavaDoc navOpenTop;
144     private String JavaDoc navOpenTopNoSiblings;
145     private String JavaDoc navCloseTopNoSiblings;
146     private String JavaDoc navCloseTop;
147     private String JavaDoc navCloseMiddle;
148     private String JavaDoc navOpenMiddle;
149     private String JavaDoc lineMiddleNode;
150     private String JavaDoc lineBottomNode;
151     private String JavaDoc lineVertical;
152     private String JavaDoc lineBlank;
153     private String JavaDoc documentImage;
154     private String JavaDoc folderImage;
155     private String JavaDoc folderOpenImage;
156     private String JavaDoc navCloseBottom;
157     private String JavaDoc navOpenBottom;
158     private String JavaDoc var;
159     private String JavaDoc styleClass;
160     private String JavaDoc style;
161     private Boolean JavaDoc hideRootNode;
162     private Boolean JavaDoc hideNavigation;
163
164     private DefaultMutableTreeNode JavaDoc currentNode;
165     private String JavaDoc nodePath;
166
167     /**
168      * default no args constructor
169      */

170     public Tree() {
171
172     }
173
174     /**
175      * String constant specifying component type
176      */

177     public static final String JavaDoc COMPONENT_TYPE = "com.icesoft.faces.TreeView";
178
179     /**
180      * @return the renderer type of the tree component.
181      */

182     public String JavaDoc getRendererType() {
183         return "com.icesoft.faces.View";
184     }
185
186     /**
187      * @return the component type of the tree component.
188      */

189     public String JavaDoc getComponentType() {
190         return COMPONENT_TYPE;
191     }
192
193     /*
194       * (non-Javadoc)
195       *
196       * @see javax.faces.component.UIComponent#getFamily()
197       */

198     public String JavaDoc getFamily() {
199         return "com.icesoft.faces.TreeView";
200     }
201
202     // accessors & modifiers aka getters and setters
203

204     /**
205      * @param currentNode
206      */

207     public void setCurrentNode(DefaultMutableTreeNode JavaDoc currentNode) {
208         this.currentNode = currentNode;
209     }
210
211     /**
212      * @return DefaultMutableTreeNode currentNode
213      */

214     public DefaultMutableTreeNode JavaDoc getCurrentNode() {
215         return this.currentNode;
216     }
217
218     /**
219      * @param nodePath
220      */

221     public void setNodePath(String JavaDoc nodePath) {
222         FacesContext facesContext = getFacesContext();
223         // save the state of the last node
224
saveChildrenState(facesContext);
225
226         this.nodePath = nodePath;
227
228         // restore the state for current node
229
restoreChildrenState(facesContext);
230
231         // put the current node on the request map
232
this.setCurrentVarToRequestMap(facesContext, getCurrentNode());
233
234     }
235
236     /**
237      * @return String nodePath
238      */

239     public String JavaDoc getNodePath() {
240         return this.nodePath;
241     }
242
243     /**
244      * @return TreeModel model associated with tree
245      */

246     public TreeModel JavaDoc getModel() {
247         ValueBinding vb = getValueBinding("value");
248         return (TreeModel JavaDoc) vb.getValue(getFacesContext());
249     }
250
251     /**
252      * @return TreeNode template
253      * @throws MalformedTreeTagException
254      */

255     public TreeNode getTreeNodeTemplate() throws MalformedTreeTagException {
256         TreeNode template = null;
257         int childCount = this.getChildCount();
258         if (childCount != 1) {
259             throw new MalformedTreeTagException(
260                     "The tree tag requires a single treeNode child tag. Found ["
261                     + childCount + "] children");
262         }
263         UIComponent treeNodeTemplate = (UIComponent) getChildren().get(0);
264         if (treeNodeTemplate == null) {
265             throw new MalformedTreeTagException(
266                     "The Tree requires a TreeNode child. None found.");
267         }
268
269         if (!(treeNodeTemplate instanceof TreeNode)) {
270             throw new MalformedTreeTagException(
271                     "The Tree requires a TreeNode child. Found child of type ["
272                     + treeNodeTemplate.getClass() + "]");
273         }
274         return template;
275     }
276
277     /**
278      * @param pathToSelectedNode
279      * @return DefaultMutableTreeNode node at specified path
280      */

281     public DefaultMutableTreeNode JavaDoc getNodeAtPathsEnd(String JavaDoc pathToSelectedNode) {
282         if (pathToSelectedNode.equalsIgnoreCase("root")) {
283             return (DefaultMutableTreeNode JavaDoc) getModel().getRoot();
284         }
285         String JavaDoc[] indices = pathToSelectedNode
286                 .split(TreeRenderer.PATH_DELIMITER);
287         DefaultMutableTreeNode JavaDoc parent = (DefaultMutableTreeNode JavaDoc) getModel()
288                 .getRoot();
289         for (int i = 0; i < indices.length; i++) {
290             parent = (DefaultMutableTreeNode JavaDoc) parent.getChildAt(Integer
291                     .parseInt(indices[i]));
292         }
293         return parent;
294     }
295
296     // image paths
297

298     /**
299      * @return String imageDir
300      */

301     public String JavaDoc getImageDir() {
302         if (imageDir != null) {
303             return imageDir;
304         }
305         ValueBinding vb = getValueBinding("imageDir");
306         return CoreUtils.resolveResourceURL(getFacesContext(),
307                 vb != null ? (String JavaDoc) vb.getValue(getFacesContext()) : DEFAULT_CSSIMAGEDIR);
308     }
309
310     /**
311      * <p>Set the value of the <code>styleClass</code> property.</p>
312      *
313      * @return String style class property value.
314      */

315     public String JavaDoc getStyleClass() {
316         return Util.getQualifiedStyleClass(this,
317                 styleClass,
318                 CSS_DEFAULT.TREE_DEFAULT_STYLE_CLASS,
319                 "styleClass");
320     }
321
322     /**
323      * <p>Set the value of the <code>styleClass</code> property.</p>
324      *
325      * @param styleClass
326      */

327     public void setStyleClass(String JavaDoc styleClass) {
328         this.styleClass = styleClass;
329     }
330
331     /**
332      * <p>Set the value of the <code>style</code> property.</p>
333      *
334      * @return String style property value.
335      */

336     public String JavaDoc getStyle() {
337         if (style != null) {
338             return style;
339         }
340         ValueBinding vb = getValueBinding("style");
341         return vb != null ? (String JavaDoc) vb.getValue(getFacesContext()) : "";
342     }
343
344     /**
345      * <p>Set the value of the <code>style</code> property.</p>
346      *
347      * @param style
348      */

349     public void setStyle(String JavaDoc style) {
350         this.style = style;
351     }
352
353     String JavaDoc getTreeRowStyleClass() {
354         return Util.getQualifiedStyleClass(this,
355                 CSS_DEFAULT.STYLE_TREEROW);
356     }
357     /**
358      * @param imageProperty
359      * @param bindingName
360      * @param defaultImage
361      * @return String img src
362      */

363     public String JavaDoc getImage(String JavaDoc imageProperty, String JavaDoc bindingName,
364                            String JavaDoc defaultImage) {
365         if (imageProperty != null) {
366             return imageProperty;
367         }
368         ValueBinding vb = getValueBinding(bindingName);
369         if (vb != null) {
370             return (String JavaDoc) vb.getValue(getFacesContext());
371         }
372         return getImageDir() + defaultImage;
373
374     }
375
376     /**
377      * @return String folder img src
378      */

379     public String JavaDoc getFolderImage() {
380         return getImage(folderImage, "folderImage", DEFAULT_FOLDER_GIF);
381     }
382
383     /**
384      * @return String folder open img src
385      */

386     public String JavaDoc getFolderOpenImage() {
387         return getImage(folderOpenImage, "folderOpenImage",
388                         DEFAULT_FOLDER_OPEN_GIF);
389     }
390
391     /**
392      * @return String document img src
393      */

394     public String JavaDoc getDocumentImage() {
395         return getImage(documentImage, "documentImage", DEFAULT_DOCUMENT_GIF);
396     }
397
398     /**
399      * @return String line bottom img src
400      */

401     public String JavaDoc getLineBottomImage() {
402         return getImage(lineBottomNode, "lineBottom",
403                         DEFAULT_LINE_BOTTOM_NODE_GIF);
404     }
405
406     /**
407      * @return String line vertical img src
408      */

409     public String JavaDoc getLineVerticalImage() {
410         return getImage(lineVertical, "lineVertical",
411                         DEFAULT_LINE_VERTICAL_GIF);
412     }
413
414     /**
415      * @return String line middle img src
416      */

417     public String JavaDoc getLineMiddleImage() {
418         return getImage(lineMiddleNode, "lineMiddle",
419                         DEFAULT_LINE_MIDDLE_NODE_GIF);
420     }
421
422     /**
423      * @return String navigation close middle img src
424      */

425     public String JavaDoc getNavCloseMiddleImage() {
426         return getImage(navCloseMiddle, "navCloseMiddleImage",
427                         DEFAULT_NAV_CLOSE_MIDDLE_GIF);
428     }
429
430     /**
431      * @return String navigation open middle img src
432      */

433     public String JavaDoc getNavOpenMiddleImage() {
434         return getImage(navOpenMiddle, "navOpenMiddle",
435                         DEFAULT_NAV_OPEN_MIDDLE_GIF);
436     }
437
438     /**
439      * @return String navigation close top img src
440      */

441     public String JavaDoc getNavCloseTopImage() {
442         return getImage(navCloseTop, "navCloseTop", DEFAULT_NAV_CLOSE_TOP_GIF);
443     }
444
445     /**
446      * @return String navigation open top img src
447      */

448     public String JavaDoc getNavOpenTopImage() {
449         return getImage(navOpenTop, "navOpenTopImage",
450                         DEFAULT_NAV_OPEN_TOP_GIF);
451     }
452
453     /**
454      * @return String navigation open top img src
455      */

456     public String JavaDoc getNavOpenTopNoSiblingsImage() {
457         return getImage(navOpenTopNoSiblings, "navOpenTopNoSiblingsImage",
458                         DEFAULT_NAV_OPEN_TOP_NO_SIBLINGS_GIF);
459     }
460
461     /**
462      * @return String navigation close top img src
463      */

464     public String JavaDoc getNavCloseTopNoSiblingsImage() {
465         return getImage(navCloseTopNoSiblings, "navCloseTopNoSiblingsImage",
466                         DEFAULT_NAV_CLOSE_TOP_NO_SIBLINGS_GIF);
467     }
468
469     /**
470      * @return String navigation close bottom img src
471      */

472     public String JavaDoc getNavCloseBottomImage() {
473         return getImage(navCloseBottom, "navCloseBottomImage",
474                         DEFAULT_NAV_CLOSE_BOTTOM_GIF);
475     }
476
477     /**
478      * @return String navigation open bottom img src
479      */

480     public String JavaDoc getNavOpenBottomImage() {
481         return getImage(navOpenBottom, "navOpenBottomImage",
482                         DEFAULT_NAV_OPEN_BOTTOM_GIF);
483     }
484
485     /**
486      * @return String blank img src
487      */

488     public String JavaDoc getLineBlankImage() {
489         return getImage(lineBlank, "lineBlank", DEFAULT_LINE_BLANK_GIF);
490     }
491
492     /**
493      * @return String line bottom node
494      */

495     public String JavaDoc getLineBottomNode() {
496         return lineBottomNode;
497     }
498
499     /**
500      * @param lineBottomNode
501      */

502     public void setLineBottomNode(String JavaDoc lineBottomNode) {
503         this.lineBottomNode = lineBottomNode;
504     }
505
506     /**
507      * @return String line middle node
508      */

509     public String JavaDoc getLineMiddleNode() {
510         return lineMiddleNode;
511     }
512
513     /**
514      * @param lineMiddleNode
515      */

516     public void setLineMiddleNode(String JavaDoc lineMiddleNode) {
517         this.lineMiddleNode = lineMiddleNode;
518     }
519
520     /**
521      * @return String line vertical
522      */

523     public String JavaDoc getLineVertical() {
524         return lineVertical;
525     }
526
527     /**
528      * @param lineVertical
529      */

530     public void setLineVertical(String JavaDoc lineVertical) {
531         this.lineVertical = lineVertical;
532     }
533
534     /**
535      * @return String navigation expand middle
536      */

537     public String JavaDoc getNavExpandedMiddle() {
538         return navCloseMiddle;
539     }
540
541     /**
542      * @param navExpandedMiddle
543      */

544     public void setNavExpandedMiddle(String JavaDoc navExpandedMiddle) {
545         this.navCloseMiddle = navExpandedMiddle;
546     }
547
548     /**
549      * @return String navigation expanded top
550      */

551     public String JavaDoc getNavExpandedTop() {
552         return navOpenTop;
553     }
554
555     /**
556      * @param navExpandedTop
557      */

558     public void setNavExpandedTop(String JavaDoc navExpandedTop) {
559         this.navOpenTop = navExpandedTop;
560     }
561
562     /**
563      * @param imageDir
564      */

565     public void setImageDir(String JavaDoc imageDir) {
566         this.imageDir = imageDir;
567     }
568
569     /**
570      * @param documentImage
571      */

572     public void setDocumentImage(String JavaDoc documentImage) {
573         this.documentImage = documentImage;
574     }
575
576     /**
577      * @param folderImage
578      */

579     public void setFolderImage(String JavaDoc folderImage) {
580         this.folderImage = folderImage;
581     }
582
583     /**
584      * @return String navigation close top
585      */

586     public String JavaDoc getNavCloseTop() {
587         return navCloseTop;
588     }
589
590     /**
591      * @param navCloseTop
592      */

593     public void setNavCloseTop(String JavaDoc navCloseTop) {
594         this.navCloseTop = navCloseTop;
595     }
596
597     /**
598      * @return String navigation open top
599      */

600     public String JavaDoc getNavOpenTop() {
601         return navOpenTop;
602     }
603
604     /**
605      * @param navOpenTop
606      */

607     public void setNavOpenTop(String JavaDoc navOpenTop) {
608         this.navOpenTop = navOpenTop;
609     }
610
611     /**
612      * @return String navigation open top
613      */

614     public String JavaDoc getNavOpenTopNoSiblings() {
615         return navOpenTopNoSiblings;
616     }
617
618     /**
619      * @param navOpenTopNoSiblings
620      */

621     public void setNavOpenTopNoSiblings(String JavaDoc navOpenTopNoSiblings) {
622         this.navOpenTopNoSiblings = navOpenTopNoSiblings;
623     }
624
625     /**
626      * @return String navigation close top
627      */

628     public String JavaDoc getNavCloseTopNoSiblings() {
629         return navCloseTopNoSiblings;
630     }
631
632     /**
633      * @param navCloseTopNoSiblings
634      */

635     public void setNavCloseTopNoSiblings(String JavaDoc navCloseTopNoSiblings) {
636         this.navCloseTopNoSiblings = navCloseTopNoSiblings;
637     }
638
639     /**
640      * @param folderOpenImage
641      */

642     public void setFolderOpenImage(String JavaDoc folderOpenImage) {
643         this.folderOpenImage = folderOpenImage;
644     }
645
646     /**
647      * @return String navigation close bottom
648      */

649     public String JavaDoc getNavCloseBottom() {
650         return navCloseBottom;
651     }
652
653     /**
654      * @param navCloseBottom
655      */

656     public void setNavCloseBottom(String JavaDoc navCloseBottom) {
657         this.navCloseBottom = navCloseBottom;
658     }
659
660     /**
661      * @return String navigation close middle
662      */

663     public String JavaDoc getNavCloseMiddle() {
664         return navCloseMiddle;
665     }
666
667     /**
668      * @param navCloseMiddle
669      */

670     public void setNavCloseMiddle(String JavaDoc navCloseMiddle) {
671         this.navCloseMiddle = navCloseMiddle;
672     }
673
674     /**
675      * @return String navigation open bottom
676      */

677     public String JavaDoc getNavOpenBottom() {
678         return navOpenBottom;
679     }
680
681     /**
682      * @param navOpenBottom
683      */

684     public void setNavOpenBottom(String JavaDoc navOpenBottom) {
685         this.navOpenBottom = navOpenBottom;
686     }
687
688     /**
689      * @return String navigation open middle
690      */

691     public String JavaDoc getNavOpenMiddle() {
692         return navOpenMiddle;
693     }
694
695     /**
696      * @param navOpenMiddle
697      */

698     public void setNavOpenMiddle(String JavaDoc navOpenMiddle) {
699         this.navOpenMiddle = navOpenMiddle;
700     }
701
702     /**
703      * @return String var
704      */

705     public String JavaDoc getVar() {
706         return var;
707     }
708
709     /**
710      * @param var
711      */

712     public void setVar(String JavaDoc var) {
713         this.var = var;
714     }
715
716     /**
717      * @return String lineBlank
718      */

719     public String JavaDoc getLineBlank() {
720         return lineBlank;
721     }
722
723     /**
724      * @param lineBlank
725      */

726     public void setLineBlank(String JavaDoc lineBlank) {
727         this.lineBlank = lineBlank;
728     }
729
730     /**
731      * @return DefaultMutableTreeNode navigatedNode
732      */

733     public DefaultMutableTreeNode JavaDoc getNavigatedNode() {
734         return navigatedNode;
735     }
736
737     /**
738      * @param navigatedNode
739      */

740     public void setNavigatedNode(DefaultMutableTreeNode JavaDoc navigatedNode) {
741         this.navigatedNode = navigatedNode;
742     }
743
744     /**
745      * @param string
746      */

747     public void setNavigationEventType(String JavaDoc string) {
748         this.navigationEventType = string;
749     }
750
751     /**
752      * @return String navigationEventType
753      */

754     public String JavaDoc getNavigationEventType() {
755         return navigationEventType;
756     }
757
758     // StateHolder Methods
759

760     /**
761      * save the tree component state
762      *
763      * @param context
764      * @return Object values[]
765      */

766     public Object JavaDoc saveState(FacesContext context) {
767
768         Object JavaDoc values[] = new Object JavaDoc[26];
769         values[0] = super.saveState(context);
770         values[1] = navigatedNode;
771         values[2] = navigationEventType;
772         values[3] = imageDir;
773         values[4] = navOpenTop;
774         values[5] = navOpenTopNoSiblings;
775         values[6] = navCloseTopNoSiblings;
776         values[7] = navCloseTop;
777         values[8] = navCloseMiddle;
778         values[9] = navOpenMiddle;
779         values[10] = lineMiddleNode;
780         values[11] = lineBottomNode;
781         values[12] = lineVertical;
782         values[13] = lineBlank;
783         values[14] = documentImage;
784         values[15] = folderImage;
785         values[16] = folderOpenImage;
786         values[17] = navCloseBottom;
787         values[18] = navOpenBottom;
788         values[19] = var;
789         values[20] = styleClass;
790         values[21] = style;
791         values[22] = hideRootNode;
792         values[23] = hideNavigation;
793         values[24] = currentNode;
794         values[25] = nodePath;
795
796         return (values);
797
798     }
799
800     /**
801      * restore the tree component state
802      *
803      * @param context
804      * @param state
805      */

806     public void restoreState(FacesContext context, Object JavaDoc state) {
807
808         Object JavaDoc values[] = (Object JavaDoc[]) state;
809         super.restoreState(context, values[0]);
810         navigatedNode = (DefaultMutableTreeNode JavaDoc) values[1];
811         navigationEventType = (String JavaDoc) values[2];
812         imageDir = (String JavaDoc) values[3];
813         navOpenTop = (String JavaDoc) values[4];
814         navOpenTopNoSiblings = (String JavaDoc) values[5];
815         navCloseTopNoSiblings = (String JavaDoc) values[6];
816         navCloseTop = (String JavaDoc) values[7];
817         navCloseMiddle = (String JavaDoc) values[8];
818         navOpenMiddle = (String JavaDoc) values[9];
819         lineMiddleNode = (String JavaDoc) values[10];
820         lineBottomNode = (String JavaDoc) values[11];
821         lineVertical = (String JavaDoc) values[12];
822         lineBlank = (String JavaDoc) values[13];
823         documentImage = (String JavaDoc) values[14];
824         folderImage = (String JavaDoc) values[15];
825         folderOpenImage = (String JavaDoc) values[16];
826         navCloseBottom = (String JavaDoc) values[17];
827         navOpenBottom = (String JavaDoc) values[18];
828         var = (String JavaDoc) values[19];
829         styleClass = (String JavaDoc) values[20];
830         style = (String JavaDoc) values[21];
831         hideRootNode = (Boolean JavaDoc) values[22];
832         hideNavigation = (Boolean JavaDoc) values[23];
833         currentNode = (DefaultMutableTreeNode JavaDoc) values[24];
834         nodePath = (String JavaDoc) values[25];
835     }
836
837
838     /*
839     * (non-Javadoc)
840     *
841     * @see javax.faces.component.UIComponent#processDecodes(javax.faces.context.FacesContext)
842     */

843     public void processDecodes(FacesContext context) {
844         if (context == null) {
845             throw new NullPointerException JavaDoc("context");
846         }
847         if (!isRendered()) {
848             return;
849         }
850
851         savedChildren = new HashMap JavaDoc();
852
853         this.processTreeNodes((DefaultMutableTreeNode JavaDoc) getModel().getRoot(),
854                               PhaseId.APPLY_REQUEST_VALUES, context);
855
856         try {
857             this.setNodePath(null);
858             this.setCurrentNode(null);
859             decode(context);
860         } catch (RuntimeException JavaDoc e) {
861             context.renderResponse();
862             throw e;
863         }
864     }
865
866     // see superclass for documentation
867
/* (non-Javadoc)
868      * @see javax.faces.component.UIComponentBase#processValidators(javax.faces.context.FacesContext)
869      */

870     public void processValidators(FacesContext context) {
871         if (context == null) {
872             throw new NullPointerException JavaDoc("context");
873         }
874         if (!isRendered()) {
875             return;
876         }
877
878         this.processTreeNodes((DefaultMutableTreeNode JavaDoc) getModel().getRoot(),
879                               PhaseId.PROCESS_VALIDATIONS, context);
880
881         this.setNodePath(null);
882         this.setCurrentNode(null);
883     }
884
885
886     // see superclass for documentation
887
/* (non-Javadoc)
888      * @see javax.faces.component.UIComponentBase#processUpdates(javax.faces.context.FacesContext)
889      */

890     public void processUpdates(FacesContext context) {
891         if (context == null) {
892             throw new NullPointerException JavaDoc("context");
893         }
894         if (!isRendered()) {
895             return;
896         }
897
898         this.processTreeNodes((DefaultMutableTreeNode JavaDoc) getModel().getRoot(),
899                               PhaseId.UPDATE_MODEL_VALUES, context);
900
901         this.setNodePath(null);
902         this.setCurrentNode(null);
903     }
904
905     /**
906      * Recursively process all TreeNodes starting at the currentNode. TreeNodes
907      * will be process according the the phaseId
908      *
909      * @param currentNode
910      * @param phaseId
911      * @param context
912      */

913     private void processTreeNodes(DefaultMutableTreeNode JavaDoc currentNode,
914                                   Object JavaDoc phaseId,
915                                   FacesContext context) {
916         // set currentNode on tree
917
this.setCurrentNode(currentNode);
918
919         TreeNode treeNodeTemplate = (TreeNode) this.getChildren().get(0);
920         String JavaDoc pathToCurrentNode = TreeRenderer.getPathAsString(currentNode,
921                                                                 (DefaultMutableTreeNode JavaDoc) getModel()
922                                                                         .getRoot());
923         treeNodeTemplate.setMutable(currentNode);
924         treeNodeTemplate.setId(ID_PREFIX + pathToCurrentNode);
925         treeNodeTemplate.setParent(this);
926
927         this.setNodePath(pathToCurrentNode);
928
929         // get TreeNode facets from treeNodeTemplate
930
UIComponent iconFacet;
931         UIComponent contentFacet;
932
933         iconFacet = treeNodeTemplate.getIcon();
934         contentFacet = treeNodeTemplate.getContent();
935
936         // call appropriate phase handler
937
if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
938             if (iconFacet != null) {
939                 iconFacet.processDecodes(context);
940             }
941             if (contentFacet != null) {
942                 contentFacet.processDecodes(context);
943             }
944         } else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
945             if (iconFacet != null) {
946                 iconFacet.processValidators(context);
947             }
948             if (contentFacet != null) {
949                 contentFacet.processValidators(context);
950             }
951
952         } else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
953             if (iconFacet != null) {
954                 iconFacet.processUpdates(context);
955             }
956             if (contentFacet != null) {
957                 contentFacet.processUpdates(context);
958             }
959
960         }
961
962         // recurse currentRoot's children
963
IceUserObject userObject = (IceUserObject) currentNode.getUserObject();
964         if (userObject.isExpanded()) {
965             int childCount = currentNode.getChildCount();
966             for (int childIndex = 0; childIndex < childCount; childIndex++) {
967                 DefaultMutableTreeNode JavaDoc nextNode =
968                         (DefaultMutableTreeNode JavaDoc) currentNode
969                                 .getChildAt(childIndex);
970
971                 processTreeNodes(nextNode,
972                                  phaseId,
973                                  context);
974             }
975         }
976     }
977
978     /*
979       * (non-Javadoc)
980       *
981       * @see javax.faces.component.UIComponent#queueEvent(javax.faces.event.FacesEvent)
982       */

983     public void queueEvent(FacesEvent event) {
984         UIComponent eventComponent = event.getComponent();
985         UIComponent parentTreeNode = eventComponent.getParent();
986         while (parentTreeNode != null &&
987                !(parentTreeNode instanceof TreeNode)) {
988             parentTreeNode = parentTreeNode.getParent();
989         }
990         if (parentTreeNode == null) {
991             // queue a non-wrapper event
992
super.queueEvent(event);
993             return;
994         }
995         super.queueEvent(new NodeEvent(this, event,
996                                        ((TreeNode) parentTreeNode).getMutable()));
997     }
998
999     /*
1000      * (non-Javadoc)
1001      *
1002      * @see javax.faces.component.UIComponent#broadcast(javax.faces.event.FacesEvent)
1003      */

1004    public void broadcast(FacesEvent event) throws AbortProcessingException {
1005
1006        if (!(event instanceof NodeEvent)) {
1007            super.broadcast(event);
1008            return;
1009        }
1010
1011        // Set up the correct context and fire our wrapped event
1012
NodeEvent wrapperEvent = (NodeEvent) event;
1013        DefaultMutableTreeNode JavaDoc eventNode = wrapperEvent.getNode();
1014        this.setCurrentNode(eventNode);
1015        this.setNodePath(TreeRenderer.getPathAsString(eventNode,
1016                                                      (DefaultMutableTreeNode JavaDoc) getModel()
1017                                                              .getRoot()));
1018
1019        FacesEvent facesEvent = wrapperEvent.getFacesEvent();
1020        facesEvent.getComponent().broadcast(facesEvent);
1021    }
1022
1023    /**
1024     * @param context
1025     * @param currentVar
1026     */

1027    private void setCurrentVarToRequestMap(FacesContext context,
1028                                           DefaultMutableTreeNode JavaDoc currentVar) {
1029        Map JavaDoc requestMap = context.getExternalContext().getRequestMap();
1030        String JavaDoc varAttribute = getVar();
1031        if (currentVar != null) {
1032            requestMap.put(varAttribute, currentVar);
1033        }
1034    }
1035
1036    /**
1037     * @return String hideNavigation
1038     */

1039    public String JavaDoc getHideNavigation() {
1040
1041        if (hideNavigation != null) {
1042            return hideNavigation.toString();
1043        }
1044        ValueBinding vb = getValueBinding("hideNavigation");
1045        if (vb != null) {
1046            return vb.getValue(getFacesContext()).toString();
1047        }
1048        return String.valueOf(false);
1049
1050    }
1051
1052    /**
1053     * @param b
1054     */

1055    public void setHideNavigation(String JavaDoc b) {
1056        hideNavigation = new Boolean JavaDoc(b);
1057    }
1058
1059    /**
1060     * @return String hideRootNode
1061     */

1062    public String JavaDoc getHideRootNode() {
1063
1064        if (hideRootNode != null) {
1065            return hideRootNode.toString();
1066        }
1067        ValueBinding vb = getValueBinding("hideRootNode");
1068        if (vb != null) {
1069            return vb.getValue(getFacesContext()).toString();
1070        }
1071        return String.valueOf(false);
1072    }
1073
1074    /**
1075     * @param b
1076     */

1077    public void setHideRootNode(String JavaDoc b) {
1078        hideRootNode = new Boolean JavaDoc(b);
1079    }
1080
1081    // This class wraps TreeNode events
1082
// the TreeNode generates an event and the Tree.queueEvent()
1083
// wraps the event in a NodeEvent which the Tree.broadcast
1084
// recieves and passes on to the TreeNode.
1085
class NodeEvent extends FacesEvent {
1086
1087        /**
1088         *
1089         */

1090        private static final long serialVersionUID = 1L;
1091
1092        private FacesEvent event = null;
1093
1094        private DefaultMutableTreeNode JavaDoc node = null;
1095
1096        /**
1097         * @param component
1098         * @param event
1099         * @param node
1100         */

1101        public NodeEvent(UIComponent component, FacesEvent event,
1102                         DefaultMutableTreeNode JavaDoc node) {
1103            super(component);
1104            this.event = event;
1105            this.node = node;
1106        }
1107
1108        /**
1109         * @return DefaultMutableTreeNode node
1110         */

1111        public DefaultMutableTreeNode JavaDoc getNode() {
1112            return node;
1113        }
1114
1115        /**
1116         * @param node
1117         */

1118        public void setNode(DefaultMutableTreeNode JavaDoc node) {
1119            this.node = node;
1120        }
1121
1122        /**
1123         * @return FacesEvent event
1124         */

1125        public FacesEvent getFacesEvent() {
1126            return (this.event);
1127        }
1128
1129        /* (non-Javadoc)
1130         * @see javax.faces.event.FacesEvent#getPhaseId()
1131         */

1132        public PhaseId getPhaseId() {
1133            return (this.event.getPhaseId());
1134        }
1135
1136        /* (non-Javadoc)
1137         * @see javax.faces.event.FacesEvent#setPhaseId(javax.faces.event.PhaseId)
1138         */

1139        public void setPhaseId(PhaseId phaseId) {
1140            this.event.setPhaseId(phaseId);
1141        }
1142
1143        /* (non-Javadoc)
1144         * @see javax.faces.event.FacesEvent#isAppropriateListener(javax.faces.event.FacesListener)
1145         */

1146        public boolean isAppropriateListener(FacesListener listener) {
1147            return (false);
1148        }
1149
1150        /* (non-Javadoc)
1151         * @see javax.faces.event.FacesEvent#processListener(javax.faces.event.FacesListener)
1152         */

1153        public void processListener(FacesListener listener) {
1154            throw new IllegalStateException JavaDoc();
1155        }
1156
1157    }
1158
1159
1160    /**
1161     * <p>This map contains <code>ChildState</code> instances for each child
1162     * component, keyed by the client id of the child.</p>
1163     */

1164    protected Map JavaDoc savedChildren = new HashMap JavaDoc();
1165
1166
1167    /**
1168     * <p>Restore state information for all child components.</p>
1169     *
1170     * @param context
1171     */

1172    protected void restoreChildrenState(FacesContext context) {
1173        Iterator JavaDoc kids = getChildren().iterator();
1174        while (kids.hasNext()) {
1175            UIComponent kid = (UIComponent) kids.next();
1176            restoreChildState(kid, context);
1177        }
1178    }
1179
1180    /**
1181     * <p>Restore state information for the given child component.</p>
1182     *
1183     * @param component
1184     * @param context
1185     */

1186    protected void restoreChild(UIComponent component, FacesContext context) {
1187        // Restore state for this component (if it is a EditableValueHolder)
1188
if (component instanceof EditableValueHolder) {
1189            EditableValueHolder input = (EditableValueHolder) component;
1190            String JavaDoc clientId = component.getClientId(context);
1191            ChildState state = (ChildState) savedChildren.get(clientId);
1192            if (state == null) {
1193                state = new ChildState();
1194            }
1195            input.setValue(state.getValue());
1196            input.setValid(state.isValid());
1197            input.setSubmittedValue(state.getSubmittedValue());
1198            input.setLocalValueSet(state.isLocalValueSet());
1199        }
1200    }
1201
1202    /**
1203     * <p>Restore state information for the given child component and its
1204     * children.</p>
1205     *
1206     * @param component
1207     * @param context
1208     */

1209    private void restoreChildState(UIComponent component,
1210                                   FacesContext context) {
1211
1212        // Reset the client identifier for this component
1213
String JavaDoc id = component.getId();
1214        component.setId(id); // Forces client id to be reset
1215
// restore state for child component
1216
restoreChild(component, context);
1217
1218        // Restore state for children of this component
1219
Iterator JavaDoc kids = component.getFacetsAndChildren();
1220        while (kids.hasNext()) {
1221            restoreChildState((UIComponent) kids.next(), context);
1222        }
1223    }
1224
1225    /**
1226     * <p>Save state information for all children of this component.</p>
1227     *
1228     * @param context
1229     */

1230    protected void saveChildrenState(FacesContext context) {
1231
1232        Iterator JavaDoc kids = getChildren().iterator();
1233        while (kids.hasNext()) {
1234            UIComponent kid = (UIComponent) kids.next();
1235            saveChildState(kid, context);
1236        }
1237    }
1238
1239    /**
1240     * <p>Save state information for the given child component.</p>
1241     *
1242     * @param component
1243     * @param context
1244     */

1245    protected void saveChild(UIComponent component, FacesContext context) {
1246        // Save state for this component (if it is a EditableValueHolder)
1247
if (component instanceof EditableValueHolder) {
1248            EditableValueHolder input = (EditableValueHolder) component;
1249            String JavaDoc clientId = component.getClientId(context);
1250            ChildState state = (ChildState) savedChildren.get(clientId);
1251            if (state == null) {
1252                state = new ChildState();
1253                savedChildren.put(clientId, state);
1254            }
1255            state.setValue(input.getLocalValue());
1256            state.setValid(input.isValid());
1257            state.setSubmittedValue(input.getSubmittedValue());
1258            state.setLocalValueSet(input.isLocalValueSet());
1259        }
1260    }
1261
1262    /**
1263     * <p>Save state information for the given child component and its
1264     * children.</p>
1265     *
1266     * @param component
1267     * @param context
1268     */

1269    protected void saveChildState(UIComponent component, FacesContext context) {
1270        // Save state for this child
1271
saveChild(component, context);
1272        // Save state for children of this component including facets as tree nodes are made up of facets
1273
Iterator JavaDoc kids = component.getFacetsAndChildren();
1274        while (kids.hasNext()) {
1275            saveChildState((UIComponent) kids.next(), context);
1276        }
1277    }
1278}
1279
1280// Private class to represent saved state information for the children of the Tree component
1281

1282class ChildState implements Serializable JavaDoc {
1283
1284    /**
1285     *
1286     */

1287    private static final long serialVersionUID = 1L;
1288    private Object JavaDoc submittedValue;
1289    private boolean valid = true;
1290    private Object JavaDoc value;
1291    private boolean localValueSet;
1292
1293    Object JavaDoc getSubmittedValue() {
1294        return (this.submittedValue);
1295    }
1296
1297    void setSubmittedValue(Object JavaDoc submittedValue) {
1298        this.submittedValue = submittedValue;
1299    }
1300
1301    boolean isValid() {
1302        return (this.valid);
1303    }
1304
1305    void setValid(boolean valid) {
1306        this.valid = valid;
1307    }
1308
1309    Object JavaDoc getValue() {
1310        return (this.value);
1311    }
1312
1313    /**
1314     * @param value
1315     */

1316    public void setValue(Object JavaDoc value) {
1317        this.value = value;
1318    }
1319
1320    boolean isLocalValueSet() {
1321        return (this.localValueSet);
1322    }
1323
1324    /**
1325     * @param localValueSet
1326     */

1327    public void setLocalValueSet(boolean localValueSet) {
1328        this.localValueSet = localValueSet;
1329    }
1330}
1331
1332
1333
Popular Tags