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.kim.api.identity.Person;
20 import org.kuali.rice.krad.uif.CssConstants;
21 import org.kuali.rice.krad.uif.UifConstants;
22 import org.kuali.rice.krad.uif.UifParameters;
23 import org.kuali.rice.krad.uif.UifPropertyPaths;
24 import org.kuali.rice.krad.uif.component.BindingInfo;
25 import org.kuali.rice.krad.uif.component.Component;
26 import org.kuali.rice.krad.uif.component.ComponentSecurity;
27 import org.kuali.rice.krad.uif.component.DataBinding;
28 import org.kuali.rice.krad.uif.container.collections.LineBuilderContext;
29 import org.kuali.rice.krad.uif.control.Control;
30 import org.kuali.rice.krad.uif.control.ControlBase;
31 import org.kuali.rice.krad.uif.element.Action;
32 import org.kuali.rice.krad.uif.field.DataField;
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.layout.TableLayoutManagerBase;
39 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
40 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleUtils;
41 import org.kuali.rice.krad.uif.util.ComponentFactory;
42 import org.kuali.rice.krad.uif.util.ComponentUtils;
43 import org.kuali.rice.krad.uif.util.ContextUtils;
44 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
45 import org.kuali.rice.krad.uif.util.ScriptUtils;
46 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
47 import org.kuali.rice.krad.uif.view.View;
48 import org.kuali.rice.krad.uif.view.ViewAuthorizer;
49 import org.kuali.rice.krad.uif.view.ViewModel;
50 import org.kuali.rice.krad.uif.view.ViewPresentationController;
51 import org.kuali.rice.krad.util.GlobalVariables;
52 import org.kuali.rice.krad.web.form.UifFormBase;
53
54 import java.io.Serializable;
55 import java.util.ArrayList;
56 import java.util.HashMap;
57 import java.util.Iterator;
58 import java.util.List;
59 import java.util.Map;
60
61
62
63
64
65
66
67 public class CollectionGroupLineBuilder implements Serializable {
68
69 private static final long serialVersionUID = 981187437246864378L;
70
71 private LineBuilderContext lineBuilderContext;
72 private List<Field> unauthorizedFields = new ArrayList<Field>();
73
74 public CollectionGroupLineBuilder(LineBuilderContext lineBuilderContext) {
75 this.lineBuilderContext = lineBuilderContext;
76 }
77
78
79
80
81
82
83
84 public void buildLine() {
85 preprocessLine();
86
87 boolean hasLineFields =
88 (lineBuilderContext.getLineFields() != null) && (!lineBuilderContext.getLineFields().isEmpty());
89 boolean hasSubCollections =
90 (lineBuilderContext.getSubCollectionFields() != null) && (!lineBuilderContext.getSubCollectionFields()
91 .isEmpty());
92
93
94 if (hasLineFields || hasSubCollections) {
95
96 if (!lineBuilderContext.isAddLine()) {
97 setupEditLineDetails();
98 }
99
100
101 List<Component> actions = new ArrayList<Component>();
102 actions.addAll(lineBuilderContext.getLineActions());
103 List<DialogGroup> dialogGroups = lineBuilderContext.getCollectionGroup().getLineDialogs();
104 if (Boolean.TRUE.equals(lineBuilderContext.getCollectionGroup().getReadOnly())) {
105 for (DialogGroup group : dialogGroups) {
106 group.setReadOnly(true);
107 }
108 }
109 actions.addAll(dialogGroups);
110 lineBuilderContext.setLineActions(actions);
111 lineBuilderContext.getCollectionGroup().getLineDialogs().clear();
112
113
114 lineBuilderContext.getLayoutManager().buildLine(lineBuilderContext);
115 }
116
117
118
119 applyOnChangeForSave(lineBuilderContext.getLineFields());
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 public void preprocessLine() {
136 List<? extends Component> lineItems = initializeLineItems();
137
138 List<Field> lineFields = processAnyRemoteFieldsHolder(lineBuilderContext.getCollectionGroup(), lineItems);
139
140 adjustFieldBindingAndId(lineFields, lineBuilderContext.getBindingPath());
141
142 ContextUtils.updateContextsForLine(lineFields, lineBuilderContext.getCollectionGroup(),
143 lineBuilderContext.getCurrentLine(), lineBuilderContext.getLineIndex(),
144 lineBuilderContext.getIdSuffix());
145
146 boolean canViewLine = checkViewLineAuthorization();
147 if (!canViewLine) {
148 return;
149 }
150
151 List<Action> actions = ViewLifecycleUtils.getElementsOfTypeDeep(lineBuilderContext.getLineActions(),
152 Action.class);
153 setFocusOnIdForActions(actions, lineFields);
154
155 boolean canEditLine = checkEditLineAuthorization(lineFields);
156 ContextUtils.pushObjectToContextDeep(lineFields, UifConstants.ContextVariableNames.READONLY_LINE, !canEditLine);
157 ContextUtils.pushObjectToContextDeep(actions, UifConstants.ContextVariableNames.READONLY_LINE, !canEditLine);
158
159 if (!canEditLine) {
160 Iterator<Action> actionsIterator = actions.iterator();
161 while (actionsIterator.hasNext()) {
162 Action action = actionsIterator.next();
163 if (action.getId().startsWith(ComponentFactory.EDIT_LINE_IN_DIALOG_ACTION + "_" +
164 lineBuilderContext.getCollectionGroup().getId())) {
165 actionsIterator.remove();
166 break;
167 }
168 }
169 lineBuilderContext.setLineActions(actions);
170 }
171
172
173 applyLineFieldAuthorizationAndPresentationLogic(!canEditLine, lineFields, actions);
174
175
176 lineFields = removeNonRenderLineFields(lineFields);
177
178 buildSubCollectionFieldGroups();
179
180
181 List<Action> lineFieldActions = ViewLifecycleUtils.getElementsOfTypeDeep(lineFields, Action.class);
182 if (lineFieldActions != null) {
183 lineBuilderContext.getCollectionGroup().getCollectionGroupBuilder().initializeActions(lineFieldActions,
184 lineBuilderContext.getCollectionGroup(), lineBuilderContext.getLineIndex());
185 }
186
187 setupAddLineControlValidation(lineFields);
188
189 lineBuilderContext.setLineFields(lineFields);
190 }
191
192
193
194
195
196
197
198 protected List<? extends Component> initializeLineItems() {
199 List<? extends Component> lineItems;
200
201 if (lineBuilderContext.isAddLine()) {
202 lineItems = ComponentUtils.copyComponentList(lineBuilderContext.getCollectionGroup().getAddLineItems(),
203 null);
204 } else {
205 lineItems = ComponentUtils.copyComponentList(lineBuilderContext.getCollectionGroup().getItems(), null);
206 }
207
208 return lineItems;
209 }
210
211
212
213
214
215
216
217
218
219
220 public List<Field> processAnyRemoteFieldsHolder(CollectionGroup group, List<? extends Component> items) {
221 List<Field> processedItems = new ArrayList<Field>();
222
223
224
225 for (Component item : items) {
226 if (item instanceof RemoteFieldsHolder) {
227 List<InputField> translatedFields = ((RemoteFieldsHolder) item).fetchAndTranslateRemoteFields(group);
228 processedItems.addAll(translatedFields);
229 } else if (item instanceof Field) {
230 processedItems.add((Field) item);
231 }
232 }
233
234 return processedItems;
235 }
236
237
238
239
240
241
242
243
244 protected void adjustFieldBindingAndId(List<Field> lineFields, String bindingPath) {
245 for (Field lineField : lineFields) {
246 adjustFieldBinding(lineField, bindingPath);
247 adjustFieldId(lineField);
248 }
249
250 if (lineBuilderContext.isBindToForm()) {
251 ComponentUtils.setComponentsPropertyDeep(lineFields, UifPropertyPaths.BIND_TO_FORM, Boolean.valueOf(true));
252 }
253 }
254
255
256
257
258
259
260
261 protected void adjustFieldBinding(Field lineField, String bindingPath) {
262 if (lineField instanceof DataBinding && ((DataBinding) lineField).getBindingInfo().isBindToForm()) {
263 BindingInfo bindingInfo = ((DataBinding) lineField).getBindingInfo();
264 bindingInfo.setCollectionPath(null);
265 bindingInfo.setBindingName(bindingInfo.getBindingName() + "[" + lineBuilderContext.getLineIndex() + "]");
266 } else {
267 ComponentUtils.prefixBindingPath(lineField, bindingPath);
268 }
269 }
270
271
272
273
274
275
276 protected void adjustFieldId(Field lineField) {
277 ComponentUtils.updateIdWithSuffix(lineField, lineBuilderContext.getIdSuffix());
278
279 lineField.setContainerIdSuffix(lineBuilderContext.getIdSuffix());
280 }
281
282
283
284
285
286
287
288
289
290 protected void setFocusOnIdForActions(List<Action> actions, List<Field> lineFields) {
291 for (Action action : actions) {
292 if (action == null) {
293 continue;
294 }
295
296 boolean focusLineFirst = StringUtils.isNotBlank(action.getFocusOnIdAfterSubmit()) && action
297 .getFocusOnIdAfterSubmit().equalsIgnoreCase(UifConstants.Order.LINE_FIRST.toString());
298 boolean lineHasFields = !lineFields.isEmpty();
299 if (focusLineFirst && lineHasFields) {
300 action.setFocusOnIdAfterSubmit(lineFields.get(0).getId() + UifConstants.IdSuffixes.CONTROL);
301 }
302 }
303 }
304
305
306
307
308
309
310
311 protected void applyOnChangeForSave(List<Field> lineFields) {
312 boolean isLineNewlyAdded = ((UifFormBase) lineBuilderContext.getModel()).isAddedCollectionItem(
313 lineBuilderContext.getCurrentLine());
314 boolean saveLineEnabled = lineBuilderContext.getCollectionGroup().isRenderSaveLineActions();
315
316 if (!isLineNewlyAdded && !saveLineEnabled) {
317 return;
318 }
319
320 for (Field field : lineFields) {
321 boolean isInputField = (field instanceof InputField);
322 if (field.isHidden() || Boolean.TRUE.equals(field.getReadOnly()) || !isInputField) {
323 continue;
324 }
325
326
327 InputField inputField = (InputField) field;
328 if (inputField.getControl() == null) {
329 inputField.setControl(ComponentFactory.getTextControl());
330 }
331
332 ControlBase control = (ControlBase) ((InputField) field).getControl();
333
334 String onBlurScript = UifConstants.JsFunctions.COLLECTION_LINE_CHANGED + "(this, '" +
335 CssConstants.Classes.NEW_COLLECTION_ITEM + "');";
336 onBlurScript = ScriptUtils.appendScript(control.getOnBlurScript(), onBlurScript);
337
338 control.setOnBlurScript(onBlurScript);
339 }
340 }
341
342
343
344
345
346
347
348
349
350
351
352
353 protected List<Field> removeNonRenderLineFields(List<Field> lineFields) {
354 List<Field> fields = new ArrayList<Field>();
355
356 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
357
358 for (Field lineField : lineFields) {
359 String conditionalRender = lineField.getPropertyExpression(UifPropertyPaths.RENDER);
360
361
362 if (StringUtils.isNotBlank(conditionalRender)) {
363 Map<String, Object> context = getContextForField(ViewLifecycle.getView(),
364 lineBuilderContext.getCollectionGroup(), lineField);
365
366
367
368 conditionalRender = expressionEvaluator.replaceBindingPrefixes(ViewLifecycle.getView(), lineField,
369 conditionalRender);
370
371 Boolean render = (Boolean) expressionEvaluator.evaluateExpression(context, conditionalRender);
372 lineField.setRender(render);
373 }
374
375
376 if (lineField.isRender() || StringUtils.isNotBlank(lineField.getProgressiveRender())) {
377 fields.add(lineField);
378 }
379 }
380
381 return fields;
382 }
383
384
385
386
387
388
389 protected boolean checkViewLineAuthorization() {
390 boolean canViewLine = true;
391
392
393 if (!lineBuilderContext.isAddLine()) {
394 canViewLine = checkViewLineAuthorizationAndPresentationLogic();
395 }
396
397 if (!canViewLine) {
398 addUnauthorizedBindingInfo();
399 }
400
401 return canViewLine;
402 }
403
404
405
406
407
408
409
410 protected boolean checkViewLineAuthorizationAndPresentationLogic() {
411 ViewPresentationController presentationController = ViewLifecycle.getView().getPresentationController();
412 ViewAuthorizer authorizer = ViewLifecycle.getView().getAuthorizer();
413
414 Person user = GlobalVariables.getUserSession().getPerson();
415
416 CollectionGroup collectionGroup = lineBuilderContext.getCollectionGroup();
417
418 boolean canViewLine = authorizer.canViewLine(ViewLifecycle.getView(), lineBuilderContext.getModel(),
419 collectionGroup, collectionGroup.getPropertyName(), lineBuilderContext.getCurrentLine(), user);
420 if (canViewLine) {
421 canViewLine = presentationController.canViewLine(ViewLifecycle.getView(), lineBuilderContext.getModel(),
422 collectionGroup, collectionGroup.getPropertyName(), lineBuilderContext.getCurrentLine());
423 }
424
425 return canViewLine;
426 }
427
428
429
430
431
432
433
434 protected boolean checkEditLineAuthorization(List<Field> lineFields) {
435 boolean canEditLine = !Boolean.TRUE.equals(lineBuilderContext.getCollectionGroup().getReadOnly());
436
437 if (!canEditLine) {
438 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
439 View view = ViewLifecycle.getView();
440
441 for (Field field : lineFields) {
442 field.pushObjectToContext(UifConstants.ContextVariableNames.PARENT,
443 lineBuilderContext.getCollectionGroup());
444 field.pushAllToContext(view.getContext());
445 field.pushObjectToContext(UifConstants.ContextVariableNames.COMPONENT, field);
446
447 expressionEvaluator.evaluatePropertyExpression(view, field.getContext(), field,
448 UifPropertyPaths.READ_ONLY, true);
449
450 if (!Boolean.TRUE.equals(field.getReadOnly())) {
451 canEditLine = true;
452 break;
453 }
454 }
455 }
456
457 if (canEditLine && !lineBuilderContext.isAddLine()) {
458 canEditLine = checkEditLineAuthorizationAndPresentationLogic(lineBuilderContext.getCollectionGroup(),
459 lineBuilderContext.getModel(), lineBuilderContext.getCurrentLine());
460 }
461
462 if (!canEditLine) {
463 addUnauthorizedBindingInfo();
464 }
465
466 return canEditLine;
467 }
468
469
470
471
472
473
474
475 protected boolean checkEditLineAuthorizationAndPresentationLogic(CollectionGroup collectionGroup, ViewModel model,
476 Object currentLine) {
477 ViewPresentationController presentationController = ViewLifecycle.getView().getPresentationController();
478 ViewAuthorizer authorizer = ViewLifecycle.getView().getAuthorizer();
479
480 Person user = GlobalVariables.getUserSession().getPerson();
481
482 boolean canEditLine = authorizer.canEditLine(ViewLifecycle.getView(), model, collectionGroup,
483 collectionGroup.getPropertyName(), currentLine, user);
484 if (canEditLine) {
485 canEditLine = presentationController.canEditLine(ViewLifecycle.getView(), model, collectionGroup,
486 collectionGroup.getPropertyName(), currentLine);
487 }
488
489 return canEditLine;
490 }
491
492
493
494
495
496 protected void addUnauthorizedBindingInfo() {
497 if (lineBuilderContext.getCollectionGroup().getUnauthorizedLineBindingInfos() == null) {
498 lineBuilderContext.getCollectionGroup().setUnauthorizedLineBindingInfos(new ArrayList<BindingInfo>());
499 }
500
501 BindingInfo bindingInfo = new BindingInfo();
502 bindingInfo.setDefaults(ViewLifecycle.getView(), lineBuilderContext.getBindingPath());
503 lineBuilderContext.getCollectionGroup().getUnauthorizedLineBindingInfos().add(bindingInfo);
504 }
505
506
507
508
509
510
511
512
513
514
515
516
517
518 protected void applyLineFieldAuthorizationAndPresentationLogic(boolean readOnlyLine, List<Field> lineFields,
519 List<? extends Component> actionList) {
520 ViewPresentationController presentationController = ViewLifecycle.getView().getPresentationController();
521 ViewAuthorizer authorizer = ViewLifecycle.getView().getAuthorizer();
522
523 Person user = GlobalVariables.getUserSession().getPerson();
524 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
525
526 CollectionGroup collectionGroup = lineBuilderContext.getCollectionGroup();
527 View view = ViewLifecycle.getView();
528 ViewModel model = lineBuilderContext.getModel();
529 Object currentLine = lineBuilderContext.getCurrentLine();
530
531 for (Field lineField : lineFields) {
532 String propertyName = null;
533 if (lineField instanceof DataBinding) {
534 propertyName = ((DataBinding) lineField).getPropertyName();
535 }
536
537
538
539 ComponentSecurity componentSecurity = lineField.getComponentSecurity();
540
541 Map<String, Object> context = getContextForField(ViewLifecycle.getView(), collectionGroup, lineField);
542 expressionEvaluator.evaluateExpressionsOnConfigurable(ViewLifecycle.getView(), componentSecurity, context);
543
544
545 if (!lineField.isRender() || lineField.isHidden()) {
546 continue;
547 }
548
549 boolean canViewField = authorizer.canViewLineField(view, model, collectionGroup,
550 collectionGroup.getPropertyName(), currentLine, lineField, propertyName, user);
551 if (canViewField) {
552 canViewField = presentationController.canViewLineField(view, model, collectionGroup,
553 collectionGroup.getPropertyName(), currentLine, lineField, propertyName);
554 }
555
556 if (!canViewField) {
557
558
559 lineField.setHidden(true);
560
561 if (lineField.getPropertyExpressions().containsKey(UifPropertyPaths.HIDDEN)) {
562 lineField.getPropertyExpressions().remove(UifPropertyPaths.HIDDEN);
563 }
564
565 continue;
566 }
567
568
569 boolean canEditField = !readOnlyLine;
570 if (!readOnlyLine) {
571 canEditField = authorizer.canEditLineField(view, model, collectionGroup,
572 collectionGroup.getPropertyName(), currentLine, lineField, propertyName, user);
573 if (canEditField) {
574 canEditField = presentationController.canEditLineField(view, model, collectionGroup,
575 collectionGroup.getPropertyName(), currentLine, lineField, propertyName);
576 }
577 }
578
579 if (readOnlyLine || !canEditField) {
580 lineField.setReadOnly(true);
581
582 if (lineField.getPropertyExpressions().containsKey(UifPropertyPaths.READ_ONLY)) {
583 lineField.getPropertyExpressions().remove(UifPropertyPaths.READ_ONLY);
584 }
585 }
586 }
587
588
589 List<Action> actions = ViewLifecycleUtils.getElementsOfTypeDeep(actionList, Action.class);
590 for (Action action : actions) {
591 if (!action.isRender()) {
592 continue;
593 }
594
595 boolean canPerformAction = authorizer.canPerformLineAction(view, model, collectionGroup,
596 collectionGroup.getPropertyName(), currentLine, action, action.getActionEvent(), action.getId(),
597 user);
598 if (canPerformAction) {
599 canPerformAction = presentationController.canPerformLineAction(view, model, collectionGroup,
600 collectionGroup.getPropertyName(), currentLine, action, action.getActionEvent(),
601 action.getId());
602 }
603
604 if (!canPerformAction) {
605 action.setRender(false);
606
607 if (action.getPropertyExpressions().containsKey(UifPropertyPaths.RENDER)) {
608 action.getPropertyExpressions().remove(UifPropertyPaths.RENDER);
609 }
610 }
611 }
612 }
613
614
615
616
617
618
619 protected void buildSubCollectionFieldGroups() {
620 CollectionGroup collectionGroup = lineBuilderContext.getCollectionGroup();
621
622 String idSuffix = lineBuilderContext.getIdSuffix();
623
624
625 if (lineBuilderContext.isAddLine() || (collectionGroup.getSubCollections() == null)) {
626 return;
627 }
628
629 List<FieldGroup> subCollectionFields = new ArrayList<FieldGroup>();
630 for (int subLineIndex = 0; subLineIndex < collectionGroup.getSubCollections().size(); subLineIndex++) {
631 CollectionGroup subCollectionPrototype = collectionGroup.getSubCollections().get(subLineIndex);
632 CollectionGroup subCollectionGroup = ComponentUtils.copy(subCollectionPrototype);
633
634
635 boolean renderSubCollection = checkSubCollectionRender(subCollectionGroup);
636 if (!renderSubCollection) {
637 continue;
638 }
639
640 subCollectionGroup.getBindingInfo().setBindByNamePrefix(lineBuilderContext.getBindingPath());
641 if (subCollectionGroup.isRenderAddLine()) {
642 subCollectionGroup.getAddLineBindingInfo().setBindByNamePrefix(lineBuilderContext.getBindingPath());
643 }
644
645 FieldGroup fieldGroupPrototype =
646 lineBuilderContext.getLayoutManager().getSubCollectionFieldGroupPrototype();
647
648 FieldGroup subCollectionFieldGroup = ComponentUtils.copy(fieldGroupPrototype,
649 idSuffix + UifConstants.IdSuffixes.SUB + subLineIndex);
650 subCollectionFieldGroup.setGroup(subCollectionGroup);
651
652 subCollectionFieldGroup.setContainerIdSuffix(idSuffix);
653
654 ContextUtils.updateContextForLine(subCollectionFieldGroup, collectionGroup,
655 lineBuilderContext.getCurrentLine(), lineBuilderContext.getLineIndex(),
656 idSuffix + UifConstants.IdSuffixes.SUB + subLineIndex);
657 ContextUtils.pushObjectToContextDeep(subCollectionGroup, UifConstants.ContextVariableNames.PARENT_LINE,
658 lineBuilderContext.getCurrentLine());
659
660 subCollectionFields.add(subCollectionFieldGroup);
661 }
662
663 ContextUtils.pushObjectToContextDeep(subCollectionFields, UifConstants.ContextVariableNames.PARENT_LINE,
664 lineBuilderContext.getCurrentLine());
665
666
667 for (FieldGroup subCollectionField : subCollectionFields) {
668 Group group = subCollectionField.getGroup();
669 if (group != null && group instanceof CollectionGroup) {
670 CollectionGroup collectionGroup1 = (CollectionGroup) group;
671 ContextUtils.pushObjectToContextDeep(collectionGroup1.getItems(),
672 UifConstants.ContextVariableNames.PARENT_LINE, lineBuilderContext.getCurrentLine());
673 }
674 }
675
676 lineBuilderContext.setSubCollectionFields(subCollectionFields);
677 }
678
679
680
681
682
683
684
685
686 protected boolean checkSubCollectionRender(CollectionGroup subCollectionGroup) {
687 String conditionalRender = subCollectionGroup.getPropertyExpression(UifPropertyPaths.RENDER);
688
689
690
691
692 if (StringUtils.isNotBlank(conditionalRender)) {
693 Map<String, Object> context = new HashMap<String, Object>();
694 Map<String, Object> viewContext = ViewLifecycle.getView().getContext();
695
696 if (viewContext != null) {
697 context.putAll(viewContext);
698 }
699
700 context.put(UifConstants.ContextVariableNames.PARENT, lineBuilderContext.getCollectionGroup());
701 context.put(UifConstants.ContextVariableNames.COMPONENT, subCollectionGroup);
702
703 Boolean render = (Boolean) ViewLifecycle.getExpressionEvaluator().evaluateExpression(context,
704 conditionalRender);
705 subCollectionGroup.setRender(render);
706 }
707
708 return subCollectionGroup.isRender();
709 }
710
711
712
713
714
715
716 protected void setupAddLineControlValidation(List<Field> lineFields) {
717
718 if (!lineBuilderContext.isAddLine()) {
719 return;
720 }
721
722
723
724 List<String> selectors = new ArrayList<String>();
725 String lineFieldSelector = UifConstants.IdSuffixes.CONTROL;
726 String nestedLineFieldSelector = UifConstants.IdSuffixes.ADD_LINE + UifConstants.IdSuffixes.CONTROL;
727
728
729 for (Field lineField : lineFields) {
730 if (lineField instanceof InputField) {
731 setupAddLineControlValidation((InputField) lineField, selectors, lineFieldSelector);
732 } else if (lineField instanceof FieldGroup) {
733 Group group = ((FieldGroup) lineField).getGroup();
734 List<InputField> nestedLineFields = ViewLifecycleUtils.getElementsOfTypeDeep(group, InputField.class);
735
736 for (InputField nestedLineField : nestedLineFields) {
737 setupAddLineControlValidation(nestedLineField, selectors, nestedLineFieldSelector);
738 }
739 }
740 }
741
742
743 lineBuilderContext.getCollectionGroup().addDataAttribute(
744 UifConstants.DataAttributes.ADD_CONTROLS, StringUtils.join(selectors, ","));
745 }
746
747
748
749
750
751
752
753
754 protected void setupAddLineControlValidation(InputField lineField, List<String> selectors, String suffix) {
755 Control control = lineField.getControl();
756
757
758 if (control != null) {
759 control.addStyleClass(CssConstants.Classes.IGNORE_VALID);
760 selectors.add("#" + lineField.getId() + suffix);
761 }
762 }
763
764
765
766
767
768
769
770 protected void setupEditLineDetails() {
771 CollectionGroup group = lineBuilderContext.getCollectionGroup();
772
773 if (!group.isEditWithDialog()) {
774 return;
775 }
776
777 for (DialogGroup lineDialog : group.getLineDialogs()) {
778 String dialogId = lineDialog.getId();
779
780 UifFormBase form = (UifFormBase) lineBuilderContext.getModel();
781 if (group.getCollectionGroupBuilder().refreshEditLineDialogContents(lineDialog, form, group,
782 lineBuilderContext.getLineIndex()) && lineDialog.getId().contains(
783 ComponentFactory.EDIT_LINE_DIALOG)) {
784 form.setUpdateComponent(lineDialog);
785
786 if (lineDialog.getItems() == null || lineDialog.getItems().isEmpty() || !group
787 .isCustomEditLineDialog()) {
788 List<Field> lineFields = lineBuilderContext.getLineFields();
789
790
791 lineDialog.setItems(processDialogFieldsFromLineFields(lineFields, dialogId));
792
793
794 List<Component> items = new ArrayList<Component>(lineDialog.getItems());
795 items.addAll(processDialogSubFieldsFromLineSubFields(lineDialog));
796 items.addAll(processDialogSubFieldsFromRowDetails(lineDialog));
797 lineDialog.setItems(items);
798 } else {
799 List<Component> dialogFields = new ArrayList<>(lineDialog.getItems());
800 List<Component> dialogComponents = new ArrayList<>();
801 int fieldIndex = 0;
802 int subIndex = 0;
803
804
805 for (Component dialogField : dialogFields) {
806 if (dialogField instanceof DataField) {
807 DataField dataField = (DataField) dialogField;
808 DataField lineField = findItemInLineFields(dataField);
809
810 if (lineField != null) {
811 dataField.getBindingInfo().setCollectionPath(
812 lineField.getBindingInfo().getCollectionPath());
813
814 lineField.setReadOnly(true);
815 } else {
816
817 dataField.getBindingInfo().setCollectionPath(group.getBindingInfo().getBindingName());
818 }
819
820 dataField.getBindingInfo().setBindByNamePrefix(UifPropertyPaths.DIALOG_DATA_OBJECT);
821 dialogComponents.add(dataField);
822 } else if (dialogField instanceof FieldGroup) {
823 FieldGroup fieldGroup = (FieldGroup) dialogField;
824
825 if (fieldGroup.getGroup() instanceof CollectionGroup) {
826 dialogComponents.add(getNewFieldGroup(fieldGroup, (CollectionGroup) fieldGroup.
827 getGroup(), lineDialog, fieldIndex, subIndex, null));
828 subIndex++;
829 }
830 } else if (dialogField instanceof CollectionGroup) {
831 CollectionGroup collectionGroup = (CollectionGroup) dialogField;
832 FieldGroup fieldGroupPrototype =
833 lineBuilderContext.getLayoutManager().getSubCollectionFieldGroupPrototype();
834
835 dialogComponents.add(getNewFieldGroup(fieldGroupPrototype, collectionGroup, lineDialog,
836 fieldIndex, subIndex, UifPropertyPaths.DIALOG_DATA_OBJECT));
837 subIndex++;
838 } else {
839 ComponentUtils.prefixBindingPath(dialogField, UifPropertyPaths.DIALOG_DATA_OBJECT);
840 dialogComponents.add(dialogField);
841 }
842 fieldIndex++;
843 }
844 lineDialog.setItems(dialogComponents);
845 }
846 }
847
848 }
849
850
851 if (lineBuilderContext.getCollectionGroup().isEditWithDialog()) {
852 for (Field lineField : lineBuilderContext.getLineFields()) {
853 if (lineField instanceof InputField) {
854 lineField.setReadOnly(Boolean.TRUE);
855 }
856 }
857 List<FieldGroup> subLineFields = lineBuilderContext.getSubCollectionFields();
858 if (subLineFields != null) {
859 for (FieldGroup subLineField : subLineFields) {
860 subLineField.setReadOnly(Boolean.TRUE);
861 }
862 }
863 }
864 }
865
866
867
868
869
870
871
872 private List<FieldGroup> processDialogSubFieldsFromLineSubFields(DialogGroup lineDialog) {
873
874 List<FieldGroup> subCollectionFields = lineBuilderContext.getSubCollectionFields();
875 List<FieldGroup> newSubCollectionFields = new ArrayList<FieldGroup>();
876 int fieldIndex = lineDialog.getItems().size();
877 int subIndex = 0;
878
879 for (FieldGroup subCollectionFieldGroup : subCollectionFields) {
880 CollectionGroup subCollectionGroup = (CollectionGroup) subCollectionFieldGroup.getGroup();
881
882
883 newSubCollectionFields.add(getNewFieldGroup(subCollectionFieldGroup, subCollectionGroup, lineDialog,
884 fieldIndex, subIndex, UifPropertyPaths.DIALOG_DATA_OBJECT));
885 fieldIndex++;
886 subIndex++;
887
888 List<Component> components = ViewLifecycleUtils.getElementsOfTypeDeep(subCollectionGroup.getItems(),
889 Component.class);
890 for (Component component : components) {
891 component.setReadOnly(Boolean.TRUE);
892 }
893 }
894
895 return newSubCollectionFields;
896 }
897
898
899
900
901
902
903
904 private List<Field> processDialogSubFieldsFromRowDetails(DialogGroup lineDialog) {
905 List<Field> newSubCollectionFields = new ArrayList<Field>();
906
907
908 CollectionLayoutManager layoutManager = (CollectionLayoutManager) lineBuilderContext.
909 getCollectionGroup().getLayoutManager();
910
911
912 if (layoutManager instanceof TableLayoutManagerBase) {
913 TableLayoutManagerBase tableLayoutManagerBase = (TableLayoutManagerBase) layoutManager;
914 Group rowDetailsGroup = tableLayoutManagerBase.getRowDetailsGroup();
915
916 if (rowDetailsGroup != null) {
917 List<Component> subCollectionComponents = new ArrayList<Component>(rowDetailsGroup.getItems());
918
919 int fieldIndex = lineDialog.getItems().size();
920 int subIndex = 0;
921
922
923 for (Component component : subCollectionComponents) {
924 if (component instanceof CollectionGroup) {
925 CollectionGroup subCollectionGroup = (CollectionGroup) component;
926
927 boolean renderSubCollection = checkSubCollectionRender(subCollectionGroup);
928 if (!renderSubCollection) {
929 continue;
930 }
931
932 FieldGroup fieldGroupPrototype = lineBuilderContext.
933 getLayoutManager().getSubCollectionFieldGroupPrototype();
934 newSubCollectionFields.add(getNewFieldGroup(fieldGroupPrototype, subCollectionGroup, lineDialog,
935 fieldIndex, subIndex, UifPropertyPaths.DIALOG_DATA_OBJECT));
936 subIndex++;
937 } else if (component instanceof Field) {
938 Field subCollectionField = (Field) component;
939 Field newSubCollectionField = getNewFieldForEditLineDialog(subCollectionField,
940 lineDialog.getId() + UifConstants.IdSuffixes.FIELDSET + Integer.toString(fieldIndex++));
941
942 newSubCollectionFields.add(newSubCollectionField);
943 }
944
945 ContextUtils.pushObjectToContextDeep(newSubCollectionFields,
946 UifConstants.ContextVariableNames.PARENT_LINE,
947 ((UifFormBase) lineBuilderContext.getModel()).getDialogDataObject());
948 }
949 }
950 }
951
952 return newSubCollectionFields;
953 }
954
955
956
957
958
959
960
961
962
963
964
965 private FieldGroup getNewFieldGroup(FieldGroup fieldGroupPrototype, CollectionGroup subCollectionGroup,
966 DialogGroup lineDialog, int fieldIndex, int subIndex, String bindingPrefix) {
967 FieldGroup newSubCollectionFieldGroup = ComponentUtils.copy(fieldGroupPrototype);
968 newSubCollectionFieldGroup.setId(lineDialog.getId() +
969 UifConstants.IdSuffixes.FIELDSET + Integer.toString(fieldIndex));
970 newSubCollectionFieldGroup.pushObjectToContext(UifConstants.ContextVariableNames.PARENT, lineDialog);
971
972 CollectionGroup newSubCollectionGroup = ComponentUtils.copy(subCollectionGroup);
973 newSubCollectionGroup.setId(newSubCollectionFieldGroup.getId() + UifConstants.IdSuffixes.SUB +
974 Integer.toString(subIndex));
975 if (bindingPrefix != null) {
976 newSubCollectionGroup.getBindingInfo().setBindByNamePrefix(bindingPrefix);
977 }
978
979 if (newSubCollectionGroup.getBindingInfo().getBindingName() == null) {
980 newSubCollectionGroup.getBindingInfo().setBindingName(newSubCollectionGroup.getPropertyName());
981 }
982
983 newSubCollectionGroup.pushObjectToContext(UifConstants.ContextVariableNames.PARENT, lineDialog);
984 newSubCollectionGroup.addDataAttribute(UifConstants.
985 ContextVariableNames.PARENT, lineDialog.getId());
986
987 if (newSubCollectionGroup.isRenderAddLine()) {
988 newSubCollectionGroup.getAddLineBindingInfo().setBindByNamePrefix(newSubCollectionGroup.
989 getBindingInfo().getBindByNamePrefix());
990 newSubCollectionGroup.getAddLineBindingInfo().setBindingName(newSubCollectionGroup.
991 getBindingInfo().getBindingName());
992 String addBindingPath = UifPropertyPaths.NEW_COLLECTION_LINES + "['" +
993 newSubCollectionGroup.getBindingInfo().getBindByNamePrefix() + "." +
994 newSubCollectionGroup.getBindingInfo().getBindingName() + "']";
995 Object addLine = ObjectPropertyUtils.getPropertyValue(lineBuilderContext.getModel(), addBindingPath);
996 if (addLine != null) {
997 ObjectPropertyUtils.setPropertyValue(lineBuilderContext.getModel(), addBindingPath, null);
998 }
999 }
1000
1001
1002
1003 List<Action> subLineActions = ViewLifecycleUtils.getElementsOfTypeDeep(newSubCollectionGroup.getLineActions(),
1004 Action.class);
1005 setupSubCollectionActions(subLineActions, lineDialog.getId(),
1006 lineBuilderContext.getCollectionGroup().getBindingInfo().getBindingName(),
1007 lineBuilderContext.getLineIndex());
1008
1009
1010 lineBuilderContext.getCollectionGroup().getCollectionGroupBuilder().initializeLineActions(subLineActions,
1011 ViewLifecycle.getView(), newSubCollectionGroup, lineBuilderContext.getCurrentLine(),
1012 lineBuilderContext.getLineIndex());
1013
1014
1015 List<Component> subAddLineComponents = new ArrayList<Component>(newSubCollectionGroup.getAddLineActions());
1016 if (newSubCollectionGroup.getAddBlankLineAction() != null) {
1017 subAddLineComponents.add(newSubCollectionGroup.getAddBlankLineAction());
1018 }
1019 List<Action> subAddLineActions = ViewLifecycleUtils.getElementsOfTypeDeep(subAddLineComponents,
1020 Action.class);
1021
1022
1023 setupSubCollectionActions(subAddLineActions, lineDialog.getId(), lineBuilderContext.
1024 getCollectionGroup().getBindingInfo().getBindingName(), lineBuilderContext.getLineIndex()
1025 );
1026
1027 newSubCollectionFieldGroup.setGroup(newSubCollectionGroup);
1028
1029 ContextUtils.updateContextForLine(newSubCollectionFieldGroup, lineBuilderContext.
1030 getCollectionGroup(), ((UifFormBase) lineBuilderContext.getModel()).
1031 getDialogDataObject(), lineBuilderContext.getLineIndex(),
1032 lineBuilderContext.getIdSuffix() + UifConstants.IdSuffixes.SUB + subIndex
1033 );
1034 ContextUtils.pushObjectToContextDeep(newSubCollectionGroup, UifConstants.ContextVariableNames.PARENT_LINE,
1035 ((UifFormBase) lineBuilderContext.getModel()).getDialogDataObject());
1036 return newSubCollectionFieldGroup;
1037 }
1038
1039
1040
1041
1042
1043
1044
1045
1046 private List<Field> processDialogFieldsFromLineFields(List<Field> lineFields, String prefix) {
1047 List<Field> newLineFields = new ArrayList<Field>();
1048
1049
1050 int fieldIndex = 0;
1051 for (Field lineField : lineFields) {
1052 if (!(lineField instanceof FieldGroup)) {
1053 Field newLineField = getNewFieldForEditLineDialog(lineField, prefix +
1054 UifConstants.IdSuffixes.FIELDSET + Integer.toString(fieldIndex));
1055 newLineFields.add(newLineField);
1056 fieldIndex++;
1057 }
1058 }
1059 return newLineFields;
1060 }
1061
1062
1063
1064
1065
1066
1067
1068
1069 private Field getNewFieldForEditLineDialog(Field field, String id) {
1070 Field newLineField = ComponentUtils.copy(field, id);
1071
1072
1073 if (newLineField instanceof DataField) {
1074 ((DataField) newLineField).getBindingInfo().setBindByNamePrefix(UifPropertyPaths.DIALOG_DATA_OBJECT);
1075 }
1076 return newLineField;
1077 }
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 private void setupSubCollectionActions(List<Action> actions, String dialogId, String bindingName, int lineIndex) {
1088 for (Action action : actions) {
1089 action.setDialogDismissOption("REQUEST");
1090 action.setRefreshId(StringUtils.substring(dialogId, dialogId.indexOf("_") + 1, dialogId.lastIndexOf("_")));
1091 String actionScript = UifConstants.JsFunctions.SHOW_EDIT_LINE_DIALOG + "('" +
1092 dialogId + "', '" + bindingName + "', " + lineIndex + ");";
1093 action.setRefreshedByAction(false);
1094 action.setSuccessCallback("jQuery.unblockUI();" + actionScript);
1095 action.setOnClickScript("jQuery('#" + dialogId +
1096 "').one('hide.bs.modal', function(e) { jQuery.blockUI({ message: '<h1>Editing line ...</h1>' }); });");
1097 action.addActionParameter(UifParameters.DIALOG_ID, dialogId);
1098 }
1099 }
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 private DataField findItemInLineFields(DataField dataItem) {
1110 for (Field field : lineBuilderContext.getLineFields()) {
1111 if (field instanceof DataField) {
1112 if (dataItem.getPropertyName().equals(((DataField) field).getPropertyName())) {
1113 return (DataField) field;
1114 }
1115 }
1116 }
1117 return null;
1118 }
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129 protected Map<String, Object> getContextForField(View view, CollectionGroup collectionGroup, Field field) {
1130 Map<String, Object> context = new HashMap<String, Object>();
1131
1132 Map<String, Object> viewContext = view.getContext();
1133 if (viewContext != null) {
1134 context.putAll(viewContext);
1135 }
1136
1137 Map<String, Object> fieldContext = field.getContext();
1138 if (fieldContext != null) {
1139 context.putAll(fieldContext);
1140 }
1141
1142 context.put(UifConstants.ContextVariableNames.PARENT, collectionGroup);
1143 context.put(UifConstants.ContextVariableNames.COMPONENT, field);
1144
1145 return context;
1146 }
1147 }