TreeController.jpf Sample

This topic inludes the source code for the TreeController.jpf Sample.

Sample Location

This sample is located in the following directory in your WebLogic Workshop installation:

BEA_HOME/weblogic81/samples/workshop/SamplesApp/WebApp/tagSamples/netui/tree_dynamic/

Sample Source Code


001 package tagSamples.netui.tree_dynamic;
002 
003 import com.bea.wlw.netui.pageflow.PageFlowController;
004 import com.bea.wlw.netui.pageflow.Forward;
005 import com.bea.wlw.netui.pageflow.FormData;
006 
007 import com.bea.wlw.netui.tags.html.TreeNode;
008 import com.bea.xml.XmlObject;
009 import java.io.File;
010 import javax.xml.parsers.*;
011 
012 /**
013  * This sample demonstrates how to build a navigation tree dynamically from an arbitrary XML document.
014  
015  * Any XML document can be consumed by this controller and displayed as a set of links,
016  * arranged as an expandable/collapsible tree of nodes.
017  
018  * The XML document is parsed (by the makeTree() method below) and from
019  * the parsed data a set of TreeNodes is constructed (by calling the TreeNode API).
020  * TreeNodes are the server-side representations of <netui:node> tags.
021  * The TreeNodes are displayed by data binding the TreeNodes to a <netui:tree> tag (on tree.jsp).
022  
023  * Any attributes in the XML docuument can be parsed for href and label content. 
024  * If an element cannot be parsed for url and label content, then
025  * a dummy TreeNode is created for that element.
026  
027  * @jpf:controller
028  * @jpf:view-properties view-properties::
029  <!-- This data is auto-generated. Hand-editing this section is not recommended. -->
030  <view-properties>
031  <pageflow-object id="pageflow:/tagSamples/netui/tree_dynamic/treeController.jpf"/>
032  <pageflow-object id="action:treeState.do">
033  *   <property value="80" name="x"/>
034  *   <property value="160" name="y"/>
035  </pageflow-object>
036  <pageflow-object id="action:begin.do">
037  *   <property value="80" name="x"/>
038  *   <property value="60" name="y"/>
039  </pageflow-object>
040  <pageflow-object id="action-call:@page:tree.jsp@#@action:treeState.do@">
041  *   <property value="204,160,160,116" name="elbowsX"/>
042  *   <property value="152,152,141,141" name="elbowsY"/>
043  *   <property value="West_1" name="fromPort"/>
044  *   <property value="East_0" name="toPort"/>
045  </pageflow-object>
046  <pageflow-object id="page:tree.jsp">
047  *   <property value="240" name="x"/>
048  *   <property value="160" name="y"/>
049  </pageflow-object>
050  <pageflow-object id="page:frameSet.jsp">
051  *   <property value="240" name="x"/>
052  *   <property value="60" name="y"/>
053  </pageflow-object>
054  <pageflow-object id="forward:path#tree#tree.jsp#@action:treeState.do@">
055  *   <property value="116,160,160,204" name="elbowsX"/>
056  *   <property value="152,152,141,141" name="elbowsY"/>
057  *   <property value="East_1" name="fromPort"/>
058  *   <property value="West_0" name="toPort"/>
059  *   <property value="tree" name="label"/>
060  </pageflow-object>
061  <pageflow-object id="forward:path#begin#frameSet.jsp#@action:begin.do@">
062  *   <property value="116,160,160,204" name="elbowsX"/>
063  *   <property value="52,52,52,52" name="elbowsY"/>
064  *   <property value="East_1" name="fromPort"/>
065  *   <property value="West_1" name="toPort"/>
066  *   <property value="begin" name="label"/>
067  </pageflow-object>
068  </view-properties>
069  * ::
070  */
071 public class treeController extends PageFlowController
072 {
073     /**
074      * This TreeNode object is the top-level parent node of the tree.
075      * The makeTree() method constructs and adds children TreeNodes to this top level node.
076      
077      * The tree is displayed by data binding the top-level node (along with its
078      * children branch nodes) to a <netui:tree> tag (on tree.jsp).
079      */
080     public TreeNode _rootNode = null;
081 
082     public void onCreate() throws Exception
083     {
084         //System.out.println(getClass().getResource("/content/toc1.xml").getFile());
085         
086         //String beaHomePath = weblogic.Home.getFile().getParentFile().toString() + "/samples/workshop/SamplesApp/WebApp/";
087         String beaHomePath = weblogic.Home.getPath().replaceAll("/server""/samples/workshop/SamplesApp/WebApp/");
088 System.out.println(beaHomePath);
089                 
090         _rootNode = this.makeTree(
091             "http://localhost:7001/WebApp/tagSamples/netui/tree_dynamic/content/"
092             beaHomePath + "tagSamples/netui/tree_dynamic/toc.xml",  
093             "url"
094             "label",
095             true);         
096     }
097     
098     /**
099      * Parses an XML docuemnt and creates a set of links, arranging them as an expandable and collapsible tree
100      * with the same shape as the XML document.
101      
102      * The labelAttribute and hrefAttribute parameters specify the attributes in the XML document that 
103      * hold the label and href content.
104      
105      * The links are constructed from TreeNode objects, the server-side representations of <netui:node> tags.
106      * The method returns a single TreeNode containing the remaining TreeNode as children. 
107      
108      @param String rootHref The url fragment to prepend to each links' href attribute.
109      @param String tocFile Location of the toc.xml file.  A link will be made for each
110      *   element in the file.
111      @param String hrefAttribute The name of the attribute where the href content can be found.
112      @param String labelAttribute The name of the attribute where the label content can be found.
113      @param boolean nodesInit Whether the nodes should be initially open or closed. 
114      
115      @return TreeNode The top-level node containing all the child, branch nodes. 
116      */
117     public TreeNode makeTree(String rootHref, String tocFile, String hrefAttribute, String labelAttribute, boolean nodesInit
118         throws Exception
119     {        
120         // Get the toc.xml file
121         File fl = new File(tocFile);
122         // Parse it as an org.w3c.doc.Document
123         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
124         factory.setNamespaceAware(true);                
125         DocumentBuilder parser = factory.newDocumentBuilder();
126         org.w3c.dom.Document document = parser.parse(fl);
127         // Get the list of Nodes.
128         org.w3c.dom.NodeList nodeList = document.getElementsByTagName("*")
129         
130         // Make an Array of TreeNode, each TreeNode has the label and url of the nodes in toc.xml.
131         // No parent information is added to the TreeNodes yet.
132         int length = nodeList.getLength();
133         TreeNode[] treeNodeArr = new TreeNode[length];
134         for(int i = 0; i<length; i++)
135         {    
136             // Try to make a TreeNode based on the org.w3c.dom.Node.
137             // If the node does not have both "label" and "url" attributes... 
138             try
139             {       
140             treeNodeArr[inew TreeNode(
141                 null, 
142                 nodeList.item(i).getAttributes().getNamedItem(labelAttribute).getNodeValue()
143                 null, 
144                 rootHref 
145                     + nodeList.item(i).getAttributes().getNamedItem(hrefAttribute).getNodeValue()
146                 "contentFrame"
147                 nodesInit);            
148             }
149             catch(Exception e)
150             {            
151             // ...make a dummy TreeNode 
152             treeNodeArr[inew TreeNode(
153                 null, 
154                 "[-label-]"
155                 null, 
156                 "[-href-]"
157                 "contentFrame"
158                 nodesInit)
159             System.out.println("<Warning> Could not parse " + labelAttribute + " and " + hrefAttribute 
160                 " attributes in node: <" + nodeList.item(i).getNodeName() ">, #" + i);
161             }
162         }
163 
164         // Make a parent mapping:  parentMap[child_i] = parent_k.
165         int[] parentMap = new int[length];
166         // for each Node...
167         for(int i = 0; i<length; i++)
168         {
169             // ... find its parent (loop goes from 0 - i for the sake of efficiency, no parent is found after the child)
170             org.w3c.dom.Node parentNode = nodeList.item(i).getParentNode();
171             for(int k = 0; k<i; k++)
172             {
173                 if(parentNode == nodeList.item(k))
174                 
175                     parentMap[i= k; 
176                 }
177             }
178         }
179         
180         // Assign parentage to the Array of TreeNodes.
181         // The top-level TreeNode is made the rootNode.
182         TreeNode rootNode = treeNodeArr[0];
183         // Apply parent map to the TreeNode Array
184         for(int i=1; i<length; i++)
185         {
186             if(treeNodeArr[parentMap[i]] != null)
187             {
188                 treeNodeArr[parentMap[i]].addChild(treeNodeArr[i]);
189             }
190         }
191         
192         return rootNode;
193     }
194             
195     /**
196      * Handles the state of the tree when a a link is clicked.
197      
198      * @jpf:action
199      * @jpf:forward name="tree" path="tree.jsp"
200      */
201     public Forward treeState()
202     {
203         String nodeSel = null;
204         String nodeExpanded = null;
205         
206         /*
207          * Handles expansion / collapse of a tree node.
208          
209          * Get the String name of the content node or the expandable/collapsable node 
210          * selected by the user.
211          */        
212         nodeSel = getRequest().getParameter(TreeNode.SELECTED_NODE);
213         nodeExpanded = getRequest().getParameter(TreeNode.EXPAND_NODE);
214         
215         /*
216          * If the user selected an expandable/collapsable node...
217          */
218         if (nodeExpanded != null)
219         {
220             /*
221              * ...then get the TreeNode object based on the node's String name... 
222              */
223             TreeNode node = _rootNode.findNode(nodeExpanded);
224             if (node != null)
225             {
226                 /*
227                  * ...and reverse the expand/collapse state of the node.
228                  * (I.e. if the node was previously collapsed, then expand it; 
229                  * if it was previously expanded, then collapse it.)
230                  */ 
231                 node.setExpanded(!node.isExpanded());
232 
233             }
234             /*
235              * When a node is selected for expansion/collapse, display changes only in the 
236              * navigation frame.
237              */
238             return new Forward("tree");
239         }
240 
241         return new Forward(nodeSel);
242     }
243 
244     /**
245      * @jpf:action
246      * @jpf:forward name="begin" path="frameSet.jsp"
247      */
248     public Forward begin()
249     {
250         return new Forward("begin");
251     }
252 
253 
254 }