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 com.google.common.collect.Sets;
19 import org.apache.commons.lang.ObjectUtils;
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.log4j.Logger;
22 import org.kuali.rice.core.api.CoreApiServiceLocator;
23 import org.kuali.rice.core.api.config.property.ConfigurationService;
24 import org.kuali.rice.core.api.util.RiceKeyConstants;
25 import org.kuali.rice.kim.api.identity.Person;
26 import org.kuali.rice.krad.bo.PersistableBusinessObject;
27 import org.kuali.rice.krad.data.DataObjectService;
28 import org.kuali.rice.krad.data.DataObjectWrapper;
29 import org.kuali.rice.krad.data.KradDataServiceLocator;
30 import org.kuali.rice.krad.inquiry.Inquirable;
31 import org.kuali.rice.krad.messages.MessageService;
32 import org.kuali.rice.krad.service.DataDictionaryService;
33 import org.kuali.rice.krad.service.KRADServiceLocator;
34 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
35 import org.kuali.rice.krad.service.LegacyDataAdapter;
36 import org.kuali.rice.krad.service.ModuleService;
37 import org.kuali.rice.krad.uif.UifConstants;
38 import org.kuali.rice.krad.uif.component.BindingInfo;
39 import org.kuali.rice.krad.uif.component.Component;
40 import org.kuali.rice.krad.uif.component.PropertyReplacer;
41 import org.kuali.rice.krad.uif.component.RequestParameter;
42 import org.kuali.rice.krad.uif.container.CollectionGroup;
43 import org.kuali.rice.krad.uif.container.Container;
44 import org.kuali.rice.krad.uif.field.DataField;
45 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
46 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleUtils;
47 import org.kuali.rice.krad.uif.service.ViewDictionaryService;
48 import org.kuali.rice.krad.uif.service.ViewHelperService;
49 import org.kuali.rice.krad.uif.util.BooleanMap;
50 import org.kuali.rice.krad.uif.util.CloneUtils;
51 import org.kuali.rice.krad.uif.util.LifecycleElement;
52 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
53 import org.kuali.rice.krad.uif.util.RecycleUtils;
54 import org.kuali.rice.krad.uif.view.ExpressionEvaluator;
55 import org.kuali.rice.krad.uif.view.ExpressionEvaluatorFactory;
56 import org.kuali.rice.krad.uif.view.View;
57 import org.kuali.rice.krad.uif.view.ViewAuthorizer;
58 import org.kuali.rice.krad.uif.view.ViewModel;
59 import org.kuali.rice.krad.uif.view.ViewPresentationController;
60 import org.kuali.rice.krad.uif.widget.Inquiry;
61 import org.kuali.rice.krad.util.ErrorMessage;
62 import org.kuali.rice.krad.util.GlobalVariables;
63 import org.kuali.rice.krad.util.GrowlMessage;
64 import org.kuali.rice.krad.util.KRADConstants;
65 import org.kuali.rice.krad.util.KRADUtils;
66 import org.kuali.rice.krad.util.MessageMap;
67 import org.kuali.rice.krad.valuefinder.ValueFinder;
68 import org.kuali.rice.krad.web.form.UifFormBase;
69 import org.springframework.beans.PropertyAccessorUtils;
70
71 import java.io.Serializable;
72 import java.lang.annotation.Annotation;
73 import java.text.MessageFormat;
74 import java.util.ArrayList;
75 import java.util.Collection;
76 import java.util.Collections;
77 import java.util.HashMap;
78 import java.util.HashSet;
79 import java.util.LinkedList;
80 import java.util.List;
81 import java.util.Map;
82 import java.util.Map.Entry;
83 import java.util.Queue;
84 import java.util.Set;
85
86
87
88
89
90
91 public class ViewHelperServiceImpl implements ViewHelperService, Serializable {
92 private static final long serialVersionUID = 1772618197133239852L;
93 private static final Logger LOG = Logger.getLogger(ViewHelperServiceImpl.class);
94
95 private transient ConfigurationService configurationService;
96 private transient DataDictionaryService dataDictionaryService;
97 private transient LegacyDataAdapter legacyDataAdapter;
98 private transient DataObjectService dataObjectService;
99 private transient ViewDictionaryService viewDictionaryService;
100 private transient ExpressionEvaluatorFactory expressionEvaluatorFactory;
101
102
103
104
105 @Override
106 public void addCustomContainerComponents(ViewModel model, Container container) {
107
108 }
109
110
111
112
113
114
115
116 public void buildInquiryLink(Object dataObject, String propertyName, Inquiry inquiry) {
117 Inquirable inquirable = getViewDictionaryService().getInquirable(dataObject.getClass(), inquiry.getViewName());
118 if (inquirable != null) {
119 inquirable.buildInquirableLink(dataObject, propertyName, inquiry);
120 } else {
121
122
123
124 inquiry.setRender(false);
125 }
126 }
127
128
129
130
131 @Override
132 public void performCustomApplyModel(LifecycleElement element, Object model) {
133
134 }
135
136
137
138
139 @Override
140 public void performCustomFinalize(LifecycleElement element, Object model, LifecycleElement parent) {
141
142 }
143
144
145
146
147 @Override
148 public void performCustomInitialization(LifecycleElement element) {
149
150 }
151
152
153
154
155 @Override
156 public void performCustomViewFinalize(Object model) {
157
158 }
159
160
161
162
163 @Override
164 public void performCustomViewInitialization(Object model) {
165
166 }
167
168
169
170
171 @Override
172 public void processAfterAddLine(ViewModel model, Object lineObject, String collectionId, String collectionPath,
173 boolean isValidLine) {
174
175 }
176
177
178
179
180 @Override
181 public void processAfterDeleteLine(ViewModel model, String collectionId, String collectionPath, int lineIndex) {
182
183 }
184
185
186
187
188 @Override
189 public void processAfterSaveLine(ViewModel model, Object lineObject, String collectionId, String collectionPath) {
190
191 }
192
193
194
195
196 @Override
197 public void processBeforeAddLine(ViewModel model, Object addLine, String collectionId, String collectionPath) {
198
199 }
200
201
202
203
204 @Override
205 public void processBeforeSaveLine(ViewModel model, Object lineObject, String collectionId, String collectionPath) {
206
207 }
208
209
210
211
212 @SuppressWarnings("unchecked")
213 @Override
214 public void processCollectionAddBlankLine(ViewModel model, String collectionId, String collectionPath) {
215 if (!(model instanceof ViewModel)) {
216 return;
217 }
218
219 ViewModel viewModel = (ViewModel) model;
220
221 if (collectionId == null) {
222 logAndThrowRuntime(
223 "Unable to get collection group component for Id: " + collectionPath + " path: " + collectionPath);
224 }
225
226
227 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model, collectionPath);
228 if (collection == null) {
229 logAndThrowRuntime("Unable to get collection property from model for path: " + collectionPath);
230 }
231
232 Class<?> collectionObjectClass = (Class<?>) viewModel.getViewPostMetadata().getComponentPostData(collectionId,
233 UifConstants.PostMetadata.COLL_OBJECT_CLASS);
234 Object newLine = KRADUtils.createNewObjectFromClass(collectionObjectClass);
235
236 List<Object> lineDataObjects = new ArrayList<Object>();
237 lineDataObjects.add(newLine);
238 viewModel.getViewPostMetadata().getAddedCollectionObjects().put(collectionId, lineDataObjects);
239 processAndAddLineObject(viewModel, newLine, collectionId, collectionPath);
240 }
241
242
243
244
245 @SuppressWarnings("unchecked")
246 @Override
247 public void processCollectionAddLine(ViewModel model, String collectionId, String collectionPath) {
248 if (!(model instanceof ViewModel)) {
249 return;
250 }
251
252 ViewModel viewModel = (ViewModel) model;
253
254 if (collectionId == null) {
255 logAndThrowRuntime(
256 "Unable to get collection group component for Id: " + collectionPath + " path: " + collectionPath);
257 }
258
259
260 BindingInfo addLineBindingInfo = (BindingInfo) viewModel.getViewPostMetadata().getComponentPostData(
261 collectionId, UifConstants.PostMetadata.ADD_LINE_BINDING_INFO);
262 Object addLine = ObjectPropertyUtils.getPropertyValue(model, addLineBindingInfo.getBindingPath());
263 if (addLine == null) {
264 logAndThrowRuntime("Add line instance not found for path: " + addLineBindingInfo.getBindingPath());
265 }
266
267
268
269 List<Object> lineDataObjects = new ArrayList<Object>();
270 viewModel.getViewPostMetadata().getAddedCollectionObjects().put(collectionId, lineDataObjects);
271
272 processAndAddLineObject(viewModel, addLine, collectionId, collectionPath);
273
274 }
275
276
277
278
279
280
281
282
283
284
285 protected void processAndAddLineObject(ViewModel viewModel, Object newLine, String collectionId,
286 String collectionPath) {
287 String addLinePlacement = (String) viewModel.getViewPostMetadata().getComponentPostData(collectionId,
288 UifConstants.PostMetadata.ADD_LINE_PLACEMENT);
289
290
291 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(viewModel, collectionPath);
292 if (collection == null) {
293 logAndThrowRuntime("Unable to get collection property from model for path: " + collectionPath);
294 }
295
296 processBeforeAddLine(viewModel, newLine, collectionId, collectionPath);
297
298 boolean isValidLine = performAddLineValidation(viewModel, newLine, collectionId, collectionPath);
299 if (isValidLine) {
300 int addedIndex = addLine(collection, newLine, addLinePlacement.equals("TOP"));
301
302
303 linkAddedLine(viewModel, collectionPath, addedIndex);
304
305 if (viewModel instanceof UifFormBase) {
306 ((UifFormBase) viewModel).getAddedCollectionItems().add(newLine);
307 }
308 processAfterAddLine(viewModel, newLine, collectionId, collectionPath, isValidLine);
309 }
310 }
311
312
313
314
315 @Override
316 public void processCollectionDeleteLine(ViewModel model, String collectionId, String collectionPath,
317 int lineIndex) {
318
319 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model, collectionPath);
320 if (collection == null) {
321 logAndThrowRuntime("Unable to get collection property from model for path: " + collectionPath);
322 }
323
324
325
326 if (collection instanceof List) {
327 Object deleteLine = ((List<Object>) collection).get(lineIndex);
328
329
330 boolean isValid = performDeleteLineValidation(model, collectionId, collectionPath, deleteLine);
331 if (isValid) {
332 ((List<Object>) collection).remove(lineIndex);
333 processAfterDeleteLine(model, collectionId, collectionPath, lineIndex);
334 }
335 } else {
336 logAndThrowRuntime("Only List collection implementations are supported for the delete by index method");
337 }
338 }
339
340
341
342
343 @Override
344 public void processCollectionSaveLine(ViewModel model, String collectionId, String collectionPath,
345 int selectedLineIndex) {
346
347 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model, collectionPath);
348 if (collection == null) {
349 logAndThrowRuntime("Unable to get collection property from model for path: " + collectionPath);
350 }
351
352
353
354 if (collection instanceof List) {
355 Object saveLine = ((List<Object>) collection).get(selectedLineIndex);
356
357 processBeforeSaveLine(model, saveLine, collectionId, collectionPath);
358
359 ((UifFormBase) model).getAddedCollectionItems().remove(saveLine);
360
361 processAfterSaveLine(model, saveLine, collectionId, collectionPath);
362
363 } else {
364 logAndThrowRuntime("Only List collection implementations are supported for the delete by index method");
365 }
366
367 }
368
369
370
371
372 @SuppressWarnings("unchecked")
373 public void processMultipleValueLookupResults(ViewModel model, String collectionId, String collectionPath,
374 String multiValueReturnFields, String lookupResultValues) {
375
376 if (StringUtils.isBlank(lookupResultValues) || !(model instanceof ViewModel)) {
377 return;
378 }
379
380 ViewModel viewModel = (ViewModel) model;
381
382 if (StringUtils.isBlank(collectionId)) {
383 throw new RuntimeException(
384 "Id is not set for this collection lookup: " + collectionId + ", " + "path: " + collectionPath);
385 }
386
387
388 Class<?> collectionObjectClass = (Class<?>) viewModel.getViewPostMetadata().getComponentPostData(collectionId,
389 UifConstants.PostMetadata.COLL_OBJECT_CLASS);
390 Collection<Object> collection = ObjectPropertyUtils.getPropertyValue(model, collectionPath);
391 if (collection == null) {
392 Class<?> collectionClass = ObjectPropertyUtils.getPropertyType(model, collectionPath);
393 collection = (Collection<Object>) KRADUtils.createNewObjectFromClass(collectionClass);
394 ObjectPropertyUtils.setPropertyValue(model, collectionPath, collection);
395 }
396
397
398 Map<String, String> fieldConversions =
399 (Map<String, String>) viewModel.getViewPostMetadata().getComponentPostData(collectionId,
400 UifConstants.PostMetadata.COLL_LOOKUP_FIELD_CONVERSIONS);
401
402
403 Map <String, String> returnedFieldConversions = filterByReturnedFieldConversions(multiValueReturnFields,
404 fieldConversions);
405
406 List<String> toFieldNamesColl = new ArrayList<String>(returnedFieldConversions.values());
407 Collections.sort(toFieldNamesColl);
408 String[] toFieldNames = new String[toFieldNamesColl.size()];
409 toFieldNamesColl.toArray(toFieldNames);
410
411
412 String[] lineValues = StringUtils.split(lookupResultValues, ",");
413
414 List<Object> lineDataObjects = new ArrayList<Object>();
415
416 for (String lineValue : lineValues) {
417 Object lineDataObject = null;
418
419
420 ModuleService moduleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
421 collectionObjectClass);
422 if (moduleService != null && moduleService.isExternalizable(collectionObjectClass)) {
423 lineDataObject = moduleService.createNewObjectFromExternalizableClass(collectionObjectClass.asSubclass(
424 org.kuali.rice.krad.bo.ExternalizableBusinessObject.class));
425 } else {
426 lineDataObject = KRADUtils.createNewObjectFromClass(collectionObjectClass);
427 }
428
429 String[] fieldValues = StringUtils.splitByWholeSeparatorPreserveAllTokens(lineValue, ":");
430 if (fieldValues.length != toFieldNames.length) {
431 throw new RuntimeException(
432 "Value count passed back from multi-value lookup does not match field conversion count");
433 }
434
435
436 for (int i = 0; i < fieldValues.length; i++) {
437 String fieldName = toFieldNames[i];
438 ObjectPropertyUtils.setPropertyValue(lineDataObject, fieldName, fieldValues[i]);
439 }
440
441 lineDataObjects.add(lineDataObject);
442 processAndAddLineObject(viewModel, lineDataObject, collectionId, collectionPath);
443 }
444
445 viewModel.getViewPostMetadata().getAddedCollectionObjects().put(collectionId, lineDataObjects);
446 }
447
448
449
450
451
452
453
454
455
456
457
458 protected int addLine(Collection<Object> collection, Object addLine, boolean insertFirst) {
459 int index = -1;
460 if (insertFirst && (collection instanceof List)) {
461 ((List<Object>) collection).add(0, addLine);
462 index = 0;
463 } else {
464 boolean added = collection.add(addLine);
465 if (added) {
466 index = collection.size() - 1;
467 }
468 }
469 return index;
470 }
471
472 protected void linkAddedLine(Object model, String collectionPath, int addedIndex) {
473 int lastSepIndex = PropertyAccessorUtils.getLastNestedPropertySeparatorIndex(collectionPath);
474 if (lastSepIndex != -1) {
475 String collectionParentPath = collectionPath.substring(0, lastSepIndex);
476 Object parent = ObjectPropertyUtils.getPropertyValue(model, collectionParentPath);
477 if (parent != null && getDataObjectService().supports(parent.getClass())) {
478 DataObjectWrapper<?> wrappedParent = getDataObjectService().wrap(parent);
479 String collectionName = collectionPath.substring(lastSepIndex + 1);
480 wrappedParent.linkChanges(Sets.newHashSet(collectionName + "[" + addedIndex + "]"));
481 }
482 }
483 }
484
485
486
487
488
489
490
491
492
493 protected boolean performAddLineValidation(ViewModel viewModel, Object newLine, String collectionId,
494 String collectionPath) {
495 boolean isValid = true;
496
497 Collection<Object> collectionItems = ObjectPropertyUtils.getPropertyValue(viewModel, collectionPath);
498
499 if (viewModel.getViewPostMetadata().getComponentPostData(collectionId,
500 UifConstants.PostMetadata.DUPLICATE_LINE_PROPERTY_NAMES) == null) {
501 return isValid;
502 }
503
504 List<String> duplicateLinePropertyNames = (List<String>) viewModel.getViewPostMetadata().getComponentPostData(
505 collectionId, UifConstants.PostMetadata.DUPLICATE_LINE_PROPERTY_NAMES);
506
507 String collectionLabel = null;
508 if (viewModel.getViewPostMetadata().getComponentPostData(collectionId, UifConstants.PostMetadata.COLL_LABEL)
509 != null) {
510 collectionLabel = (String) viewModel.getViewPostMetadata().getComponentPostData(collectionId,
511 UifConstants.PostMetadata.COLL_LABEL);
512 }
513
514 String duplicateLineLabelString = null;
515 if (viewModel.getViewPostMetadata().getComponentPostData(collectionId,
516 UifConstants.PostMetadata.DUPLICATE_LINE_LABEL_STRING) != null) {
517 duplicateLineLabelString = (String) viewModel.getViewPostMetadata().getComponentPostData(collectionId,
518 UifConstants.PostMetadata.DUPLICATE_LINE_LABEL_STRING);
519 }
520
521 if (containsDuplicateLine(newLine, collectionItems, duplicateLinePropertyNames)) {
522 isValid = false;
523 GlobalVariables.getMessageMap().putErrorForSectionId(collectionId, RiceKeyConstants.ERROR_DUPLICATE_ELEMENT,
524 collectionLabel, duplicateLineLabelString);
525 }
526
527 return isValid;
528 }
529
530
531
532
533
534
535
536 private Map<String, String> filterByReturnedFieldConversions(String multiValueReturnFields,
537 Map<String, String> fieldConversions) {
538
539 Map <String, String> returnedFieldConversions = new HashMap<String, String>();
540 returnedFieldConversions.putAll(fieldConversions);
541
542
543 String[] returnedFieldsStrArr = StringUtils.split(multiValueReturnFields, ",");
544
545 if (returnedFieldsStrArr != null && returnedFieldsStrArr.length > 0) {
546 returnedFieldConversions.clear();
547 for (String fieldConversion : returnedFieldsStrArr) {
548 if (fieldConversions.containsKey(fieldConversion)) {
549 returnedFieldConversions.put(fieldConversion, fieldConversions.get(fieldConversion));
550 }
551 }
552 }
553
554 return returnedFieldConversions;
555 }
556
557
558
559
560
561
562
563
564
565
566 private boolean containsDuplicateLine(Object addLine, Collection<Object> collectionItems,
567 List<String> duplicateLinePropertyNames) {
568 if (collectionItems.isEmpty() || duplicateLinePropertyNames.isEmpty()) {
569 return false;
570 }
571
572 for (Object collectionItem : collectionItems) {
573 if (isDuplicateLine(addLine, collectionItem, duplicateLinePropertyNames)) {
574 return true;
575 }
576 }
577
578 return false;
579 }
580
581
582
583
584
585
586
587
588
589
590 private boolean isDuplicateLine(Object addLine, Object collectionItem, List<String> duplicateLinePropertyNames) {
591 if (duplicateLinePropertyNames.isEmpty()) {
592 return false;
593 }
594
595 for (String duplicateLinePropertyName : duplicateLinePropertyNames) {
596 Object addLinePropertyValue = ObjectPropertyUtils.getPropertyValue(addLine, duplicateLinePropertyName);
597 Object duplicateLinePropertyValue = ObjectPropertyUtils.getPropertyValue(collectionItem,
598 duplicateLinePropertyName);
599
600 if (!ObjectUtils.equals(addLinePropertyValue, duplicateLinePropertyValue)) {
601 return false;
602 }
603 }
604
605 return true;
606 }
607
608
609
610
611
612
613
614
615
616
617 protected boolean performDeleteLineValidation(ViewModel model, String collectionId, String collectionPath,
618 Object deleteLine) {
619 return true;
620 }
621
622
623
624
625 @Override
626 public void applyDefaultValuesForCollectionLine(CollectionGroup collectionGroup, Object line) {
627
628 List<DataField> dataFields = ViewLifecycleUtils.getElementsOfTypeDeep(collectionGroup.getAddLineItems(),
629 DataField.class);
630 for (DataField dataField : dataFields) {
631 String bindingPath = "";
632 if (StringUtils.isNotBlank(dataField.getBindingInfo().getBindByNamePrefix())) {
633 bindingPath = dataField.getBindingInfo().getBindByNamePrefix() + ".";
634 }
635 bindingPath += dataField.getBindingInfo().getBindingName();
636
637 populateDefaultValueForField(line, dataField, bindingPath);
638 }
639 }
640
641
642
643
644 @Override
645 public void applyDefaultValues(Component component) {
646 if (component == null) {
647 return;
648 }
649
650 View view = ViewLifecycle.getView();
651 Object model = ViewLifecycle.getModel();
652
653 @SuppressWarnings("unchecked") Queue<LifecycleElement> elementQueue = RecycleUtils.getInstance(
654 LinkedList.class);
655 elementQueue.offer(component);
656 try {
657 while (!elementQueue.isEmpty()) {
658 LifecycleElement currentElement = elementQueue.poll();
659
660
661 if (currentElement instanceof DataField) {
662 DataField dataField = ((DataField) currentElement);
663
664
665 dataField.getBindingInfo().setDefaults(view, dataField.getPropertyName());
666
667 populateDefaultValueForField(model, dataField, dataField.getBindingInfo().getBindingPath());
668 }
669
670 elementQueue.addAll(ViewLifecycleUtils.getElementsForLifecycle(currentElement).values());
671 }
672 } finally {
673 elementQueue.clear();
674 RecycleUtils.recycle(elementQueue);
675 }
676 }
677
678
679
680
681 @Override
682 public void populateViewFromRequestParameters(Map<String, String> parameters) {
683 View view = ViewLifecycle.getView();
684
685
686
687 Map<String, Set<PropertyReplacer>> viewPropertyReplacers = new HashMap<String, Set<PropertyReplacer>>();
688 List<PropertyReplacer> propertyReplacerSource = view.getPropertyReplacers();
689 if (propertyReplacerSource != null) {
690 for (PropertyReplacer replacer : propertyReplacerSource) {
691 String replacerPropertyName = replacer.getPropertyName();
692 Set<PropertyReplacer> propertyReplacers = viewPropertyReplacers.get(replacerPropertyName);
693
694 if (propertyReplacers == null) {
695 viewPropertyReplacers.put(replacerPropertyName,
696 propertyReplacers = new HashSet<PropertyReplacer>());
697 }
698
699 propertyReplacers.add(replacer);
700 }
701 }
702
703 Map<String, Annotation> annotatedFields = CloneUtils.getFieldsWithAnnotation(view.getClass(),
704 RequestParameter.class);
705
706
707
708 Map<String, String> viewRequestParameters = new HashMap<String, String>();
709 for (String fieldToPopulate : annotatedFields.keySet()) {
710 RequestParameter requestParameter = (RequestParameter) annotatedFields.get(fieldToPopulate);
711
712
713 String requestParameterName = requestParameter.parameterName();
714 if (StringUtils.isBlank(requestParameterName)) {
715 requestParameterName = fieldToPopulate;
716 }
717
718 if (!parameters.containsKey(requestParameterName)) {
719 continue;
720 }
721
722 String fieldValue = parameters.get(requestParameterName);
723 if (StringUtils.isNotBlank(fieldValue)) {
724 viewRequestParameters.put(requestParameterName, fieldValue);
725 ObjectPropertyUtils.setPropertyValue(view, fieldToPopulate, fieldValue);
726
727
728
729 if (view.getPropertyExpressions().containsKey(fieldToPopulate)) {
730 view.getPropertyExpressions().remove(fieldToPopulate);
731 }
732
733 if (viewPropertyReplacers.containsKey(fieldToPopulate)) {
734 Set<PropertyReplacer> propertyReplacers = viewPropertyReplacers.get(fieldToPopulate);
735 for (PropertyReplacer replacer : propertyReplacers) {
736 view.getPropertyReplacers().remove(replacer);
737 }
738 }
739 }
740 }
741
742 view.setViewRequestParameters(viewRequestParameters);
743 }
744
745
746
747
748 @Override
749 public String buildGrowlScript() {
750 View view = ViewLifecycle.getView();
751 String growlScript = "";
752
753 MessageService messageService = KRADServiceLocatorWeb.getMessageService();
754
755 MessageMap messageMap = GlobalVariables.getMessageMap();
756 for (GrowlMessage growl : messageMap.getGrowlMessages()) {
757 if (view.isGrowlMessagingEnabled()) {
758 String message = messageService.getMessageText(growl.getNamespaceCode(), growl.getComponentCode(),
759 growl.getMessageKey());
760
761 if (StringUtils.isNotBlank(message)) {
762 if (growl.getMessageParameters() != null) {
763 message = message.replace("'", "''");
764 message = MessageFormat.format(message, (Object[]) growl.getMessageParameters());
765 }
766
767
768 message = message.replace("'", "\\'");
769
770 String title = growl.getTitle();
771 if (StringUtils.isNotBlank(growl.getTitleKey())) {
772 title = messageService.getMessageText(growl.getNamespaceCode(), growl.getComponentCode(),
773 growl.getTitleKey());
774 }
775 title = title.replace("'", "\\'");
776
777 growlScript =
778 growlScript + "showGrowl('" + message + "', '" + title + "', '" + growl.getTheme() + "');";
779 }
780 } else {
781 ErrorMessage infoMessage = new ErrorMessage(growl.getMessageKey(), growl.getMessageParameters());
782 infoMessage.setNamespaceCode(growl.getNamespaceCode());
783 infoMessage.setComponentCode(growl.getComponentCode());
784
785 messageMap.putInfoForSectionId(KRADConstants.GLOBAL_INFO, infoMessage);
786 }
787 }
788
789 return growlScript;
790 }
791
792
793
794
795 @Override
796 public void populateDefaultValueForField(Object object, DataField dataField, String bindingPath) {
797
798 if (!ObjectPropertyUtils.isReadableProperty(object, bindingPath) || !ObjectPropertyUtils.isWritableProperty(
799 object, bindingPath)) {
800 return;
801 }
802 Object currentValue = ObjectPropertyUtils.getPropertyValue(object, bindingPath);
803 Object defaultValue = getDefaultValueForField(object, dataField);
804
805 if (defaultValue != null) {
806 ObjectPropertyUtils.setPropertyValue(object, bindingPath, defaultValue);
807 }
808 }
809
810
811
812
813 @Override
814 public Object getDefaultValueForField(Object object, DataField dataField) {
815 View view = ViewLifecycle.getView();
816 Object defaultValue = null;
817
818
819 if (dataField.getDefaultValue() != null && !(dataField.getDefaultValue() instanceof String && StringUtils
820 .isBlank((String) dataField.getDefaultValue()))) {
821 defaultValue = dataField.getDefaultValue();
822 } else if ((dataField.getExpressionGraph() != null) && dataField.getExpressionGraph().containsKey(
823 UifConstants.ComponentProperties.DEFAULT_VALUE)) {
824 defaultValue = dataField.getExpressionGraph().get(UifConstants.ComponentProperties.DEFAULT_VALUE);
825 } else if (dataField.getDefaultValueFinderClass() != null) {
826 ValueFinder defaultValueFinder = KRADUtils.createNewObjectFromClass(dataField.getDefaultValueFinderClass());
827
828 defaultValue = defaultValueFinder.getValue();
829 } else if ((dataField.getExpressionGraph() != null) && dataField.getExpressionGraph().containsKey(
830 UifConstants.ComponentProperties.DEFAULT_VALUES)) {
831 defaultValue = dataField.getExpressionGraph().get(UifConstants.ComponentProperties.DEFAULT_VALUES);
832 } else if (dataField.getDefaultValues() != null) {
833 defaultValue = dataField.getDefaultValues();
834 }
835
836 ExpressionEvaluator expressionEvaluator = ViewLifecycle.getExpressionEvaluator();
837
838 if ((defaultValue != null) && (defaultValue instanceof String) && expressionEvaluator.containsElPlaceholder(
839 (String) defaultValue)) {
840 Map<String, Object> context = new HashMap<String, Object>(view.getPreModelContext());
841 context.putAll(dataField.getContext());
842
843 defaultValue = expressionEvaluator.replaceBindingPrefixes(view, object, (String) defaultValue);
844 defaultValue = expressionEvaluator.evaluateExpressionTemplate(context, (String) defaultValue);
845 }
846
847 return defaultValue;
848 }
849
850
851
852
853 @Override
854 public void refreshReference(Object parentObject, String referenceObjectName) {
855 if (!(parentObject instanceof PersistableBusinessObject)) {
856 LOG.warn("Could not refresh reference " + referenceObjectName + " off class " + parentObject.getClass()
857 .getName() + ". Class not of type PersistableBusinessObject");
858 return;
859 }
860
861 LegacyDataAdapter legacyDataAdapter = KRADServiceLocatorWeb.getLegacyDataAdapter();
862 DataDictionaryService dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
863
864 if (legacyDataAdapter.hasReference(parentObject.getClass(), referenceObjectName) || legacyDataAdapter
865 .hasCollection(parentObject.getClass(), referenceObjectName)) {
866
867 legacyDataAdapter.retrieveReferenceObject(parentObject, referenceObjectName);
868 } else if (dataDictionaryService.hasRelationship(parentObject.getClass().getName(), referenceObjectName)) {
869
870 Object referenceObject = KradDataServiceLocator.getDataObjectService().wrap(parentObject).getPropertyValue(
871 referenceObjectName);
872 if (!(referenceObject instanceof PersistableBusinessObject)) {
873 LOG.warn("Could not refresh reference " + referenceObjectName + " off class " + parentObject.getClass()
874 .getName() + ". Class not of type PersistableBusinessObject");
875 return;
876 }
877
878 referenceObject = legacyDataAdapter.retrieve((PersistableBusinessObject) referenceObject);
879 if (referenceObject == null) {
880 LOG.warn("Could not refresh reference " + referenceObjectName + " off class " + parentObject.getClass()
881 .getName() + ".");
882 return;
883 }
884
885 try {
886 KRADUtils.setObjectProperty(parentObject, referenceObjectName, referenceObject);
887 } catch (Exception e) {
888 LOG.error("Unable to refresh persistable business object: " + referenceObjectName + "\n" + e
889 .getMessage());
890 throw new RuntimeException(
891 "Unable to refresh persistable business object: " + referenceObjectName + "\n" + e
892 .getMessage());
893 }
894 } else {
895 LOG.warn("Could not refresh reference " + referenceObjectName + " off class " + parentObject.getClass()
896 .getName() + ".");
897 }
898 }
899
900
901
902
903 @Override
904 public void refreshReferences(String referencesToRefresh) {
905 Object model = ViewLifecycle.getModel();
906 for (String reference : StringUtils.split(referencesToRefresh, KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR)) {
907 if (StringUtils.isBlank(reference)) {
908 continue;
909 }
910
911
912
913 if (PropertyAccessorUtils.isNestedOrIndexedProperty(reference)) {
914 String parentPath = KRADUtils.getNestedAttributePrefix(reference);
915 Object parentObject = ObjectPropertyUtils.getPropertyValue(model, parentPath);
916 String referenceObjectName = KRADUtils.getNestedAttributePrimitive(reference);
917
918 if (parentObject == null) {
919 LOG.warn("Unable to refresh references for " + referencesToRefresh +
920 ". Object not found in model. Nothing refreshed.");
921 continue;
922 }
923
924 refreshReference(parentObject, referenceObjectName);
925 } else {
926 refreshReference(model, reference);
927 }
928 }
929 }
930
931
932
933
934 @Override
935 public void retrieveEditModesAndActionFlags() {
936 View view = ViewLifecycle.getView();
937 UifFormBase model = (UifFormBase) ViewLifecycle.getModel();
938 ViewPresentationController presentationController = view.getPresentationController();
939 ViewAuthorizer authorizer = view.getAuthorizer();
940
941 Set<String> actionFlags = presentationController.getActionFlags(view, model);
942 Set<String> editModes = presentationController.getEditModes(view, model);
943
944
945 if (GlobalVariables.getUserSession() != null) {
946 Person user = GlobalVariables.getUserSession().getPerson();
947
948 actionFlags = authorizer.getActionFlags(view, model, user, actionFlags);
949 editModes = authorizer.getEditModes(view, model, user, editModes);
950 }
951
952 view.setActionFlags(new BooleanMap(actionFlags));
953 view.setEditModes(new BooleanMap(editModes));
954 }
955
956
957
958
959 @Override
960 public void setViewContext() {
961 View view = ViewLifecycle.getView();
962 view.pushAllToContext(view.getPreModelContext());
963
964
965 for (Entry<String, String> variableExpression : view.getExpressionVariables().entrySet()) {
966 String variableName = variableExpression.getKey();
967 Object value = ViewLifecycle.getExpressionEvaluator().evaluateExpression(view.getContext(),
968 variableExpression.getValue());
969 view.pushObjectToContext(variableName, value);
970 }
971 }
972
973
974
975
976
977
978 protected ConfigurationService getConfigurationService() {
979 if (this.configurationService == null) {
980 this.configurationService = CoreApiServiceLocator.getKualiConfigurationService();
981 }
982 return this.configurationService;
983 }
984
985
986
987
988
989
990 public void setConfigurationService(ConfigurationService configurationService) {
991 this.configurationService = configurationService;
992 }
993
994
995
996
997
998
999 protected DataDictionaryService getDataDictionaryService() {
1000 if (this.dataDictionaryService == null) {
1001 this.dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
1002 }
1003
1004 return this.dataDictionaryService;
1005 }
1006
1007
1008
1009
1010
1011
1012 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
1013 this.dataDictionaryService = dataDictionaryService;
1014 }
1015
1016
1017
1018
1019
1020
1021 protected ViewDictionaryService getViewDictionaryService() {
1022 if (this.viewDictionaryService == null) {
1023 this.viewDictionaryService = KRADServiceLocatorWeb.getViewDictionaryService();
1024 }
1025 return this.viewDictionaryService;
1026 }
1027
1028
1029
1030
1031
1032
1033 public void setViewDictionaryService(ViewDictionaryService viewDictionaryService) {
1034 this.viewDictionaryService = viewDictionaryService;
1035 }
1036
1037
1038
1039
1040 @Override
1041 public ExpressionEvaluatorFactory getExpressionEvaluatorFactory() {
1042 if (expressionEvaluatorFactory == null) {
1043 expressionEvaluatorFactory = KRADServiceLocatorWeb.getExpressionEvaluatorFactory();
1044 }
1045
1046 return expressionEvaluatorFactory;
1047 }
1048
1049
1050
1051
1052
1053
1054 public void setExpressionEvaluatorFactory(ExpressionEvaluatorFactory expressionEvaluatorFactory) {
1055 this.expressionEvaluatorFactory = expressionEvaluatorFactory;
1056 }
1057
1058
1059
1060
1061
1062
1063 protected LegacyDataAdapter getLegacyDataAdapter() {
1064 if (legacyDataAdapter == null) {
1065 legacyDataAdapter = KRADServiceLocatorWeb.getLegacyDataAdapter();
1066 }
1067 return legacyDataAdapter;
1068 }
1069
1070 protected DataObjectService getDataObjectService() {
1071 if (dataObjectService == null) {
1072 dataObjectService = KRADServiceLocator.getDataObjectService();
1073 }
1074 return dataObjectService;
1075 }
1076
1077 protected void setDataObjectService(DataObjectService dataObjectService) {
1078 this.dataObjectService = dataObjectService;
1079 }
1080
1081
1082
1083
1084
1085
1086 public void setLegacyDataAdapter(LegacyDataAdapter legacyDataAdapter) {
1087 this.legacyDataAdapter = legacyDataAdapter;
1088 }
1089
1090
1091
1092
1093
1094
1095 protected void logAndThrowRuntime(String message) {
1096 LOG.error(message);
1097 throw new RuntimeException(message);
1098 }
1099
1100 }