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.collections.ListUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.kuali.rice.core.api.mo.common.active.Inactivatable;
23 import org.kuali.rice.kim.api.identity.Person;
24 import org.kuali.rice.krad.uif.UifConstants;
25 import org.kuali.rice.krad.uif.UifParameters;
26 import org.kuali.rice.krad.uif.UifPropertyPaths;
27 import org.kuali.rice.krad.uif.component.Component;
28 import org.kuali.rice.krad.uif.component.ComponentSecurity;
29 import org.kuali.rice.krad.uif.component.DataBinding;
30 import org.kuali.rice.krad.uif.control.Control;
31 import org.kuali.rice.krad.uif.control.ControlBase;
32 import org.kuali.rice.krad.uif.element.Action;
33 import org.kuali.rice.krad.uif.field.Field;
34 import org.kuali.rice.krad.uif.field.FieldGroup;
35 import org.kuali.rice.krad.uif.field.InputField;
36 import org.kuali.rice.krad.uif.field.RemoteFieldsHolder;
37 import org.kuali.rice.krad.uif.layout.CollectionLayoutManager;
38 import org.kuali.rice.krad.uif.util.ComponentUtils;
39 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
40 import org.kuali.rice.krad.uif.util.ScriptUtils;
41 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
42 import org.kuali.rice.krad.uif.view.View;
43 import org.kuali.rice.krad.uif.view.ViewAuthorizer;
44 import org.kuali.rice.krad.uif.view.ViewModel;
45 import org.kuali.rice.krad.uif.view.ViewPresentationController;
46 import org.kuali.rice.krad.util.GlobalVariables;
47 import org.kuali.rice.krad.util.KRADUtils;
48 import org.kuali.rice.krad.util.ObjectUtils;
49 import org.kuali.rice.krad.web.form.UifFormBase;
50
51 import java.io.Serializable;
52 import java.util.ArrayList;
53 import java.util.Collection;
54 import java.util.HashMap;
55 import java.util.List;
56 import java.util.Map;
57
58
59
60
61
62
63
64
65
66 public class CollectionGroupBuilder implements Serializable {
67 private static final long serialVersionUID = -4762031957079895244L;
68 private static Log LOG = LogFactory.getLog(CollectionGroupBuilder.class);
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 public void build(View view, Object model, CollectionGroup collectionGroup) {
91
92 if (collectionGroup.isRenderAddLine() && !collectionGroup.isReadOnly() &&
93 !collectionGroup.isRenderAddBlankLineButton()) {
94 buildAddLine(view, model, collectionGroup);
95 }
96
97
98 if (collectionGroup.isRenderAddBlankLineButton() && (collectionGroup.getAddBlankLineAction() != null)) {
99 collectionGroup.getAddBlankLineAction().setRefreshId(collectionGroup.getId());
100 }
101
102
103 List<Object> modelCollection = ObjectPropertyUtils.getPropertyValue(model,
104 ((DataBinding) collectionGroup).getBindingInfo().getBindingPath());
105
106 if (modelCollection != null) {
107
108 List<Integer> showIndexes = performCollectionFiltering(view, model, collectionGroup, modelCollection);
109
110 if (collectionGroup.getDisplayCollectionSize() != -1 && showIndexes.size() > collectionGroup
111 .getDisplayCollectionSize()) {
112
113 List<Integer> newShowIndexes = new ArrayList<Integer>();
114 Integer counter = 0;
115
116 for (int index = 0; index < showIndexes.size(); index++) {
117 newShowIndexes.add(showIndexes.get(index));
118
119 counter++;
120
121 if (counter == collectionGroup.getDisplayCollectionSize()) {
122 break;
123 }
124 }
125
126 showIndexes = newShowIndexes;
127 }
128
129 List<IndexedElement> filteredIndexedElements = buildFilteredIndexedCollection(showIndexes, modelCollection);
130
131 collectionGroup.setFilteredCollectionSize(filteredIndexedElements.size());
132 buildLinesForDisplayedRows(filteredIndexedElements, view, model, collectionGroup);
133 }
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 private List<IndexedElement> buildFilteredIndexedCollection(List<Integer> showIndexes,
152 List<Object> modelCollection) {
153 List<IndexedElement> filteredIndexedElements = new ArrayList<IndexedElement>(modelCollection.size());
154 for (Integer showIndex : showIndexes) {
155 filteredIndexedElements.add(new IndexedElement(showIndex, modelCollection.get(showIndex)));
156 }
157 return filteredIndexedElements;
158 }
159
160
161
162
163
164
165
166
167
168 protected void buildLinesForDisplayedRows(List<IndexedElement> filteredIndexedElements, View view, Object model,
169 CollectionGroup collectionGroup) {
170
171
172
173 if (collectionGroup.isUseServerPaging() && collectionGroup.getDisplayLength() == -1) {
174 collectionGroup.setDisplayLength(1);
175 }
176
177 final int displayStart = (collectionGroup.getDisplayStart() != -1 && collectionGroup.isUseServerPaging()) ?
178 collectionGroup.getDisplayStart() : 0;
179
180 final int displayLength = (collectionGroup.getDisplayLength() != -1 && collectionGroup.isUseServerPaging()) ?
181 collectionGroup.getDisplayLength() : filteredIndexedElements.size() - displayStart;
182
183
184 final int displayEndExclusive =
185 (displayStart + displayLength > filteredIndexedElements.size()) ? filteredIndexedElements.size() :
186 displayStart + displayLength;
187
188
189 final List<IndexedElement> renderedIndexedElements = filteredIndexedElements.subList(displayStart,
190 displayEndExclusive);
191
192
193 for (IndexedElement indexedElement : renderedIndexedElements) {
194 final Object currentLine = indexedElement.element;
195
196 String bindingPathPrefix =
197 collectionGroup.getBindingInfo().getBindingName() + "[" + indexedElement.index + "]";
198
199 if (StringUtils.isNotBlank(collectionGroup.getBindingInfo().getBindByNamePrefix())) {
200 bindingPathPrefix = collectionGroup.getBindingInfo().getBindByNamePrefix() + "." + bindingPathPrefix;
201 }
202
203 List<Action> lineActions = initializeLineActions(collectionGroup.getLineActions(), view, model,
204 collectionGroup, currentLine, indexedElement.index);
205
206 buildLine(view, model, collectionGroup, bindingPathPrefix, lineActions, false, currentLine,
207 indexedElement.index);
208 }
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226 protected List<Integer> performCollectionFiltering(View view, Object model, CollectionGroup collectionGroup,
227 Collection<?> collection) {
228 List<Integer> filteredIndexes = new ArrayList<Integer>();
229 for (int i = 0; i < collection.size(); i++) {
230 filteredIndexes.add(Integer.valueOf(i));
231 }
232
233 if (Inactivatable.class.isAssignableFrom(collectionGroup.getCollectionObjectClass()) && !collectionGroup
234 .isShowInactiveLines()) {
235 List<Integer> activeIndexes = collectionGroup.getActiveCollectionFilter().filter(view, model,
236 collectionGroup);
237 filteredIndexes = ListUtils.intersection(filteredIndexes, activeIndexes);
238 }
239
240 for (CollectionFilter collectionFilter : collectionGroup.getFilters()) {
241 List<Integer> indexes = collectionFilter.filter(view, model, collectionGroup);
242 filteredIndexes = ListUtils.intersection(filteredIndexes, indexes);
243 if (filteredIndexes.isEmpty()) {
244 break;
245 }
246 }
247
248 return filteredIndexes;
249 }
250
251
252
253
254
255
256
257
258
259
260 protected void buildAddLine(View view, Object model, CollectionGroup collectionGroup) {
261 boolean addLineBindsToForm = false;
262
263
264 initializeNewCollectionLine(view, model, collectionGroup, false);
265
266
267
268 if (StringUtils.isBlank(collectionGroup.getAddLinePropertyName())) {
269 addLineBindsToForm = true;
270 }
271
272 String addLineBindingPath = collectionGroup.getAddLineBindingInfo().getBindingPath();
273 List<Action> actions = getAddLineActions(view, model, collectionGroup);
274
275 Object addLine = ObjectPropertyUtils.getPropertyValue(model, addLineBindingPath);
276 buildLine(view, model, collectionGroup, addLineBindingPath, actions, addLineBindsToForm, addLine, -1);
277 }
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297 @SuppressWarnings("unchecked")
298 protected void buildLine(View view, Object model, CollectionGroup collectionGroup, String bindingPath,
299 List<Action> actions, boolean bindToForm, Object currentLine, int lineIndex) {
300 CollectionLayoutManager layoutManager = (CollectionLayoutManager) collectionGroup.getLayoutManager();
301
302
303 List<? extends Component> lineItems = null;
304 String lineSuffix = null;
305 if (lineIndex == -1) {
306 lineItems = ComponentUtils.copyComponentList(collectionGroup.getAddLineItems(), null);
307 lineSuffix = UifConstants.IdSuffixes.ADD_LINE;
308 } else {
309 lineItems = ComponentUtils.copyComponentList(collectionGroup.getItems(), null);
310 lineSuffix = UifConstants.IdSuffixes.LINE + Integer.toString(lineIndex);
311 }
312
313 if (StringUtils.isNotBlank(collectionGroup.getSubCollectionSuffix())) {
314 lineSuffix = collectionGroup.getSubCollectionSuffix() + lineSuffix;
315 }
316
317
318 List<Field> lineFields = processAnyRemoteFieldsHolder(view, model, collectionGroup, lineItems);
319
320
321 ComponentUtils.bindAndIdFieldList(lineFields, bindingPath, lineSuffix);
322
323
324
325 for (Field field : lineFields) {
326 List<CollectionGroup> components = ComponentUtils.getComponentsOfTypeDeep(field, CollectionGroup.class);
327 for (CollectionGroup fieldCollectionGroup : components) {
328 ComponentUtils.prefixBindingPath(fieldCollectionGroup, bindingPath);
329 fieldCollectionGroup.setSubCollectionSuffix(lineSuffix);
330 }
331
332
333 List<LightTable> lightTables = ComponentUtils.getComponentsOfTypeDeep(field, LightTable.class);
334 for (LightTable lightTable : lightTables) {
335 ComponentUtils.prefixBindingPath(lightTable, bindingPath);
336 }
337 }
338
339 boolean readOnlyLine = collectionGroup.isReadOnly();
340
341
342 ComponentUtils.updateContextsForLine(lineFields, currentLine, lineIndex, lineSuffix);
343
344 for (Action action : actions) {
345 if (action != null && StringUtils.isNotBlank(action.getFocusOnIdAfterSubmit()) &&
346 action.getFocusOnIdAfterSubmit().equalsIgnoreCase(UifConstants.Order.LINE_FIRST.toString()) && (
347 lineFields.size()
348 > 0)) {
349 action.setFocusOnIdAfterSubmit(lineFields.get(0).getId() + UifConstants.IdSuffixes.CONTROL);
350 }
351 }
352
353
354 if (lineIndex == -1) {
355
356 } else {
357
358 boolean canViewLine = checkViewLineAuthorizationAndPresentationLogic(view, (ViewModel) model,
359 collectionGroup, currentLine);
360
361
362 if (!canViewLine) {
363 return;
364 }
365
366
367 if (!collectionGroup.isReadOnly()) {
368 readOnlyLine = !checkEditLineAuthorizationAndPresentationLogic(view, (ViewModel) model, collectionGroup,
369 currentLine);
370
371
372 if (!readOnlyLine && !((UifFormBase) model).isAddedCollectionItem(currentLine) &&
373 collectionGroup.isRenderSaveLineActions()) {
374 for (Field f : lineFields) {
375 if (f instanceof InputField && f.isRender()) {
376 ControlBase control = (ControlBase) ((InputField) f).getControl();
377 control.setOnChangeScript(control.getOnChangeScript() == null ?
378 ";collectionLineChanged(this, 'uif-newCollectionItem');" :
379 control.getOnChangeScript()
380 + ";collectionLineChanged(this, 'uif-newCollectionItem');");
381 }
382 }
383 }
384 }
385
386 ComponentUtils.pushObjectToContext(lineFields, UifConstants.ContextVariableNames.READONLY_LINE,
387 readOnlyLine);
388 ComponentUtils.pushObjectToContext(actions, UifConstants.ContextVariableNames.READONLY_LINE, readOnlyLine);
389 }
390
391
392 applyLineFieldAuthorizationAndPresentationLogic(view, (ViewModel) model, collectionGroup, currentLine,
393 readOnlyLine, lineFields, actions);
394
395 if (bindToForm) {
396 ComponentUtils.setComponentsPropertyDeep(lineFields, UifPropertyPaths.BIND_TO_FORM, Boolean.valueOf(true));
397 }
398
399
400 lineFields = removeNonRenderLineFields(view, model, collectionGroup, lineFields, currentLine, lineIndex);
401
402
403 List<FieldGroup> subCollectionFields = new ArrayList<FieldGroup>();
404 if ((lineIndex != -1) && (collectionGroup.getSubCollections() != null)) {
405 for (int subLineIndex = 0; subLineIndex < collectionGroup.getSubCollections().size(); subLineIndex++) {
406 CollectionGroup subCollectionPrototype = collectionGroup.getSubCollections().get(subLineIndex);
407 CollectionGroup subCollectionGroup = ComponentUtils.copy(subCollectionPrototype, lineSuffix);
408
409
410 boolean renderSubCollection = checkSubCollectionRender(view, model, collectionGroup,
411 subCollectionGroup);
412 if (!renderSubCollection) {
413 continue;
414 }
415
416 subCollectionGroup.getBindingInfo().setBindByNamePrefix(bindingPath);
417 if (subCollectionGroup.isRenderAddLine()) {
418 subCollectionGroup.getAddLineBindingInfo().setBindByNamePrefix(bindingPath);
419 }
420
421
422 String subCollectionSuffix = lineSuffix;
423 if (StringUtils.isNotBlank(subCollectionGroup.getSubCollectionSuffix())) {
424 subCollectionSuffix = subCollectionGroup.getSubCollectionSuffix() + lineSuffix;
425 }
426 subCollectionGroup.setSubCollectionSuffix(subCollectionSuffix);
427
428 FieldGroup fieldGroupPrototype = layoutManager.getSubCollectionFieldGroupPrototype();
429
430 FieldGroup subCollectionFieldGroup = ComponentUtils.copy(fieldGroupPrototype,
431 lineSuffix + UifConstants.IdSuffixes.SUB + subLineIndex);
432 subCollectionFieldGroup.setGroup(subCollectionGroup);
433
434 ComponentUtils.updateContextForLine(subCollectionFieldGroup, currentLine, lineIndex,
435 lineSuffix + UifConstants.IdSuffixes.SUB + subLineIndex);
436
437 subCollectionFields.add(subCollectionFieldGroup);
438 }
439 ComponentUtils.pushObjectToContext(subCollectionFields, UifConstants.ContextVariableNames.PARENT_LINE,
440 currentLine);
441 }
442
443
444 layoutManager.buildLine(view, model, collectionGroup, lineFields, subCollectionFields, bindingPath, actions,
445 lineSuffix, currentLine, lineIndex);
446
447
448 String selector = "";
449 if (lineIndex == -1) {
450 List<String> addIds = new ArrayList<String>();
451 for (Field f : lineFields) {
452 if (f instanceof InputField) {
453
454
455 Control control = ((InputField) f).getControl();
456 if (control != null) {
457 control.addStyleClass("ignoreValid");
458 selector = selector + ",#" + f.getId() + UifConstants.IdSuffixes.CONTROL;
459 }
460 } else if (f instanceof FieldGroup) {
461 List<InputField> fields = ComponentUtils.getComponentsOfTypeDeep(((FieldGroup) f).getGroup(),
462 InputField.class);
463 for (InputField nestedField : fields) {
464 Control control = nestedField.getControl();
465 if (control != null) {
466 control.addStyleClass("ignoreValid");
467 selector = selector + ",#" + nestedField.getId() + UifConstants.IdSuffixes.CONTROL;
468 }
469 }
470 }
471 }
472 collectionGroup.addDataAttribute(UifConstants.DataAttributes.ADD_CONTROLS, selector.replaceFirst(",", ""));
473 }
474 }
475
476
477
478
479
480
481
482
483
484
485
486 protected List<Field> processAnyRemoteFieldsHolder(View view, Object model, CollectionGroup group,
487 List<? extends Component> items) {
488 List<Field> processedItems = new ArrayList<Field>();
489
490
491
492 for (Component item : items) {
493 if (item instanceof RemoteFieldsHolder) {
494 List<InputField> translatedFields = ((RemoteFieldsHolder) item).fetchAndTranslateRemoteFields(view,
495 model, group);
496 processedItems.addAll(translatedFields);
497 } else {
498 processedItems.add((Field) item);
499 }
500 }
501
502 return processedItems;
503 }
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521 protected List<Field> removeNonRenderLineFields(View view, Object model, CollectionGroup collectionGroup,
522 List<Field> lineFields, Object currentLine, int lineIndex) {
523 List<Field> fields = new ArrayList<Field>();
524
525 ExpressionEvaluator expressionEvaluator = view.getViewHelperService().getExpressionEvaluator();
526
527 for (Field lineField : lineFields) {
528 String conditionalRender = lineField.getPropertyExpression("render");
529
530
531 if (StringUtils.isNotBlank(conditionalRender)) {
532 Map<String, Object> context = getContextForField(view, collectionGroup, lineField);
533
534
535
536 conditionalRender = expressionEvaluator.replaceBindingPrefixes(view, lineField, conditionalRender);
537
538 Boolean render = (Boolean) expressionEvaluator.evaluateExpression(context, conditionalRender);
539 lineField.setRender(render);
540 }
541
542
543 if (lineField.isRender() || StringUtils.isNotBlank(lineField.getProgressiveRender())) {
544 fields.add(lineField);
545 }
546 }
547
548 return fields;
549 }
550
551
552
553
554
555
556
557
558
559
560
561
562 protected boolean checkViewLineAuthorizationAndPresentationLogic(View view, ViewModel model,
563 CollectionGroup collectionGroup, Object line) {
564 ViewPresentationController presentationController = view.getPresentationController();
565 ViewAuthorizer authorizer = view.getAuthorizer();
566
567 Person user = GlobalVariables.getUserSession().getPerson();
568
569
570 boolean canViewLine = authorizer.canViewLine(view, model, collectionGroup, collectionGroup.getPropertyName(),
571 line, user);
572 if (canViewLine) {
573 canViewLine = presentationController.canViewLine(view, model, collectionGroup,
574 collectionGroup.getPropertyName(), line);
575 }
576
577 return canViewLine;
578 }
579
580
581
582
583
584
585
586
587
588
589
590
591 protected boolean checkEditLineAuthorizationAndPresentationLogic(View view, ViewModel model,
592 CollectionGroup collectionGroup, Object line) {
593 ViewPresentationController presentationController = view.getPresentationController();
594 ViewAuthorizer authorizer = view.getAuthorizer();
595
596 Person user = GlobalVariables.getUserSession().getPerson();
597
598
599 boolean canEditLine = authorizer.canEditLine(view, model, collectionGroup, collectionGroup.getPropertyName(),
600 line, user);
601 if (canEditLine) {
602 canEditLine = presentationController.canEditLine(view, model, collectionGroup,
603 collectionGroup.getPropertyName(), line);
604 }
605
606 return canEditLine;
607 }
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624 protected void applyLineFieldAuthorizationAndPresentationLogic(View view, ViewModel model,
625 CollectionGroup collectionGroup, Object line, boolean readOnlyLine, List<Field> lineFields,
626 List<Action> actions) {
627 ViewPresentationController presentationController = view.getPresentationController();
628 ViewAuthorizer authorizer = view.getAuthorizer();
629
630 Person user = GlobalVariables.getUserSession().getPerson();
631
632 ExpressionEvaluator expressionEvaluator = view.getViewHelperService().getExpressionEvaluator();
633
634 for (Field lineField : lineFields) {
635 String propertyName = null;
636 if (lineField instanceof DataBinding) {
637 propertyName = ((DataBinding) lineField).getPropertyName();
638 }
639
640
641
642 ComponentSecurity componentSecurity = lineField.getComponentSecurity();
643
644 Map<String, Object> context = getContextForField(view, collectionGroup, lineField);
645 expressionEvaluator.evaluateExpressionsOnConfigurable(view, componentSecurity, context);
646
647
648 if (lineField.isRender() && !lineField.isHidden()) {
649 boolean canViewField = authorizer.canViewLineField(view, model, collectionGroup,
650 collectionGroup.getPropertyName(), line, lineField, propertyName, user);
651 if (canViewField) {
652 canViewField = presentationController.canViewLineField(view, model, collectionGroup,
653 collectionGroup.getPropertyName(), line, lineField, propertyName);
654 }
655
656 if (!canViewField) {
657
658
659 lineField.setHidden(true);
660
661 if (lineField.getPropertyExpressions().containsKey("hidden")) {
662 lineField.getPropertyExpressions().remove("hidden");
663 }
664
665 continue;
666 }
667
668
669 boolean canEditField = !readOnlyLine;
670 if (!readOnlyLine) {
671 canEditField = authorizer.canEditLineField(view, model, collectionGroup,
672 collectionGroup.getPropertyName(), line, lineField, propertyName, user);
673 if (canEditField) {
674 canEditField = presentationController.canEditLineField(view, model, collectionGroup,
675 collectionGroup.getPropertyName(), line, lineField, propertyName);
676 }
677 }
678
679 if (readOnlyLine || !canEditField) {
680 lineField.setReadOnly(true);
681
682 if (lineField.getPropertyExpressions().containsKey("readOnly")) {
683 lineField.getPropertyExpressions().remove("readOnly");
684 }
685 }
686 }
687 }
688
689
690 for (Action action : actions) {
691 if (action.isRender()) {
692 boolean canPerformAction = authorizer.canPerformLineAction(view, model, collectionGroup,
693 collectionGroup.getPropertyName(), line, action, action.getActionEvent(), action.getId(), user);
694 if (canPerformAction) {
695 canPerformAction = presentationController.canPerformLineAction(view, model, collectionGroup,
696 collectionGroup.getPropertyName(), line, action, action.getActionEvent(), action.getId());
697 }
698
699 if (!canPerformAction) {
700 action.setRender(false);
701
702 if (action.getPropertyExpressions().containsKey("render")) {
703 action.getPropertyExpressions().remove("render");
704 }
705 }
706 }
707 }
708 }
709
710
711
712
713
714
715
716
717
718
719
720
721 protected boolean checkSubCollectionRender(View view, Object model, CollectionGroup collectionGroup,
722 CollectionGroup subCollectionGroup) {
723 String conditionalRender = subCollectionGroup.getPropertyExpression("render");
724
725
726
727
728 if (StringUtils.isNotBlank(conditionalRender)) {
729 Map<String, Object> context = new HashMap<String, Object>();
730 Map<String, Object> viewContext = view.getContext();
731
732 if (viewContext != null) {
733 context.putAll(viewContext);
734 }
735
736 context.put(UifConstants.ContextVariableNames.PARENT, collectionGroup);
737 context.put(UifConstants.ContextVariableNames.COMPONENT, subCollectionGroup);
738
739 Boolean render = (Boolean) view.getViewHelperService().getExpressionEvaluator().evaluateExpression(context,
740 conditionalRender);
741 subCollectionGroup.setRender(render);
742 }
743
744 return subCollectionGroup.isRender();
745 }
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762 protected List<Action> initializeLineActions(List<Action> lineActions, View view, Object model,
763 CollectionGroup collectionGroup, Object collectionLine, int lineIndex) {
764 String lineSuffix = UifConstants.IdSuffixes.LINE + Integer.toString(lineIndex);
765 if (StringUtils.isNotBlank(collectionGroup.getSubCollectionSuffix())) {
766 lineSuffix = collectionGroup.getSubCollectionSuffix() + lineSuffix;
767 }
768 List<Action> actions = ComponentUtils.copyComponentList(lineActions, lineSuffix);
769
770 for (Action action : actions) {
771 if (ComponentUtils.containsPropertyExpression(action, UifPropertyPaths.ACTION_PARAMETERS, true)) {
772
773 action.getPropertyExpressions().put(
774 UifPropertyPaths.ACTION_PARAMETERS + "['" + UifParameters.SELLECTED_COLLECTION_PATH + "']",
775 UifConstants.EL_PLACEHOLDER_PREFIX + "'" + collectionGroup.getBindingInfo().getBindingPath() +
776 "'" + UifConstants.EL_PLACEHOLDER_SUFFIX);
777 action.getPropertyExpressions().put(
778 UifPropertyPaths.ACTION_PARAMETERS + "['" + UifParameters.SELECTED_LINE_INDEX + "']",
779 UifConstants.EL_PLACEHOLDER_PREFIX + "'" + Integer.toString(lineIndex) +
780 "'" + UifConstants.EL_PLACEHOLDER_SUFFIX);
781 } else {
782 action.addActionParameter(UifParameters.SELLECTED_COLLECTION_PATH,
783 collectionGroup.getBindingInfo().getBindingPath());
784 action.addActionParameter(UifParameters.SELECTED_LINE_INDEX, Integer.toString(lineIndex));
785 }
786
787 action.setJumpToIdAfterSubmit(collectionGroup.getId());
788 action.setRefreshId(collectionGroup.getId());
789
790
791
792 if (action.isPerformClientSideValidation()) {
793 String preSubmitScript = "var valid=validateLine('" +
794 collectionGroup.getBindingInfo().getBindingPath() + "'," + Integer.toString(lineIndex) +
795 ");";
796
797
798 if (StringUtils.isNotBlank(action.getPreSubmitCall())) {
799 preSubmitScript = ScriptUtils.appendScript(preSubmitScript,
800 "if(valid){valid=function(){" + action.getPreSubmitCall() + "}();}");
801 }
802
803 preSubmitScript += " return valid;";
804
805 action.setPreSubmitCall(preSubmitScript);
806 action.setPerformClientSideValidation(false);
807 }
808 }
809
810 ComponentUtils.updateContextsForLine(actions, collectionLine, lineIndex, lineSuffix);
811
812 return actions;
813 }
814
815
816
817
818
819
820
821
822
823
824
825
826
827 protected List<Action> getAddLineActions(View view, Object model, CollectionGroup collectionGroup) {
828 String lineSuffix = UifConstants.IdSuffixes.ADD_LINE;
829 if (StringUtils.isNotBlank(collectionGroup.getSubCollectionSuffix())) {
830 lineSuffix = collectionGroup.getSubCollectionSuffix() + lineSuffix;
831 }
832 List<Action> lineActions = ComponentUtils.copyComponentList(collectionGroup.getAddLineActions(), lineSuffix);
833
834 for (Action action : lineActions) {
835 action.addActionParameter(UifParameters.SELLECTED_COLLECTION_PATH,
836 collectionGroup.getBindingInfo().getBindingPath());
837 action.setJumpToIdAfterSubmit(collectionGroup.getId());
838 action.addActionParameter(UifParameters.ACTION_TYPE, UifParameters.ADD_LINE);
839 action.setRefreshId(collectionGroup.getId());
840
841 String baseId = collectionGroup.getBaseId();
842 if (StringUtils.isNotBlank(collectionGroup.getSubCollectionSuffix())) {
843 baseId += collectionGroup.getSubCollectionSuffix();
844 }
845
846 if (action.isPerformClientSideValidation()) {
847 String preSubmitScript = "var valid=";
848 if (collectionGroup.isAddViaLightBox()) {
849 preSubmitScript += "validateAddLine('" + collectionGroup.getId() + "', true);";
850 } else {
851 preSubmitScript += "validateAddLine('" + collectionGroup.getId() + "');";
852 }
853
854
855 if (StringUtils.isNotBlank(action.getPreSubmitCall())) {
856 preSubmitScript = ScriptUtils.appendScript(preSubmitScript,
857 "if(valid){valid=function(){" + action.getPreSubmitCall() + "}();}");
858 }
859
860 if (collectionGroup.isAddViaLightBox()) {
861 preSubmitScript += " if(valid){closeLightbox();}";
862 }
863 preSubmitScript += "return valid;";
864
865 action.setPreSubmitCall(preSubmitScript);
866 action.setPerformClientSideValidation(false);
867 }
868 }
869
870
871 String addLinePath = collectionGroup.getAddLineBindingInfo().getBindingPath();
872 Object addLine = ObjectPropertyUtils.getPropertyValue(model, addLinePath);
873
874 ComponentUtils.updateContextsForLine(lineActions, addLine, -1, lineSuffix);
875
876 return lineActions;
877 }
878
879
880
881
882
883
884
885
886
887
888 protected Map<String, Object> getContextForField(View view, CollectionGroup collectionGroup, Field field) {
889 Map<String, Object> context = new HashMap<String, Object>();
890
891 Map<String, Object> viewContext = view.getContext();
892 if (viewContext != null) {
893 context.putAll(viewContext);
894 }
895
896 Map<String, Object> fieldContext = field.getContext();
897 if (fieldContext != null) {
898 context.putAll(fieldContext);
899 }
900
901 context.put(UifConstants.ContextVariableNames.PARENT, collectionGroup);
902 context.put(UifConstants.ContextVariableNames.COMPONENT, field);
903
904 return context;
905 }
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926 public void initializeNewCollectionLine(View view, Object model, CollectionGroup collectionGroup,
927 boolean clearExistingLine) {
928 Object newLine = null;
929
930
931 if (StringUtils.isBlank(collectionGroup.getAddLinePropertyName())) {
932
933 if (!(model instanceof UifFormBase)) {
934 throw new RuntimeException("Cannot create new collection line for group: "
935 + collectionGroup.getPropertyName()
936 + ". Model does not extend "
937 + UifFormBase.class.getName());
938 }
939
940
941 Map<String, Object> newCollectionLines = ObjectPropertyUtils.getPropertyValue(model,
942 UifPropertyPaths.NEW_COLLECTION_LINES);
943 if (newCollectionLines == null) {
944 newCollectionLines = new HashMap<String, Object>();
945 ObjectPropertyUtils.setPropertyValue(model, UifPropertyPaths.NEW_COLLECTION_LINES, newCollectionLines);
946 }
947
948
949 String newCollectionLineKey = KRADUtils.translateToMapSafeKey(
950 collectionGroup.getBindingInfo().getBindingPath());
951 String addLineBindingPath = UifPropertyPaths.NEW_COLLECTION_LINES + "['" + newCollectionLineKey + "']";
952 collectionGroup.getAddLineBindingInfo().setBindingPath(addLineBindingPath);
953
954
955 if (!newCollectionLines.containsKey(newCollectionLineKey) || (newCollectionLines.get(newCollectionLineKey)
956 == null) || clearExistingLine) {
957
958 newLine = ObjectUtils.newInstance(collectionGroup.getCollectionObjectClass());
959 newCollectionLines.put(newCollectionLineKey, newLine);
960 }
961 } else {
962
963 Object addLine = ObjectPropertyUtils.getPropertyValue(model,
964 collectionGroup.getAddLineBindingInfo().getBindingPath());
965 if ((addLine == null) || clearExistingLine) {
966 newLine = ObjectUtils.newInstance(collectionGroup.getCollectionObjectClass());
967 ObjectPropertyUtils.setPropertyValue(model, collectionGroup.getAddLineBindingInfo().getBindingPath(),
968 newLine);
969 }
970 }
971
972
973 if (newLine != null) {
974 view.getViewHelperService().applyDefaultValuesForCollectionLine(view, model, collectionGroup, newLine);
975 }
976 }
977
978
979
980
981 private static class IndexedElement {
982
983
984
985
986 final int index;
987
988
989
990
991 final Object element;
992
993
994
995
996
997
998
999 private IndexedElement(int index, Object element) {
1000 this.index = index;
1001 this.element = element;
1002 }
1003 }
1004
1005 }