Coverage Report - org.kuali.rice.kns.uif.container.TreeGroup
 
Classes in this File Line Coverage Branch Coverage Complexity
TreeGroup
0%
0/70
0%
0/8
1.19
 
 1  
 package org.kuali.rice.kns.uif.container;
 2  
 
 3  
 import org.kuali.rice.core.util.Node;
 4  
 import org.kuali.rice.core.util.Tree;
 5  
 import org.kuali.rice.kns.uif.UifConstants;
 6  
 import org.kuali.rice.kns.uif.core.BindingInfo;
 7  
 import org.kuali.rice.kns.uif.core.Component;
 8  
 import org.kuali.rice.kns.uif.field.MessageField;
 9  
 import org.kuali.rice.kns.uif.util.ComponentUtils;
 10  
 import org.kuali.rice.kns.uif.util.ObjectPropertyUtils;
 11  
 import org.kuali.rice.kns.uif.widget.TreeWidget;
 12  
 
 13  
 import java.util.ArrayList;
 14  
 import java.util.HashMap;
 15  
 import java.util.List;
 16  
 import java.util.Map;
 17  
 
 18  
 /**
 19  
  * Group component that is backed by a <code>Tree</code> data structure and typically
 20  
  * rendered as a tree in the user interface
 21  
  *
 22  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 23  
  */
 24  
 public class TreeGroup extends Group {
 25  
     private static final long serialVersionUID = 5841343037089286740L;
 26  
 
 27  
     private String propertyName;
 28  
     private BindingInfo bindingInfo;
 29  
 
 30  
     private Group dataGroupPrototype;
 31  
 
 32  
     private MessageField nodeLabelPrototype;
 33  
     private Map<String, String> nodeTypeStyleClasses;
 34  
 
 35  
     private Tree<Group, MessageField> treeGroups;
 36  
 
 37  
     private TreeWidget treeWidget;
 38  
 
 39  
     public TreeGroup() {
 40  0
         super();
 41  
 
 42  0
         nodeTypeStyleClasses = new HashMap<String, String>();
 43  0
         treeGroups = new Tree<Group, MessageField>();
 44  0
     }
 45  
 
 46  
     /**
 47  
      * The following actions are performed:
 48  
      *
 49  
      * <ul>
 50  
      * <li>Set fieldBindModelPath to the collection model path (since the fields
 51  
      * have to belong to the same model as the collection)</li>
 52  
      * <li>Set defaults for binding</li>
 53  
      * <li>Calls view helper service to initialize prototypes</li>
 54  
      * </ul>
 55  
      *
 56  
      * @see org.kuali.rice.kns.uif.core.ComponentBase#performInitialization(org.kuali.rice.kns.uif.container.View)
 57  
      */
 58  
     @Override
 59  
     public void performInitialization(View view) {
 60  0
         setFieldBindingObjectPath(getBindingInfo().getBindingObjectPath());
 61  
 
 62  0
         super.performInitialization(view);
 63  
 
 64  0
         if (bindingInfo != null) {
 65  0
             bindingInfo.setDefaults(view, getPropertyName());
 66  
         }
 67  
 
 68  
         // TODO: set object path for prototypes equal to the tree group object path?
 69  
 
 70  0
         view.getViewHelperService().performComponentInitialization(view, nodeLabelPrototype);
 71  0
         view.getViewHelperService().performComponentInitialization(view, dataGroupPrototype);
 72  0
     }
 73  
 
 74  
     /**
 75  
      * @see org.kuali.rice.kns.uif.container.ContainerBase#performApplyModel(org.kuali.rice.kns.uif.container.View,
 76  
      *      java.lang.Object)
 77  
      */
 78  
     @Override
 79  
     public void performApplyModel(View view, Object model) {
 80  0
         super.performApplyModel(view, model);
 81  
 
 82  0
         buildTreeGroups(view, model);
 83  0
     }
 84  
 
 85  
     /**
 86  
      * Builds the components that will be rendered as part of the tree group
 87  
      *
 88  
      * <p>
 89  
      *  The component tree group mirrors the tree data structure on the model. For each node of
 90  
      *  the data structure, a corresponding <code>MessageField</code>  will be created for the node
 91  
      *  label, and a <code>Group</code> component for the node data. These are placed into a new
 92  
      *  node for the component tree. After the tree is built it is set as a property on the tree group
 93  
      *  to be read by the renderer
 94  
      * </p>
 95  
      *
 96  
      * @param view - view instance the tree group belongs to
 97  
      * @param model - object containing the view data from which the tree data will be retrieved
 98  
      */
 99  
     protected void buildTreeGroups(View view, Object model) {
 100  
         // get Tree data property
 101  0
         Tree<Object, String> treeData = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
 102  
 
 103  
         // build component tree that corresponds with tree data
 104  0
         Tree<Group, MessageField> treeGroups = new Tree<Group, MessageField>();
 105  
 
 106  0
         String bindingPrefix = getBindingInfo().getBindingPrefixForNested();
 107  0
         Node<Group, MessageField> rootNode = buildTreeNode(treeData.getRootElement(), bindingPrefix, 0);
 108  0
         treeGroups.setRootElement(rootNode);
 109  
 
 110  0
         setTreeGroups(treeGroups);
 111  0
     }
 112  
 
 113  
     protected Node<Group, MessageField> buildTreeNode(Node<Object, String> nodeData, String bindingPrefix, int nodeCounter) {
 114  0
         Node<Group, MessageField> node = new Node<Group, MessageField>();
 115  
 
 116  0
         String idSuffix = "_n" + nodeCounter;
 117  
 
 118  0
         MessageField messageField = ComponentUtils.copy(this.nodeLabelPrototype, idSuffix);
 119  0
         ComponentUtils.pushObjectToContext(messageField, UifConstants.ContextVariableNames.NODE, nodeData);
 120  0
         messageField.setMessageText(nodeData.getNodeLabel());
 121  0
         node.setNodeLabel(messageField);
 122  
 
 123  0
         Group nodeGroup = ComponentUtils.copyComponent(this.dataGroupPrototype, bindingPrefix + ".data", idSuffix);
 124  0
         ComponentUtils.pushObjectToContext(nodeGroup, UifConstants.ContextVariableNames.NODE, nodeData);
 125  0
         node.setData(nodeGroup);
 126  
 
 127  0
         List<Node<Group, MessageField>> nodeChildren = new ArrayList<Node<Group, MessageField>>();
 128  
 
 129  0
         int childIndex = -1;
 130  0
         for (Node<Object, String> childDataNode : nodeData.getChildren()) {
 131  0
             String nextBindingPrefix = bindingPrefix + ".children[" + childIndex + "]";
 132  0
             Node<Group, MessageField> childNode = buildTreeNode(childDataNode, nextBindingPrefix, nodeCounter++);
 133  
 
 134  0
             nodeChildren.add(childNode);
 135  0
         }
 136  0
         node.setChildren(nodeChildren);
 137  
 
 138  0
         return node;
 139  
     }
 140  
 
 141  
     /**
 142  
      * @see org.kuali.rice.kns.uif.container.ContainerBase#getNestedComponents()
 143  
      */
 144  
     @Override
 145  
     public List<Component> getNestedComponents() {
 146  0
         List<Component> components = super.getNestedComponents();
 147  
 
 148  0
         components.add(treeWidget);
 149  0
         addNodeComponents(treeGroups.getRootElement(), components);
 150  
 
 151  0
         return components;
 152  
     }
 153  
 
 154  
     /**
 155  
      * Retrieves the <code>Component</code> instances from the node for building the nested
 156  
      * components list
 157  
      *
 158  
      * @param node - node to pull components from
 159  
      * @param components - list to add components to
 160  
      */
 161  
     protected void addNodeComponents(Node<Group, MessageField> node, List<Component> components) {
 162  0
         if (node != null) {
 163  0
             components.add(node.getNodeLabel());
 164  0
             components.add(node.getData());
 165  
 
 166  0
             for (Node<Group, MessageField> nodeChild : node.getChildren()) {
 167  0
                 addNodeComponents(nodeChild, components);
 168  
             }
 169  
         }
 170  0
     }
 171  
 
 172  
     public String getPropertyName() {
 173  0
         return propertyName;
 174  
     }
 175  
 
 176  
     public void setPropertyName(String propertyName) {
 177  0
         this.propertyName = propertyName;
 178  0
     }
 179  
 
 180  
     public BindingInfo getBindingInfo() {
 181  0
         return bindingInfo;
 182  
     }
 183  
 
 184  
     public void setBindingInfo(BindingInfo bindingInfo) {
 185  0
         this.bindingInfo = bindingInfo;
 186  0
     }
 187  
 
 188  
     public Group getDataGroupPrototype() {
 189  0
         return dataGroupPrototype;
 190  
     }
 191  
 
 192  
     public void setDataGroupPrototype(Group dataGroupPrototype) {
 193  0
         this.dataGroupPrototype = dataGroupPrototype;
 194  0
     }
 195  
 
 196  
     public MessageField getNodeLabelPrototype() {
 197  0
         return nodeLabelPrototype;
 198  
     }
 199  
 
 200  
     public void setNodeLabelPrototype(MessageField nodeLabelPrototype) {
 201  0
         this.nodeLabelPrototype = nodeLabelPrototype;
 202  0
     }
 203  
 
 204  
     public Map<String, String> getNodeTypeStyleClasses() {
 205  0
         return nodeTypeStyleClasses;
 206  
     }
 207  
 
 208  
     public void setNodeTypeStyleClasses(Map<String, String> nodeTypeStyleClasses) {
 209  0
         this.nodeTypeStyleClasses = nodeTypeStyleClasses;
 210  0
     }
 211  
 
 212  
     public Tree<Group, MessageField> getTreeGroups() {
 213  0
         return treeGroups;
 214  
     }
 215  
 
 216  
     public void setTreeGroups(Tree<Group, MessageField> treeGroups) {
 217  0
         this.treeGroups = treeGroups;
 218  0
     }
 219  
 
 220  
     public TreeWidget getTreeWidget() {
 221  0
         return treeWidget;
 222  
     }
 223  
 
 224  
     public void setTreeWidget(TreeWidget treeWidget) {
 225  0
         this.treeWidget = treeWidget;
 226  0
     }
 227  
 }