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.KRADServiceLocator;
35 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
36 import org.kuali.rice.krad.service.LookupService;
37 import org.kuali.rice.krad.service.ModuleService;
38 import org.kuali.rice.krad.uif.UifConstants;
39 import org.kuali.rice.krad.uif.UifParameters;
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.field.InputField;
44 import org.kuali.rice.krad.uif.field.LinkField;
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 Map<String, String> parameters;
80 private List<String> defaultSortAttributeNames;
81
82
83 private boolean sortAscending;
84
85 private Map<String, String> fieldConversions;
86 private List<String> readOnlyFieldsList;
87
88 private transient ConfigurationService configurationService;
89 private transient DataObjectAuthorizationService dataObjectAuthorizationService;
90 private transient DataObjectMetaDataService dataObjectMetaDataService;
91 private transient DocumentDictionaryService documentDictionaryService;
92 private transient LookupService lookupService;
93 private transient EncryptionService encryptionService;
94
95
96
97
98
99 @Override
100 public void populateViewFromRequestParameters(View view, Map<String, String> parameters) {
101 super.populateViewFromRequestParameters(view, parameters);
102
103
104
105 setParameters(parameters);
106 }
107
108
109
110
111
112
113
114 @Override
115 public void performInitialization(View view, Object model) {
116 if (!LookupView.class.isAssignableFrom(view.getClass())) {
117 throw new IllegalArgumentException(
118 "View class '" + view.getClass() + " is not assignable from the '" + LookupView.class + "'");
119 }
120
121 LookupView lookupView = (LookupView) view;
122 initializeLookupViewHelperService(lookupView);
123
124 super.performInitialization(view, model);
125 }
126
127
128
129
130
131
132 protected void initializeLookupViewHelperService(LookupView lookupView) {
133 setDefaultSortAttributeNames(lookupView.getDefaultSortAttributeNames());
134 setSortAscending(lookupView.isDefaultSortAscending());
135 setDataObjectClass(lookupView.getDataObjectClassName());
136 }
137
138
139
140
141 @Override
142 public Collection<?> performSearch(LookupForm form, Map<String, String> searchCriteria, boolean bounded) {
143 Collection<?> displayList;
144
145 LookupUtils.preprocessDateFields(searchCriteria);
146
147
148 displayList = getSearchResults(form, LookupUtils.forceUppercase(getDataObjectClass(), searchCriteria),
149 !bounded);
150
151
152 List<String> pkNames = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
153 Person user = GlobalVariables.getUserSession().getPerson();
154
155 for (Object object : displayList) {
156 if (isResultReturnable(object)) {
157 form.setAtLeastOneRowReturnable(true);
158 }
159 }
160
161 return displayList;
162 }
163
164 protected List<?> getSearchResults(LookupForm form, Map<String, String> searchCriteria, boolean unbounded) {
165 List<?> searchResults;
166
167
168 Map<String, String> nonBlankSearchCriteria = processSearchCriteria(form, searchCriteria);
169
170 boolean searchUsingOnlyPrimaryKeyValues =
171 getLookupService().allPrimaryKeyValuesPresentAndNotWildcard(getDataObjectClass(), searchCriteria);
172
173
174 if (ExternalizableBusinessObject.class.isAssignableFrom(getDataObjectClass())) {
175 return getSearchResultsForEBO(nonBlankSearchCriteria, unbounded);
176 }
177
178
179
180 try {
181 if (LookupUtils.hasExternalBusinessObjectProperty(getDataObjectClass(), nonBlankSearchCriteria)) {
182 Map<String, String> eboSearchCriteria = adjustCriteriaForNestedEBOs(nonBlankSearchCriteria, unbounded);
183
184 if (LOG.isDebugEnabled()) {
185 LOG.debug("Passing these results into the lookup service: " + eboSearchCriteria);
186 }
187
188
189 searchResults = (List<?>) getLookupService()
190 .findCollectionBySearchHelper(getDataObjectClass(), eboSearchCriteria, unbounded);
191 } else {
192 searchResults = (List<?>) getLookupService()
193 .findCollectionBySearchHelper(getDataObjectClass(), nonBlankSearchCriteria, unbounded);
194 }
195 } catch (IllegalAccessException e) {
196 LOG.error("Error trying to perform search", e);
197 throw new RuntimeException("Error trying to perform search", e);
198 } catch (InstantiationException e1) {
199 LOG.error("Error trying to perform search", e1);
200 throw new RuntimeException("Error trying to perform search", e1);
201 }
202
203 if (searchResults == null) {
204 searchResults = new ArrayList<Object>();
205 }
206
207
208 List<String> defaultSortColumns = getDefaultSortAttributeNames();
209 if ((defaultSortColumns != null) && (defaultSortColumns.size() > 0)) {
210 Collections.sort(searchResults, new BeanPropertyComparator(defaultSortColumns, true));
211 }
212
213 return searchResults;
214 }
215
216 protected Map<String, String> processSearchCriteria(LookupForm lookupForm, Map<String, String> searchCriteria) {
217 Map<String, InputField> criteriaFields = getCriteriaFieldsForValidation((LookupView) lookupForm.getView(),
218 lookupForm);
219
220 Map<String, String> nonBlankSearchCriteria = new HashMap<String, String>();
221 for (String fieldName : searchCriteria.keySet()) {
222 String fieldValue = searchCriteria.get(fieldName);
223
224
225 LookupView lookupView = (LookupView) lookupForm.getView();
226 InputField inputField = criteriaFields.get(fieldName);
227 if (inputField.getControl() instanceof HiddenControl) {
228 continue;
229 }
230
231
232 if (StringUtils.isNotBlank(fieldValue)) {
233 if (fieldValue.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
234 String encryptedValue = StringUtils.removeEnd(fieldValue, EncryptionService.ENCRYPTION_POST_PREFIX);
235 try {
236 fieldValue = getEncryptionService().decrypt(encryptedValue);
237 } catch (GeneralSecurityException e) {
238 LOG.error("Error decrypting value for business object class " + getDataObjectClass() +
239 " attribute " + fieldName, e);
240 throw new RuntimeException(
241 "Error decrypting value for business object class " + getDataObjectClass() +
242 " attribute " + fieldName, e);
243 }
244 }
245
246 nonBlankSearchCriteria.put(fieldName, fieldValue);
247 }
248 }
249
250 return nonBlankSearchCriteria;
251 }
252
253 protected List<?> getSearchResultsForEBO(Map<String, String> searchCriteria, boolean unbounded) {
254 ModuleService eboModuleService =
255 KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(getDataObjectClass());
256 BusinessObjectEntry ddEntry =
257 eboModuleService.getExternalizableBusinessObjectDictionaryEntry(getDataObjectClass());
258
259 Map<String, String> filteredFieldValues = new HashMap<String, String>();
260 for (String fieldName : searchCriteria.keySet()) {
261 if (ddEntry.getAttributeNames().contains(fieldName)) {
262 filteredFieldValues.put(fieldName, searchCriteria.get(fieldName));
263 }
264 }
265
266 List<?> searchResults = eboModuleService.getExternalizableBusinessObjectsListForLookup(
267 (Class<? extends ExternalizableBusinessObject>) getDataObjectClass(), (Map) filteredFieldValues,
268 unbounded);
269
270 return searchResults;
271 }
272
273 protected Map<String, String> adjustCriteriaForNestedEBOs(Map<String, String> searchCriteria,
274 boolean unbounded) throws InstantiationException, IllegalAccessException {
275 if (LOG.isDebugEnabled()) {
276 LOG.debug("has EBO reference: " + getDataObjectClass());
277 LOG.debug("properties: " + searchCriteria);
278 }
279
280
281 Map<String, String> nonEboFieldValues =
282 LookupUtils.removeExternalizableBusinessObjectFieldValues(getDataObjectClass(), searchCriteria);
283 if (LOG.isDebugEnabled()) {
284 LOG.debug("Non EBO properties removed: " + nonEboFieldValues);
285 }
286
287
288 List<String> eboPropertyNames =
289 LookupUtils.getExternalizableBusinessObjectProperties(getDataObjectClass(), searchCriteria);
290 if (LOG.isDebugEnabled()) {
291 LOG.debug("EBO properties: " + eboPropertyNames);
292 }
293
294
295 for (String eboPropertyName : eboPropertyNames) {
296
297 Map<String, String> eboFieldValues =
298 LookupUtils.getExternalizableBusinessObjectFieldValues(eboPropertyName, searchCriteria);
299 if (LOG.isDebugEnabled()) {
300 LOG.debug("EBO properties for master EBO property: " + eboPropertyName);
301 LOG.debug("properties: " + eboFieldValues);
302 }
303
304
305 ModuleService eboModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(
306 LookupUtils.getExternalizableBusinessObjectClass(getDataObjectClass(), eboPropertyName));
307
308
309
310 List<?> eboResults = Collections.emptyList();
311 if (eboModuleService != null) {
312 eboResults = eboModuleService.getExternalizableBusinessObjectsListForLookup(
313 LookupUtils.getExternalizableBusinessObjectClass(getDataObjectClass(), eboPropertyName),
314 (Map) eboFieldValues, unbounded);
315 } else {
316 LOG.debug("EBO ModuleService is null: " + eboPropertyName);
317 }
318
319
320
321
322
323 Class<?> eboParentClass;
324 String eboParentPropertyName;
325 if (ObjectUtils.isNestedAttribute(eboPropertyName)) {
326 eboParentPropertyName = StringUtils.substringBeforeLast(eboPropertyName, ".");
327 try {
328 eboParentClass =
329 PropertyUtils.getPropertyType(getDataObjectClass().newInstance(), eboParentPropertyName);
330 } catch (Exception ex) {
331 throw new RuntimeException("Unable to create an instance of the business object class: " +
332 getDataObjectClass().getName(), ex);
333 }
334 } else {
335 eboParentClass = getDataObjectClass();
336 eboParentPropertyName = null;
337 }
338
339 if (LOG.isDebugEnabled()) {
340 LOG.debug("determined EBO parent class/property name: " + eboParentClass + "/" + eboParentPropertyName);
341 }
342
343
344
345
346
347 RelationshipDefinition rd =
348 getDataObjectMetaDataService().getDictionaryRelationship(eboParentClass, eboPropertyName);
349 if (LOG.isDebugEnabled()) {
350 LOG.debug("Obtained RelationshipDefinition for " + eboPropertyName);
351 LOG.debug(rd);
352 }
353
354
355
356
357
358
359
360 if (ObjectUtils.isNotNull(rd)) {
361 if (rd.getPrimitiveAttributes().size() > 1) {
362 throw new RuntimeException(
363 "EBO Links don't work for relationships with multiple-field primary keys.");
364 }
365 String boProperty = rd.getPrimitiveAttributes().get(0).getSourceName();
366 String eboProperty = rd.getPrimitiveAttributes().get(0).getTargetName();
367 StringBuffer boPropertyValue = new StringBuffer();
368
369
370
371
372 for (Object ebo : eboResults) {
373 if (boPropertyValue.length() != 0) {
374 boPropertyValue.append(SearchOperator.OR.op());
375 }
376 try {
377 boPropertyValue.append(PropertyUtils.getProperty(ebo, eboProperty).toString());
378 } catch (Exception ex) {
379 LOG.warn("Unable to get value for " + eboProperty + " on " + ebo);
380 }
381 }
382
383 if (eboParentPropertyName == null) {
384
385 nonEboFieldValues.put(boProperty, boPropertyValue.toString());
386 } else {
387
388
389 nonEboFieldValues.put(eboParentPropertyName + "." + boProperty, boPropertyValue.toString());
390 }
391 }
392 }
393
394 return nonEboFieldValues;
395 }
396
397
398
399
400 @Override
401 public Map<String, String> performClear(LookupForm form, Map<String, String> searchCriteria) {
402 Map<String, InputField> criteriaFieldMap = getCriteriaFieldsForValidation((LookupView) form.getView(), form);
403 Map<String, String> clearedSearchCriteria = new HashMap<String, String>();
404 for (Map.Entry<String, String> searchKeyValue : searchCriteria.entrySet()) {
405 String searchPropertyName = searchKeyValue.getKey();
406
407 InputField inputField = criteriaFieldMap.get(searchPropertyName);
408 if (inputField != null) {
409
410
411
412
413
414
415
416
417
418 clearedSearchCriteria.put(searchPropertyName, inputField.getDefaultValue());
419 } else {
420 throw new RuntimeException("Invalid search field sent for property name: " + searchPropertyName);
421 }
422 }
423
424 return clearedSearchCriteria;
425 }
426
427
428
429
430 @Override
431 public boolean validateSearchParameters(LookupForm form, Map<String, String> searchCriteria) {
432 boolean valid = true;
433
434 if (!getViewDictionaryService().isLookupable(getDataObjectClass())) {
435 throw new RuntimeException("Lookup not defined for data object " + getDataObjectClass());
436 }
437
438 Map<String, InputField> criteriaFields = getCriteriaFieldsForValidation((LookupView) form.getView(), form);
439
440
441
442 for (Map.Entry<String, String> searchKeyValue : searchCriteria.entrySet()) {
443 String searchPropertyName = searchKeyValue.getKey();
444 String searchPropertyValue = searchKeyValue.getValue();
445
446 LookupView lookupView = (LookupView) form.getView();
447 InputField inputField = criteriaFields.get(searchPropertyName);
448 if (inputField != null) {
449 if (StringUtils.isBlank(searchPropertyValue) && BooleanUtils.isTrue(inputField.getRequired())) {
450 GlobalVariables.getMessageMap()
451 .putError(inputField.getPropertyName(), RiceKeyConstants.ERROR_REQUIRED,
452 inputField.getLabel());
453 }
454
455 validateSearchParameterWildcardAndOperators(inputField, searchPropertyValue);
456 } else {
457 throw new RuntimeException("Invalid search field sent for property name: " + searchPropertyName);
458 }
459 }
460
461 if (GlobalVariables.getMessageMap().hasErrors()) {
462 valid = false;
463 }
464
465 return valid;
466 }
467
468 protected Map<String, InputField> getCriteriaFieldsForValidation(LookupView lookupView, LookupForm form) {
469 Map<String, InputField> criteriaFieldMap = new HashMap<String, InputField>();
470
471
472
473 List<InputField> fields = ComponentUtils.getComponentsOfTypeDeep(lookupView.getCriteriaFields(),
474 InputField.class);
475 for (InputField field : fields) {
476 criteriaFieldMap.put(field.getPropertyName(), field);
477 }
478
479 return criteriaFieldMap;
480 }
481
482
483
484
485
486
487
488
489 protected void validateSearchParameterWildcardAndOperators(InputField inputField,
490 String searchPropertyValue) {
491 if (StringUtils.isBlank(searchPropertyValue))
492 return;
493
494
495 boolean found = false;
496 for (SearchOperator op : SearchOperator.QUERY_CHARACTERS) {
497 String queryCharacter = op.op();
498
499 if (searchPropertyValue.contains(queryCharacter)) {
500 found = true;
501 }
502 }
503
504 if (!found) {
505 return;
506 }
507
508 String attributeLabel = inputField.getLabel();
509 if ((LookupInputField.class.isAssignableFrom(inputField.getClass())) &&
510 (((LookupInputField) inputField).isTreatWildcardsAndOperatorsAsLiteral())) {
511 Object dataObjectExample = null;
512 try {
513 dataObjectExample = getDataObjectClass().newInstance();
514 } catch (Exception e) {
515 LOG.error("Exception caught instantiating " + getDataObjectClass().getName(), e);
516 throw new RuntimeException("Cannot instantiate " + getDataObjectClass().getName(), e);
517 }
518
519 Class<?> propertyType =
520 ObjectPropertyUtils.getPropertyType(getDataObjectClass(), inputField.getPropertyName());
521 if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ||
522 TypeUtils.isTemporalClass(propertyType)) {
523 GlobalVariables.getMessageMap().putError(inputField.getPropertyName(),
524 RiceKeyConstants.ERROR_WILDCARDS_AND_OPERATORS_NOT_ALLOWED_ON_FIELD, attributeLabel);
525 }
526
527 if (TypeUtils.isStringClass(propertyType)) {
528 GlobalVariables.getMessageMap().putInfo(inputField.getPropertyName(),
529 RiceKeyConstants.INFO_WILDCARDS_AND_OPERATORS_TREATED_LITERALLY, attributeLabel);
530 }
531 } else {
532 if (getDataObjectAuthorizationService()
533 .attributeValueNeedsToBeEncryptedOnFormsAndLinks(getDataObjectClass(),
534 inputField.getPropertyName())) {
535 if (!searchPropertyValue.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
536
537
538
539
540
541
542 GlobalVariables.getMessageMap()
543 .putError(inputField.getPropertyName(), RiceKeyConstants.ERROR_SECURE_FIELD,
544 attributeLabel);
545 }
546 }
547 }
548 }
549
550
551
552
553 public void getReturnUrlForResults(LinkField returnLinkField, Object model) {
554 LookupForm lookupForm = (LookupForm) model;
555 LookupView lookupView = (LookupView) returnLinkField.getContext().get(UifConstants.ContextVariableNames.VIEW);
556
557 Object dataObject = returnLinkField.getContext().get(UifConstants.ContextVariableNames.LINE);
558
559
560 if ((dataObject == null) || (!isResultReturnable(dataObject))) {
561 returnLinkField.setRender(false);
562 return;
563 }
564
565
566 String href = getReturnUrl(lookupView, lookupForm, dataObject);
567 if (StringUtils.isBlank(href)) {
568 returnLinkField.setRender(false);
569 return;
570 }
571
572 returnLinkField.setHrefText(href);
573
574
575 String linkLabel = getConfigurationService().getPropertyValueAsString(
576 KRADConstants.Lookup.TITLE_RETURN_URL_PREPENDTEXT_PROPERTY);
577 returnLinkField.setLinkLabel(linkLabel);
578
579 List<String> returnKeys = getReturnKeys(lookupView, lookupForm, dataObject);
580 Map<String, String> returnKeyValues = KRADUtils.getPropertyKeyValuesFromDataObject(returnKeys, dataObject);
581
582 String title = LookupInquiryUtils.getLinkTitleText(linkLabel, getDataObjectClass(), returnKeyValues);
583 returnLinkField.setTitle(title);
584
585
586 String returnTarget = lookupView.getReturnTarget();
587 if (returnTarget != null) {
588 returnLinkField.setTarget(returnTarget);
589
590
591 if (!returnTarget.equals("_self")) {
592
593
594 if (lookupView.isReturnByScript()) {
595 Properties props = getReturnUrlParameters(lookupView, lookupForm, dataObject);
596
597 StringBuilder script = new StringBuilder("e.preventDefault();");
598 for (String returnField : lookupForm.getFieldConversions().values()) {
599 if (props.containsKey(returnField)) {
600 Object fieldName = returnField.replace("'", "\\'");
601 Object value = props.get(returnField);
602 script = script.append("returnLookupResultByScript(\"" + returnField + "\", '" + value + "');");
603 }
604 }
605 returnLinkField.setOnClickScript(script.append("closeLightbox();").toString());
606 } else{
607
608 returnLinkField.setOnClickScript("e.preventDefault();closeLightbox();createLoading(true);window.open(jq(this).attr('href'), jq(this).attr('target'));");
609 }
610 }
611 } else {
612
613
614 returnLinkField.setTarget("_self");
615 }
616 }
617
618
619
620
621
622
623
624
625
626
627
628
629
630 protected String getReturnUrl(LookupView lookupView, LookupForm lookupForm, Object dataObject) {
631 Properties props = getReturnUrlParameters(lookupView, lookupForm, dataObject);
632
633 String href = "";
634 if (StringUtils.isNotBlank(lookupForm.getReturnLocation())) {
635 href = UrlFactory.parameterizeUrl(lookupForm.getReturnLocation(), props);
636 }
637
638 return href;
639 }
640
641
642
643
644
645
646
647
648
649
650 protected Properties getReturnUrlParameters(LookupView lookupView, LookupForm lookupForm, Object dataObject) {
651 Properties props = new Properties();
652 props.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.RETURN_METHOD_TO_CALL);
653
654 if (StringUtils.isNotBlank(lookupForm.getReturnFormKey())) {
655 props.put(UifParameters.FORM_KEY, lookupForm.getReturnFormKey());
656 }
657
658 props.put(KRADConstants.REFRESH_CALLER, lookupView.getId());
659 props.put(KRADConstants.REFRESH_DATA_OBJECT_CLASS, getDataObjectClass().getName());
660
661 if (StringUtils.isNotBlank(lookupForm.getDocNum())) {
662 props.put(UifParameters.DOC_NUM, lookupForm.getDocNum());
663 }
664
665 if (StringUtils.isNotBlank(lookupForm.getReferencesToRefresh())) {
666 props.put(KRADConstants.REFERENCES_TO_REFRESH, lookupForm.getReferencesToRefresh());
667 }
668
669 List<String> returnKeys = getReturnKeys(lookupView, lookupForm, dataObject);
670 Map<String, String> returnKeyValues = KRADUtils.getPropertyKeyValuesFromDataObject(returnKeys, dataObject);
671
672 for (String returnKey : returnKeyValues.keySet()) {
673 String returnValue = returnKeyValues.get(returnKey);
674 if (lookupForm.getFieldConversions().containsKey(returnKey)) {
675 returnKey = lookupForm.getFieldConversions().get(returnKey);
676 }
677
678 props.put(returnKey, returnValue);
679 }
680
681 return props;
682 }
683
684
685
686
687
688
689
690 protected List<String> getReturnKeys(LookupView lookupView, LookupForm lookupForm, Object dataObject) {
691 List<String> returnKeys;
692 if (lookupForm.getFieldConversions() != null && !lookupForm.getFieldConversions().isEmpty()) {
693 returnKeys = new ArrayList<String>(lookupForm.getFieldConversions().keySet());
694 } else {
695 returnKeys = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
696 }
697
698 return returnKeys;
699 }
700
701
702
703
704 public void getMaintenanceActionLink(LinkField actionLinkField, Object model, String maintenanceMethodToCall) {
705 LookupForm lookupForm = (LookupForm) model;
706 LookupView lookupView = (LookupView) actionLinkField.getContext().get(UifConstants.ContextVariableNames.VIEW);
707 Object dataObject = actionLinkField.getContext().get(UifConstants.ContextVariableNames.LINE);
708
709 List<String> pkNames = getDataObjectMetaDataService().listPrimaryKeyFieldNames(getDataObjectClass());
710
711
712 String href = getActionUrlHref(lookupForm, dataObject, maintenanceMethodToCall, pkNames);
713 if (StringUtils.isBlank(href)) {
714 actionLinkField.setRender(false);
715 return;
716 }
717
718 actionLinkField.setHrefText(href);
719
720
721 String prependTitleText = actionLinkField.getLinkLabel() + " " +
722 getDataDictionaryService().getDataDictionary().getDataObjectEntry(getDataObjectClass().getName())
723 .getObjectLabel() + " " +
724 getConfigurationService().getPropertyValueAsString(
725 KRADConstants.Lookup.TITLE_ACTION_URL_PREPENDTEXT_PROPERTY);
726
727 Map<String, String> primaryKeyValues = KRADUtils.getPropertyKeyValuesFromDataObject(pkNames, dataObject);
728 String title = LookupInquiryUtils.getLinkTitleText(prependTitleText, getDataObjectClass(), primaryKeyValues);
729 actionLinkField.setTitle(title);
730
731 actionLinkField.setTarget("_self");
732 lookupForm.setAtLeastOneRowHasActions(true);
733 }
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749 protected String getActionUrlHref(LookupForm lookupForm, Object dataObject, String methodToCall,
750 List<String> pkNames) {
751 LookupView lookupView = (LookupView) lookupForm.getView();
752
753 Properties props = new Properties();
754 props.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, methodToCall);
755
756 Map<String, String> primaryKeyValues = KRADUtils.getPropertyKeyValuesFromDataObject(pkNames, dataObject);
757 for (String primaryKey : primaryKeyValues.keySet()) {
758 String primaryKeyValue = primaryKeyValues.get(primaryKey);
759
760 props.put(primaryKey, primaryKeyValue);
761 }
762
763 if (StringUtils.isNotBlank(lookupForm.getReturnLocation())) {
764 props.put(KRADConstants.RETURN_LOCATION_PARAMETER, lookupForm.getReturnLocation());
765 }
766
767 props.put(UifParameters.DATA_OBJECT_CLASS_NAME, lookupForm.getDataObjectClassName());
768 props.put(UifParameters.VIEW_TYPE_NAME, UifConstants.ViewType.MAINTENANCE.name());
769
770 String maintenanceMapping = KRADConstants.Maintenance.REQUEST_MAPPING_MAINTENANCE;
771 if (StringUtils.isNotBlank(lookupView.getMaintenanceUrlMapping())) {
772 maintenanceMapping = lookupView.getMaintenanceUrlMapping();
773 }
774
775 return UrlFactory.parameterizeUrl(maintenanceMapping, props);
776 }
777
778
779
780
781
782
783 @Override
784 public void setMultiValueLookupSelect(InputField selectField, Object model) {
785 LookupForm lookupForm = (LookupForm) model;
786 Object lineDataObject = selectField.getContext().get(UifConstants.ContextVariableNames.LINE);
787 if (lineDataObject == null) {
788 throw new RuntimeException("Unable to get data object for line from component: " + selectField.getId());
789 }
790
791 Control selectControl = ((InputField) selectField).getControl();
792 if ((selectControl != null) && (selectControl instanceof ValueConfiguredControl)) {
793 String lineIdentifier = "";
794
795
796 Map<String, String> fieldConversions = lookupForm.getFieldConversions();
797 List<String> fromFieldNames = new ArrayList<String>(fieldConversions.keySet());
798 Collections.sort(fromFieldNames);
799 for (String fromFieldName : fromFieldNames) {
800 Object fromFieldValue = ObjectPropertyUtils.getPropertyValue(lineDataObject, fromFieldName);
801 if (fromFieldValue != null) {
802 lineIdentifier += fromFieldValue;
803 }
804 lineIdentifier += ":";
805 }
806 lineIdentifier = StringUtils.removeEnd(lineIdentifier, ":");
807
808 ((ValueConfiguredControl) selectControl).setValue(lineIdentifier);
809 }
810 }
811
812
813
814
815
816
817
818
819
820 public boolean allowsMaintenanceNewOrCopyAction() {
821 boolean allowsNewOrCopy = false;
822
823 String maintDocTypeName = getMaintenanceDocumentTypeName();
824 if (StringUtils.isNotBlank(maintDocTypeName)) {
825 allowsNewOrCopy = getDataObjectAuthorizationService()
826 .canCreate(getDataObjectClass(), GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
827 }
828
829 return allowsNewOrCopy;
830 }
831
832
833
834
835
836
837
838 public boolean allowsMaintenanceEditAction(Object dataObject) {
839 boolean allowsEdit = false;
840
841 String maintDocTypeName = getMaintenanceDocumentTypeName();
842 if (StringUtils.isNotBlank(maintDocTypeName)) {
843 allowsEdit = getDataObjectAuthorizationService()
844 .canMaintain(dataObject, GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
845 }
846
847 return allowsEdit;
848 }
849
850
851
852
853
854
855
856 public boolean allowsMaintenanceDeleteAction(Object dataObject) {
857 boolean allowsMaintain = false;
858 boolean allowsDelete = false;
859
860 String maintDocTypeName = getMaintenanceDocumentTypeName();
861 if (StringUtils.isNotBlank(maintDocTypeName)) {
862 allowsMaintain = getDataObjectAuthorizationService()
863 .canMaintain(dataObject, GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
864 }
865
866 allowsDelete = getDocumentDictionaryService().getAllowsRecordDeletion(getDataObjectClass());
867
868 return allowsDelete && allowsMaintain;
869 }
870
871
872
873
874
875
876 protected String getMaintenanceDocumentTypeName() {
877 DocumentDictionaryService dd = getDocumentDictionaryService();
878 String maintDocTypeName = dd.getMaintenanceDocumentTypeName(getDataObjectClass());
879
880 return maintDocTypeName;
881 }
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896 protected boolean isResultReturnable(Object dataObject) {
897 return true;
898 }
899
900
901
902
903 @Override
904 public void setDataObjectClass(Class<?> dataObjectClass) {
905 this.dataObjectClass = dataObjectClass;
906 }
907
908
909
910
911 @Override
912 public Class<?> getDataObjectClass() {
913 return this.dataObjectClass;
914 }
915
916
917
918
919 @Override
920 public void setFieldConversions(Map<String, String> fieldConversions) {
921 this.fieldConversions = fieldConversions;
922 }
923
924
925
926
927 @Override
928 public void setReadOnlyFieldsList(List<String> readOnlyFieldsList) {
929 this.readOnlyFieldsList = readOnlyFieldsList;
930 }
931
932 public Map<String, String> getParameters() {
933 return parameters;
934 }
935
936 public void setParameters(Map<String, String> parameters) {
937 this.parameters = parameters;
938 }
939
940 public List<String> getDefaultSortAttributeNames() {
941 return defaultSortAttributeNames;
942 }
943
944 public void setDefaultSortAttributeNames(List<String> defaultSortAttributeNames) {
945 this.defaultSortAttributeNames = defaultSortAttributeNames;
946 }
947
948 public boolean isSortAscending() {
949 return sortAscending;
950 }
951
952 public void setSortAscending(boolean sortAscending) {
953 this.sortAscending = sortAscending;
954 }
955
956 public List<String> getReadOnlyFieldsList() {
957 return readOnlyFieldsList;
958 }
959
960 public Map<String, String> getFieldConversions() {
961 return fieldConversions;
962 }
963
964 protected ConfigurationService getConfigurationService() {
965 if (configurationService == null) {
966 this.configurationService = KRADServiceLocator.getKualiConfigurationService();
967 }
968 return configurationService;
969 }
970
971 public void setConfigurationService(ConfigurationService configurationService) {
972 this.configurationService = configurationService;
973 }
974
975 protected DataObjectAuthorizationService getDataObjectAuthorizationService() {
976 if (dataObjectAuthorizationService == null) {
977 this.dataObjectAuthorizationService = KRADServiceLocatorWeb.getDataObjectAuthorizationService();
978 }
979 return dataObjectAuthorizationService;
980 }
981
982 public void setDataObjectAuthorizationService(DataObjectAuthorizationService dataObjectAuthorizationService) {
983 this.dataObjectAuthorizationService = dataObjectAuthorizationService;
984 }
985
986 protected DataObjectMetaDataService getDataObjectMetaDataService() {
987 if (dataObjectMetaDataService == null) {
988 this.dataObjectMetaDataService = KRADServiceLocatorWeb.getDataObjectMetaDataService();
989 }
990 return dataObjectMetaDataService;
991 }
992
993 public void setDataObjectMetaDataService(DataObjectMetaDataService dataObjectMetaDataService) {
994 this.dataObjectMetaDataService = dataObjectMetaDataService;
995 }
996
997 public DocumentDictionaryService getDocumentDictionaryService() {
998 if (documentDictionaryService == null) {
999 documentDictionaryService = KRADServiceLocatorWeb.getDocumentDictionaryService();
1000 }
1001 return documentDictionaryService;
1002 }
1003
1004 public void setDocumentDictionaryService(DocumentDictionaryService documentDictionaryService) {
1005 this.documentDictionaryService = documentDictionaryService;
1006 }
1007
1008 protected LookupService getLookupService() {
1009 if (lookupService == null) {
1010 this.lookupService = KRADServiceLocatorWeb.getLookupService();
1011 }
1012 return lookupService;
1013 }
1014
1015 public void setLookupService(LookupService lookupService) {
1016 this.lookupService = lookupService;
1017 }
1018
1019 protected EncryptionService getEncryptionService() {
1020 if (encryptionService == null) {
1021 this.encryptionService = CoreApiServiceLocator.getEncryptionService();
1022 }
1023 return encryptionService;
1024 }
1025
1026 public void setEncryptionService(EncryptionService encryptionService) {
1027 this.encryptionService = encryptionService;
1028 }
1029 }