1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.container;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.util.tree.Node;
20 import org.kuali.rice.core.api.util.tree.Tree;
21 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
22 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
23 import org.kuali.rice.krad.datadictionary.parse.BeanTags;
24 import org.kuali.rice.krad.uif.UifConstants;
25 import org.kuali.rice.krad.uif.component.BindingInfo;
26 import org.kuali.rice.krad.uif.component.Component;
27 import org.kuali.rice.krad.uif.component.DataBinding;
28 import org.kuali.rice.krad.uif.element.Message;
29 import org.kuali.rice.krad.uif.util.ComponentUtils;
30 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
31 import org.kuali.rice.krad.uif.view.View;
32
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.Map;
36
37
38
39
40
41
42
43 @BeanTags({@BeanTag(name = "treeGroup-bean", parent = "Uif-TreeGroup"),
44 @BeanTag(name = "treeSection-bean", parent = "Uif-TreeSection"),
45 @BeanTag(name = "treeSubSection-bean", parent = "Uif-TreeSubSection")})
46 public class TreeGroup extends Group implements DataBinding {
47 private static final long serialVersionUID = 5841343037089286740L;
48
49 private String propertyName;
50 private BindingInfo bindingInfo;
51
52 private Map<Class<?>, NodePrototype> nodePrototypeMap;
53 private NodePrototype defaultNodePrototype;
54
55 private Tree<Group, Message> treeGroups;
56
57 private org.kuali.rice.krad.uif.widget.Tree tree;
58
59 public TreeGroup() {
60 super();
61
62 treeGroups = new Tree<Group, Message>();
63 }
64
65
66
67
68
69
70
71
72
73
74
75 @Override
76 public void performInitialization(View view, Object model) {
77 setFieldBindingObjectPath(getBindingInfo().getBindingObjectPath());
78
79 super.performInitialization(view, model);
80
81 if (bindingInfo != null) {
82 bindingInfo.setDefaults(view, getPropertyName());
83 }
84
85
86 }
87
88 @Override
89 public void performApplyModel(View view, Object model, Component parent) {
90 super.performApplyModel(view, model, parent);
91
92 buildTreeGroups(view, model);
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 protected void buildTreeGroups(View view, Object model) {
110
111 Tree<Object, String> treeData = ObjectPropertyUtils.getPropertyValue(model, getBindingInfo().getBindingPath());
112
113
114 Tree<Group, Message> treeGroups = new Tree<Group, Message>();
115
116 String bindingPrefix = getBindingInfo().getBindingPrefixForNested();
117 Node<Group, Message> rootNode = buildTreeNode(treeData.getRootElement(),
118 bindingPrefix +
119 treeGroups.setRootElement(rootNode);
120
121 setTreeGroups(treeGroups);
122 }
123
124 protected Node<Group, Message> buildTreeNode(Node<Object, String> nodeData, String bindingPrefix,
125 String parentNode) {
126 if (nodeData == null) {
127 return null;
128 }
129
130 Node<Group, Message> node = new Node<Group, Message>();
131 node.setNodeType(nodeData.getNodeType());
132
133 NodePrototype prototype = getNodePrototype(nodeData);
134
135 Message message = ComponentUtils.copy(prototype.getLabelPrototype(), parentNode);
136 ComponentUtils.pushObjectToContext(message, UifConstants.ContextVariableNames.NODE, nodeData);
137 message.setMessageText(nodeData.getNodeLabel());
138 node.setNodeLabel(message);
139
140 Group nodeGroup = ComponentUtils.copyComponent(prototype.getDataGroupPrototype(), bindingPrefix + ".data",
141 parentNode);
142 ComponentUtils.pushObjectToContext(nodeGroup, UifConstants.ContextVariableNames.NODE, nodeData);
143
144 String nodePath = bindingPrefix + ".data";
145 if (StringUtils.isNotBlank(getBindingInfo().getBindingObjectPath())) {
146 nodePath = getBindingInfo().getBindingObjectPath() + "." + nodePath;
147 }
148 ComponentUtils.pushObjectToContext(nodeGroup, UifConstants.ContextVariableNames.NODE_PATH, nodePath);
149 node.setData(nodeGroup);
150
151 List<Node<Group, Message>> nodeChildren = new ArrayList<Node<Group, Message>>();
152
153 int childIndex = 0;
154 for (Node<Object, String> childDataNode : nodeData.getChildren()) {
155 String nextBindingPrefix = bindingPrefix + ".children[" + childIndex + "]";
156 Node<Group, Message> childNode = buildTreeNode(childDataNode, nextBindingPrefix,
157 "_node_" + childIndex + ("root".equals(parentNode) ? "_parent_" : "_parent") + parentNode);
158
159 nodeChildren.add(childNode);
160
161
162 ++childIndex;
163 }
164 node.setChildren(nodeChildren);
165
166 return node;
167 }
168
169
170
171
172 private NodePrototype getNodePrototype(Node<Object, String> nodeData) {
173 NodePrototype result = null;
174 if (nodeData != null && nodeData.getData() != null) {
175 Class<?> dataClass = nodeData.getData().getClass();
176 result = nodePrototypeMap.get(dataClass);
177
178
179
180 if (result == null) {
181 for (Map.Entry<Class<?>, NodePrototype> prototypeEntry : nodePrototypeMap.entrySet()) {
182 if (prototypeEntry.getKey().isAssignableFrom(dataClass)) {
183 result = prototypeEntry.getValue();
184 break;
185 }
186 }
187 }
188 }
189
190 if (result == null) {
191 result = defaultNodePrototype;
192 }
193
194 return result;
195 }
196
197
198
199
200 @Override
201 public List<Component> getComponentsForLifecycle() {
202 List<Component> components = super.getComponentsForLifecycle();
203
204 components.add(tree);
205 addNodeComponents(treeGroups.getRootElement(), components);
206
207 return components;
208 }
209
210
211
212
213 @Override
214 public List<Component> getComponentPrototypes() {
215 List<Component> components = super.getComponentPrototypes();
216
217 if (defaultNodePrototype != null) {
218 components.add(defaultNodePrototype.getLabelPrototype());
219 components.add(defaultNodePrototype.getDataGroupPrototype());
220 }
221
222 if (nodePrototypeMap != null) {
223 for (Map.Entry<Class<?>, NodePrototype> prototypeEntry : nodePrototypeMap.entrySet()) {
224 NodePrototype prototype = prototypeEntry.getValue();
225 if (prototype != null) {
226 components.add(prototype.getLabelPrototype());
227 components.add(prototype.getDataGroupPrototype());
228 }
229 }
230 }
231
232 return components;
233 }
234
235
236
237
238
239
240
241
242 protected void addNodeComponents(Node<Group, Message> node, List<Component> components) {
243 if (node != null) {
244 components.add(node.getNodeLabel());
245 components.add(node.getData());
246
247 for (Node<Group, Message> nodeChild : node.getChildren()) {
248 addNodeComponents(nodeChild, components);
249 }
250 }
251 }
252
253 @BeanTagAttribute(name = "propertyName")
254 public String getPropertyName() {
255 return propertyName;
256 }
257
258 public void setPropertyName(String propertyName) {
259 this.propertyName = propertyName;
260 }
261
262 @BeanTagAttribute(name = "bindingInfo", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
263 public BindingInfo getBindingInfo() {
264 return bindingInfo;
265 }
266
267 public void setBindingInfo(BindingInfo bindingInfo) {
268 this.bindingInfo = bindingInfo;
269 }
270
271
272
273
274 @BeanTagAttribute(name = "defaultNodePrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
275 public NodePrototype getDefaultNodePrototype() {
276 return this.defaultNodePrototype;
277 }
278
279
280
281
282 public void setDefaultNodePrototype(NodePrototype defaultNodePrototype) {
283 this.defaultNodePrototype = defaultNodePrototype;
284 }
285
286
287
288
289 @BeanTagAttribute(name = "NodePrototypeMap", type = BeanTagAttribute.AttributeType.MAPBEAN)
290 public Map<Class<?>, NodePrototype> getNodePrototypeMap() {
291 return this.nodePrototypeMap;
292 }
293
294
295
296
297 public void setNodePrototypeMap(Map<Class<?>, NodePrototype> nodePrototypeMap) {
298 this.nodePrototypeMap = nodePrototypeMap;
299 }
300
301 @BeanTagAttribute(name = "treeGroups", type = BeanTagAttribute.AttributeType.MAP2BEAN)
302 public Tree<Group, Message> getTreeGroups() {
303 return treeGroups;
304 }
305
306 public void setTreeGroups(Tree<Group, Message> treeGroups) {
307 this.treeGroups = treeGroups;
308 }
309
310 @BeanTagAttribute(name = "tree", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
311 public org.kuali.rice.krad.uif.widget.Tree getTree() {
312 return tree;
313 }
314
315 public void setTree(org.kuali.rice.krad.uif.widget.Tree tree) {
316 this.tree = tree;
317 }
318 }