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