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