1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.lookup;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.CoreApiServiceLocator;
20 import org.kuali.rice.core.api.config.property.ConfigurationService;
21 import org.kuali.rice.core.api.encryption.EncryptionService;
22 import org.kuali.rice.core.api.search.SearchOperator;
23 import org.kuali.rice.core.api.util.RiceKeyConstants;
24 import org.kuali.rice.core.api.util.cache.CopiedObject;
25 import org.kuali.rice.core.api.util.type.TypeUtils;
26 import org.kuali.rice.core.framework.parameter.ParameterService;
27 import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
28 import org.kuali.rice.core.web.format.DateFormatter;
29 import org.kuali.rice.core.web.format.Formatter;
30 import org.kuali.rice.kim.api.identity.Person;
31 import org.kuali.rice.kns.document.authorization.BusinessObjectRestrictions;
32 import org.kuali.rice.kns.document.authorization.FieldRestriction;
33 import org.kuali.rice.kns.inquiry.Inquirable;
34 import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
35 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
36 import org.kuali.rice.kns.service.KNSServiceLocator;
37 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
38 import org.kuali.rice.kns.util.FieldUtils;
39 import org.kuali.rice.kns.web.comparator.CellComparatorHelper;
40 import org.kuali.rice.kns.web.struts.form.LookupForm;
41 import org.kuali.rice.kns.web.struts.form.MultipleValueLookupForm;
42 import org.kuali.rice.kns.web.ui.Column;
43 import org.kuali.rice.kns.web.ui.Field;
44 import org.kuali.rice.kns.web.ui.ResultRow;
45 import org.kuali.rice.kns.web.ui.Row;
46 import org.kuali.rice.krad.bo.BusinessObject;
47 import org.kuali.rice.krad.bo.PersistableBusinessObject;
48 import org.kuali.rice.krad.datadictionary.AttributeSecurity;
49 import org.kuali.rice.krad.datadictionary.mask.MaskFormatter;
50 import org.kuali.rice.krad.exception.ValidationException;
51 import org.kuali.rice.krad.service.BusinessObjectDictionaryService;
52 import org.kuali.rice.krad.service.BusinessObjectService;
53 import org.kuali.rice.krad.service.DataDictionaryService;
54 import org.kuali.rice.krad.service.KRADServiceLocator;
55 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
56 import org.kuali.rice.krad.service.LookupService;
57 import org.kuali.rice.krad.service.PersistenceStructureService;
58 import org.kuali.rice.krad.service.SequenceAccessorService;
59 import org.kuali.rice.krad.util.GlobalVariables;
60 import org.kuali.rice.krad.util.KRADConstants;
61 import org.kuali.rice.krad.util.ObjectUtils;
62 import org.kuali.rice.krad.util.UrlFactory;
63
64 import java.security.GeneralSecurityException;
65 import java.sql.Date;
66 import java.util.ArrayList;
67 import java.util.Collection;
68 import java.util.HashMap;
69 import java.util.HashSet;
70 import java.util.Iterator;
71 import java.util.List;
72 import java.util.Map;
73 import java.util.Properties;
74 import java.util.Set;
75
76
77
78
79
80 public abstract class AbstractLookupableHelperServiceImpl implements LookupableHelperService {
81
82 protected static final String TITLE_RETURN_URL_PREPENDTEXT_PROPERTY = "title.return.url.value.prependtext";
83 protected static final String TITLE_ACTION_URL_PREPENDTEXT_PROPERTY = "title.action.url.value.prependtext";
84 protected static final String ACTION_URLS_CHILDREN_SEPARATOR = " | ";
85 protected static final String ACTION_URLS_CHILDREN_STARTER = " [";
86 protected static final String ACTION_URLS_CHILDREN_END = "]";
87 protected static final String ACTION_URLS_SEPARATOR = " ";
88 protected static final String ACTION_URLS_EMPTY = " ";
89
90 protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AbstractLookupableHelperServiceImpl.class);
91
92 protected Class businessObjectClass;
93 protected Map<String, String[]> parameters;
94 protected BusinessObjectDictionaryService businessObjectDictionaryService;
95 protected BusinessObjectMetaDataService businessObjectMetaDataService;
96 protected DataDictionaryService dataDictionaryService;
97 protected PersistenceStructureService persistenceStructureService;
98 protected EncryptionService encryptionService;
99 protected List<String> readOnlyFieldsList;
100 protected String backLocation;
101 protected String docFormKey;
102 protected Map fieldConversions;
103 protected LookupService lookupService;
104 protected List<Row> rows;
105 protected String referencesToRefresh;
106 protected SequenceAccessorService sequenceAccessorService;
107 protected BusinessObjectService businessObjectService;
108 protected LookupResultsService lookupResultsService;
109 protected String docNum;
110 protected ConfigurationService configurationService;
111 protected ParameterService parameterService;
112 protected BusinessObjectAuthorizationService businessObjectAuthorizationService;
113
114
115
116
117 public String getDocNum() {
118 return this.docNum;
119 }
120
121
122
123
124 public void setDocNum(String docNum) {
125 this.docNum = docNum;
126 }
127
128 public AbstractLookupableHelperServiceImpl() {
129 rows = null;
130 }
131
132
133
134
135
136
137 public boolean checkForAdditionalFields(Map fieldValues) {
138 return false;
139 }
140
141
142
143
144 public Class getBusinessObjectClass() {
145 return businessObjectClass;
146 }
147
148
149
150
151 public void setBusinessObjectClass(Class businessObjectClass) {
152 this.businessObjectClass = businessObjectClass;
153 setRows();
154 }
155
156
157
158
159 public Map<String, String[]> getParameters() {
160 return parameters;
161 }
162
163
164
165
166 public void setParameters(Map<String, String[]> parameters) {
167 this.parameters = parameters;
168 }
169
170
171
172
173
174
175 public DataDictionaryService getDataDictionaryService() {
176 return dataDictionaryService != null ? dataDictionaryService : KRADServiceLocatorWeb.getDataDictionaryService();
177 }
178
179
180
181
182
183
184 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
185 this.dataDictionaryService = dataDictionaryService;
186 }
187
188
189
190
191
192
193 public BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
194 return businessObjectDictionaryService != null ? businessObjectDictionaryService : KRADServiceLocatorWeb
195 .getBusinessObjectDictionaryService();
196 }
197
198
199
200
201
202
203
204 public void setBusinessObjectDictionaryService(BusinessObjectDictionaryService businessObjectDictionaryService) {
205 this.businessObjectDictionaryService = businessObjectDictionaryService;
206 }
207
208
209
210
211
212
213 public BusinessObjectMetaDataService getBusinessObjectMetaDataService() {
214 return businessObjectMetaDataService != null ? businessObjectMetaDataService : KNSServiceLocator
215 .getBusinessObjectMetaDataService();
216 }
217
218
219
220
221
222
223 public void setBusinessObjectMetaDataService(BusinessObjectMetaDataService businessObjectMetaDataService) {
224 this.businessObjectMetaDataService = businessObjectMetaDataService;
225 }
226
227
228
229
230
231
232 protected PersistenceStructureService getPersistenceStructureService() {
233 return persistenceStructureService != null ? persistenceStructureService : KRADServiceLocator
234 .getPersistenceStructureService();
235 }
236
237
238
239
240
241
242 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
243 this.persistenceStructureService = persistenceStructureService;
244 }
245
246
247
248
249
250
251 protected EncryptionService getEncryptionService() {
252 return encryptionService != null ? encryptionService : CoreApiServiceLocator.getEncryptionService();
253 }
254
255
256
257
258
259
260 public void setEncryptionService(EncryptionService encryptionService) {
261 this.encryptionService = encryptionService;
262 }
263
264 protected MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
265
266 public MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
267 if (maintenanceDocumentDictionaryService == null) {
268 maintenanceDocumentDictionaryService = KNSServiceLocator.getMaintenanceDocumentDictionaryService();
269 }
270 return maintenanceDocumentDictionaryService;
271 }
272
273
274 public BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
275 if (businessObjectAuthorizationService == null) {
276 businessObjectAuthorizationService = KNSServiceLocator.getBusinessObjectAuthorizationService();
277 }
278 return businessObjectAuthorizationService;
279 }
280
281 protected Inquirable kualiInquirable;
282
283 public Inquirable getKualiInquirable() {
284 if (kualiInquirable == null) {
285 kualiInquirable = KNSServiceLocator.getKualiInquirable();
286 }
287 return kualiInquirable;
288 }
289
290 public void setMaintenanceDocumentDictionaryService(MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService) {
291 this.maintenanceDocumentDictionaryService = maintenanceDocumentDictionaryService;
292 }
293
294 public void setKualiInquirable(Inquirable kualiInquirable) {
295 this.kualiInquirable = kualiInquirable;
296 }
297
298
299 public ConfigurationService getKualiConfigurationService() {
300 if (configurationService == null) {
301 configurationService = KRADServiceLocator.getKualiConfigurationService();
302 }
303 return configurationService;
304 }
305
306 public void setParameterService(ConfigurationService configurationService) {
307 this.configurationService = configurationService;
308 }
309
310
311 public ParameterService getParameterService() {
312 if (parameterService == null) {
313 parameterService = CoreFrameworkServiceLocator.getParameterService();
314 }
315 return parameterService;
316 }
317
318 public void setParameterService(ParameterService parameterService) {
319 this.parameterService = parameterService;
320 }
321
322
323
324
325
326
327 public boolean allowsMaintenanceNewOrCopyAction() {
328 boolean allowsNewOrCopy = false;
329
330 String maintDocTypeName = getMaintenanceDocumentTypeName();
331 Class boClass = this.getBusinessObjectClass();
332
333 if (StringUtils.isNotBlank(maintDocTypeName)) {
334 allowsNewOrCopy = getBusinessObjectAuthorizationService().canCreate(boClass, GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
335 }
336 return allowsNewOrCopy;
337 }
338
339 protected boolean allowsMaintenanceEditAction(BusinessObject businessObject) {
340 boolean allowsEdit = false;
341
342 String maintDocTypeName = getMaintenanceDocumentTypeName();
343
344 if (StringUtils.isNotBlank(maintDocTypeName)) {
345 allowsEdit = getBusinessObjectAuthorizationService().canMaintain(businessObject, GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
346 }
347 return allowsEdit;
348 }
349
350
351
352
353
354
355
356
357
358 final public String getMaintenanceUrl(BusinessObject businessObject, HtmlData htmlData, List pkNames, BusinessObjectRestrictions businessObjectRestrictions) {
359 htmlData.setTitle(getActionUrlTitleText(businessObject, htmlData.getDisplayText(), pkNames, businessObjectRestrictions));
360 return htmlData.constructCompleteHtmlTag();
361 }
362
363
364
365
366
367
368
369
370 final public String getActionUrls(BusinessObject businessObject, List pkNames, BusinessObjectRestrictions businessObjectRestrictions) {
371 StringBuffer actions = new StringBuffer();
372 List<HtmlData> htmlDataList = getCustomActionUrls(businessObject, pkNames);
373 for (HtmlData htmlData : htmlDataList) {
374 actions.append(getMaintenanceUrl(businessObject, htmlData, pkNames, businessObjectRestrictions));
375 if (htmlData.getChildUrlDataList() != null) {
376 if (htmlData.getChildUrlDataList().size() > 0) {
377 actions.append(ACTION_URLS_CHILDREN_STARTER);
378 for (HtmlData childURLData : htmlData.getChildUrlDataList()) {
379 actions.append(getMaintenanceUrl(businessObject, childURLData, pkNames, businessObjectRestrictions));
380 actions.append(ACTION_URLS_CHILDREN_SEPARATOR);
381 }
382 if (actions.toString().endsWith(ACTION_URLS_CHILDREN_SEPARATOR))
383 actions.delete(actions.length() - ACTION_URLS_CHILDREN_SEPARATOR.length(), actions.length());
384 actions.append(ACTION_URLS_CHILDREN_END);
385 }
386 }
387 actions.append(ACTION_URLS_SEPARATOR);
388 }
389 if (actions.toString().endsWith(ACTION_URLS_SEPARATOR))
390 actions.delete(actions.length() - ACTION_URLS_SEPARATOR.length(), actions.length());
391 return actions.toString();
392 }
393
394
395
396
397
398
399
400
401
402 public List<HtmlData> getCustomActionUrls(BusinessObject businessObject, List pkNames) {
403 List<HtmlData> htmlDataList = new ArrayList<HtmlData>();
404 if (allowsMaintenanceEditAction(businessObject)) {
405 htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL, pkNames));
406 }
407 if (allowsMaintenanceNewOrCopyAction()) {
408 htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_COPY_METHOD_TO_CALL, pkNames));
409 }
410 if (allowsMaintenanceDeleteAction(businessObject)) {
411 htmlDataList.add(getUrlData(businessObject, KRADConstants.MAINTENANCE_DELETE_METHOD_TO_CALL, pkNames));
412 }
413 return htmlDataList;
414 }
415
416
417
418
419
420
421
422 protected boolean allowsMaintenanceDeleteAction(BusinessObject businessObject) {
423
424 boolean allowsMaintain = false;
425 boolean allowsDelete = false;
426
427 String maintDocTypeName = getMaintenanceDocumentTypeName();
428
429 if (StringUtils.isNotBlank(maintDocTypeName)) {
430 allowsMaintain = getBusinessObjectAuthorizationService().canMaintain(businessObject, GlobalVariables.getUserSession().getPerson(), maintDocTypeName);
431 }
432
433 allowsDelete = KNSServiceLocator.getMaintenanceDocumentDictionaryService().getAllowsRecordDeletion(businessObjectClass);
434
435 return allowsDelete && allowsMaintain;
436 }
437
438
439
440
441
442
443
444
445
446
447
448
449 protected HtmlData.AnchorHtmlData getUrlData(BusinessObject businessObject, String methodToCall, String displayText, List pkNames) {
450
451 String href = getActionUrlHref(businessObject, methodToCall, pkNames);
452
453 HtmlData.AnchorHtmlData anchorHtmlData = new HtmlData.AnchorHtmlData(href, methodToCall, displayText);
454 return anchorHtmlData;
455 }
456
457
458
459
460
461
462
463
464
465 protected HtmlData.AnchorHtmlData getUrlData(BusinessObject businessObject, String methodToCall, List pkNames) {
466 return getUrlData(businessObject, methodToCall, methodToCall, pkNames);
467 }
468
469
470
471
472
473
474 protected List<HtmlData> getEmptyActionUrls() {
475 return new ArrayList<HtmlData>();
476 }
477
478 protected HtmlData getEmptyAnchorHtmlData() {
479 return new HtmlData.AnchorHtmlData();
480 }
481
482
483
484
485
486
487
488
489
490
491
492 protected String getActionUrlHref(BusinessObject businessObject, String methodToCall, List pkNames) {
493 Properties parameters = new Properties();
494 parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, methodToCall);
495
496 parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObject.getClass().getName());
497 parameters.putAll(getParametersFromPrimaryKey(businessObject, pkNames));
498 if (StringUtils.isNotBlank(getReturnLocation())) {
499 parameters.put(KRADConstants.RETURN_LOCATION_PARAMETER, getReturnLocation());
500 }
501 return UrlFactory.parameterizeUrl(KRADConstants.MAINTENANCE_ACTION, parameters);
502 }
503
504 protected Properties getParametersFromPrimaryKey(BusinessObject businessObject, List pkNames) {
505 Properties parameters = new Properties();
506 for (Iterator iter = pkNames.iterator(); iter.hasNext();) {
507 String fieldNm = (String) iter.next();
508
509 Object fieldVal = ObjectUtils.getPropertyValue(businessObject, fieldNm);
510 if (fieldVal == null) {
511 fieldVal = KRADConstants.EMPTY_STRING;
512 }
513 if (fieldVal instanceof java.sql.Date) {
514 String formattedString = "";
515 if (Formatter.findFormatter(fieldVal.getClass()) != null) {
516 Formatter formatter = Formatter.getFormatter(fieldVal.getClass());
517 formattedString = (String) formatter.format(fieldVal);
518 fieldVal = formattedString;
519 }
520 }
521
522
523 if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(businessObjectClass, fieldNm)) {
524 try {
525 fieldVal = getEncryptionService().encrypt(fieldVal) + EncryptionService.ENCRYPTION_POST_PREFIX;
526 } catch (GeneralSecurityException e) {
527 LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
528 throw new RuntimeException(e);
529 }
530
531 }
532
533 parameters.put(fieldNm, fieldVal.toString());
534 }
535 return parameters;
536 }
537
538
539
540
541
542
543
544
545
546
547
548 protected String getActionUrlTitleText(BusinessObject businessObject, String displayText, List pkNames, BusinessObjectRestrictions businessObjectRestrictions) {
549 String prependTitleText = displayText + " "
550 + getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(getBusinessObjectClass().getName()).getObjectLabel()
551 + " "
552 + this.getKualiConfigurationService().getPropertyValueAsString(TITLE_ACTION_URL_PREPENDTEXT_PROPERTY);
553 return HtmlData.getTitleText(prependTitleText, businessObject, pkNames, businessObjectRestrictions);
554 }
555
556
557
558
559
560
561
562 protected String getMaintenanceDocumentTypeName() {
563 MaintenanceDocumentDictionaryService dd = getMaintenanceDocumentDictionaryService();
564 String maintDocTypeName = dd.getDocumentTypeName(getBusinessObjectClass());
565 return maintDocTypeName;
566 }
567
568
569
570
571
572
573 public List<String> getReadOnlyFieldsList() {
574 return readOnlyFieldsList;
575 }
576
577
578
579
580
581
582
583 public void setReadOnlyFieldsList(List<String> readOnlyFieldsList) {
584 this.readOnlyFieldsList = readOnlyFieldsList;
585 }
586
587 protected HashMap<String, Boolean> noLookupResultFieldInquiryCache = new HashMap<String, Boolean>();
588 protected HashMap<Class, Class> inquirableClassCache = new HashMap<Class, Class>();
589 protected HashMap<String, Boolean> forceLookupResultFieldInquiryCache = new HashMap<String, Boolean>();
590
591
592
593
594
595
596
597
598 public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) {
599 HtmlData inquiryUrl = new HtmlData.AnchorHtmlData();
600
601 String cacheKey = bo.getClass().getName() + "." + propertyName;
602 Boolean noLookupResultFieldInquiry = noLookupResultFieldInquiryCache.get(cacheKey);
603 if (noLookupResultFieldInquiry == null) {
604 noLookupResultFieldInquiry = getBusinessObjectDictionaryService().noLookupResultFieldInquiry(bo.getClass(), propertyName);
605 if (noLookupResultFieldInquiry == null) {
606 noLookupResultFieldInquiry = Boolean.TRUE;
607 }
608 noLookupResultFieldInquiryCache.put(cacheKey, noLookupResultFieldInquiry);
609 }
610 if (!noLookupResultFieldInquiry) {
611
612 Class<Inquirable> inquirableClass = inquirableClassCache.get(bo.getClass());
613 if (!inquirableClassCache.containsKey(bo.getClass())) {
614 inquirableClass = getBusinessObjectDictionaryService().getInquirableClass(bo.getClass());
615 inquirableClassCache.put(bo.getClass(), inquirableClass);
616 }
617 Inquirable inq = null;
618 try {
619 if (inquirableClass != null) {
620 inq = inquirableClass.newInstance();
621 } else {
622 inq = getKualiInquirable();
623 if (LOG.isDebugEnabled()) {
624 LOG.debug("Default Inquirable Class: " + inq.getClass());
625 }
626 }
627 Boolean forceLookupResultFieldInquiry = forceLookupResultFieldInquiryCache.get(cacheKey);
628 if (forceLookupResultFieldInquiry == null) {
629 forceLookupResultFieldInquiry = getBusinessObjectDictionaryService().forceLookupResultFieldInquiry(bo.getClass(), propertyName);
630 if (forceLookupResultFieldInquiry == null) {
631 forceLookupResultFieldInquiry = Boolean.FALSE;
632 }
633 forceLookupResultFieldInquiryCache.put(cacheKey, forceLookupResultFieldInquiry);
634 }
635 inquiryUrl = inq.getInquiryUrl(bo, propertyName, forceLookupResultFieldInquiry);
636 } catch (Exception ex) {
637 LOG.error("unable to create inquirable to get inquiry URL", ex);
638 }
639 }
640
641 return inquiryUrl;
642 }
643
644 protected CopiedObject<ArrayList<Column>> resultColumns = null;
645
646
647
648
649 public List<Column> getColumns() {
650 if (resultColumns == null) {
651 ArrayList<Column> columns = new ArrayList<Column>();
652 for (String attributeName : getBusinessObjectDictionaryService().getLookupResultFieldNames(getBusinessObjectClass())) {
653 Column column = new Column();
654 column.setPropertyName(attributeName);
655 String columnTitle = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), attributeName);
656 Boolean useShortLabel = getBusinessObjectDictionaryService().getLookupResultFieldUseShortLabel(businessObjectClass, attributeName);
657 if (useShortLabel != null && useShortLabel) {
658 columnTitle = getDataDictionaryService().getAttributeShortLabel(getBusinessObjectClass(), attributeName);
659 }
660 if (StringUtils.isBlank(columnTitle)) {
661 columnTitle = getDataDictionaryService().getCollectionLabel(getBusinessObjectClass(), attributeName);
662 }
663 column.setColumnTitle(columnTitle);
664 column.setMaxLength(getColumnMaxLength(attributeName));
665
666 if (!businessObjectClass.isInterface()) {
667 try {
668 column.setFormatter(ObjectUtils.getFormatterWithDataDictionary(getBusinessObjectClass()
669 .newInstance(), attributeName));
670 } catch (InstantiationException e) {
671 LOG.info("Unable to get new instance of business object class: " + businessObjectClass.getName(), e);
672
673 } catch (IllegalAccessException e) {
674 LOG.info("Unable to get new instance of business object class: " + businessObjectClass.getName(), e);
675
676 }
677 }
678
679 String alternateDisplayPropertyName = getBusinessObjectDictionaryService()
680 .getLookupFieldAlternateDisplayAttributeName(getBusinessObjectClass(), attributeName);
681 if (StringUtils.isNotBlank(alternateDisplayPropertyName)) {
682 column.setAlternateDisplayPropertyName(alternateDisplayPropertyName);
683 }
684
685 String additionalDisplayPropertyName = getBusinessObjectDictionaryService()
686 .getLookupFieldAdditionalDisplayAttributeName(getBusinessObjectClass(), attributeName);
687 if (StringUtils.isNotBlank(additionalDisplayPropertyName)) {
688 column.setAdditionalDisplayPropertyName(additionalDisplayPropertyName);
689 } else {
690 boolean translateCodes = getBusinessObjectDictionaryService().tranlateCodesInLookup(getBusinessObjectClass());
691 if (translateCodes) {
692 FieldUtils.setAdditionalDisplayPropertyForCodes(getBusinessObjectClass(), attributeName, column);
693 }
694 }
695
696 column.setTotal(getBusinessObjectDictionaryService().getLookupResultFieldTotal(getBusinessObjectClass(), attributeName));
697
698 columns.add(column);
699 }
700 resultColumns = ObjectUtils.deepCopyForCaching(columns);
701 return columns;
702 }
703 return resultColumns.getContent();
704 }
705
706 protected static Integer RESULTS_DEFAULT_MAX_COLUMN_LENGTH = null;
707
708 protected int getColumnMaxLength(String attributeName) {
709 Integer fieldDefinedMaxLength = getBusinessObjectDictionaryService().getLookupResultFieldMaxLength(getBusinessObjectClass(), attributeName);
710 if (fieldDefinedMaxLength == null) {
711 if (RESULTS_DEFAULT_MAX_COLUMN_LENGTH == null) {
712 try {
713 RESULTS_DEFAULT_MAX_COLUMN_LENGTH = Integer.valueOf(getParameterService().getParameterValueAsString(
714 KRADConstants.KRAD_NAMESPACE, KRADConstants.DetailTypes.LOOKUP_PARM_DETAIL_TYPE, KRADConstants.RESULTS_DEFAULT_MAX_COLUMN_LENGTH));
715 } catch (NumberFormatException ex) {
716 LOG.error("Lookup field max length parameter not found and unable to parse default set in system parameters (RESULTS_DEFAULT_MAX_COLUMN_LENGTH).");
717 }
718 }
719 return RESULTS_DEFAULT_MAX_COLUMN_LENGTH.intValue();
720 }
721 return fieldDefinedMaxLength.intValue();
722 }
723
724
725
726
727 public String getBackLocation() {
728 return backLocation;
729 }
730
731
732
733
734 public void setBackLocation(String backLocation) {
735 this.backLocation = backLocation;
736 }
737
738
739
740
741 public String getReturnLocation() {
742 return backLocation;
743 }
744
745
746
747
748
749
750 final public HtmlData getReturnUrl(BusinessObject businessObject, Map fieldConversions, String lookupImpl, List returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
751 String href = getReturnHref(businessObject, fieldConversions, lookupImpl, returnKeys);
752 String returnUrlAnchorLabel =
753 this.getKualiConfigurationService().getPropertyValueAsString(TITLE_RETURN_URL_PREPENDTEXT_PROPERTY);
754 HtmlData.AnchorHtmlData anchor = new HtmlData.AnchorHtmlData(href, HtmlData.getTitleText(returnUrlAnchorLabel, businessObject, returnKeys, businessObjectRestrictions));
755 anchor.setDisplayText(returnUrlAnchorLabel);
756 return anchor;
757 }
758
759
760
761
762
763
764
765
766
767
768 final protected String getReturnHref(BusinessObject businessObject, Map fieldConversions, String lookupImpl, List returnKeys) {
769 if (StringUtils.isNotBlank(backLocation)) {
770 return UrlFactory.parameterizeUrl(backLocation, getParameters(
771 businessObject, fieldConversions, lookupImpl, returnKeys));
772 }
773 return "";
774 }
775
776
777
778
779 public HtmlData getReturnUrl(BusinessObject businessObject, LookupForm lookupForm, List returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
780 Properties parameters = getParameters(
781 businessObject, lookupForm.getFieldConversions(), lookupForm.getLookupableImplServiceName(), returnKeys);
782 if (StringUtils.isEmpty(lookupForm.getHtmlDataType()) || HtmlData.ANCHOR_HTML_DATA_TYPE.equals(lookupForm.getHtmlDataType()))
783 return getReturnAnchorHtmlData(businessObject, parameters, lookupForm, returnKeys, businessObjectRestrictions);
784 else
785 return getReturnInputHtmlData(businessObject, parameters, lookupForm, returnKeys, businessObjectRestrictions);
786 }
787
788 protected HtmlData getReturnInputHtmlData(BusinessObject businessObject, Properties parameters, LookupForm lookupForm, List returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
789 String returnUrlAnchorLabel =
790 this.getKualiConfigurationService().getPropertyValueAsString(TITLE_RETURN_URL_PREPENDTEXT_PROPERTY);
791 String name = KRADConstants.MULTIPLE_VALUE_LOOKUP_SELECTED_OBJ_ID_PARAM_PREFIX + lookupForm.getLookupObjectId();
792 HtmlData.InputHtmlData input = new HtmlData.InputHtmlData(name, HtmlData.InputHtmlData.CHECKBOX_INPUT_TYPE);
793 input.setTitle(HtmlData.getTitleText(returnUrlAnchorLabel, businessObject, returnKeys, businessObjectRestrictions));
794 if (((MultipleValueLookupForm) lookupForm).getCompositeObjectIdMap() == null ||
795 ((MultipleValueLookupForm) lookupForm).getCompositeObjectIdMap().get(
796 ((PersistableBusinessObject) businessObject).getObjectId()) == null) {
797 input.setChecked("");
798 } else {
799 input.setChecked(HtmlData.InputHtmlData.CHECKBOX_CHECKED_VALUE);
800 }
801 input.setValue(HtmlData.InputHtmlData.CHECKBOX_CHECKED_VALUE);
802 return input;
803 }
804
805 protected HtmlData getReturnAnchorHtmlData(BusinessObject businessObject, Properties parameters, LookupForm lookupForm, List returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
806 String returnUrlAnchorLabel =
807 this.getKualiConfigurationService().getPropertyValueAsString(TITLE_RETURN_URL_PREPENDTEXT_PROPERTY);
808 HtmlData.AnchorHtmlData anchor = new HtmlData.AnchorHtmlData(
809 getReturnHref(parameters, lookupForm, returnKeys),
810 HtmlData.getTitleText(returnUrlAnchorLabel, businessObject, returnKeys, businessObjectRestrictions));
811 anchor.setDisplayText(returnUrlAnchorLabel);
812 return anchor;
813 }
814
815 protected String getReturnHref(Properties parameters, LookupForm lookupForm, List returnKeys) {
816 if (StringUtils.isNotBlank(backLocation)) {
817 String href = UrlFactory.parameterizeUrl(backLocation, parameters);
818 return addToReturnHref(href, lookupForm);
819 }
820 return "";
821 }
822
823 protected String addToReturnHref(String href, LookupForm lookupForm) {
824 String lookupAnchor = "";
825 if (StringUtils.isNotEmpty(lookupForm.getAnchor())) {
826 lookupAnchor = lookupForm.getAnchor();
827 }
828 href += "&anchor=" + lookupAnchor + "&docNum=" + (StringUtils.isEmpty(getDocNum()) ? "" : getDocNum());
829 return href;
830 }
831
832 protected Properties getParameters(BusinessObject bo, Map fieldConversions, String lookupImpl, List returnKeys) {
833 Properties parameters = new Properties();
834 parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.RETURN_METHOD_TO_CALL);
835 if (getDocFormKey() != null) {
836 parameters.put(KRADConstants.DOC_FORM_KEY, getDocFormKey());
837 }
838 if (lookupImpl != null) {
839 parameters.put(KRADConstants.REFRESH_CALLER, lookupImpl);
840 }
841 if (getDocNum() != null) {
842 parameters.put(KRADConstants.DOC_NUM, getDocNum());
843 }
844
845 if (getReferencesToRefresh() != null) {
846 parameters.put(KRADConstants.REFERENCES_TO_REFRESH, getReferencesToRefresh());
847 }
848
849 Iterator returnKeysIt = getReturnKeys().iterator();
850 while (returnKeysIt.hasNext()) {
851 String fieldNm = (String) returnKeysIt.next();
852
853 Object fieldVal = ObjectUtils.getPropertyValue(bo, fieldNm);
854 if (fieldVal == null) {
855 fieldVal = KRADConstants.EMPTY_STRING;
856 }
857
858 if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(businessObjectClass, fieldNm)) {
859 try {
860 fieldVal = getEncryptionService().encrypt(fieldVal) + EncryptionService.ENCRYPTION_POST_PREFIX;
861 } catch (GeneralSecurityException e) {
862 LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
863 throw new RuntimeException(e);
864 }
865
866 }
867
868
869 if (fieldVal instanceof Date) {
870 DateFormatter dateFormatter = new DateFormatter();
871 fieldVal = dateFormatter.format(fieldVal);
872 }
873
874 if (fieldConversions.containsKey(fieldNm)) {
875 fieldNm = (String) fieldConversions.get(fieldNm);
876 }
877
878 parameters.put(fieldNm, fieldVal.toString());
879 }
880
881 return parameters;
882 }
883
884
885
886
887 public List getReturnKeys() {
888 List returnKeys;
889 if (fieldConversions != null && !fieldConversions.isEmpty()) {
890 returnKeys = new ArrayList(fieldConversions.keySet());
891 } else {
892 returnKeys = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(getBusinessObjectClass());
893 }
894
895 return returnKeys;
896 }
897
898
899
900
901
902
903 public String getDocFormKey() {
904 return docFormKey;
905 }
906
907
908
909
910
911
912 public void setDocFormKey(String docFormKey) {
913 this.docFormKey = docFormKey;
914 }
915
916
917
918
919 public void setFieldConversions(Map fieldConversions) {
920 this.fieldConversions = fieldConversions;
921 }
922
923
924
925
926
927
928 protected LookupService getLookupService() {
929 return lookupService != null ? lookupService : KRADServiceLocatorWeb.getLookupService();
930 }
931
932
933
934
935
936
937 public void setLookupService(LookupService lookupService) {
938 this.lookupService = lookupService;
939 }
940
941
942
943
944
945
946 public List getDefaultSortColumns() {
947 return getBusinessObjectDictionaryService().getLookupDefaultSortFieldNames(getBusinessObjectClass());
948 }
949
950
951
952
953
954
955 public void validateSearchParameters(Map fieldValues) {
956 List<String> lookupFieldAttributeList = null;
957 if (getBusinessObjectMetaDataService().isLookupable(getBusinessObjectClass())) {
958 lookupFieldAttributeList = getBusinessObjectMetaDataService().getLookupableFieldNames(getBusinessObjectClass());
959 }
960 if (lookupFieldAttributeList == null) {
961 throw new RuntimeException("Lookup not defined for business object " + getBusinessObjectClass());
962 }
963 for (Iterator iter = lookupFieldAttributeList.iterator(); iter.hasNext();) {
964 String attributeName = (String) iter.next();
965 if (fieldValues.containsKey(attributeName)) {
966
967 String attributeLabel = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), attributeName);
968
969 String attributeValue = (String) fieldValues.get(attributeName);
970
971
972 if (StringUtils.isBlank(attributeValue)) {
973 if ((getBusinessObjectDictionaryService().getLookupAttributeRequired(getBusinessObjectClass(), attributeName)).booleanValue()) {
974 GlobalVariables.getMessageMap().putError(attributeName, RiceKeyConstants.ERROR_REQUIRED, attributeLabel);
975 }
976 }
977 validateSearchParameterWildcardAndOperators(attributeName, attributeValue);
978 }
979 }
980
981 if (GlobalVariables.getMessageMap().hasErrors()) {
982 throw new ValidationException("errors in search criteria");
983 }
984 }
985
986 protected void validateSearchParameterWildcardAndOperators(String attributeName, String attributeValue) {
987 if (StringUtils.isBlank(attributeValue))
988 return;
989
990
991 boolean found = false;
992 for (SearchOperator op : SearchOperator.QUERY_CHARACTERS) {
993 String queryCharacter = op.op();
994
995 if (attributeValue.contains(queryCharacter)) {
996 found = true;
997 }
998 }
999 if (!found)
1000 return;
1001
1002 String attributeLabel = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), attributeName);
1003 if (getBusinessObjectDictionaryService().isLookupFieldTreatWildcardsAndOperatorsAsLiteral(businessObjectClass, attributeName)) {
1004 BusinessObject example = null;
1005 try {
1006 example = (BusinessObject) businessObjectClass.newInstance();
1007 } catch (Exception e) {
1008 LOG.error("Exception caught instantiating " + businessObjectClass.getName(), e);
1009 throw new RuntimeException("Cannot instantiate " + businessObjectClass.getName(), e);
1010 }
1011
1012 Class propertyType = ObjectUtils.getPropertyType(example, attributeName, getPersistenceStructureService());
1013 if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) || TypeUtils.isTemporalClass(propertyType)) {
1014 GlobalVariables.getMessageMap().putError(attributeName, RiceKeyConstants.ERROR_WILDCARDS_AND_OPERATORS_NOT_ALLOWED_ON_FIELD, attributeLabel);
1015 }
1016 if (TypeUtils.isStringClass(propertyType)) {
1017 GlobalVariables.getMessageMap().putInfo(attributeName, RiceKeyConstants.INFO_WILDCARDS_AND_OPERATORS_TREATED_LITERALLY, attributeLabel);
1018 }
1019 } else {
1020 if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(businessObjectClass, attributeName)) {
1021 if (!attributeValue.endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
1022
1023
1024
1025
1026
1027 GlobalVariables.getMessageMap().putError(attributeName, RiceKeyConstants.ERROR_SECURE_FIELD, attributeLabel);
1028 }
1029 }
1030 }
1031 }
1032
1033
1034
1035
1036
1037 protected void setRows() {
1038 List<String> lookupFieldAttributeList = null;
1039 if (getBusinessObjectMetaDataService().isLookupable(getBusinessObjectClass())) {
1040 lookupFieldAttributeList = getBusinessObjectMetaDataService().getLookupableFieldNames(
1041 getBusinessObjectClass());
1042 }
1043 if (lookupFieldAttributeList == null) {
1044 throw new RuntimeException("Lookup not defined for business object " + getBusinessObjectClass());
1045 }
1046
1047
1048 List fields = new ArrayList();
1049 try {
1050 fields = FieldUtils.createAndPopulateFieldsForLookup(lookupFieldAttributeList, getReadOnlyFieldsList(),
1051 getBusinessObjectClass());
1052 } catch (InstantiationException e) {
1053 throw new RuntimeException("Unable to create instance of business object class" + e.getMessage());
1054 } catch (IllegalAccessException e) {
1055 throw new RuntimeException("Unable to create instance of business object class" + e.getMessage());
1056 }
1057
1058 int numCols = getBusinessObjectDictionaryService().getLookupNumberOfColumns(this.getBusinessObjectClass());
1059
1060 this.rows = FieldUtils.wrapFields(fields, numCols);
1061 }
1062
1063 public List<Row> getRows() {
1064 return rows;
1065 }
1066
1067 public abstract List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues);
1068
1069
1070
1071
1072
1073
1074
1075
1076 public List<? extends BusinessObject> getSearchResultsUnbounded(Map<String, String> fieldValues) {
1077 throw new UnsupportedOperationException("Lookupable helper services do not always support getSearchResultsUnbounded");
1078 }
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088 public Collection performLookup(LookupForm lookupForm, Collection resultTable, boolean bounded) {
1089 Map lookupFormFields = lookupForm.getFieldsForLookup();
1090
1091 setBackLocation((String) lookupForm.getFieldsForLookup().get(KRADConstants.BACK_LOCATION));
1092 setDocFormKey((String) lookupForm.getFieldsForLookup().get(KRADConstants.DOC_FORM_KEY));
1093 Collection displayList;
1094
1095 preProcessRangeFields(lookupFormFields);
1096
1097 Map fieldsForLookup = new HashMap(lookupForm.getFieldsForLookup());
1098
1099 if (bounded) {
1100 displayList = getSearchResults(lookupForm.getFieldsForLookup());
1101 } else {
1102 displayList = getSearchResultsUnbounded(lookupForm.getFieldsForLookup());
1103 }
1104
1105 boolean hasReturnableRow = false;
1106
1107 List returnKeys = getReturnKeys();
1108 List pkNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(getBusinessObjectClass());
1109 Person user = GlobalVariables.getUserSession().getPerson();
1110
1111
1112
1113 for (Iterator iter = displayList.iterator(); iter.hasNext();) {
1114 BusinessObject element = (BusinessObject) iter.next();
1115
1116 final String lookupId = KNSServiceLocator.getLookupResultsService().getLookupId(element);
1117 if (lookupId != null) {
1118 lookupForm.setLookupObjectId(lookupId);
1119 }
1120
1121 BusinessObjectRestrictions businessObjectRestrictions = getBusinessObjectAuthorizationService()
1122 .getLookupResultRestrictions(element, user);
1123
1124 HtmlData returnUrl = getReturnUrl(element, lookupForm, returnKeys, businessObjectRestrictions);
1125 String actionUrls = getActionUrls(element, pkNames, businessObjectRestrictions);
1126
1127 if ("".equals(actionUrls)) {
1128 actionUrls = ACTION_URLS_EMPTY;
1129 }
1130
1131 List<Column> columns = getColumns();
1132 for (Iterator iterator = columns.iterator(); iterator.hasNext();) {
1133 Column col = (Column) iterator.next();
1134
1135 String propValue = ObjectUtils.getFormattedPropertyValue(element, col.getPropertyName(), col.getFormatter());
1136 Class propClass = getPropertyClass(element, col.getPropertyName());
1137
1138 col.setComparator(CellComparatorHelper.getAppropriateComparatorForPropertyClass(propClass));
1139 col.setValueComparator(CellComparatorHelper.getAppropriateValueComparatorForPropertyClass(propClass));
1140
1141 String propValueBeforePotientalMasking = propValue;
1142 propValue = maskValueIfNecessary(element.getClass(), col.getPropertyName(), propValue,
1143 businessObjectRestrictions);
1144 col.setPropertyValue(propValue);
1145
1146
1147 if (StringUtils.equals(propValueBeforePotientalMasking, propValue)) {
1148 if (StringUtils.isNotBlank(col.getAlternateDisplayPropertyName())) {
1149 String alternatePropertyValue = ObjectUtils.getFormattedPropertyValue(element, col
1150 .getAlternateDisplayPropertyName(), null);
1151 col.setPropertyValue(alternatePropertyValue);
1152 }
1153
1154 if (StringUtils.isNotBlank(col.getAdditionalDisplayPropertyName())) {
1155 String additionalPropertyValue = ObjectUtils.getFormattedPropertyValue(element, col
1156 .getAdditionalDisplayPropertyName(), null);
1157 col.setPropertyValue(col.getPropertyValue() + " *-* " + additionalPropertyValue);
1158 }
1159 } else {
1160 col.setTotal(false);
1161 }
1162
1163 if (col.isTotal()) {
1164 Object unformattedPropValue = ObjectUtils.getPropertyValue(element, col.getPropertyName());
1165 col.setUnformattedPropertyValue(unformattedPropValue);
1166 }
1167
1168 if (StringUtils.isNotBlank(propValue)) {
1169 col.setColumnAnchor(getInquiryUrl(element, col.getPropertyName()));
1170 }
1171 }
1172
1173 ResultRow row = new ResultRow(columns, returnUrl.constructCompleteHtmlTag(), actionUrls);
1174 row.setRowId(returnUrl.getName());
1175 row.setReturnUrlHtmlData(returnUrl);
1176
1177
1178
1179
1180
1181 if (getBusinessObjectDictionaryService().isExportable(getBusinessObjectClass())) {
1182 row.setBusinessObject(element);
1183 }
1184
1185 if (lookupId != null) {
1186 row.setObjectId(lookupId);
1187 }
1188
1189 boolean rowReturnable = isResultReturnable(element);
1190 row.setRowReturnable(rowReturnable);
1191 if (rowReturnable) {
1192 hasReturnableRow = true;
1193 }
1194 resultTable.add(row);
1195 }
1196
1197 lookupForm.setHasReturnableRow(hasReturnableRow);
1198
1199 return displayList;
1200 }
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210 protected Class getPropertyClass(BusinessObject element, String propertyName) {
1211 Class propClass = null;
1212
1213 try {
1214 propClass = ObjectUtils.getPropertyType(element, propertyName, getPersistenceStructureService());
1215
1216 } catch (Exception e) {
1217 throw new RuntimeException("Cannot access PropertyType for property " + "'" + propertyName + "' "
1218 + " on an instance of '" + element.getClass().getName() + "'.", e);
1219 }
1220
1221 return propClass;
1222 }
1223
1224
1225
1226
1227
1228 protected Map<String, String> preProcessRangeFields(Map<String, String> lookupFormFields) {
1229 Map<String, String> fieldsToUpdate = new HashMap<String, String>();
1230 Set<String> fieldsForLookup = lookupFormFields.keySet();
1231 for (String propName : fieldsForLookup) {
1232 if (propName.startsWith(KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
1233 String rangedLowerBoundValue = lookupFormFields.get(propName);
1234 String rangedFieldName = StringUtils.remove(propName, KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX);
1235 String rangedValue = lookupFormFields.get(rangedFieldName);
1236 String newPropValue = rangedValue;
1237 if (StringUtils.isNotEmpty(rangedLowerBoundValue) && StringUtils.isNotEmpty(rangedValue)) {
1238 newPropValue = rangedLowerBoundValue + SearchOperator.BETWEEN + rangedValue;
1239 } else if (StringUtils.isNotEmpty(rangedLowerBoundValue) && StringUtils.isEmpty(rangedValue)) {
1240 newPropValue = ">=" + rangedLowerBoundValue;
1241 } else if (StringUtils.isNotEmpty(rangedValue) && StringUtils.isEmpty(rangedLowerBoundValue)) {
1242 newPropValue = "<=" + rangedValue;
1243 }
1244 fieldsToUpdate.put(rangedFieldName, newPropValue);
1245 }
1246 }
1247
1248 Set<String> keysToUpdate = fieldsToUpdate.keySet();
1249 for (String updateKey : keysToUpdate) {
1250 lookupFormFields.put(updateKey, fieldsToUpdate.get(updateKey));
1251 }
1252 return fieldsToUpdate;
1253 }
1254
1255 protected String maskValueIfNecessary(Class businessObjectClass, String propertyName, String propertyValue, BusinessObjectRestrictions businessObjectRestrictions) {
1256 String maskedPropertyValue = propertyValue;
1257 if (businessObjectRestrictions != null) {
1258 FieldRestriction fieldRestriction = businessObjectRestrictions.getFieldRestriction(propertyName);
1259 if (fieldRestriction != null && (fieldRestriction.isMasked() || fieldRestriction.isPartiallyMasked())) {
1260 maskedPropertyValue = fieldRestriction.getMaskFormatter().maskValue(propertyValue);
1261 }
1262 }
1263 return maskedPropertyValue;
1264 }
1265
1266
1267 protected void setReferencesToRefresh(String referencesToRefresh) {
1268 this.referencesToRefresh = referencesToRefresh;
1269 }
1270
1271 public String getReferencesToRefresh() {
1272 return referencesToRefresh;
1273 }
1274
1275 protected SequenceAccessorService getSequenceAccessorService() {
1276 return sequenceAccessorService != null ? sequenceAccessorService : KRADServiceLocator
1277 .getSequenceAccessorService();
1278 }
1279
1280 public void setSequenceAccessorService(SequenceAccessorService sequenceAccessorService) {
1281 this.sequenceAccessorService = sequenceAccessorService;
1282 }
1283
1284 public BusinessObjectService getBusinessObjectService() {
1285 return businessObjectService != null ? businessObjectService : KRADServiceLocator.getBusinessObjectService();
1286 }
1287
1288 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
1289 this.businessObjectService = businessObjectService;
1290 }
1291
1292 protected LookupResultsService getLookupResultsService() {
1293 return lookupResultsService != null ? lookupResultsService : KNSServiceLocator.getLookupResultsService();
1294 }
1295
1296 public void setLookupResultsService(LookupResultsService lookupResultsService) {
1297 this.lookupResultsService = lookupResultsService;
1298 }
1299
1300
1301
1302
1303
1304 public boolean isSearchUsingOnlyPrimaryKeyValues() {
1305
1306 return false;
1307 }
1308
1309
1310
1311
1312
1313
1314
1315 public String getPrimaryKeyFieldLabels() {
1316 return KRADConstants.NOT_AVAILABLE_STRING;
1317 }
1318
1319
1320
1321
1322 public boolean isResultReturnable(BusinessObject object) {
1323 return true;
1324 }
1325
1326
1327
1328
1329
1330
1331 public void performClear(LookupForm lookupForm) {
1332 for (Iterator iter = this.getRows().iterator(); iter.hasNext();) {
1333 Row row = (Row) iter.next();
1334 for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
1335 Field field = (Field) iterator.next();
1336 if (field.isSecure()) {
1337 field.setSecure(false);
1338 field.setDisplayMaskValue(null);
1339 field.setEncryptedValue(null);
1340 }
1341
1342 if (!field.getFieldType().equals(Field.RADIO)) {
1343 field.setPropertyValue(field.getDefaultValue());
1344 }
1345 }
1346 }
1347 }
1348
1349
1350
1351
1352 public boolean shouldDisplayHeaderNonMaintActions() {
1353 return true;
1354 }
1355
1356
1357
1358
1359 public boolean shouldDisplayLookupCriteria() {
1360 return true;
1361 }
1362
1363
1364
1365
1366 public String getSupplementalMenuBar() {
1367 return new String();
1368 }
1369
1370
1371
1372
1373 public String getTitle() {
1374 return getBusinessObjectDictionaryService().getLookupTitle(getBusinessObjectClass());
1375 }
1376
1377
1378
1379
1380 public boolean performCustomAction(boolean ignoreErrors) {
1381 return false;
1382 }
1383
1384
1385
1386
1387 public Field getExtraField() {
1388 return null;
1389 }
1390
1391 public boolean allowsNewOrCopyAction(String documentTypeName) {
1392 throw new UnsupportedOperationException("Function not supported.");
1393 }
1394
1395
1396
1397
1398
1399
1400 public void applyFieldAuthorizationsFromNestedLookups(Field field) {
1401 BusinessObjectAuthorizationService boAuthzService = this.getBusinessObjectAuthorizationService();
1402 if (!Field.MULTI_VALUE_FIELD_TYPES.contains(field.getFieldType())) {
1403 if (field.getPropertyValue() != null && field.getPropertyValue().endsWith(EncryptionService.ENCRYPTION_POST_PREFIX)) {
1404 if (boAuthzService.attributeValueNeedsToBeEncryptedOnFormsAndLinks(businessObjectClass, field.getPropertyName())) {
1405 AttributeSecurity attributeSecurity = getDataDictionaryService().getAttributeSecurity(businessObjectClass.getName(), field.getPropertyName());
1406 Person user = GlobalVariables.getUserSession().getPerson();
1407 String decryptedValue;
1408 try {
1409 String cipherText = StringUtils.removeEnd(field.getPropertyValue(), EncryptionService.ENCRYPTION_POST_PREFIX);
1410 decryptedValue = getEncryptionService().decrypt(cipherText);
1411 } catch (GeneralSecurityException e) {
1412 throw new RuntimeException("Error decrypting value for business object " + businessObjectClass + " attribute " + field.getPropertyName(), e);
1413 }
1414 if (attributeSecurity.isMask() && !boAuthzService.canFullyUnmaskField(user,
1415 businessObjectClass, field.getPropertyName(), null)) {
1416 MaskFormatter maskFormatter = attributeSecurity.getMaskFormatter();
1417 field.setEncryptedValue(field.getPropertyValue());
1418 field.setDisplayMaskValue(maskFormatter.maskValue(decryptedValue));
1419 field.setSecure(true);
1420 } else if (attributeSecurity.isPartialMask() && !boAuthzService.canPartiallyUnmaskField(user,
1421 businessObjectClass, field.getPropertyName(), null)) {
1422 MaskFormatter maskFormatter = attributeSecurity.getPartialMaskFormatter();
1423 field.setEncryptedValue(field.getPropertyValue());
1424 field.setDisplayMaskValue(maskFormatter.maskValue(decryptedValue));
1425 field.setSecure(true);
1426 } else {
1427 field.setPropertyValue(org.kuali.rice.krad.lookup.LookupUtils
1428 .forceUppercase(businessObjectClass, field.getPropertyName(), decryptedValue));
1429 }
1430 } else {
1431 throw new RuntimeException("Field " + field.getPersonNameAttributeName() + " was encrypted on " + businessObjectClass.getName() +
1432 " lookup was encrypted when it should not have been encrypted according to the data dictionary.");
1433 }
1434 }
1435 } else {
1436 if (boAuthzService.attributeValueNeedsToBeEncryptedOnFormsAndLinks(businessObjectClass, field.getPropertyName())) {
1437 LOG.error("Cannot handle multiple value field types that have field authorizations, please implement custom lookupable helper service");
1438 throw new RuntimeException("Cannot handle multiple value field types that have field authorizations.");
1439 }
1440 }
1441 }
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453 public void applyConditionalLogicForFieldDisplay() {
1454 Set<String> readOnlyFields = getConditionallyReadOnlyPropertyNames();
1455 Set<String> requiredFields = getConditionallyRequiredPropertyNames();
1456 Set<String> hiddenFields = getConditionallyHiddenPropertyNames();
1457
1458 for (Iterator iter = this.getRows().iterator(); iter.hasNext();) {
1459 Row row = (Row) iter.next();
1460 for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
1461 Field field = (Field) iterator.next();
1462
1463 if (readOnlyFields != null && readOnlyFields.contains(field.getPropertyName())) {
1464 field.setReadOnly(true);
1465 }
1466
1467 if (requiredFields != null && requiredFields.contains(field.getPropertyName())) {
1468 field.setFieldRequired(true);
1469 }
1470
1471 if (hiddenFields != null && hiddenFields.contains(field.getPropertyName())) {
1472 field.setFieldType(Field.HIDDEN);
1473 }
1474 }
1475 }
1476 }
1477
1478
1479
1480
1481
1482
1483 public Set<String> getConditionallyReadOnlyPropertyNames() {
1484 return new HashSet<String>();
1485 }
1486
1487
1488
1489
1490
1491
1492 public Set<String> getConditionallyRequiredPropertyNames() {
1493 return new HashSet<String>();
1494 }
1495
1496
1497
1498
1499
1500
1501 public Set<String> getConditionallyHiddenPropertyNames() {
1502 return new HashSet<String>();
1503 }
1504
1505
1506
1507
1508
1509
1510
1511
1512 protected String getCurrentSearchFieldValue(String propertyName) {
1513 String currentValue = null;
1514
1515 boolean fieldFound = false;
1516 for (Iterator iter = this.getRows().iterator(); iter.hasNext();) {
1517 Row row = (Row) iter.next();
1518 for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
1519 Field field = (Field) iterator.next();
1520
1521 if (StringUtils.equalsIgnoreCase(propertyName, field.getPropertyName())) {
1522 if (Field.MULTI_VALUE_FIELD_TYPES.contains(field.getFieldType())) {
1523 currentValue = StringUtils.join(field.getPropertyValues(), ";");
1524 } else {
1525 currentValue = field.getPropertyValue();
1526 }
1527 fieldFound = true;
1528 }
1529
1530 if (fieldFound) {
1531 break;
1532 }
1533 }
1534
1535 if (fieldFound) {
1536 break;
1537 }
1538 }
1539
1540 return currentValue;
1541 }
1542 }