1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sec.businessobject.lookup;
17
18 import java.beans.PropertyDescriptor;
19 import java.sql.Date;
20 import java.util.Collection;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.apache.commons.beanutils.PropertyUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.kuali.ole.sec.SecKeyConstants;
30 import org.kuali.ole.sec.service.AccessSecurityService;
31 import org.kuali.ole.sys.OLEConstants;
32 import org.kuali.rice.core.web.format.BooleanFormatter;
33 import org.kuali.rice.core.web.format.CollectionFormatter;
34 import org.kuali.rice.core.web.format.DateFormatter;
35 import org.kuali.rice.core.web.format.Formatter;
36 import org.kuali.rice.kim.api.identity.Person;
37 import org.kuali.rice.kns.document.authorization.BusinessObjectRestrictions;
38 import org.kuali.rice.kns.document.authorization.FieldRestriction;
39 import org.kuali.rice.kns.lookup.HtmlData;
40 import org.kuali.rice.kns.lookup.LookupableHelperService;
41 import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
42 import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
43 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
44 import org.kuali.rice.kns.web.comparator.CellComparatorHelper;
45 import org.kuali.rice.kns.web.struts.form.LookupForm;
46 import org.kuali.rice.kns.web.ui.Column;
47 import org.kuali.rice.kns.web.ui.Field;
48 import org.kuali.rice.kns.web.ui.ResultRow;
49 import org.kuali.rice.kns.web.ui.Row;
50 import org.kuali.rice.krad.bo.BusinessObject;
51 import org.kuali.rice.krad.bo.PersistableBusinessObject;
52 import org.kuali.rice.krad.service.DataDictionaryService;
53 import org.kuali.rice.krad.service.PersistenceStructureService;
54 import org.kuali.rice.krad.util.GlobalVariables;
55 import org.kuali.rice.krad.util.KRADConstants;
56 import org.kuali.rice.krad.util.ObjectUtils;
57
58
59
60
61
62 public class AccessSecurityBalanceLookupableHelperServiceImpl implements LookupableHelperService {
63 protected static final String ACTION_URLS_EMPTY = " ";
64
65 protected AccessSecurityService accessSecurityService;
66 protected LookupableHelperService lookupableHelperService;
67 protected BusinessObjectMetaDataService businessObjectMetaDataService;
68 protected BusinessObjectAuthorizationService businessObjectAuthorizationService;
69 protected PersistenceStructureService persistenceStructureService;
70
71 protected boolean glInquiry;
72 protected boolean laborInquiry;
73
74 public AccessSecurityBalanceLookupableHelperServiceImpl() {
75 glInquiry = false;
76 laborInquiry = false;
77 }
78
79 @Override
80 public boolean allowsMaintenanceNewOrCopyAction() {
81 return lookupableHelperService.allowsMaintenanceNewOrCopyAction();
82 }
83
84 @Override
85 public boolean allowsNewOrCopyAction(String documentTypeName) {
86 return lookupableHelperService.allowsNewOrCopyAction(documentTypeName);
87 }
88
89 @Override
90 public void applyFieldAuthorizationsFromNestedLookups(Field field) {
91 lookupableHelperService.applyFieldAuthorizationsFromNestedLookups(field);
92 }
93
94 @Override
95 public boolean checkForAdditionalFields(Map fieldValues) {
96 return lookupableHelperService.checkForAdditionalFields(fieldValues);
97 }
98
99 @Override
100 public String getActionUrls(BusinessObject businessObject, List pkNames, BusinessObjectRestrictions businessObjectRestrictions) {
101 return lookupableHelperService.getActionUrls(businessObject, pkNames, businessObjectRestrictions);
102 }
103
104 @Override
105 public String getBackLocation() {
106 return lookupableHelperService.getBackLocation();
107 }
108
109 @Override
110 public Class getBusinessObjectClass() {
111 return lookupableHelperService.getBusinessObjectClass();
112 }
113
114 @Override
115 public BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
116 return lookupableHelperService.getBusinessObjectDictionaryService();
117 }
118
119 @Override
120 public List getColumns() {
121 return lookupableHelperService.getColumns();
122 }
123
124 @Override
125 public List<HtmlData> getCustomActionUrls(BusinessObject businessObject, List pkNames) {
126 return lookupableHelperService.getCustomActionUrls(businessObject, pkNames);
127 }
128
129 @Override
130 public DataDictionaryService getDataDictionaryService() {
131 return lookupableHelperService.getDataDictionaryService();
132 }
133
134 @Override
135 public List getDefaultSortColumns() {
136 return lookupableHelperService.getDefaultSortColumns();
137 }
138
139 @Override
140 public String getDocFormKey() {
141 return lookupableHelperService.getDocFormKey();
142 }
143
144 @Override
145 public String getDocNum() {
146 return lookupableHelperService.getDocNum();
147 }
148
149 @Override
150 public Field getExtraField() {
151 return lookupableHelperService.getExtraField();
152 }
153
154 @Override
155 public HtmlData getInquiryUrl(BusinessObject businessObject, String propertyName) {
156 return lookupableHelperService.getInquiryUrl(businessObject, propertyName);
157 }
158
159 @Override
160 public String getMaintenanceUrl(BusinessObject businessObject, HtmlData htmlData, List pkNames, BusinessObjectRestrictions businessObjectRestrictions) {
161 return lookupableHelperService.getMaintenanceUrl(businessObject, htmlData, pkNames, businessObjectRestrictions);
162 }
163
164 @Override
165 public Map getParameters() {
166 return lookupableHelperService.getParameters();
167 }
168
169 @Override
170 public String getPrimaryKeyFieldLabels() {
171 return lookupableHelperService.getPrimaryKeyFieldLabels();
172 }
173
174 @Override
175 public List<String> getReadOnlyFieldsList() {
176 return lookupableHelperService.getReadOnlyFieldsList();
177 }
178
179 @Override
180 public List getReturnKeys() {
181 return lookupableHelperService.getReturnKeys();
182 }
183
184 @Override
185 public String getReturnLocation() {
186 return lookupableHelperService.getReturnLocation();
187 }
188
189 @Override
190 public HtmlData getReturnUrl(BusinessObject businessObject, LookupForm lookupForm, List returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
191 return lookupableHelperService.getReturnUrl(businessObject, lookupForm, returnKeys, businessObjectRestrictions);
192 }
193
194 @Override
195 public HtmlData getReturnUrl(BusinessObject businessObject, Map fieldConversions, String lookupImpl, List returnKeys, BusinessObjectRestrictions businessObjectRestrictions) {
196 return lookupableHelperService.getReturnUrl(businessObject, fieldConversions, lookupImpl, returnKeys, businessObjectRestrictions);
197 }
198
199 @Override
200 public List<Row> getRows() {
201 return lookupableHelperService.getRows();
202 }
203
204
205
206
207
208
209 @Override
210 public List getSearchResults(Map<String, String> fieldValues) {
211 List results = lookupableHelperService.getSearchResults(fieldValues);
212
213 int resultSizeBeforeRestrictions = results.size();
214 if (glInquiry) {
215 accessSecurityService.applySecurityRestrictionsForGLInquiry(results, GlobalVariables.getUserSession().getPerson());
216 }
217
218
219
220
221
222 accessSecurityService.compareListSizeAndAddMessageIfChanged(resultSizeBeforeRestrictions, results, SecKeyConstants.MESSAGE_BALANCE_INQUIRY_RESULTS_RESTRICTED);
223
224 return results;
225 }
226
227
228
229
230
231
232 @Override
233 public List getSearchResultsUnbounded(Map<String, String> fieldValues) {
234 List results = lookupableHelperService.getSearchResultsUnbounded(fieldValues);
235
236 int resultSizeBeforeRestrictions = results.size();
237 if (glInquiry) {
238 accessSecurityService.applySecurityRestrictionsForGLInquiry(results, GlobalVariables.getUserSession().getPerson());
239 }
240
241
242
243
244 accessSecurityService.compareListSizeAndAddMessageIfChanged(resultSizeBeforeRestrictions, results, SecKeyConstants.MESSAGE_BALANCE_INQUIRY_RESULTS_RESTRICTED);
245
246 return results;
247 }
248
249 @Override
250 public String getSupplementalMenuBar() {
251 return lookupableHelperService.getSupplementalMenuBar();
252 }
253
254 @Override
255 public String getTitle() {
256 return lookupableHelperService.getTitle();
257 }
258
259 @Override
260 public boolean isResultReturnable(BusinessObject object) {
261 return lookupableHelperService.isResultReturnable(object);
262 }
263
264 @Override
265 public boolean isSearchUsingOnlyPrimaryKeyValues() {
266 return lookupableHelperService.isSearchUsingOnlyPrimaryKeyValues();
267 }
268
269 @Override
270 public void performClear(LookupForm lookupForm) {
271 lookupableHelperService.performClear(lookupForm);
272 }
273
274 @Override
275 public boolean performCustomAction(boolean ignoreErrors) {
276 return lookupableHelperService.performCustomAction(ignoreErrors);
277 }
278
279
280
281
282
283
284 @Override
285 public Collection performLookup(LookupForm lookupForm, Collection resultTable, boolean bounded) {
286 Map lookupFormFields = lookupForm.getFieldsForLookup();
287
288 setBackLocation((String) lookupForm.getFieldsForLookup().get(KRADConstants.BACK_LOCATION));
289 setDocFormKey((String) lookupForm.getFieldsForLookup().get(KRADConstants.DOC_FORM_KEY));
290 Collection displayList;
291
292
293 preprocessDateFields(lookupFormFields);
294
295 Map fieldsForLookup = new HashMap(lookupForm.getFieldsForLookup());
296
297 if (bounded) {
298 displayList = getSearchResults(lookupForm.getFieldsForLookup());
299 }
300 else {
301 displayList = getSearchResultsUnbounded(lookupForm.getFieldsForLookup());
302 }
303
304 HashMap<String, Class> propertyTypes = new HashMap<String, Class>();
305
306 boolean hasReturnableRow = false;
307
308 List returnKeys = getReturnKeys();
309 List pkNames = businessObjectMetaDataService.listPrimaryKeyFieldNames(getBusinessObjectClass());
310 Person user = GlobalVariables.getUserSession().getPerson();
311
312
313 for (Iterator iter = displayList.iterator(); iter.hasNext();) {
314 BusinessObject element = (BusinessObject) iter.next();
315 if (element instanceof PersistableBusinessObject) {
316 lookupForm.setLookupObjectId(((PersistableBusinessObject) element).getObjectId());
317 }
318
319 BusinessObjectRestrictions businessObjectRestrictions = businessObjectAuthorizationService.getLookupResultRestrictions(element, user);
320
321 HtmlData returnUrl = getReturnUrl(element, lookupForm, returnKeys, businessObjectRestrictions);
322
323 String actionUrls = getActionUrls(element, pkNames, businessObjectRestrictions);
324
325 if ("".equals(actionUrls)) {
326 actionUrls = ACTION_URLS_EMPTY;
327 }
328
329 List<Column> columns = getColumns();
330 for (Object element2 : columns) {
331
332 Column col = (Column) element2;
333 Formatter formatter = col.getFormatter();
334
335
336 String propValue = KRADConstants.EMPTY_STRING;
337 Object prop = ObjectUtils.getPropertyValue(element, col.getPropertyName());
338
339
340 Class propClass = propertyTypes.get(col.getPropertyName());
341 if (propClass == null) {
342 try {
343 propClass = ObjectUtils.getPropertyType(element, col.getPropertyName(), persistenceStructureService);
344 propertyTypes.put(col.getPropertyName(), propClass);
345 }
346 catch (Exception e) {
347 throw new RuntimeException("Cannot access PropertyType for property " + "'" + col.getPropertyName() + "' " + " on an instance of '" + element.getClass().getName() + "'.", e);
348 }
349 }
350
351
352 if (prop != null) {
353
354 if (prop instanceof Boolean) {
355 formatter = new BooleanFormatter();
356 }
357
358
359 if (prop instanceof Date) {
360 formatter = new DateFormatter();
361 }
362
363
364 if (prop instanceof Collection && formatter == null) {
365 formatter = new CollectionFormatter();
366 }
367
368 if (formatter != null) {
369 propValue = (String) formatter.format(prop);
370 }
371 else {
372 propValue = prop.toString();
373 }
374 }
375
376
377 col.setComparator(CellComparatorHelper.getAppropriateComparatorForPropertyClass(propClass));
378 col.setValueComparator(CellComparatorHelper.getAppropriateValueComparatorForPropertyClass(propClass));
379
380 propValue = maskValueIfNecessary(element.getClass(), col.getPropertyName(), propValue, businessObjectRestrictions);
381
382 col.setPropertyValue(propValue);
383
384 if (StringUtils.isNotBlank(propValue)) {
385 col.setColumnAnchor(getInquiryUrl(element, col.getPropertyName()));
386
387 }
388 }
389
390 ResultRow row = new ResultRow(columns, returnUrl.constructCompleteHtmlTag(), actionUrls);
391 row.setRowId(returnUrl.getName());
392 row.setReturnUrlHtmlData(returnUrl);
393
394
395 if (getBusinessObjectDictionaryService().isExportable(getBusinessObjectClass())) {
396 row.setBusinessObject(element);
397 }
398
399 if (element instanceof PersistableBusinessObject) {
400 row.setObjectId((((PersistableBusinessObject) element).getObjectId()));
401 }
402
403
404 boolean rowReturnable = isResultReturnable(element);
405 row.setRowReturnable(rowReturnable);
406 if (rowReturnable) {
407 hasReturnableRow = true;
408 }
409 resultTable.add(row);
410 }
411
412 lookupForm.setHasReturnableRow(hasReturnableRow);
413
414 return displayList;
415 }
416
417
418
419
420
421
422 protected Column setupResultsColumn(BusinessObject element, String attributeName, BusinessObjectRestrictions businessObjectRestrictions) {
423 Column col = new Column();
424
425 col.setPropertyName(attributeName);
426
427 String columnTitle = getDataDictionaryService().getAttributeLabel(getBusinessObjectClass(), attributeName);
428 if (StringUtils.isBlank(columnTitle)) {
429 columnTitle = getDataDictionaryService().getCollectionLabel(getBusinessObjectClass(), attributeName);
430 }
431 col.setColumnTitle(columnTitle);
432 col.setMaxLength(getDataDictionaryService().getAttributeMaxLength(getBusinessObjectClass(), attributeName));
433
434 Class formatterClass = getDataDictionaryService().getAttributeFormatter(getBusinessObjectClass(), attributeName);
435 Formatter formatter = null;
436 if (formatterClass != null) {
437 try {
438 formatter = (Formatter) formatterClass.newInstance();
439 col.setFormatter(formatter);
440 }
441 catch (InstantiationException e) {
442 throw new RuntimeException("Unable to get new instance of formatter class: " + formatterClass.getName());
443 }
444 catch (IllegalAccessException e) {
445 throw new RuntimeException("Unable to get new instance of formatter class: " + formatterClass.getName());
446 }
447 }
448
449
450 String propValue = OLEConstants.EMPTY_STRING;
451 Object prop = ObjectUtils.getPropertyValue(element, attributeName);
452
453
454 Class propClass = null;
455 try {
456 PropertyDescriptor propDescriptor = PropertyUtils.getPropertyDescriptor(element, col.getPropertyName());
457 if (propDescriptor != null) {
458 propClass = propDescriptor.getPropertyType();
459 }
460 }
461 catch (Exception e) {
462 throw new RuntimeException("Cannot access PropertyType for property " + "'" + col.getPropertyName() + "' " + " on an instance of '" + element.getClass().getName() + "'.", e);
463 }
464
465
466 if (prop != null) {
467
468 if (prop instanceof Boolean) {
469 formatter = new BooleanFormatter();
470 }
471
472 if (formatter != null) {
473 propValue = (String) formatter.format(prop);
474 }
475 else {
476 propValue = prop.toString();
477 }
478 }
479
480
481 col.setComparator(CellComparatorHelper.getAppropriateComparatorForPropertyClass(propClass));
482 col.setValueComparator(CellComparatorHelper.getAppropriateValueComparatorForPropertyClass(propClass));
483
484 propValue = maskValueIfNecessary(element.getClass(), col.getPropertyName(), propValue, businessObjectRestrictions);
485 col.setPropertyValue(propValue);
486
487
488 if (StringUtils.isNotBlank(propValue)) {
489 col.setColumnAnchor(getInquiryUrl(element, col.getPropertyName()));
490 }
491 return col;
492 }
493
494
495
496
497
498
499
500 protected Map<String, String> preprocessDateFields(Map lookupFormFields) {
501 Map<String, String> fieldsToUpdate = new HashMap<String, String>();
502 Set<String> fieldsForLookup = lookupFormFields.keySet();
503 for (String propName : fieldsForLookup) {
504 if (propName.startsWith(KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX)) {
505 String fromDateValue = (String) lookupFormFields.get(propName);
506 String dateFieldName = StringUtils.remove(propName, KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX);
507 String dateValue = (String) lookupFormFields.get(dateFieldName);
508 String newPropValue = dateValue;
509 if (StringUtils.isNotEmpty(fromDateValue) && StringUtils.isNotEmpty(dateValue)) {
510 newPropValue = fromDateValue + ".." + dateValue;
511 }
512 else if (StringUtils.isNotEmpty(fromDateValue) && StringUtils.isEmpty(dateValue)) {
513 newPropValue = ">=" + fromDateValue;
514 }
515 else if (StringUtils.isNotEmpty(dateValue) && StringUtils.isEmpty(fromDateValue)) {
516 newPropValue = "<=" + dateValue;
517 }
518
519 fieldsToUpdate.put(dateFieldName, newPropValue);
520 }
521 }
522
523 Set<String> keysToUpdate = fieldsToUpdate.keySet();
524 for (String updateKey : keysToUpdate) {
525 lookupFormFields.put(updateKey, fieldsToUpdate.get(updateKey));
526 }
527 return fieldsToUpdate;
528 }
529
530 protected String maskValueIfNecessary(Class businessObjectClass, String propertyName, String propertyValue, BusinessObjectRestrictions businessObjectRestrictions) {
531 String maskedPropertyValue = propertyValue;
532 if (businessObjectRestrictions != null) {
533 FieldRestriction fieldRestriction = businessObjectRestrictions.getFieldRestriction(propertyName);
534 if (fieldRestriction != null && (fieldRestriction.isMasked() || fieldRestriction.isPartiallyMasked())) {
535 maskedPropertyValue = fieldRestriction.getMaskFormatter().maskValue(propertyValue);
536 }
537 }
538 return maskedPropertyValue;
539 }
540
541 @Override
542 public void setBackLocation(String backLocation) {
543 lookupableHelperService.setBackLocation(backLocation);
544 }
545
546 @Override
547 public void setBusinessObjectClass(Class businessObjectClass) {
548 lookupableHelperService.setBusinessObjectClass(businessObjectClass);
549 }
550
551 @Override
552 public void setDocFormKey(String docFormKey) {
553 lookupableHelperService.setDocFormKey(docFormKey);
554 }
555
556 @Override
557 public void setDocNum(String docNum) {
558 lookupableHelperService.setDocNum(docNum);
559 }
560
561 @Override
562 public void setFieldConversions(Map fieldConversions) {
563 lookupableHelperService.setFieldConversions(fieldConversions);
564 }
565
566 @Override
567 public void setParameters(Map parameters) {
568 lookupableHelperService.setParameters(parameters);
569 }
570
571 @Override
572 public void setReadOnlyFieldsList(List<String> readOnlyFieldsList) {
573 lookupableHelperService.setReadOnlyFieldsList(readOnlyFieldsList);
574 }
575
576 @Override
577 public boolean shouldDisplayHeaderNonMaintActions() {
578 return lookupableHelperService.shouldDisplayHeaderNonMaintActions();
579 }
580
581 @Override
582 public boolean shouldDisplayLookupCriteria() {
583 return lookupableHelperService.shouldDisplayLookupCriteria();
584 }
585
586 @Override
587 public void validateSearchParameters(Map fieldValues) {
588 lookupableHelperService.validateSearchParameters(fieldValues);
589 }
590
591
592
593
594
595
596 public void setAccessSecurityService(AccessSecurityService accessSecurityService) {
597 this.accessSecurityService = accessSecurityService;
598 }
599
600
601
602
603
604
605 public void setLookupableHelperService(LookupableHelperService lookupableHelperService) {
606 this.lookupableHelperService = lookupableHelperService;
607 }
608
609
610
611
612
613
614 public void setBusinessObjectMetaDataService(BusinessObjectMetaDataService businessObjectMetaDataService) {
615 this.businessObjectMetaDataService = businessObjectMetaDataService;
616 }
617
618
619
620
621
622
623 public void setBusinessObjectAuthorizationService(BusinessObjectAuthorizationService businessObjectAuthorizationService) {
624 this.businessObjectAuthorizationService = businessObjectAuthorizationService;
625 }
626
627
628
629
630
631
632 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
633 this.persistenceStructureService = persistenceStructureService;
634 }
635
636
637
638
639
640
641 public void setGlInquiry(boolean glInquiry) {
642 this.glInquiry = glInquiry;
643 }
644
645
646
647
648
649
650 public void setLaborInquiry(boolean laborInquiry) {
651 this.laborInquiry = laborInquiry;
652 }
653
654
655 @Override
656 public void applyConditionalLogicForFieldDisplay() {
657
658 }
659
660 }