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