1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.service.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.config.property.ConfigurationService;
20 import org.kuali.rice.core.api.exception.RiceRuntimeException;
21 import org.kuali.rice.kim.api.identity.Person;
22 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
23 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
24 import org.kuali.rice.krad.inquiry.Inquirable;
25 import org.kuali.rice.krad.messages.MessageService;
26 import org.kuali.rice.krad.service.DataDictionaryService;
27 import org.kuali.rice.krad.service.KRADServiceLocator;
28 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
29 import org.kuali.rice.krad.service.ModuleService;
30 import org.kuali.rice.krad.uif.UifConstants;
31 import org.kuali.rice.krad.uif.component.BindingInfo;
32 import org.kuali.rice.krad.uif.component.ClientSideState;
33 import org.kuali.rice.krad.uif.component.Component;
34 import org.kuali.rice.krad.uif.component.ComponentSecurity;
35 import org.kuali.rice.krad.uif.component.DataBinding;
36 import org.kuali.rice.krad.uif.component.PropertyReplacer;
37 import org.kuali.rice.krad.uif.component.RequestParameter;
38 import org.kuali.rice.krad.uif.container.CollectionGroup;
39 import org.kuali.rice.krad.uif.container.Container;
40 import org.kuali.rice.krad.uif.container.Group;
41 import org.kuali.rice.krad.uif.control.Control;
42 import org.kuali.rice.krad.uif.element.Action;
43 import org.kuali.rice.krad.uif.field.ActionField;
44 import org.kuali.rice.krad.uif.field.DataField;
45 import org.kuali.rice.krad.uif.field.Field;
46 import org.kuali.rice.krad.uif.field.FieldGroup;
47 import org.kuali.rice.krad.uif.field.InputField;
48 import org.kuali.rice.krad.uif.field.RemoteFieldsHolder;
49 import org.kuali.rice.krad.uif.layout.LayoutManager;
50 import org.kuali.rice.krad.uif.modifier.ComponentModifier;
51 import org.kuali.rice.krad.uif.service.ExpressionEvaluatorService;
52 import org.kuali.rice.krad.uif.service.ViewDictionaryService;
53 import org.kuali.rice.krad.uif.service.ViewHelperService;
54 import org.kuali.rice.krad.uif.util.BooleanMap;
55 import org.kuali.rice.krad.uif.util.CloneUtils;
56 import org.kuali.rice.krad.uif.util.ComponentFactory;
57 import org.kuali.rice.krad.uif.util.ComponentUtils;
58 import org.kuali.rice.krad.uif.util.ExpressionUtils;
59 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
60 import org.kuali.rice.krad.uif.util.ScriptUtils;
61 import org.kuali.rice.krad.uif.util.ViewCleaner;
62 import org.kuali.rice.krad.uif.util.ViewModelUtils;
63 import org.kuali.rice.krad.uif.view.View;
64 import org.kuali.rice.krad.uif.view.ViewAuthorizer;
65 import org.kuali.rice.krad.uif.view.ViewModel;
66 import org.kuali.rice.krad.uif.view.ViewPresentationController;
67 import org.kuali.rice.krad.uif.widget.Inquiry;
68 import org.kuali.rice.krad.uif.widget.Widget;
69 import org.kuali.rice.krad.util.ErrorMessage;
70 import org.kuali.rice.krad.util.GlobalVariables;
71 import org.kuali.rice.krad.util.GrowlMessage;
72 import org.kuali.rice.krad.util.KRADConstants;
73 import org.kuali.rice.krad.util.MessageMap;
74 import org.kuali.rice.krad.util.ObjectUtils;
75 import org.kuali.rice.krad.valuefinder.ValueFinder;
76 import org.kuali.rice.krad.web.form.UifFormBase;
77 import org.springframework.expression.spel.support.StandardEvaluationContext;
78 import org.springframework.util.ClassUtils;
79 import org.springframework.util.MethodInvoker;
80
81 import java.io.Serializable;
82 import java.lang.annotation.Annotation;
83 import java.text.MessageFormat;
84 import java.util.ArrayList;
85 import java.util.Collection;
86 import java.util.Collections;
87 import java.util.HashMap;
88 import java.util.HashSet;
89 import java.util.List;
90 import java.util.Map;
91 import java.util.Map.Entry;
92 import java.util.Set;
93
94
95
96
97
98
99 public class ViewHelperServiceImpl implements ViewHelperService, Serializable {
100 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ViewHelperServiceImpl.class);
101
102 private transient DataDictionaryService dataDictionaryService;
103 private transient ExpressionEvaluatorServiceImpl expressionEvaluatorService;
104 private transient ViewDictionaryService viewDictionaryService;
105 private transient ConfigurationService configurationService;
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 @Override
122 public void populateViewFromRequestParameters(View view, Map<String, String> parameters) {
123
124
125 Map<String, Set<PropertyReplacer>> viewPropertyReplacers = new HashMap<String, Set<PropertyReplacer>>();
126 for (PropertyReplacer replacer : view.getPropertyReplacers()) {
127 Set<PropertyReplacer> propertyReplacers = new HashSet<PropertyReplacer>();
128 if (viewPropertyReplacers.containsKey(replacer.getPropertyName())) {
129 propertyReplacers = viewPropertyReplacers.get(replacer.getPropertyName());
130 }
131 propertyReplacers.add(replacer);
132
133 viewPropertyReplacers.put(replacer.getPropertyName(), propertyReplacers);
134 }
135
136 Map<String, Annotation> annotatedFields = CloneUtils.getFieldsWithAnnotation(view.getClass(),
137 RequestParameter.class);
138
139
140
141 Map<String, String> viewRequestParameters = new HashMap<String, String>();
142 for (String fieldToPopulate : annotatedFields.keySet()) {
143 RequestParameter requestParameter = (RequestParameter) annotatedFields.get(fieldToPopulate);
144
145
146 String requestParameterName = requestParameter.parameterName();
147 if (StringUtils.isBlank(requestParameterName)) {
148 requestParameterName = fieldToPopulate;
149 }
150
151 if (!parameters.containsKey(requestParameterName)) {
152 continue;
153 }
154
155 String fieldValue = parameters.get(requestParameterName);
156 if (StringUtils.isNotBlank(fieldValue)) {
157 viewRequestParameters.put(requestParameterName, fieldValue);
158 ObjectPropertyUtils.setPropertyValue(view, fieldToPopulate, fieldValue);
159
160
161
162 if (view.getPropertyExpressions().containsKey(fieldToPopulate)) {
163 view.getPropertyExpressions().remove(fieldToPopulate);
164 }
165
166 if (viewPropertyReplacers.containsKey(fieldToPopulate)) {
167 Set<PropertyReplacer> propertyReplacers = viewPropertyReplacers.get(fieldToPopulate);
168 for (PropertyReplacer replacer : propertyReplacers) {
169 view.getPropertyReplacers().remove(replacer);
170 }
171 }
172 }
173 }
174
175 view.setViewRequestParameters(viewRequestParameters);
176 }
177
178
179
180
181
182 @Override
183 public void performInitialization(View view, Object model) {
184 view.assignComponentIds(view);
185
186
187
188 view.setIdSequence(100000);
189 performComponentInitialization(view, model, view);
190
191
192
193
194
195 for(Component dialog : view.getDialogs()) {
196 dialog.setRefreshedByAction(true);
197 }
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211
212 public void performComponentLifecycle(View view, Object model, Component component, String origId) {
213 Component origComponent = view.getViewIndex().getComponentById(origId);
214
215
216
217 Integer currentSequenceVal = view.getIdSequence();
218 Integer startingSequenceVal = view.getViewIndex().getIdSequenceSnapshot().get(component.getId());
219
220 if (startingSequenceVal != null) {
221 view.setIdSequence(startingSequenceVal);
222 }
223
224 view.assignComponentIds(component);
225
226
227
228 view.setIdSequence(currentSequenceVal);
229
230 String suffix = StringUtils.replaceOnce(origComponent.getId(), origComponent.getBaseId(), "");
231 if (StringUtils.isNotBlank(suffix)) {
232 ComponentUtils.updateIdWithSuffix(component, suffix);
233 }
234
235 Component parent = (Component) origComponent.getContext().get(UifConstants.ContextVariableNames.PARENT);
236
237
238 component.pushAllToContext(origComponent.getContext());
239 List<Component> nestedComponents = ComponentUtils.getAllNestedComponents(component);
240 for (Component nestedComponent : nestedComponents) {
241 nestedComponent.pushAllToContext(origComponent.getContext());
242 }
243
244
245
246
247 Map<String, String> expressionGraph = view.getViewIndex().getComponentExpressionGraphs().get(
248 component.getBaseId());
249 component.setExpressionGraph(expressionGraph);
250 ExpressionUtils.populatePropertyExpressionsFromGraph(component, false);
251
252
253 if (component instanceof DataBinding) {
254 ((DataBinding) component).setBindingInfo(((DataBinding) origComponent).getBindingInfo());
255 ((DataBinding) component).getBindingInfo().setBindingPath(
256 ((DataBinding) origComponent).getBindingInfo().getBindingPath());
257 }
258
259
260 if (component instanceof Field) {
261 ((Field) component).setLabelRendered(((Field) origComponent).isLabelRendered());
262 } else if (component instanceof CollectionGroup) {
263 String subCollectionSuffix = ((CollectionGroup) origComponent).getSubCollectionSuffix();
264 ((CollectionGroup) component).setSubCollectionSuffix(subCollectionSuffix);
265
266 suffix = StringUtils.removeStart(suffix, subCollectionSuffix);
267 }
268
269 if (origComponent.isRefreshedByAction()) {
270 component.setRefreshedByAction(true);
271 }
272
273
274 if (component.isResetDataOnRefresh()) {
275
276 if (component instanceof DataField) {
277
278
279
280 ObjectPropertyUtils.initializeProperty(model,
281 ((DataField) component).getBindingInfo().getBindingPath());
282 }
283 }
284
285 performComponentInitialization(view, model, component);
286 view.getViewIndex().indexComponent(component);
287
288 Map<String, Integer> visitedIds = new HashMap<String, Integer>();
289 performComponentApplyModel(view, component, model, visitedIds);
290 view.getViewIndex().indexComponent(component);
291
292
293 if (StringUtils.isNotBlank(suffix)) {
294 ComponentUtils.updateChildIdsWithSuffixNested(component, suffix);
295 }
296
297
298 if (component.isDisclosedByAction()) {
299 component.setRender(true);
300 component.setHidden(false);
301 }
302
303
304 Map<String, Object> clientState = new HashMap<String, Object>();
305 performComponentFinalize(view, component, model, parent, clientState);
306
307
308 if (component instanceof Group || component instanceof FieldGroup) {
309 List<Component> nestedGroupComponents = ComponentUtils.getAllNestedComponents(component);
310 List<Component> originalNestedGroupComponents = ComponentUtils.getAllNestedComponents(origComponent);
311
312 for (Component nestedComponent : nestedGroupComponents) {
313 Component origNestedComponent = ComponentUtils.findComponentInList(originalNestedGroupComponents,
314 nestedComponent.getId());
315
316 if (origNestedComponent != null) {
317
318 if (nestedComponent instanceof DataBinding) {
319 ((DataBinding) nestedComponent).setBindingInfo(
320 ((DataBinding) origNestedComponent).getBindingInfo());
321 ((DataBinding) nestedComponent).getBindingInfo().setBindingPath(
322 ((DataBinding) origNestedComponent).getBindingInfo().getBindingPath());
323 }
324
325
326 if (nestedComponent instanceof Field) {
327 ((Field) nestedComponent).setLabelRendered(((Field) origNestedComponent).isLabelRendered());
328 }
329
330 if (origNestedComponent.isRefreshedByAction()) {
331 nestedComponent.setRefreshedByAction(true);
332 }
333 }
334 }
335 }
336
337
338 String clientStateScript = buildClientSideStateScript(view, clientState, true);
339 String onLoadScript = component.getOnLoadScript();
340 if (StringUtils.isNotBlank(onLoadScript)) {
341 clientStateScript = onLoadScript + clientStateScript;
342 }
343 component.setOnLoadScript(clientStateScript);
344
345
346 String growlScript = buildGrowlScript(view);
347 ((ViewModel) model).setGrowlScript(growlScript);
348
349 view.getViewIndex().indexComponent(component);
350 }
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377 public void performComponentInitialization(View view, Object model, Component component) {
378 if (component == null) {
379 return;
380 }
381
382 if (StringUtils.isBlank(component.getId())) {
383 throw new RiceRuntimeException("Id is not set, this should not happen unless a component is misconfigured");
384 }
385
386
387
388 LOG.debug("Initializing component: " + component.getId() + " with type: " + component.getClass());
389
390
391 if (!(component instanceof View)) {
392 view.getViewIndex().addInitialComponentStateIfNeeded(component);
393 }
394
395
396
397 ExpressionUtils.populatePropertyExpressionsFromGraph(component, true);
398
399
400 component.performInitialization(view, model);
401
402
403 for (PropertyReplacer replacer : component.getPropertyReplacers()) {
404 ExpressionUtils.populatePropertyExpressionsFromGraph(replacer, true);
405 }
406
407 for (ComponentModifier modifier : component.getComponentModifiers()) {
408 ExpressionUtils.populatePropertyExpressionsFromGraph(modifier, true);
409 }
410
411
412 if (component instanceof DataField) {
413 initializeDataFieldFromDataDictionary(view, (DataField) component);
414 }
415
416 if (component instanceof Container) {
417 LayoutManager layoutManager = ((Container) component).getLayoutManager();
418
419
420 addCustomContainerComponents(view, model, (Container) component);
421
422
423
424 if (!(component instanceof CollectionGroup)) {
425 processAnyRemoteFieldsHolder(view, model, (Container) component);
426 }
427 }
428
429
430 if (component instanceof CollectionGroup) {
431
432 }
433
434
435 performCustomInitialization(view, component);
436
437
438 runComponentModifiers(view, component, null, UifConstants.ViewPhases.INITIALIZE);
439
440
441 for (Component nestedComponent : component.getComponentsForLifecycle()) {
442 performComponentInitialization(view, model, nestedComponent);
443 }
444
445
446 for (Component nestedComponent : component.getComponentPrototypes()) {
447 performComponentInitialization(view, model, nestedComponent);
448 }
449 }
450
451
452
453
454
455
456
457
458
459
460 protected void processAnyRemoteFieldsHolder(View view, Object model, Container container) {
461 List<Component> processedItems = new ArrayList<Component>();
462
463
464
465 for (Component item : container.getItems()) {
466 if (item instanceof RemoteFieldsHolder) {
467 List<InputField> translatedFields = ((RemoteFieldsHolder) item).fetchAndTranslateRemoteFields(view,
468 model, container);
469 processedItems.addAll(translatedFields);
470 } else {
471 processedItems.add(item);
472 }
473 }
474
475
476 container.setItems(processedItems);
477 }
478
479
480
481
482
483
484
485
486 protected void initializeDataFieldFromDataDictionary(View view, DataField field) {
487 AttributeDefinition attributeDefinition = null;
488
489 String dictionaryAttributeName = field.getDictionaryAttributeName();
490 String dictionaryObjectEntry = field.getDictionaryObjectEntry();
491
492
493
494 if (StringUtils.isNotBlank(dictionaryObjectEntry) && StringUtils.isBlank(dictionaryAttributeName)) {
495 dictionaryAttributeName = field.getPropertyName();
496 }
497
498
499 if (StringUtils.isNotBlank(dictionaryAttributeName) && StringUtils.isNotBlank(dictionaryObjectEntry)) {
500 attributeDefinition = getDataDictionaryService().getAttributeDefinition(dictionaryObjectEntry,
501 dictionaryAttributeName);
502 }
503
504
505 if (attributeDefinition == null) {
506 String propertyPath = field.getBindingInfo().getBindingPath();
507 if (StringUtils.isNotBlank(field.getBindingInfo().getCollectionPath())) {
508 propertyPath = field.getBindingInfo().getCollectionPath();
509 if (StringUtils.isNotBlank(field.getBindingInfo().getBindByNamePrefix())) {
510 propertyPath += "." + field.getBindingInfo().getBindByNamePrefix();
511 }
512 propertyPath += "." + field.getBindingInfo().getBindingName();
513 }
514
515 attributeDefinition = findNestedDictionaryAttribute(view, field, null, propertyPath);
516 }
517
518
519 if (attributeDefinition != null) {
520 field.copyFromAttributeDefinition(view, attributeDefinition);
521 }
522
523
524 if (field instanceof InputField) {
525 InputField inputField = (InputField) field;
526 if (inputField.getControl() == null) {
527 Control control = ComponentFactory.getTextControl();
528 view.assignComponentIds(control);
529
530 inputField.setControl(control);
531 }
532 }
533 }
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560 protected AttributeDefinition findNestedDictionaryAttribute(View view, DataField field, String parentPath,
561 String propertyPath) {
562 AttributeDefinition attributeDefinition = null;
563
564
565 String dictionaryAttributeName = propertyPath;
566 String dictionaryObjectEntry = null;
567
568 if (field.getBindingInfo().isBindToMap()) {
569 parentPath = "";
570 if (!field.getBindingInfo().isBindToForm() && StringUtils.isNotBlank(
571 field.getBindingInfo().getBindingObjectPath())) {
572 parentPath = field.getBindingInfo().getBindingObjectPath();
573 }
574 if (StringUtils.isNotBlank(field.getBindingInfo().getBindByNamePrefix())) {
575 if (StringUtils.isNotBlank(parentPath)) {
576 parentPath += "." + field.getBindingInfo().getBindByNamePrefix();
577 } else {
578 parentPath = field.getBindingInfo().getBindByNamePrefix();
579 }
580 }
581
582 dictionaryAttributeName = field.getBindingInfo().getBindingName();
583 }
584
585 if (StringUtils.isNotBlank(parentPath)) {
586 Class<?> dictionaryModelClass = ViewModelUtils.getPropertyTypeByClassAndView(view, parentPath);
587 if (dictionaryModelClass != null) {
588 dictionaryObjectEntry = dictionaryModelClass.getName();
589
590 attributeDefinition = getDataDictionaryService().getAttributeDefinition(dictionaryObjectEntry,
591 dictionaryAttributeName);
592 }
593 }
594
595
596
597 if ((attributeDefinition == null) && StringUtils.contains(propertyPath, ".")) {
598 String nextParentPath = StringUtils.substringBefore(propertyPath, ".");
599 if (StringUtils.isNotBlank(parentPath)) {
600 nextParentPath = parentPath + "." + nextParentPath;
601 }
602 String nextPropertyPath = StringUtils.substringAfter(propertyPath, ".");
603
604 return findNestedDictionaryAttribute(view, field, nextParentPath, nextPropertyPath);
605 }
606
607
608 if (attributeDefinition != null) {
609 field.setDictionaryAttributeName(dictionaryAttributeName);
610 field.setDictionaryObjectEntry(dictionaryObjectEntry);
611 }
612
613 return attributeDefinition;
614 }
615
616
617
618
619
620 @Override
621 public void performApplyModel(View view, Object model) {
622
623 retrieveEditModesAndActionFlags(view, (UifFormBase) model);
624
625
626 setViewContext(view, model);
627
628 Map<String, Integer> visitedIds = new HashMap<String, Integer>();
629 performComponentApplyModel(view, view, model, visitedIds);
630 }
631
632
633
634
635
636
637
638
639
640 protected void retrieveEditModesAndActionFlags(View view, UifFormBase model) {
641 ViewPresentationController presentationController = view.getPresentationController();
642 ViewAuthorizer authorizer = view.getAuthorizer();
643
644 Person user = GlobalVariables.getUserSession().getPerson();
645
646 Set<String> actionFlags = presentationController.getActionFlags(view, model);
647 actionFlags = authorizer.getActionFlags(view, model, user, actionFlags);
648
649 view.setActionFlags(new BooleanMap(actionFlags));
650
651 Set<String> editModes = presentationController.getEditModes(view, model);
652 editModes = authorizer.getEditModes(view, model, user, editModes);
653
654 view.setEditModes(new BooleanMap(editModes));
655 }
656
657
658
659
660
661
662
663
664 protected void setViewContext(View view, Object model) {
665 view.pushAllToContext(getPreModelContext(view));
666
667
668 for (Entry<String, String> variableExpression : view.getExpressionVariables().entrySet()) {
669 String variableName = variableExpression.getKey();
670 Object value = getExpressionEvaluatorService().evaluateExpression(model, view.getContext(),
671 variableExpression.getValue());
672 view.pushObjectToContext(variableName, value);
673 }
674 }
675
676
677
678
679
680
681
682
683 protected Map<String, Object> getPreModelContext(View view) {
684 Map<String, Object> context = new HashMap<String, Object>();
685
686 context.put(UifConstants.ContextVariableNames.VIEW, view);
687 context.put(UifConstants.ContextVariableNames.VIEW_HELPER, this);
688
689 Map<String, String> properties = KRADServiceLocator.getKualiConfigurationService().getAllProperties();
690 context.put(UifConstants.ContextVariableNames.CONFIG_PROPERTIES, properties);
691 context.put(UifConstants.ContextVariableNames.CONSTANTS, KRADConstants.class);
692 context.put(UifConstants.ContextVariableNames.UIF_CONSTANTS, UifConstants.class);
693
694 return context;
695 }
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713 protected void performComponentApplyModel(View view, Component component, Object model,
714 Map<String, Integer> visitedIds) {
715 if (component == null) {
716 return;
717 }
718
719
720 component.pushAllToContext(getCommonContext(view, component));
721
722 StandardEvaluationContext context = getExpressionEvaluatorService().getContext(model,component.getContext());
723
724 for (PropertyReplacer replacer : component.getPropertyReplacers()) {
725 getExpressionEvaluatorService().evaluateExpressionsOnConfigurable(view, replacer, context);
726 }
727
728 for (ComponentModifier modifier : component.getComponentModifiers()) {
729 getExpressionEvaluatorService().evaluateExpressionsOnConfigurable(view, modifier, context);
730 }
731
732 getExpressionEvaluatorService().evaluateExpressionsOnConfigurable(view, component, context);
733
734
735 ComponentSecurity componentSecurity = component.getComponentSecurity();
736 getExpressionEvaluatorService().evaluateExpressionsOnConfigurable(view, componentSecurity, context);
737
738
739 if (component instanceof DataBinding) {
740 BindingInfo bindingInfo = ((DataBinding) component).getBindingInfo();
741 getExpressionEvaluatorService().evaluateExpressionsOnConfigurable(view, bindingInfo, context);
742 }
743
744
745 if (component instanceof Container) {
746 LayoutManager layoutManager = ((Container) component).getLayoutManager();
747
748 if (layoutManager != null) {
749 layoutManager.getContext().putAll(getCommonContext(view, component));
750 layoutManager.pushObjectToContext(UifConstants.ContextVariableNames.PARENT, component);
751 layoutManager.pushObjectToContext(UifConstants.ContextVariableNames.MANAGER, layoutManager);
752
753 getExpressionEvaluatorService().evaluateExpressionsOnConfigurable(view, layoutManager, model,
754 layoutManager.getContext());
755
756 layoutManager.setId(adjustIdIfNecessary(layoutManager.getId(), visitedIds));
757 }
758 }
759
760
761 syncClientSideStateForComponent(component, ((ViewModel) model).getClientStateForSyncing());
762
763
764 applyAuthorizationAndPresentationLogic(view, component, (ViewModel) model);
765
766
767
768
769
770 Component parent = (Component) component.getContext().get(UifConstants.ContextVariableNames.PARENT);
771 component.performApplyModel(view, model, parent);
772
773
774 performCustomApplyModel(view, component, model);
775
776
777 runComponentModifiers(view, component, model, UifConstants.ViewPhases.APPLY_MODEL);
778
779
780 for (Component nestedComponent : component.getComponentsForLifecycle()) {
781 if (nestedComponent != null) {
782 nestedComponent.pushObjectToContext(UifConstants.ContextVariableNames.PARENT, component);
783 performComponentApplyModel(view, nestedComponent, model, visitedIds);
784 }
785 }
786 }
787
788
789
790
791
792
793
794
795
796 protected String adjustIdIfNecessary(String id, Map<String, Integer> visitedIds) {
797 String adjustedId = id;
798
799 if (visitedIds.containsKey(id)) {
800 Integer nextAdjustSeq = visitedIds.get(id);
801 adjustedId = id + nextAdjustSeq;
802
803
804 while (visitedIds.containsKey(adjustedId)) {
805 nextAdjustSeq = nextAdjustSeq + 1;
806 adjustedId = id + nextAdjustSeq;
807 }
808
809 visitedIds.put(adjustedId, new Integer(1));
810
811 nextAdjustSeq = nextAdjustSeq + 1;
812 visitedIds.put(id, nextAdjustSeq);
813 } else {
814 visitedIds.put(id, new Integer(1));
815 }
816
817 return adjustedId;
818 }
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841 protected void applyAuthorizationAndPresentationLogic(View view, Component component, ViewModel model) {
842 ViewPresentationController presentationController = view.getPresentationController();
843 ViewAuthorizer authorizer = view.getAuthorizer();
844
845 Person user = GlobalVariables.getUserSession().getPerson();
846
847
848 if (!component.isRender()) {
849 return;
850 }
851
852
853 if (component instanceof View) {
854 if (!view.isReadOnly()) {
855 boolean canEditView = authorizer.canEditView(view, model, user);
856 if (canEditView) {
857 canEditView = presentationController.canEditView(view, model);
858 }
859 view.setReadOnly(!canEditView);
860 }
861 }
862
863
864 else if (component instanceof Group) {
865 Group group = (Group) component;
866
867
868 if (!group.isHidden()) {
869 boolean canViewGroup = authorizer.canViewGroup(view, model, group, group.getId(), user);
870 if (canViewGroup) {
871 canViewGroup = presentationController.canViewGroup(view, model, group, group.getId());
872 }
873 group.setHidden(!canViewGroup);
874 group.setRender(canViewGroup);
875 }
876
877
878 if (!group.isReadOnly()) {
879 boolean canEditGroup = authorizer.canEditGroup(view, model, group, group.getId(), user);
880 if (canEditGroup) {
881 canEditGroup = presentationController.canEditGroup(view, model, group, group.getId());
882 }
883 group.setReadOnly(!canEditGroup);
884 }
885 }
886
887
888 else if (component instanceof Field && !(component instanceof ActionField)) {
889 Field field = (Field) component;
890
891 String propertyName = null;
892 if (field instanceof DataBinding) {
893 propertyName = ((DataBinding) field).getPropertyName();
894 }
895
896
897 if (!field.isHidden()) {
898 boolean canViewField = authorizer.canViewField(view, model, field, propertyName, user);
899 if (canViewField) {
900 canViewField = presentationController.canViewField(view, model, field, propertyName);
901 }
902 field.setHidden(!canViewField);
903 field.setRender(canViewField);
904 }
905
906
907 if (!field.isReadOnly()) {
908
909 boolean canEditField = authorizer.canEditField(view, model, field, propertyName, user);
910 if (canEditField) {
911 canEditField = presentationController.canEditField(view, model, field, propertyName);
912 }
913 field.setReadOnly(!canEditField);
914 }
915
916
917 if ((field.getRequired() == null) || !field.getRequired().booleanValue()) {
918 boolean fieldIsRequired = presentationController.fieldIsRequired(view, model, field, propertyName);
919 }
920
921 if (field instanceof DataField) {
922 DataField dataField = (DataField) field;
923
924
925 boolean canUnmaskValue = authorizer.canUnmaskField(view, model, dataField, dataField.getPropertyName(),
926 user);
927 if (!canUnmaskValue) {
928 dataField.setApplyMask(true);
929 dataField.setMaskFormatter(dataField.getDataFieldSecurity().getAttributeSecurity().
930 getMaskFormatter());
931 } else {
932
933 boolean canPartiallyUnmaskValue = authorizer.canPartialUnmaskField(view, model, dataField,
934 dataField.getPropertyName(), user);
935 if (!canPartiallyUnmaskValue) {
936 dataField.setApplyMask(true);
937 dataField.setMaskFormatter(
938 dataField.getDataFieldSecurity().getAttributeSecurity().getPartialMaskFormatter());
939 }
940 }
941 }
942 }
943
944
945 else if (component instanceof ActionField || component instanceof Action) {
946 Action action = null;
947 if (component instanceof ActionField) {
948 action = ((ActionField) component).getAction();
949 } else {
950 action = (Action) component;
951 }
952
953 boolean canTakeAction = authorizer.canPerformAction(view, model, action, action.getActionEvent(),
954 action.getId(), user);
955 if (canTakeAction) {
956 canTakeAction = presentationController.canPerformAction(view, model, action, action.getActionEvent(),
957 action.getId());
958 }
959 action.setRender(canTakeAction);
960 }
961
962
963 else if (component instanceof Widget) {
964 Widget widget = (Widget) component;
965
966
967 if (!widget.isHidden()) {
968 boolean canViewWidget = authorizer.canViewWidget(view, model, widget, widget.getId(), user);
969 if (canViewWidget) {
970 canViewWidget = presentationController.canViewWidget(view, model, widget, widget.getId());
971 }
972 widget.setHidden(!canViewWidget);
973 widget.setRender(canViewWidget);
974 }
975
976
977 if (!widget.isReadOnly()) {
978 boolean canEditWidget = authorizer.canEditWidget(view, model, widget, widget.getId(), user);
979 if (canEditWidget) {
980 canEditWidget = presentationController.canEditWidget(view, model, widget, widget.getId());
981 }
982 widget.setReadOnly(!canEditWidget);
983 }
984 }
985 }
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002 protected void runComponentModifiers(View view, Component component, Object model, String runPhase) {
1003 for (ComponentModifier modifier : component.getComponentModifiers()) {
1004
1005 if (StringUtils.equals(runPhase, UifConstants.ViewPhases.INITIALIZE)) {
1006 modifier.performInitialization(view, model, component);
1007 }
1008
1009
1010 if (StringUtils.equals(modifier.getRunPhase(), runPhase)) {
1011
1012 boolean runModifier = true;
1013 if (StringUtils.isNotBlank(modifier.getRunCondition())) {
1014 Map<String, Object> context = new HashMap<String, Object>();
1015 context.put(UifConstants.ContextVariableNames.COMPONENT, component);
1016 context.put(UifConstants.ContextVariableNames.VIEW, view);
1017
1018 String conditionEvaluation = getExpressionEvaluatorService().evaluateExpressionTemplate(model,
1019 context, modifier.getRunCondition());
1020 runModifier = Boolean.parseBoolean(conditionEvaluation);
1021 }
1022
1023 if (runModifier) {
1024 modifier.performModification(view, model, component);
1025 }
1026 }
1027 }
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037 protected Map<String, Object> getCommonContext(View view, Component component) {
1038 Map<String, Object> context = new HashMap<String, Object>();
1039
1040 context.putAll(view.getContext());
1041 context.put(UifConstants.ContextVariableNames.THEME_IMAGES, view.getTheme().getImageDirectory());
1042 context.put(UifConstants.ContextVariableNames.COMPONENT, component);
1043
1044 return context;
1045 }
1046
1047
1048
1049
1050
1051 @Override
1052 public void performFinalize(View view, Object model) {
1053
1054 String growlScript = buildGrowlScript(view);
1055 ((ViewModel) model).setGrowlScript(growlScript);
1056
1057 Map<String, Object> clientState = new HashMap<String, Object>();
1058 performComponentFinalize(view, view, model, null, clientState);
1059
1060 String clientStateScript = buildClientSideStateScript(view, clientState, false);
1061 String viewPreLoadScript = view.getPreLoadScript();
1062 if (StringUtils.isNotBlank(viewPreLoadScript)) {
1063 clientStateScript = viewPreLoadScript + clientStateScript;
1064 }
1065 view.setPreLoadScript(clientStateScript);
1066
1067
1068 if (!((ViewModel) model).isDefaultsApplied()) {
1069 applyDefaultValues(view, view, model);
1070 ((ViewModel) model).setDefaultsApplied(true);
1071 }
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 protected String buildClientSideStateScript(View view, Map<String, Object> clientSideState, boolean updateOnly) {
1086
1087
1088
1089 for (Entry<String, Object> additionalState : view.getClientSideState().entrySet()) {
1090 if (!clientSideState.containsKey(additionalState.getKey())) {
1091 clientSideState.put(additionalState.getKey(), additionalState.getValue());
1092 } else {
1093 Object state = clientSideState.get(additionalState.getKey());
1094 Object mergeState = additionalState.getValue();
1095 if ((state instanceof Map) && (mergeState instanceof Map)) {
1096 ((Map) state).putAll((Map) mergeState);
1097 } else {
1098 clientSideState.put(additionalState.getKey(), additionalState.getValue());
1099 }
1100 }
1101 }
1102
1103
1104 String clientStateScript = "";
1105 if (!clientSideState.isEmpty()) {
1106 if (updateOnly) {
1107 clientStateScript = "updateViewState({";
1108 } else {
1109 clientStateScript = "initializeViewState({";
1110 }
1111
1112 for (Entry<String, Object> stateEntry : clientSideState.entrySet()) {
1113 clientStateScript += "'" + stateEntry.getKey() + "':";
1114 clientStateScript += ScriptUtils.translateValue(stateEntry.getValue());
1115 clientStateScript += ",";
1116 }
1117 clientStateScript = StringUtils.removeEnd(clientStateScript, ",");
1118 clientStateScript += "});";
1119 }
1120
1121
1122 if (!updateOnly) {
1123 String kradImageLocation = KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
1124 "krad.externalizable.images.url");
1125 clientStateScript += "setConfigParam('"
1126 + UifConstants.ClientSideVariables.KRAD_IMAGE_LOCATION
1127 + "','"
1128 + kradImageLocation
1129 + "');";
1130
1131 String kradURL = KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString("krad.url");
1132 clientStateScript +=
1133 "setConfigParam('" + UifConstants.ClientSideVariables.KRAD_URL + "','" + kradURL + "');";
1134 }
1135
1136 return clientStateScript;
1137 }
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 protected String buildGrowlScript(View view) {
1156 String growlScript = "";
1157
1158 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
1159
1160 MessageMap messageMap = GlobalVariables.getMessageMap();
1161 for (GrowlMessage growl : messageMap.getGrowlMessages()) {
1162 if (view.isGrowlMessagingEnabled()) {
1163 String message = messageService.getMessageText(growl.getNamespaceCode(), growl.getComponentCode(),
1164 growl.getMessageKey());
1165
1166 if (StringUtils.isNotBlank(message)) {
1167 if (growl.getMessageParameters() != null) {
1168 message = message.replace("'", "''");
1169 message = MessageFormat.format(message, (Object[]) growl.getMessageParameters());
1170 }
1171
1172
1173 message = message.replace("'", "\\'");
1174
1175 String title = growl.getTitle();
1176 if (StringUtils.isNotBlank(growl.getTitleKey())) {
1177 title = messageService.getMessageText(growl.getNamespaceCode(), growl.getComponentCode(),
1178 growl.getTitleKey());
1179 }
1180 title = title.replace("'", "\\'");
1181
1182 growlScript =
1183 growlScript + "showGrowl('" + message + "', '" + title + "', '" + growl.getTheme() + "');";
1184 }
1185 } else {
1186 ErrorMessage infoMessage = new ErrorMessage(growl.getMessageKey(), growl.getMessageParameters());
1187 infoMessage.setNamespaceCode(growl.getNamespaceCode());
1188 infoMessage.setComponentCode(growl.getComponentCode());
1189
1190 messageMap.putInfoForSectionId(KRADConstants.GLOBAL_INFO, infoMessage);
1191 }
1192 }
1193
1194 return growlScript;
1195 }
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207 protected void performComponentFinalize(View view, Component component, Object model, Component parent,
1208 Map<String, Object> clientSideState) {
1209 if (component == null) {
1210 return;
1211 }
1212
1213
1214 ViewModel viewModel = (ViewModel) model;
1215 if ((component instanceof DataBinding) && view.isSupportsRequestOverrideOfReadOnlyFields() && !viewModel
1216 .getReadOnlyFieldsList().isEmpty()) {
1217 String propertyName = ((DataBinding) component).getPropertyName();
1218 if (viewModel.getReadOnlyFieldsList().contains(propertyName)) {
1219 component.setReadOnly(true);
1220 }
1221 }
1222
1223
1224 invokeMethodFinalizer(view, component, model);
1225
1226
1227 component.performFinalize(view, model, parent);
1228
1229
1230 addClientSideStateForComponent(component, clientSideState);
1231
1232
1233 performCustomFinalize(view, component, model, parent);
1234
1235
1236 runComponentModifiers(view, component, model, UifConstants.ViewPhases.FINALIZE);
1237
1238
1239 if (!component.isSelfRendered() && StringUtils.isNotBlank(component.getTemplate()) &&
1240 !view.getViewTemplates().contains(component.getTemplate())) {
1241 view.getViewTemplates().add(component.getTemplate());
1242 }
1243
1244
1245 for (Component nestedComponent : component.getComponentsForLifecycle()) {
1246 performComponentFinalize(view, nestedComponent, model, component, clientSideState);
1247 }
1248 }
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264 protected void addClientSideStateForComponent(Component component, Map<String, Object> clientSideState) {
1265 Map<String, Annotation> annotatedFields = CloneUtils.getFieldsWithAnnotation(component.getClass(),
1266 ClientSideState.class);
1267
1268 if (!annotatedFields.isEmpty()) {
1269 Map<String, Object> componentClientState = null;
1270 if (component instanceof View) {
1271 componentClientState = clientSideState;
1272 } else {
1273 if (clientSideState.containsKey(component.getId())) {
1274 componentClientState = (Map<String, Object>) clientSideState.get(component.getId());
1275 } else {
1276 componentClientState = new HashMap<String, Object>();
1277 clientSideState.put(component.getId(), componentClientState);
1278 }
1279 }
1280
1281 for (Entry<String, Annotation> annotatedField : annotatedFields.entrySet()) {
1282 ClientSideState clientSideStateAnnot = (ClientSideState) annotatedField.getValue();
1283
1284 String variableName = clientSideStateAnnot.variableName();
1285 if (StringUtils.isBlank(variableName)) {
1286 variableName = annotatedField.getKey();
1287 }
1288
1289 Object value = ObjectPropertyUtils.getPropertyValue(component, annotatedField.getKey());
1290 componentClientState.put(variableName, value);
1291 }
1292 }
1293 }
1294
1295
1296
1297
1298
1299
1300
1301
1302 protected void syncClientSideStateForComponent(Component component, Map<String, Object> clientSideState) {
1303
1304 Map<String, Object> componentState = null;
1305 if (component instanceof View) {
1306 componentState = clientSideState;
1307 } else {
1308 if (clientSideState.containsKey(component.getId())) {
1309 componentState = (Map<String, Object>) clientSideState.get(component.getId());
1310 }
1311 }
1312
1313
1314 if ((componentState != null) && (!componentState.isEmpty())) {
1315 Map<String, Annotation> annotatedFields = CloneUtils.getFieldsWithAnnotation(component.getClass(),
1316 ClientSideState.class);
1317
1318 for (Entry<String, Annotation> annotatedField : annotatedFields.entrySet()) {
1319 ClientSideState clientSideStateAnnot = (ClientSideState) annotatedField.getValue();
1320
1321 String variableName = clientSideStateAnnot.variableName();
1322 if (StringUtils.isBlank(variableName)) {
1323 variableName = annotatedField.getKey();
1324 }
1325
1326 if (componentState.containsKey(variableName)) {
1327 Object value = componentState.get(variableName);
1328 ObjectPropertyUtils.setPropertyValue(component, annotatedField.getKey(), value);
1329 }
1330 }
1331 }
1332 }
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343 protected void invokeMethodFinalizer(View view, Component component, Object model) {
1344 String finalizeMethodToCall = component.getFinalizeMethodToCall();
1345 MethodInvoker finalizeMethodInvoker = component.getFinalizeMethodInvoker();
1346
1347 if (StringUtils.isBlank(finalizeMethodToCall) && (finalizeMethodInvoker == null)) {
1348 return;
1349 }
1350
1351 if (finalizeMethodInvoker == null) {
1352 finalizeMethodInvoker = new MethodInvoker();
1353 }
1354
1355
1356
1357 if (StringUtils.isBlank(finalizeMethodInvoker.getTargetMethod())) {
1358 finalizeMethodInvoker.setTargetMethod(finalizeMethodToCall);
1359 }
1360
1361
1362 if ((finalizeMethodInvoker.getTargetClass() == null) && (finalizeMethodInvoker.getTargetObject() == null)) {
1363 finalizeMethodInvoker.setTargetObject(view.getViewHelperService());
1364 }
1365
1366
1367 List<Object> additionalArguments = component.getFinalizeMethodAdditionalArguments();
1368 if (additionalArguments == null) {
1369 additionalArguments = new ArrayList<Object>();
1370 }
1371
1372 Object[] arguments = new Object[2 + additionalArguments.size()];
1373 arguments[0] = component;
1374 arguments[1] = model;
1375
1376 int argumentIndex = 1;
1377 for (Object argument : additionalArguments) {
1378 argumentIndex++;
1379 arguments[argumentIndex] = argument;
1380 }
1381 finalizeMethodInvoker.setArguments(arguments);
1382
1383
1384 try {
1385 LOG.debug("Invoking finalize method: "
1386 + finalizeMethodInvoker.getTargetMethod()
1387 + " for component: "
1388 + component.getId());
1389 finalizeMethodInvoker.prepare();
1390
1391 Class<?> methodReturnType = finalizeMethodInvoker.getPreparedMethod().getReturnType();
1392 if (StringUtils.equals("void", methodReturnType.getName())) {
1393 finalizeMethodInvoker.invoke();
1394 } else {
1395 String renderOutput = (String) finalizeMethodInvoker.invoke();
1396
1397 component.setSelfRendered(true);
1398 component.setRenderedHtmlOutput(renderOutput);
1399 }
1400 } catch (Exception e) {
1401 LOG.error("Error invoking finalize method for component: " + component.getId(), e);
1402 throw new RuntimeException("Error invoking finalize method for component: " + component.getId(), e);
1403 }
1404 }
1405
1406
1407
1408
1409 @Override
1410 public void cleanViewAfterRender(View view) {
1411 ViewCleaner.cleanView(view);
1412 }
1413
1414
1415
1416
1417
1418 @Override
1419 public void processCollectionAddLine(View view, Object model, String collectionPath) {
1420
1421 CollectionGroup collectionGroup = view.getViewIndex().getCollectionGroupByPath(collectionPath);
1422 if (collectionGroup == null) {
1423 logAndThrowRuntime("Unable to get collection group component for path: " + collectionPath);
1424 }
1425
1426
1427 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model, collectionPath);
1428 if (collection == null) {
1429 logAndThrowRuntime("Unable to get collection property from model for path: " + collectionPath);
1430 }
1431
1432
1433 String addLinePath = collectionGroup.getAddLineBindingInfo().getBindingPath();
1434 Object addLine = ObjectPropertyUtils.getPropertyValue(model, addLinePath);
1435 if (addLine == null) {
1436 logAndThrowRuntime("Add line instance not found for path: " + addLinePath);
1437 }
1438
1439 processBeforeAddLine(view, collectionGroup, model, addLine);
1440
1441
1442 boolean isValidLine = performAddLineValidation(view, collectionGroup, model, addLine);
1443 if (isValidLine) {
1444
1445
1446
1447 addLine(collection, addLine, collectionGroup.getAddLinePlacement().equals("TOP"));
1448
1449
1450 collectionGroup.initializeNewCollectionLine(view, model, collectionGroup, true);
1451 }
1452
1453 ((UifFormBase) model).getAddedCollectionItems().add(addLine);
1454
1455 processAfterAddLine(view, collectionGroup, model, addLine);
1456 }
1457
1458
1459
1460
1461
1462 @Override
1463 public void processCollectionSaveLine(View view, Object model, String collectionPath, int selectedLineIndex) {
1464
1465 CollectionGroup collectionGroup = view.getViewIndex().getCollectionGroupByPath(collectionPath);
1466 if (collectionGroup == null) {
1467 logAndThrowRuntime("Unable to get collection group component for path: " + collectionPath);
1468 }
1469
1470
1471 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model, collectionPath);
1472 if (collection == null) {
1473 logAndThrowRuntime("Unable to get collection property from model for path: " + collectionPath);
1474 }
1475
1476
1477
1478 if (collection instanceof List) {
1479 Object saveLine = ((List<Object>) collection).get(selectedLineIndex);
1480
1481 processBeforeSaveLine(view, collectionGroup, model, saveLine);
1482
1483 ((UifFormBase) model).getAddedCollectionItems().remove(saveLine);
1484
1485 processAfterSaveLine(view, collectionGroup, model, saveLine);
1486
1487 } else {
1488 logAndThrowRuntime("Only List collection implementations are supported for the delete by index method");
1489 }
1490
1491 }
1492
1493
1494
1495
1496
1497 @Override
1498 public void processCollectionAddBlankLine(View view, Object model, String collectionPath) {
1499
1500 CollectionGroup collectionGroup = view.getViewIndex().getCollectionGroupByPath(collectionPath);
1501 if (collectionGroup == null) {
1502 logAndThrowRuntime("Unable to get collection group component for path: " + collectionPath);
1503 }
1504
1505
1506 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model, collectionPath);
1507 if (collection == null) {
1508 logAndThrowRuntime("Unable to get collection property from model for path: " + collectionPath);
1509 }
1510
1511 Object newLine = ObjectUtils.newInstance(collectionGroup.getCollectionObjectClass());
1512 applyDefaultValuesForCollectionLine(view, model, collectionGroup, newLine);
1513 addLine(collection, newLine, collectionGroup.getAddLinePlacement().equals("TOP"));
1514
1515 ((UifFormBase) model).getAddedCollectionItems().add(newLine);
1516 }
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 protected void addLine(Collection<Object> collection, Object addLine, boolean insertFirst) {
1527 if (insertFirst && (collection instanceof List)) {
1528 ((List) collection).add(0, addLine);
1529 } else {
1530 collection.add(addLine);
1531 }
1532 }
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546 protected boolean performAddLineValidation(View view, CollectionGroup collectionGroup, Object model,
1547 Object addLine) {
1548 boolean isValid = true;
1549
1550
1551
1552
1553 return isValid;
1554 }
1555
1556
1557
1558
1559
1560 public void processCollectionDeleteLine(View view, Object model, String collectionPath, int lineIndex) {
1561
1562 CollectionGroup collectionGroup = view.getViewIndex().getCollectionGroupByPath(collectionPath);
1563 if (collectionGroup == null) {
1564 logAndThrowRuntime("Unable to get collection group component for path: " + collectionPath);
1565 }
1566
1567
1568 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model, collectionPath);
1569 if (collection == null) {
1570 logAndThrowRuntime("Unable to get collection property from model for path: " + collectionPath);
1571 }
1572
1573
1574
1575 if (collection instanceof List) {
1576 Object deleteLine = ((List<Object>) collection).get(lineIndex);
1577
1578
1579 boolean isValid = performDeleteLineValidation(view, collectionGroup, deleteLine);
1580 if (isValid) {
1581 ((List<Object>) collection).remove(lineIndex);
1582 processAfterDeleteLine(view, collectionGroup, model, lineIndex);
1583 }
1584 } else {
1585 logAndThrowRuntime("Only List collection implementations are supported for the delete by index method");
1586 }
1587 }
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599 protected boolean performDeleteLineValidation(View view, CollectionGroup collectionGroup, Object deleteLine) {
1600 boolean isValid = true;
1601
1602
1603
1604
1605 return isValid;
1606 }
1607
1608
1609
1610
1611 public void processMultipleValueLookupResults(View view, Object model, String collectionPath,
1612 String lookupResultValues) {
1613
1614 if (StringUtils.isBlank(lookupResultValues)) {
1615 return;
1616 }
1617
1618
1619 CollectionGroup collectionGroup = view.getViewIndex().getCollectionGroupByPath(collectionPath);
1620 if (collectionGroup == null) {
1621 throw new RuntimeException("Unable to find collection group for path: " + collectionPath);
1622 }
1623
1624 Class<?> collectionObjectClass = collectionGroup.getCollectionObjectClass();
1625 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model,
1626 collectionGroup.getBindingInfo().getBindingPath());
1627 if (collection == null) {
1628 Class<?> collectionClass = ObjectPropertyUtils.getPropertyType(model,
1629 collectionGroup.getBindingInfo().getBindingPath());
1630 collection = (Collection<Object>) ObjectUtils.newInstance(collectionClass);
1631 ObjectPropertyUtils.setPropertyValue(model, collectionGroup.getBindingInfo().getBindingPath(), collection);
1632 }
1633
1634 Map<String, String> fieldConversions = collectionGroup.getCollectionLookup().getFieldConversions();
1635 List<String> toFieldNamesColl = new ArrayList(fieldConversions.values());
1636 Collections.sort(toFieldNamesColl);
1637 String[] toFieldNames = new String[toFieldNamesColl.size()];
1638 toFieldNamesColl.toArray(toFieldNames);
1639
1640
1641 String[] lineValues = StringUtils.split(lookupResultValues, ",");
1642
1643
1644 for (String lineValue : lineValues) {
1645 Object lineDataObject = null;
1646
1647
1648 ModuleService moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
1649 collectionObjectClass);
1650 if (moduleService != null && moduleService.isExternalizable(collectionObjectClass)) {
1651 lineDataObject = moduleService.createNewObjectFromExternalizableClass(collectionObjectClass.asSubclass(
1652 ExternalizableBusinessObject.class));
1653 } else {
1654 lineDataObject = ObjectUtils.newInstance(collectionObjectClass);
1655 }
1656
1657
1658 applyDefaultValuesForCollectionLine(view, model, collectionGroup, lineDataObject);
1659
1660 String[] fieldValues = StringUtils.split(lineValue, ":");
1661 if (fieldValues.length != toFieldNames.length) {
1662 throw new RuntimeException(
1663 "Value count passed back from multi-value lookup does not match field conversion count");
1664 }
1665
1666
1667 for (int i = 0; i < fieldValues.length; i++) {
1668 String fieldName = toFieldNames[i];
1669 ObjectPropertyUtils.setPropertyValue(lineDataObject, fieldName, fieldValues[i]);
1670 }
1671
1672
1673
1674 collection.add(lineDataObject);
1675 }
1676 }
1677
1678
1679
1680
1681
1682
1683
1684
1685 public void buildInquiryLink(Object dataObject, String propertyName, Inquiry inquiry) {
1686 Inquirable inquirable = getViewDictionaryService().getInquirable(dataObject.getClass(), inquiry.getViewName());
1687 if (inquirable != null) {
1688 inquirable.buildInquirableLink(dataObject, propertyName, inquiry);
1689 } else {
1690
1691
1692
1693 inquiry.setRender(false);
1694 }
1695 }
1696
1697
1698
1699
1700
1701
1702 public void applyDefaultValuesForCollectionLine(View view, Object model, CollectionGroup collectionGroup,
1703 Object line) {
1704
1705 List<DataField> dataFields = ComponentUtils.getComponentsOfTypeDeep(collectionGroup.getAddLineItems(),
1706 DataField.class);
1707 for (DataField dataField : dataFields) {
1708 String bindingPath = "";
1709 if (StringUtils.isNotBlank(dataField.getBindingInfo().getBindByNamePrefix())) {
1710 bindingPath = dataField.getBindingInfo().getBindByNamePrefix() + ".";
1711 }
1712 bindingPath += dataField.getBindingInfo().getBindingName();
1713
1714 populateDefaultValueForField(view, line, dataField, bindingPath);
1715 }
1716 }
1717
1718
1719
1720
1721
1722
1723
1724
1725 protected void applyDefaultValues(View view, Component component, Object model) {
1726 if (component == null) {
1727 return;
1728 }
1729
1730
1731 if (component instanceof DataField) {
1732 DataField dataField = ((DataField) component);
1733
1734
1735 dataField.getBindingInfo().setDefaults(view, dataField.getPropertyName());
1736
1737 populateDefaultValueForField(view, model, dataField, dataField.getBindingInfo().getBindingPath());
1738 }
1739
1740 List<Component> nestedComponents = component.getComponentsForLifecycle();
1741
1742
1743 if (component instanceof View) {
1744 nestedComponents.addAll(((View) component).getItems());
1745 }
1746
1747 for (Component nested : nestedComponents) {
1748 applyDefaultValues(view, nested, model);
1749 }
1750 }
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768 protected void populateDefaultValueForField(View view, Object object, DataField dataField, String bindingPath) {
1769
1770 String defaultValue = dataField.getDefaultValue();
1771 Object[] defaultValues = dataField.getDefaultValues();
1772
1773 if (StringUtils.isBlank(defaultValue) && defaultValues != null && defaultValues.length > 0) {
1774 ObjectPropertyUtils.setPropertyValue(object, bindingPath, defaultValues);
1775 }
1776 else {
1777 if (StringUtils.isBlank(defaultValue) && (dataField.getDefaultValueFinderClass() != null)) {
1778 ValueFinder defaultValueFinder = ObjectUtils.newInstance(dataField.getDefaultValueFinderClass());
1779 defaultValue = defaultValueFinder.getValue();
1780 }
1781
1782
1783 if (StringUtils.isNotBlank(defaultValue) && ObjectPropertyUtils.isWritableProperty(object, bindingPath)) {
1784 if (getExpressionEvaluatorService().containsElPlaceholder(defaultValue)) {
1785 Map<String, Object> context = getPreModelContext(view);
1786 defaultValue = getExpressionEvaluatorService().evaluateExpressionTemplate(null, context, defaultValue);
1787 }
1788
1789
1790
1791 Object currentValue = ObjectPropertyUtils.getPropertyValue(object, bindingPath);
1792 Class currentClazz = ObjectPropertyUtils.getPropertyType(object, bindingPath);
1793 if(currentValue == null || StringUtils.isBlank(currentValue.toString()) ||
1794 ClassUtils.isPrimitiveOrWrapper(currentClazz)) {
1795 ObjectPropertyUtils.setPropertyValue(object, bindingPath, defaultValue);
1796 }
1797 }
1798 }
1799 }
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818 protected void addCustomContainerComponents(View view, Object model, Container container) {
1819
1820 }
1821
1822
1823
1824
1825
1826
1827
1828
1829 protected void performCustomInitialization(View view, Component component) {
1830
1831 }
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842 protected void performCustomApplyModel(View view, Component component, Object model) {
1843
1844 }
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854 protected void performCustomFinalize(View view, Component component, Object model, Component parent) {
1855
1856 }
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869 protected void processBeforeAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
1870
1871 }
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884 protected void processAfterAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
1885
1886 }
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898 protected void processBeforeSaveLine(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
1899
1900 }
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912 protected void processAfterSaveLine(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
1913
1914 }
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925 protected void processAfterDeleteLine(View view, CollectionGroup collectionGroup, Object model, int lineIndex) {
1926
1927 }
1928
1929
1930
1931
1932
1933
1934 protected void logAndThrowRuntime(String message) {
1935 LOG.error(message);
1936 throw new RuntimeException(message);
1937 }
1938
1939
1940
1941
1942
1943
1944 protected DataDictionaryService getDataDictionaryService() {
1945 if (this.dataDictionaryService == null) {
1946 this.dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
1947 }
1948
1949 return this.dataDictionaryService;
1950 }
1951
1952
1953
1954
1955
1956
1957 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
1958 this.dataDictionaryService = dataDictionaryService;
1959 }
1960
1961
1962
1963
1964
1965
1966 protected ExpressionEvaluatorServiceImpl getExpressionEvaluatorService() {
1967 if (this.expressionEvaluatorService == null) {
1968 this.expressionEvaluatorService = (ExpressionEvaluatorServiceImpl) KRADServiceLocatorWeb.getExpressionEvaluatorService();
1969 }
1970
1971 return this.expressionEvaluatorService;
1972 }
1973
1974
1975
1976
1977
1978
1979 public void setExpressionEvaluatorService(ExpressionEvaluatorService expressionEvaluatorService) {
1980 this.expressionEvaluatorService = (ExpressionEvaluatorServiceImpl) expressionEvaluatorService;
1981 }
1982
1983
1984
1985
1986
1987
1988 public ViewDictionaryService getViewDictionaryService() {
1989 if (this.viewDictionaryService == null) {
1990 this.viewDictionaryService = KRADServiceLocatorWeb.getViewDictionaryService();
1991 }
1992 return this.viewDictionaryService;
1993 }
1994
1995
1996
1997
1998
1999
2000 public void setViewDictionaryService(ViewDictionaryService viewDictionaryService) {
2001 this.viewDictionaryService = viewDictionaryService;
2002 }
2003
2004
2005
2006
2007
2008
2009 public ConfigurationService getConfigurationService() {
2010 if (this.configurationService == null) {
2011 this.configurationService = KRADServiceLocator.getKualiConfigurationService();
2012 }
2013 return this.configurationService;
2014 }
2015
2016
2017
2018
2019
2020
2021 public void setConfigurationService(ConfigurationService configurationService) {
2022 this.configurationService = configurationService;
2023 }
2024 }