1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.uif.container;
17
18 import java.io.Serializable;
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
26 import org.kuali.rice.kns.uif.UifConstants;
27 import org.kuali.rice.kns.uif.UifParameters;
28 import org.kuali.rice.kns.uif.UifPropertyPaths;
29 import org.kuali.rice.kns.uif.control.Control;
30 import org.kuali.rice.kns.uif.core.DataBinding;
31 import org.kuali.rice.kns.uif.field.ActionField;
32 import org.kuali.rice.kns.uif.field.AttributeField;
33 import org.kuali.rice.kns.uif.field.Field;
34 import org.kuali.rice.kns.uif.field.GroupField;
35 import org.kuali.rice.kns.uif.layout.CollectionLayoutManager;
36 import org.kuali.rice.kns.uif.service.ExpressionEvaluatorService;
37 import org.kuali.rice.kns.uif.util.ComponentUtils;
38 import org.kuali.rice.kns.uif.util.ObjectPropertyUtils;
39 import org.kuali.rice.kns.util.ObjectUtils;
40 import org.kuali.rice.kns.util.WebUtils;
41 import org.kuali.rice.kns.web.spring.form.UifFormBase;
42
43
44
45
46
47
48
49
50
51 public class CollectionGroupBuilder implements Serializable {
52 private static final long serialVersionUID = -4762031957079895244L;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public void build(View view, Object model, CollectionGroup collectionGroup) {
75
76 if (collectionGroup.isRenderAddLine() && !collectionGroup.isReadOnly()) {
77 buildAddLine(view, model, collectionGroup);
78 }
79
80
81 List<Object> modelCollection = ObjectPropertyUtils.getPropertyValue(model, ((DataBinding) collectionGroup)
82 .getBindingInfo().getBindingPath());
83
84
85 if (modelCollection != null) {
86 for (int index = 0; index < modelCollection.size(); index++) {
87 String bindingPathPrefix = collectionGroup.getBindingInfo().getBindingName() + "[" + index + "]";
88 if (StringUtils.isNotBlank(collectionGroup.getBindingInfo().getBindByNamePrefix())) {
89 bindingPathPrefix = collectionGroup.getBindingInfo().getBindByNamePrefix() + "."
90 + bindingPathPrefix;
91 }
92
93 Object currentLine = modelCollection.get(index);
94
95 List<ActionField> actions = getLineActions(view, model, collectionGroup, currentLine, index);
96 buildLine(view, model, collectionGroup, bindingPathPrefix, actions, false, currentLine, index);
97 }
98 }
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113 protected void buildAddLine(View view, Object model, CollectionGroup collectionGroup) {
114 boolean addLineBindsToForm = false;
115
116
117 initializeNewCollectionLine(view, model, collectionGroup, false);
118
119
120
121 if (StringUtils.isBlank(collectionGroup.getAddLinePropertyName())) {
122 addLineBindsToForm = true;
123 }
124
125 String addLineBindingPath = collectionGroup.getAddLineBindingInfo().getBindingPath();
126 List<ActionField> actions = getAddLineActions(view, model, collectionGroup);
127
128 buildLine(view, model, collectionGroup, addLineBindingPath, actions, addLineBindsToForm, null, -1);
129 }
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 @SuppressWarnings("unchecked")
158 protected void buildLine(View view, Object model, CollectionGroup collectionGroup, String bindingPath,
159 List<ActionField> actions, boolean bindToForm, Object currentLine, int lineIndex) {
160 CollectionLayoutManager layoutManager = (CollectionLayoutManager) collectionGroup.getLayoutManager();
161
162
163 List<Field> lineFields = null;
164 if (lineIndex == -1) {
165 lineFields = (List<Field>) ComponentUtils.copyFieldList(collectionGroup.getAddLineFields(), bindingPath,
166 "_add");
167 } else {
168 lineFields = (List<Field>) ComponentUtils.copyFieldList(collectionGroup.getItems(), bindingPath, "_"
169 + Integer.toString(lineIndex));
170 }
171
172 if(currentLine == null && !lineFields.isEmpty()){
173 for(Field f: lineFields){
174 f.addStyleClass(collectionGroup.getId() + "-addField");
175 if(f instanceof AttributeField){
176
177
178 Control control = ((AttributeField) f).getControl();
179 if (control != null) {
180 control.addStyleClass("ignoreValid");
181 }
182 }
183 }
184 for(ActionField action: actions){
185 if(action.getActionParameter(UifParameters.ACTION_TYPE).equals(UifParameters.ADD_LINE)){
186 action.setFocusOnAfterSubmit(lineFields.get(0).getId());
187 }
188 }
189 }
190
191 if(currentLine == null && !lineFields.isEmpty()){
192 for(Field f: lineFields){
193 f.addStyleClass(collectionGroup.getId() + "-addField");
194 if(f instanceof AttributeField){
195
196
197 Control control = ((AttributeField) f).getControl();
198 if (control != null) {
199 control.addStyleClass("ignoreValid");
200 }
201 }
202 }
203 for(ActionField action: actions){
204 if(action.getActionParameter(UifParameters.ACTION_TYPE).equals(UifParameters.ADD_LINE)){
205 action.setFocusOnAfterSubmit(lineFields.get(0).getId());
206 }
207 }
208 }
209
210 ComponentUtils.updateContextsForLine(lineFields, currentLine, lineIndex);
211
212 if (bindToForm) {
213 ComponentUtils.setComponentsPropertyDeep(lineFields, UifPropertyPaths.BIND_TO_FORM, new Boolean(true));
214 }
215
216
217 lineFields = removeNonRenderLineFields(view, model, collectionGroup, lineFields, currentLine, lineIndex);
218
219
220 List<GroupField> subCollectionFields = new ArrayList<GroupField>();
221 if ((lineIndex != -1) && (collectionGroup.getSubCollections() != null)) {
222 for (int subLineIndex = 0; subLineIndex < collectionGroup.getSubCollections().size(); subLineIndex++) {
223 CollectionGroup subCollectionPrototype = collectionGroup.getSubCollections().get(subLineIndex);
224 CollectionGroup subCollectionGroup = ComponentUtils.copy(subCollectionPrototype, collectionGroup.getId() + "s" + subLineIndex);
225
226
227 boolean renderSubCollection = checkSubCollectionRender(view, model, collectionGroup, subCollectionGroup);
228 if (!renderSubCollection) {
229 continue;
230 }
231
232 subCollectionGroup.getBindingInfo().setBindByNamePrefix(bindingPath);
233 subCollectionGroup.getAddLineBindingInfo().setBindByNamePrefix(bindingPath);
234
235 GroupField groupFieldPrototype = layoutManager.getSubCollectionGroupFieldPrototype();
236 GroupField subCollectionGroupField = ComponentUtils.copy(groupFieldPrototype, collectionGroup.getId() + "s" + subLineIndex);
237 subCollectionGroupField.setGroup(subCollectionGroup);
238
239 subCollectionFields.add(subCollectionGroupField);
240 }
241 }
242
243
244
245 layoutManager.buildLine(view, model, collectionGroup, lineFields, subCollectionFields, bindingPath, actions,
246 "_l" + lineIndex, currentLine, lineIndex);
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 protected List<Field> removeNonRenderLineFields(View view, Object model, CollectionGroup collectionGroup,
273 List<Field> lineFields, Object currentLine, int lineIndex) {
274 List<Field> fields = new ArrayList<Field>();
275
276 for (Field lineField : lineFields) {
277
278 if (StringUtils.isNotBlank(lineField.getConditionalRender())) {
279 Map<String, Object> context = new HashMap<String, Object>();
280 context.putAll(view.getContext());
281 context.put(UifConstants.ContextVariableNames.PARENT, collectionGroup);
282 context.put(UifConstants.ContextVariableNames.COMPONENT, lineField);
283 context.put(UifConstants.ContextVariableNames.LINE, currentLine);
284 context.put(UifConstants.ContextVariableNames.INDEX, new Integer(lineIndex));
285 context.put(UifConstants.ContextVariableNames.IS_ADD_LINE, new Boolean(lineIndex == -1));
286
287 Boolean render = (Boolean) getExpressionEvaluatorService().evaluateExpression(model, context,
288 lineField.getConditionalRender());
289 lineField.setRender(render);
290 }
291
292
293
294 if (lineField.isRender()
295 || (!lineField.isRender() && !StringUtils.isEmpty(lineField.getProgressiveRender()))) {
296 fields.add(lineField);
297 }
298 }
299
300 return fields;
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318 protected boolean checkSubCollectionRender(View view, Object model, CollectionGroup collectionGroup,
319 CollectionGroup subCollectionGroup) {
320
321 if (StringUtils.isNotBlank(subCollectionGroup.getConditionalRender())) {
322 Map<String, Object> context = new HashMap<String, Object>();
323 context.putAll(view.getContext());
324 context.put(UifConstants.ContextVariableNames.PARENT, collectionGroup);
325 context.put(UifConstants.ContextVariableNames.COMPONENT, subCollectionGroup);
326
327 Boolean render = (Boolean) getExpressionEvaluatorService().evaluateExpression(model, context,
328 subCollectionGroup.getConditionalRender());
329 subCollectionGroup.setRender(render);
330 }
331
332 return subCollectionGroup.isRender();
333 }
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 protected List<ActionField> getLineActions(View view, Object model, CollectionGroup collectionGroup,
355 Object collectionLine, int lineIndex) {
356 List<ActionField> lineActions = ComponentUtils.copyFieldList(collectionGroup.getActionFields(), Integer.toString(lineIndex));
357 for (ActionField actionField : lineActions) {
358 actionField.addActionParameter(UifParameters.SELLECTED_COLLECTION_PATH, collectionGroup.getBindingInfo()
359 .getBindingPath());
360 actionField.addActionParameter(UifParameters.SELECTED_LINE_INDEX, Integer.toString(lineIndex));
361 actionField.setJumpToIdAfterSubmit(collectionGroup.getId() + "_div");
362 }
363
364 ComponentUtils.updateContextsForLine(lineActions, collectionLine, lineIndex);
365
366 return lineActions;
367 }
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 protected List<ActionField> getAddLineActions(View view, Object model, CollectionGroup collectionGroup) {
385 List<ActionField> lineActions = ComponentUtils.copyFieldList(collectionGroup.getAddLineActionFields(), "_add");
386 for (ActionField actionField : lineActions) {
387 actionField.addActionParameter(UifParameters.SELLECTED_COLLECTION_PATH, collectionGroup.getBindingInfo()
388 .getBindingPath());
389
390 actionField.setJumpToIdAfterSubmit(collectionGroup.getId());
391 actionField.addActionParameter(UifParameters.ACTION_TYPE, UifParameters.ADD_LINE);
392 actionField.setClientSideJs("addLineToCollection('"+ collectionGroup.getId() +"');");
393 }
394
395
396 String addLinePath = collectionGroup.getAddLineBindingInfo().getBindingPath();
397 Object addLine = ObjectPropertyUtils.getPropertyValue(model, addLinePath);
398
399 ComponentUtils.updateContextsForLine(lineActions, addLine, -1);
400
401 return lineActions;
402 }
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423 public void initializeNewCollectionLine(View view, Object model, CollectionGroup collectionGroup,
424 boolean clearExistingLine) {
425 Object newLine = null;
426
427
428 if (StringUtils.isBlank(collectionGroup.getAddLinePropertyName())) {
429
430 if (!(model instanceof UifFormBase)) {
431 throw new RuntimeException("Cannot create new collection line for group: "
432 + collectionGroup.getPropertyName() + ". Model does not extend " + UifFormBase.class.getName());
433 }
434
435
436 Map<String, Object> newCollectionLines = ObjectPropertyUtils.getPropertyValue(model,
437 UifPropertyPaths.NEW_COLLECTION_LINES);
438 if (newCollectionLines == null) {
439 newCollectionLines = new HashMap<String, Object>();
440 ObjectPropertyUtils.setPropertyValue(model, UifPropertyPaths.NEW_COLLECTION_LINES, newCollectionLines);
441 }
442
443
444 String newCollectionLineKey = WebUtils.translateToMapSafeKey(collectionGroup.getBindingInfo()
445 .getBindingPath());
446 String addLineBindingPath = UifPropertyPaths.NEW_COLLECTION_LINES + "['" + newCollectionLineKey + "']";
447 collectionGroup.getAddLineBindingInfo().setBindingPath(addLineBindingPath);
448
449
450
451 if (!newCollectionLines.containsKey(newCollectionLineKey)
452 || (newCollectionLines.get(newCollectionLineKey) == null) || clearExistingLine) {
453
454 newLine = ObjectUtils.newInstance(collectionGroup.getCollectionObjectClass());
455 newCollectionLines.put(newCollectionLineKey, newLine);
456 }
457 } else {
458
459 Object addLine = ObjectPropertyUtils.getPropertyValue(model, collectionGroup.getAddLineBindingInfo()
460 .getBindingPath());
461 if ((addLine == null) || clearExistingLine) {
462 newLine = ObjectUtils.newInstance(collectionGroup.getCollectionObjectClass());
463 ObjectPropertyUtils.setPropertyValue(model, collectionGroup.getAddLineBindingInfo().getBindingPath(),
464 newLine);
465 }
466 }
467
468
469 if (newLine != null) {
470 view.getViewHelperService().applyDefaultValuesForCollectionLine(view, model, collectionGroup, newLine);
471 }
472 }
473
474 protected ExpressionEvaluatorService getExpressionEvaluatorService() {
475 return KNSServiceLocatorWeb.getExpressionEvaluatorService();
476 }
477
478 }