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