1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.lookup;
17
18 import org.apache.commons.beanutils.PropertyUtils;
19 import org.apache.commons.lang.BooleanUtils;
20 import org.apache.commons.lang.StringUtils;
21 import org.kuali.rice.core.api.CoreApiServiceLocator;
22 import org.kuali.rice.core.api.config.property.ConfigurationService;
23 import org.kuali.rice.core.api.encryption.EncryptionService;
24 import org.kuali.rice.core.api.search.SearchOperator;
25 import org.kuali.rice.core.api.util.RiceKeyConstants;
26 import org.kuali.rice.core.api.util.type.TypeUtils;
27 import org.kuali.rice.kim.api.identity.Person;
28 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
29 import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
30 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
31 import org.kuali.rice.krad.service.DataObjectAuthorizationService;
32 import org.kuali.rice.krad.service.DataObjectMetaDataService;
33 import org.kuali.rice.krad.service.DocumentDictionaryService;
34 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
35 import org.kuali.rice.krad.service.LookupService;
36 import org.kuali.rice.krad.service.ModuleService;
37 import org.kuali.rice.krad.uif.UifConstants;
38 import org.kuali.rice.krad.uif.UifParameters;
39 import org.kuali.rice.krad.uif.UifPropertyPaths;
40 import org.kuali.rice.krad.uif.control.Control;
41 import org.kuali.rice.krad.uif.control.HiddenControl;
42 import org.kuali.rice.krad.uif.control.ValueConfiguredControl;
43 import org.kuali.rice.krad.uif.element.Action;
44 import org.kuali.rice.krad.uif.field.InputField;
45 import org.kuali.rice.krad.uif.field.LookupInputField;
46 import org.kuali.rice.krad.uif.service.impl.ViewHelperServiceImpl;
47 import org.kuali.rice.krad.uif.util.ComponentUtils;
48 import org.kuali.rice.krad.uif.util.LookupInquiryUtils;
49 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
50 import org.kuali.rice.krad.uif.view.LookupView;
51 import org.kuali.rice.krad.uif.view.View;
52 import org.kuali.rice.krad.util.BeanPropertyComparator;
53 import org.kuali.rice.krad.util.GlobalVariables;
54 import org.kuali.rice.krad.util.KRADConstants;
55 import org.kuali.rice.krad.util.KRADUtils;
56 import org.kuali.rice.krad.util.ObjectUtils;
57 import org.kuali.rice.krad.util.UrlFactory;
58 import org.kuali.rice.krad.web.form.LookupForm;
59
60 import java.security.GeneralSecurityException;
61 import java.util.ArrayList;
62 import java.util.Collection;
63 import java.util.Collections;
64 import java.util.HashMap;
65 import java.util.List;
66 import java.util.Map;
67 import java.util.Properties;
68
69
70
71
72
73
74 public class LookupableImpl extends ViewHelperServiceImpl implements Lookupable {
75 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LookupableImpl.class);
76
77 private Class<?> dataObjectClass;
78
79 private transient ConfigurationService configurationService;
80 private transient DataObjectAuthorizationService dataObjectAuthorizationService;
81 private transient DataObjectMetaDataService dataObjectMetaDataService;
82 private transient DocumentDictionaryService documentDictionaryService;
83 private transient LookupService lookupService;
84 private transient EncryptionService encryptionService;
85
86
87
88
89
90
91
92
93
94 @Override
95 public void performInitialization(View view, Object model) {
96 if (!LookupView.class.isAssignableFrom(view.getClass())) {
97 throw new IllegalArgumentException(
98 "View class '" + view.getClass() + " is not assignable from the '" + LookupView.class + "'");
99 }
100
101 LookupView lookupView = (LookupView) view;
102 setDataObjectClass(lookupView.getDataObjectClassName());
103
104 super.performInitialization(view, model);
105 }
106
107
108
109
110 @Override
111 public void initSuppressAction(LookupForm lookupForm) {
112 LookupViewAuthorizerBase lookupAuthorizer = (LookupViewAuthorizerBase) lookupForm.getView().getAuthorizer();
113 Person user = GlobalVariables.getUserSession().getPerson();
114 ((LookupView) lookupForm.getView()).setSuppressActions(!lookupAuthorizer.canInitiateDocument(lookupForm, user));
115 }
116
117
118
119
120 @Override
121 public Collection<?> performSearch(LookupForm form, Map<String, String> searchCriteria, boolean bounded) {
122 Collection<?> displayList;
123
124
125 displayList = getSearchResults(form, LookupUtils.forceUppercase(getDataObjectClass(), searchCriteria),
126 !bounded);
127
128
129 for (Object object : displayList) {
130 if (isResultReturnable(object)) {
131 form.setAtLeastOneRowReturnable(true);
132 }
133 }
134
135 return displayList;
136 }
137
138
139
140
141
142
143
144
145
146
147 protected List<?> getSearchResults(LookupForm form, Map<String, String> searchCriteria, boolean unbounded) {
148 Collection<?> searchResults;
149
150
151 Map<String, String> nonBlankSearchCriteria = processSearchCriteria(form, searchCriteria);
152
153
154
155 if (nonBlankSearchCriteria == null) {
156 return new ArrayList<Object>();
157 }
158
159
160 if (ExternalizableBusinessObject.class.isAssignableFrom(getDataObjectClass())) {
161 return getSearchResultsForEBO(nonBlankSearchCriteria, unbounded);
162 }
163
164
165
166 try {
167 Integer searchResultsLimit = null;
168
169 if (!unbounded) {
170 searchResultsLimit = LookupUtils.getSearchResultsLimit(getDataObjectClass(), form);
171 }
172
173 if (LookupUtils.hasExternalBusinessObjectProperty(getDataObjectClass(), nonBlankSearchCriteria)) {
174 Map<String, String> eboSearchCriteria = adjustCriteriaForNestedEBOs(nonBlankSearchCriteria, unbounded);
175
176 if (LOG.isDebugEnabled()) {
177 LOG.debug("Passing these results into the lookup service: " + eboSearchCriteria);
178 }
179
180
181 searchResults = getLookupService().findCollectionBySearchHelper(getDataObjectClass(), eboSearchCriteria,
182 unbounded, searchResultsLimit);
183 generateLookupResultsMessages(form, eboSearchCriteria, searchResults, unbounded);
184 } else {
185 searchResults = getLookupService().findCollectionBySearchHelper(getDataObjectClass(),
186 nonBlankSearchCriteria, unbounded, searchResultsLimit);
187 generateLookupResultsMessages(form, nonBlankSearchCriteria, searchResults, unbounded);
188 }
189
190 } catch (IllegalAccessException e) {
191 throw new RuntimeException("Error trying to perform search", e);
192 } catch (InstantiationException e1) {
193 throw new RuntimeException("Error trying to perform search", e1);
194 }
195
196 if (searchResults == null) {
197 searchResults = new ArrayList<Object>();
198 } else {
199 sortSearchResults(form, (List<?>) searchResults);
200 }
201
202 return (List<?>) searchResults;
203 }
204
205
206
207
208
209
210
211 public void generateErrorMessageForResults(LookupForm form, String messageToDisplay) {
212 GlobalVariables.getMessageMap().putErrorForSectionId("LookupResultMessages", messageToDisplay);
213 }
214
215
216
217
218
219
220
221
222
223 protected void generateLookupResultsMessages(LookupForm form, Map<String, String> searchCriteria,
224 Collection<?> searchResult, boolean unbounded) {
225 String resultsPropertyName = "LookupResultMessages";
226 List<String> pkLabels = new ArrayList<String>();
227
228 Boolean usingPrimaryKey = getLookupService().allPrimaryKeyValuesPresentAndNotWildcard(getDataObjectClass(),
229 (Map<String, String>) searchCriteria);
230
231 Integer searchResultsLimit = LookupUtils.getSearchResultsLimit(getDataObjectClass(), form);
232 Long searchResultsSize = Long.valueOf(0);
233
234 if (searchResult instanceof CollectionIncomplete
235 && ((CollectionIncomplete) searchResult).getActualSizeIfTruncated() > 0) {
236 searchResultsSize = ((CollectionIncomplete) searchResult).getActualSizeIfTruncated();
237 } else if (searchResult != null) {
238 searchResultsSize = Long.valueOf(searchResult.size());
239 }
240
241 Boolean resultsExceedsLimit = !unbounded
242 && searchResultsLimit != null
243 && searchResultsSize > 0
244 && searchResultsSize > searchResultsLimit ? true : false;
245
246 if (usingPrimaryKey) {
247 List<String> pkNames = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
248 for (String pkName : pkNames) {
249 pkLabels.add(getDataDictionaryService().getAttributeLabel(getDataObjectClass(), pkName));
250 }
251
252 GlobalVariables.getMessageMap().putInfoForSectionId(resultsPropertyName,
253 RiceKeyConstants.INFO_LOOKUP_RESULTS_USING_PRIMARY_KEY, StringUtils.join(pkLabels, ","));
254 }
255
256 if (searchResultsSize == 0) {
257 GlobalVariables.getMessageMap().putInfoForSectionId(resultsPropertyName,
258 RiceKeyConstants.INFO_LOOKUP_RESULTS_NONE_FOUND);
259 } else if (searchResultsSize == 1) {
260 GlobalVariables.getMessageMap().putInfoForSectionId(resultsPropertyName,
261 RiceKeyConstants.INFO_LOOKUP_RESULTS_DISPLAY_ONE);
262 } else if (searchResultsSize > 1) {
263 if (resultsExceedsLimit) {
264 GlobalVariables.getMessageMap().putInfoForSectionId(resultsPropertyName,
265 RiceKeyConstants.INFO_LOOKUP_RESULTS_EXCEEDS_LIMIT, searchResultsSize.toString(),
266 searchResultsLimit.toString());
267 } else {
268 GlobalVariables.getMessageMap().putInfoForSectionId(resultsPropertyName,
269 RiceKeyConstants.INFO_LOOKUP_RESULTS_DISPLAY_ALL, searchResultsSize.toString());
270 }
271 }
272 }
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 protected void sortSearchResults(LookupForm form, List<?> searchResults) {
290 List<String> defaultSortColumns = null;
291 boolean defaultSortAscending = true;
292
293
294 if (form.getPostedView() != null) {
295 defaultSortColumns = ((LookupView) form.getPostedView()).getDefaultSortAttributeNames();
296 defaultSortAscending = ((LookupView) form.getPostedView()).isDefaultSortAscending();
297 }
298
299 else if (form.getView() != null) {
300 defaultSortColumns = ((LookupView) form.getView()).getDefaultSortAttributeNames();
301 defaultSortAscending = ((LookupView) form.getView()).isDefaultSortAscending();
302 boolean hasExpression = false;
303 if (defaultSortColumns != null) {
304 for (String sortColumn : defaultSortColumns) {
305 if (sortColumn == null) {
306 hasExpression = true;
307 }
308 }
309 }
310
311 if (hasExpression) {
312 defaultSortColumns = null;
313 }
314 }
315
316 if ((defaultSortColumns != null) && (!defaultSortColumns.isEmpty())) {
317 BeanPropertyComparator comparator = new BeanPropertyComparator(defaultSortColumns, true);
318 if (defaultSortAscending) {
319 Collections.sort(searchResults, comparator);
320 } else {
321 Collections.sort(searchResults, Collections.reverseOrder(comparator));
322 }
323 }
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338 protected Map<String, String> processSearchCriteria(LookupForm lookupForm, Map<String, String> searchCriteria) {
339 Map<String, InputField> criteriaFields = new HashMap<String, InputField>();
340 if (lookupForm.getPostedView() != null) {
341 criteriaFields = getCriteriaFieldsForValidation((LookupView) lookupForm.getPostedView(), lookupForm);
342 }
343
344 Map<String, String> filteredSearchCriteria = new HashMap<String, String>(searchCriteria);
345 for (String fieldName : searchCriteria.keySet()) {
346 InputField inputField = criteriaFields.get(fieldName);
347 if ((inputField == null) || !(inputField instanceof LookupInputField)) {
348 continue;
349 }
350
351 filteredSearchCriteria = ((LookupInputField) inputField).filterSearchCriteria(filteredSearchCriteria);
352 if (filteredSearchCriteria == null) {
353 return null;
354 }
355 }
356
357 Map<String, String> nonBlankSearchCriteria = new HashMap<String, String>();
358 for (String fieldName : filteredSearchCriteria.keySet()) {
359 String fieldValue = filteredSearchCriteria.get(fieldName);
360
361
362 InputField inputField = criteriaFields.get(fieldName);
363 if ((inputField != null) && (inputField.getControl() instanceof HiddenControl)) {
364 continue;
365 }
366
367
368 if (StringUtils.isNotBlank(fieldValue)) {
369 if (fieldValue.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
370 String encryptedValue = StringUtils.removeEnd(fieldValue, EncryptionService.ENCRYPTION_POST_PREFIX);
371 try {
372 if (CoreApiServiceLocator.getEncryptionService().isEnabled()) {
373 fieldValue = getEncryptionService().decrypt(encryptedValue);
374 }
375 } catch (GeneralSecurityException e) {
376 LOG.error("Error decrypting value for business object class " + getDataObjectClass() +
377 " attribute " + fieldName, e);
378 throw new RuntimeException(
379 "Error decrypting value for business object class " + getDataObjectClass() +
380 " attribute " + fieldName, e);
381 }
382 }
383
384 nonBlankSearchCriteria.put(fieldName, fieldValue);
385 }
386 }
387
388 return nonBlankSearchCriteria;
389 }
390
391
392
393
394
395
396
397
398
399 protected List<?> getSearchResultsForEBO(Map<String, String> searchCriteria, boolean unbounded) {
400 ModuleService eboModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
401 getDataObjectClass());
402 BusinessObjectEntry ddEntry = eboModuleService.getExternalizableBusinessObjectDictionaryEntry(
403 getDataObjectClass());
404
405 Map<String, String> filteredFieldValues = new HashMap<String, String>();
406 for (String fieldName : searchCriteria.keySet()) {
407 if (ddEntry.getAttributeNames().contains(fieldName)) {
408 filteredFieldValues.put(fieldName, searchCriteria.get(fieldName));
409 }
410 }
411
412 List<?> searchResults = eboModuleService.getExternalizableBusinessObjectsListForLookup(
413 (Class<? extends ExternalizableBusinessObject>) getDataObjectClass(), (Map) filteredFieldValues,
414 unbounded);
415
416 return searchResults;
417 }
418
419
420
421
422
423
424
425
426
427 protected Map<String, String> adjustCriteriaForNestedEBOs(Map<String, String> searchCriteria,
428 boolean unbounded) throws InstantiationException, IllegalAccessException {
429 if (LOG.isDebugEnabled()) {
430 LOG.debug("has EBO reference: " + getDataObjectClass());
431 LOG.debug("properties: " + searchCriteria);
432 }
433
434
435 Map<String, String> nonEboFieldValues = LookupUtils.removeExternalizableBusinessObjectFieldValues(
436 getDataObjectClass(), searchCriteria);
437 if (LOG.isDebugEnabled()) {
438 LOG.debug("Non EBO properties removed: " + nonEboFieldValues);
439 }
440
441
442 List<String> eboPropertyNames = LookupUtils.getExternalizableBusinessObjectProperties(getDataObjectClass(),
443 searchCriteria);
444 if (LOG.isDebugEnabled()) {
445 LOG.debug("EBO properties: " + eboPropertyNames);
446 }
447
448
449 for (String eboPropertyName : eboPropertyNames) {
450
451 Map<String, String> eboFieldValues = LookupUtils.getExternalizableBusinessObjectFieldValues(eboPropertyName,
452 searchCriteria);
453 if (LOG.isDebugEnabled()) {
454 LOG.debug("EBO properties for master EBO property: " + eboPropertyName);
455 LOG.debug("properties: " + eboFieldValues);
456 }
457
458
459 ModuleService eboModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
460 LookupUtils.getExternalizableBusinessObjectClass(getDataObjectClass(), eboPropertyName));
461
462
463
464 List<?> eboResults = Collections.emptyList();
465 if (eboModuleService != null) {
466 eboResults = eboModuleService.getExternalizableBusinessObjectsListForLookup(
467 LookupUtils.getExternalizableBusinessObjectClass(getDataObjectClass(), eboPropertyName),
468 (Map) eboFieldValues, unbounded);
469 } else {
470 LOG.debug("EBO ModuleService is null: " + eboPropertyName);
471 }
472
473
474
475
476
477 Class<?> eboParentClass;
478 String eboParentPropertyName;
479 if (ObjectUtils.isNestedAttribute(eboPropertyName)) {
480 eboParentPropertyName = StringUtils.substringBeforeLast(eboPropertyName, ".");
481 try {
482 eboParentClass = PropertyUtils.getPropertyType(getDataObjectClass().newInstance(),
483 eboParentPropertyName);
484 } catch (Exception ex) {
485 throw new RuntimeException(
486 "Unable to create an instance of the business object class: " + getDataObjectClass()
487 .getName(), ex);
488 }
489 } else {
490 eboParentClass = getDataObjectClass();
491 eboParentPropertyName = null;
492 }
493
494 if (LOG.isDebugEnabled()) {
495 LOG.debug("determined EBO parent class/property name: " + eboParentClass + "/" + eboParentPropertyName);
496 }
497
498
499
500
501
502 RelationshipDefinition rd = getDataObjectMetaDataService().getDictionaryRelationship(eboParentClass,
503 eboPropertyName);
504 if (LOG.isDebugEnabled()) {
505 LOG.debug("Obtained RelationshipDefinition for " + eboPropertyName);
506 LOG.debug(rd);
507 }
508
509
510
511
512
513
514
515 if (ObjectUtils.isNotNull(rd)) {
516 if (rd.getPrimitiveAttributes().size() > 1) {
517 throw new RuntimeException(
518 "EBO Links don't work for relationships with multiple-field primary keys.");
519 }
520 String boProperty = rd.getPrimitiveAttributes().get(0).getSourceName();
521 String eboProperty = rd.getPrimitiveAttributes().get(0).getTargetName();
522 StringBuffer boPropertyValue = new StringBuffer();
523
524
525
526
527 for (Object ebo : eboResults) {
528 if (boPropertyValue.length() != 0) {
529 boPropertyValue.append(SearchOperator.OR.op());
530 }
531 try {
532 boPropertyValue.append(PropertyUtils.getProperty(ebo, eboProperty).toString());
533 } catch (Exception ex) {
534 LOG.warn("Unable to get value for " + eboProperty + " on " + ebo);
535 }
536 }
537
538 if (eboParentPropertyName == null) {
539
540 nonEboFieldValues.put(boProperty, boPropertyValue.toString());
541 } else {
542
543
544 nonEboFieldValues.put(eboParentPropertyName + "." + boProperty, boPropertyValue.toString());
545 }
546 }
547 }
548
549 return nonEboFieldValues;
550 }
551
552
553
554
555 @Override
556 public Map<String, String> performClear(LookupForm form, Map<String, String> searchCriteria) {
557 Map<String, InputField> criteriaFieldMap = new HashMap<String, InputField>();
558 if (form.getPostedView() == null) {
559 criteriaFieldMap = getCriteriaFieldsForValidation((LookupView) form.getPostedView(), form);
560 }
561
562 List<String> readOnlyFieldsList = form.getReadOnlyFieldsList();
563
564 Map<String, String> clearedSearchCriteria = new HashMap<String, String>();
565 for (Map.Entry<String, String> searchKeyValue : searchCriteria.entrySet()) {
566 String searchPropertyName = searchKeyValue.getKey();
567
568 InputField inputField = criteriaFieldMap.get(searchPropertyName);
569
570 if (readOnlyFieldsList != null && readOnlyFieldsList.contains(searchPropertyName)) {
571 clearedSearchCriteria.put(searchPropertyName, searchKeyValue.getValue());
572 } else if (inputField != null) {
573
574
575
576
577
578
579
580
581
582 clearedSearchCriteria.put(searchPropertyName, inputField.getDefaultValue());
583 } else {
584 clearedSearchCriteria.put(searchPropertyName, "");
585 }
586 }
587
588 return clearedSearchCriteria;
589 }
590
591
592
593
594 @Override
595 public boolean validateSearchParameters(LookupForm form, Map<String, String> searchCriteria) {
596 boolean valid = true;
597
598
599
600 if (form.getPostedView() == null) {
601 return valid;
602 }
603
604 Map<String, InputField> criteriaFields = getCriteriaFieldsForValidation((LookupView) form.getPostedView(),
605 form);
606
607
608 List<String> hiddenCriteria = new ArrayList<String>();
609 for (InputField field : criteriaFields.values()) {
610 if (field.getAdditionalHiddenPropertyNames() != null) {
611 hiddenCriteria.addAll(field.getAdditionalHiddenPropertyNames());
612 }
613 }
614
615
616
617 for (Map.Entry<String, String> searchKeyValue : searchCriteria.entrySet()) {
618 String searchPropertyName = searchKeyValue.getKey();
619 String searchPropertyValue = searchKeyValue.getValue();
620
621 InputField inputField = criteriaFields.get(searchPropertyName);
622
623 String adjustedSearchPropertyPath = UifPropertyPaths.LOOKUP_CRITERIA + "[" + searchPropertyName + "]";
624 if (inputField == null && hiddenCriteria.contains(adjustedSearchPropertyPath)) {
625 return valid;
626 }
627
628
629 if ((inputField == null) && !searchPropertyName.contains(
630 KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
631 throw new RuntimeException("Invalid search field sent for property name: " + searchPropertyName);
632 }
633
634 if (inputField != null) {
635 if (StringUtils.isBlank(searchPropertyValue) && inputField.getRequired()) {
636 GlobalVariables.getMessageMap().putError(inputField.getPropertyName(),
637 RiceKeyConstants.ERROR_REQUIRED, inputField.getLabel());
638 }
639
640 validateSearchParameterWildcardAndOperators(inputField, searchPropertyValue);
641 }
642 }
643 if (GlobalVariables.getMessageMap().hasErrors()) {
644 valid = false;
645 }
646
647 return valid;
648 }
649
650
651
652
653
654
655
656
657 protected Map<String, InputField> getCriteriaFieldsForValidation(LookupView lookupView, LookupForm form) {
658 Map<String, InputField> criteriaFieldMap = new HashMap<String, InputField>();
659
660 if (lookupView.getCriteriaFields() == null) {
661 return criteriaFieldMap;
662 }
663
664
665
666 List<InputField> fields = ComponentUtils.getComponentsOfTypeDeep(lookupView.getCriteriaFields(),
667 InputField.class);
668 for (InputField field : fields) {
669 criteriaFieldMap.put(field.getPropertyName(), field);
670 }
671
672 return criteriaFieldMap;
673 }
674
675
676
677
678
679
680
681
682 protected void validateSearchParameterWildcardAndOperators(InputField inputField, String searchPropertyValue) {
683 if (StringUtils.isBlank(searchPropertyValue)) {
684 return;
685 }
686
687
688 boolean found = false;
689 for (SearchOperator op : SearchOperator.QUERY_CHARACTERS) {
690 String queryCharacter = op.op();
691
692 if (searchPropertyValue.contains(queryCharacter)) {
693 found = true;
694 }
695 }
696
697 if (!found) {
698 return;
699 }
700
701 String attributeLabel = inputField.getLabel();
702 if ((LookupInputField.class.isAssignableFrom(inputField.getClass())) && (((LookupInputField) inputField)
703 .isDisableWildcardsAndOperators())) {
704 Object dataObjectExample = null;
705 try {
706 dataObjectExample = getDataObjectClass().newInstance();
707 } catch (Exception e) {
708 LOG.error("Exception caught instantiating " + getDataObjectClass().getName(), e);
709 throw new RuntimeException("Cannot instantiate " + getDataObjectClass().getName(), e);
710 }
711
712 Class<?> propertyType = ObjectPropertyUtils.getPropertyType(getDataObjectClass(),
713 inputField.getPropertyName());
714 if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ||
715 TypeUtils.isTemporalClass(propertyType)) {
716 GlobalVariables.getMessageMap().putError(inputField.getPropertyName(),
717 RiceKeyConstants.ERROR_WILDCARDS_AND_OPERATORS_NOT_ALLOWED_ON_FIELD, attributeLabel);
718 }
719
720 if (TypeUtils.isStringClass(propertyType)) {
721 GlobalVariables.getMessageMap().putInfo(inputField.getPropertyName(),
722 RiceKeyConstants.INFO_WILDCARDS_AND_OPERATORS_TREATED_LITERALLY, attributeLabel);
723 }
724 } else {
725 if (getDataObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(
726 getDataObjectClass(), inputField.getPropertyName())) {
727 if (!searchPropertyValue.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
728
729
730
731
732
733
734 GlobalVariables.getMessageMap().putError(inputField.getPropertyName(),
735 RiceKeyConstants.ERROR_SECURE_FIELD, attributeLabel);
736 }
737 }
738 }
739 }
740
741
742
743
744 public void getReturnUrlForResults(Action returnLink, Object model) {
745 LookupForm lookupForm = (LookupForm) model;
746
747 Map<String, Object> returnLinkContext = returnLink.getContext();
748 LookupView lookupView = returnLinkContext == null ? null : (LookupView) returnLinkContext
749 .get(UifConstants.ContextVariableNames.VIEW);
750 Object dataObject = returnLinkContext == null ? null : returnLinkContext
751 .get(UifConstants.ContextVariableNames.LINE);
752
753
754 if ((dataObject == null) || (!isResultReturnable(dataObject))) {
755 returnLink.setRender(false);
756 return;
757 }
758
759
760 String href = getReturnUrl(lookupView, lookupForm, dataObject);
761 if (StringUtils.isBlank(href)) {
762 returnLink.setRender(false);
763 return;
764 }
765
766
767 String linkLabel = getConfigurationService().getPropertyValueAsString(
768 KRADConstants.Lookup.TITLE_RETURN_URL_PREPENDTEXT_PROPERTY);
769 returnLink.setActionLabel(linkLabel);
770
771 List<String> returnKeys = getReturnKeys(lookupView, lookupForm, dataObject);
772 List<String> secureReturnKeys = lookupView.getAdditionalSecurePropertyNames();
773 Map<String, String> returnKeyValues = KRADUtils.getPropertyKeyValuesFromDataObject(returnKeys, secureReturnKeys, dataObject);
774
775 String title = LookupInquiryUtils.getLinkTitleText(linkLabel, getDataObjectClass(), returnKeyValues);
776 returnLink.setTitle(title);
777
778
779 String returnTarget = lookupView.getReturnTarget();
780 if (returnTarget != null) {
781 returnLink.setActionScript("window.open(\"" + href + "\", '" + returnTarget + "');");
782
783
784 if (!returnTarget.equals("_self")) {
785
786 if (lookupView.isReturnByScript()) {
787 Properties props = getReturnUrlParameters(lookupView, lookupForm, dataObject);
788
789 StringBuilder script = new StringBuilder("e.preventDefault();");
790 for (String returnField : lookupForm.getFieldConversions().values()) {
791 if (props.containsKey(returnField)) {
792 Object value = props.get(returnField);
793 script = script.append(
794 "returnLookupResultByScript(\"" + returnField + "\", '" + value + "');");
795 }
796 }
797 returnLink.setActionScript(script.append("closeLightbox();").toString());
798 } else {
799
800 returnLink.setActionScript("e.preventDefault();closeLightbox();showLoading();" +
801 "returnLookupResultReload(\"" + href + "\", '" + returnTarget + "');");
802 }
803 }
804 } else {
805
806
807 returnLink.setActionScript("window.open(\"" + href + "\", '_self');");
808 }
809 }
810
811
812
813
814
815
816
817
818
819
820
821
822
823 protected String getReturnUrl(LookupView lookupView, LookupForm lookupForm, Object dataObject) {
824 Properties props = getReturnUrlParameters(lookupView, lookupForm, dataObject);
825
826 String href = "";
827 if (StringUtils.isNotBlank(lookupForm.getReturnLocation())) {
828 href = UrlFactory.parameterizeUrl(lookupForm.getReturnLocation(), props);
829 }
830
831 return href;
832 }
833
834
835
836
837
838
839
840
841
842
843 protected Properties getReturnUrlParameters(LookupView lookupView, LookupForm lookupForm, Object dataObject) {
844 Properties props = new Properties();
845 props.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.RETURN_METHOD_TO_CALL);
846
847 if (StringUtils.isNotBlank(lookupForm.getReturnFormKey())) {
848 props.put(UifParameters.FORM_KEY, lookupForm.getReturnFormKey());
849 }
850
851 props.put(KRADConstants.REFRESH_CALLER, lookupView.getId());
852 props.put(KRADConstants.REFRESH_DATA_OBJECT_CLASS, getDataObjectClass().getName());
853
854 if (StringUtils.isNotBlank(lookupForm.getDocNum())) {
855 props.put(UifParameters.DOC_NUM, lookupForm.getDocNum());
856 }
857
858 if (StringUtils.isNotBlank(lookupForm.getReferencesToRefresh())) {
859 props.put(KRADConstants.REFERENCES_TO_REFRESH, lookupForm.getReferencesToRefresh());
860 }
861
862 List<String> returnKeys = getReturnKeys(lookupView, lookupForm, dataObject);
863 List<String> secureReturnKeys = lookupView.getAdditionalSecurePropertyNames();
864 Map<String, String> returnKeyValues = KRADUtils.getPropertyKeyValuesFromDataObject(returnKeys, secureReturnKeys, dataObject);
865
866 for (String returnKey : returnKeyValues.keySet()) {
867 String returnValue = returnKeyValues.get(returnKey);
868 if (lookupForm.getFieldConversions().containsKey(returnKey)) {
869 returnKey = lookupForm.getFieldConversions().get(returnKey);
870 }
871
872 props.put(returnKey, returnValue);
873 }
874
875 return props;
876 }
877
878
879
880
881
882
883
884
885
886
887
888 protected List<String> getReturnKeys(LookupView lookupView, LookupForm lookupForm, Object dataObject) {
889 List<String> returnKeys;
890 if (lookupForm.getFieldConversions() != null && !lookupForm.getFieldConversions().isEmpty()) {
891 returnKeys = new ArrayList<String>(lookupForm.getFieldConversions().keySet());
892 } else {
893 returnKeys = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
894 }
895
896 return returnKeys;
897 }
898
899
900
901
902 public void getMaintenanceActionLink(Action actionLink, Object model, String maintenanceMethodToCall) {
903 LookupForm lookupForm = (LookupForm) model;
904 Map<String, Object> actionLinkContext = actionLink.getContext();
905 Object dataObject = actionLinkContext == null ? null : actionLinkContext
906 .get(UifConstants.ContextVariableNames.LINE);
907
908 List<String> pkNames = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
909
910
911 String href = getActionUrlHref(lookupForm, dataObject, maintenanceMethodToCall, pkNames);
912 if (StringUtils.isBlank(href)) {
913 actionLink.setRender(false);
914 return;
915 }
916
917 actionLink.setActionScript("window.open('" + href + "', '_self');");
918
919
920 String prependTitleText = actionLink.getActionLabel() + " " +
921 getDataDictionaryService().getDataDictionary().getDataObjectEntry(getDataObjectClass().getName())
922 .getObjectLabel() + " " +
923 getConfigurationService().getPropertyValueAsString(
924 KRADConstants.Lookup.TITLE_ACTION_URL_PREPENDTEXT_PROPERTY);
925
926 Map<String, String> primaryKeyValues = KRADUtils.getPropertyKeyValuesFromDataObject(pkNames, dataObject);
927 String title = LookupInquiryUtils.getLinkTitleText(prependTitleText, getDataObjectClass(), primaryKeyValues);
928 actionLink.setTitle(title);
929 lookupForm.setAtLeastOneRowHasActions(true);
930 }
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946 protected String getActionUrlHref(LookupForm lookupForm, Object dataObject, String methodToCall,
947 List<String> pkNames) {
948 LookupView lookupView = (LookupView) lookupForm.getView();
949
950 Properties props = new Properties();
951 props.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, methodToCall);
952
953 Map<String, String> primaryKeyValues = KRADUtils.getPropertyKeyValuesFromDataObject(pkNames, dataObject);
954 for (String primaryKey : primaryKeyValues.keySet()) {
955 String primaryKeyValue = primaryKeyValues.get(primaryKey);
956
957 props.put(primaryKey, primaryKeyValue);
958 }
959
960 if (StringUtils.isNotBlank(lookupForm.getReturnLocation())) {
961 props.put(KRADConstants.RETURN_LOCATION_PARAMETER, lookupForm.getReturnLocation());
962 }
963
964 props.put(UifParameters.DATA_OBJECT_CLASS_NAME, lookupForm.getDataObjectClassName());
965 props.put(UifParameters.VIEW_TYPE_NAME, UifConstants.ViewType.MAINTENANCE.name());
966
967 String maintenanceMapping = KRADConstants.Maintenance.REQUEST_MAPPING_MAINTENANCE;
968 if (lookupView != null && StringUtils.isNotBlank(lookupView.getMaintenanceUrlMapping())) {
969 maintenanceMapping = lookupView.getMaintenanceUrlMapping();
970 }
971
972 return UrlFactory.parameterizeUrl(maintenanceMapping, props);
973 }
974
975
976
977
978
979
980 @Override
981 public void setMultiValueLookupSelect(InputField selectField, Object model) {
982 LookupForm lookupForm = (LookupForm) model;
983 Map<String, Object> selectFieldContext = selectField.getContext();
984 Object lineDataObject = selectFieldContext == null ? null : selectFieldContext
985 .get(UifConstants.ContextVariableNames.LINE);
986 if (lineDataObject == null) {
987 throw new RuntimeException("Unable to get data object for line from component: " + selectField.getId());
988 }
989
990 Control selectControl = ((InputField) selectField).getControl();
991 if ((selectControl != null) && (selectControl instanceof ValueConfiguredControl)) {
992 String lineIdentifier = "";
993
994
995 Map<String, String> fieldConversions = lookupForm.getFieldConversions();
996 List<String> fromFieldNames = new ArrayList<String>(fieldConversions.keySet());
997 Collections.sort(fromFieldNames);
998 for (String fromFieldName : fromFieldNames) {
999 Object fromFieldValue = ObjectPropertyUtils.getPropertyValue(lineDataObject, fromFieldName);
1000 if (fromFieldValue != null) {
1001 lineIdentifier += fromFieldValue;
1002 }
1003 lineIdentifier += ":";
1004 }
1005 lineIdentifier = StringUtils.removeEnd(lineIdentifier, ":");
1006
1007 ((ValueConfiguredControl) selectControl).setValue(lineIdentifier);
1008 }
1009 }
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019 public boolean allowsMaintenanceNewOrCopyAction() {
1020 boolean allowsNewOrCopy = false;
1021
1022 String maintDocTypeName = getMaintenanceDocumentTypeName();
1023 if (StringUtils.isNotBlank(maintDocTypeName)) {
1024 allowsNewOrCopy = getDataObjectAuthorizationService().canCreate(getDataObjectClass(),
1025 GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
1026 }
1027
1028 return allowsNewOrCopy;
1029 }
1030
1031
1032
1033
1034
1035
1036
1037 public boolean allowsMaintenanceEditAction(Object dataObject) {
1038 boolean allowsEdit = false;
1039
1040 String maintDocTypeName = getMaintenanceDocumentTypeName();
1041 if (StringUtils.isNotBlank(maintDocTypeName)) {
1042 allowsEdit = getDataObjectAuthorizationService().canMaintain(dataObject,
1043 GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
1044 }
1045
1046 return allowsEdit;
1047 }
1048
1049
1050
1051
1052
1053
1054
1055 public boolean allowsMaintenanceDeleteAction(Object dataObject) {
1056 boolean allowsMaintain = false;
1057 boolean allowsDelete = false;
1058
1059 String maintDocTypeName = getMaintenanceDocumentTypeName();
1060 if (StringUtils.isNotBlank(maintDocTypeName)) {
1061 allowsMaintain = getDataObjectAuthorizationService().canMaintain(dataObject,
1062 GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
1063 }
1064
1065 allowsDelete = getDocumentDictionaryService().getAllowsRecordDeletion(getDataObjectClass());
1066
1067 return allowsDelete && allowsMaintain;
1068 }
1069
1070
1071
1072
1073
1074
1075 protected String getMaintenanceDocumentTypeName() {
1076 DocumentDictionaryService dd = getDocumentDictionaryService();
1077 String maintDocTypeName = dd.getMaintenanceDocumentTypeName(getDataObjectClass());
1078
1079 return maintDocTypeName;
1080 }
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095 protected boolean isResultReturnable(Object dataObject) {
1096 return true;
1097 }
1098
1099
1100
1101
1102 @Override
1103 public void setDataObjectClass(Class<?> dataObjectClass) {
1104 this.dataObjectClass = dataObjectClass;
1105 }
1106
1107
1108
1109
1110 @Override
1111 public Class<?> getDataObjectClass() {
1112 return this.dataObjectClass;
1113 }
1114
1115 public void setConfigurationService(ConfigurationService configurationService) {
1116 this.configurationService = configurationService;
1117 }
1118
1119 protected DataObjectAuthorizationService getDataObjectAuthorizationService() {
1120 if (dataObjectAuthorizationService == null) {
1121 this.dataObjectAuthorizationService = KRADServiceLocatorWeb.getDataObjectAuthorizationService();
1122 }
1123 return dataObjectAuthorizationService;
1124 }
1125
1126 public void setDataObjectAuthorizationService(DataObjectAuthorizationService dataObjectAuthorizationService) {
1127 this.dataObjectAuthorizationService = dataObjectAuthorizationService;
1128 }
1129
1130 protected DataObjectMetaDataService getDataObjectMetaDataService() {
1131 if (dataObjectMetaDataService == null) {
1132 this.dataObjectMetaDataService = KRADServiceLocatorWeb.getDataObjectMetaDataService();
1133 }
1134 return dataObjectMetaDataService;
1135 }
1136
1137 public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
1138 this.dataObjectMetaDataService = dataObjectMetaDataService;
1139 }
1140
1141 public DocumentDictionaryService getDocumentDictionaryService() {
1142 if (documentDictionaryService == null) {
1143 documentDictionaryService = KRADServiceLocatorWeb.getDocumentDictionaryService();
1144 }
1145 return documentDictionaryService;
1146 }
1147
1148 public void setDocumentDictionaryService(DocumentDictionaryService documentDictionaryService) {
1149 this.documentDictionaryService = documentDictionaryService;
1150 }
1151
1152 protected LookupService getLookupService() {
1153 if (lookupService == null) {
1154 this.lookupService = KRADServiceLocatorWeb.getLookupService();
1155 }
1156 return lookupService;
1157 }
1158
1159 public void setLookupService(LookupService lookupService) {
1160 this.lookupService = lookupService;
1161 }
1162
1163 protected EncryptionService getEncryptionService() {
1164 if (encryptionService == null) {
1165 this.encryptionService = CoreApiServiceLocator.getEncryptionService();
1166 }
1167 return encryptionService;
1168 }
1169
1170 public void setEncryptionService(EncryptionService encryptionService) {
1171 this.encryptionService = encryptionService;
1172 }
1173 }