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