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