View Javadoc

1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kns.inquiry;
17  
18  import org.apache.commons.collections.BidiMap;
19  import org.apache.commons.collections.bidimap.DualHashBidiMap;
20  import org.apache.commons.lang.StringUtils;
21  import org.kuali.rice.core.api.CoreApiServiceLocator;
22  import org.kuali.rice.core.api.config.property.ConfigurationService;
23  import org.kuali.rice.core.api.encryption.EncryptionService;
24  import org.kuali.rice.core.web.format.Formatter;
25  import org.kuali.rice.kns.datadictionary.InquirySectionDefinition;
26  import org.kuali.rice.kns.lookup.HtmlData;
27  import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
28  import org.kuali.rice.kns.lookup.LookupUtils;
29  import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
30  import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
31  import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
32  import org.kuali.rice.kns.service.KNSServiceLocator;
33  import org.kuali.rice.kns.util.InactiveRecordsHidingUtils;
34  import org.kuali.rice.kns.web.ui.Section;
35  import org.kuali.rice.kns.web.ui.SectionBridge;
36  import org.kuali.rice.krad.bo.BusinessObject;
37  import org.kuali.rice.krad.bo.DataObjectRelationship;
38  import org.kuali.rice.krad.bo.DocumentHeader;
39  import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
40  import org.kuali.rice.krad.datadictionary.AttributeSecurity;
41  import org.kuali.rice.krad.inquiry.InquirableImpl;
42  import org.kuali.rice.krad.lookup.CollectionIncomplete;
43  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
44  import org.kuali.rice.krad.service.LookupService;
45  import org.kuali.rice.krad.service.ModuleService;
46  import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
47  import org.kuali.rice.krad.util.GlobalVariables;
48  import org.kuali.rice.krad.util.KRADConstants;
49  import org.kuali.rice.krad.util.ObjectUtils;
50  import org.kuali.rice.krad.util.UrlFactory;
51  
52  import java.security.GeneralSecurityException;
53  import java.util.ArrayList;
54  import java.util.Collection;
55  import java.util.Collections;
56  import java.util.HashMap;
57  import java.util.Iterator;
58  import java.util.List;
59  import java.util.Map;
60  import java.util.Properties;
61  
62  /**
63   * Kuali inquirable implementation. Implements methods necessary to retrieve the
64   * business object and render the ui.
65   * 
66   * NOTE: this class is not thread safe. When using this class or any subclasses
67   * in Spring, make sure that this is not a singleton service, or serious errors
68   * may occur.
69   * 
70   * @author Kuali Rice Team (rice.collab@kuali.org)
71   */
72  public class KualiInquirableImpl extends InquirableImpl implements Inquirable {
73  	private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiInquirableImpl.class);
74  
75  	protected LookupService lookupService;
76  	protected BusinessObjectAuthorizationService businessObjectAuthorizationService;
77  	protected BusinessObjectDictionaryService businessObjectDictionaryService;
78  	protected BusinessObjectMetaDataService businessObjectMetaDataService;
79  	protected EncryptionService encryptionService;
80  
81  	protected Map<String, Boolean> inactiveRecordDisplay;
82  
83  	public static final String INQUIRY_TITLE_PREFIX = "title.inquiry.url.value.prependtext";
84  
85  	/**
86  	 * Default constructor, initializes services from spring
87  	 */
88  	public KualiInquirableImpl() {
89  		inactiveRecordDisplay = new HashMap<String, Boolean>();
90  	}
91  
92  	/**
93  	 * TODO: generics do not match between call to module service and call to
94  	 * lookup service
95  	 * 
96  	 * @see Inquirable#retrieveDataObject(java.util.Map)
97  	 */
98  	@SuppressWarnings("rawtypes")
99  	@Override
100 	public Object retrieveDataObject(Map fieldValues) {
101 		if (getDataObjectClass() == null) {
102 			LOG.error("Data object class not set in inquirable.");
103 			throw new RuntimeException(
104 					"Data object class not set in inquirable.");
105 		}
106 
107 		CollectionIncomplete<Object> searchResults = null;
108 		ModuleService moduleService = KRADServiceLocatorWeb
109 				.getKualiModuleService().getResponsibleModuleService(
110 						getDataObjectClass());
111 		if (moduleService != null
112 				&& moduleService.isExternalizable(getDataObjectClass())) {
113 			BusinessObject bo = moduleService.getExternalizableBusinessObject(
114 					getBusinessObjectClass(), fieldValues);
115 			if (bo != null) {
116 				ArrayList<Object> list = new ArrayList<Object>(1);
117 				list.add(bo);
118 				searchResults = new CollectionIncomplete<Object>(list, 1L);
119 			}
120 		} else {
121 			// TODO: If this is to get a single BO, why using the lookup
122 			// service?
123 			searchResults = (CollectionIncomplete<Object>) getLookupService()
124 					.findCollectionBySearch(getBusinessObjectClass(),
125 							fieldValues);
126 		}
127 		
128 		BusinessObject foundObject = null;
129 		if (searchResults != null && searchResults.size() > 0) {
130 			foundObject = (BusinessObject) searchResults.get(0);
131 		}
132 		
133 		return foundObject;
134 	}
135 
136     /**
137 	 * Return a business object by searching with map, the map keys should be a
138 	 * property name of the business object, with the map value as the value to
139 	 * search for.
140 	 */
141     @Deprecated
142 	public BusinessObject getBusinessObject(Map fieldValues) {
143 		return (BusinessObject) retrieveDataObject(fieldValues);
144 	}
145 
146 	/**
147 	 * Objects extending KualiInquirableBase must specify the Section objects
148 	 * used to display the inquiry result.
149 	 */
150 	@Deprecated
151 	public List<Section> getSections(BusinessObject bo) {
152 
153 		List<Section> sections = new ArrayList<Section>();
154 		if (getBusinessObjectClass() == null) {
155 			LOG.error("Business object class not set in inquirable.");
156 			throw new RuntimeException("Business object class not set in inquirable.");
157 		}
158 
159 		InquiryRestrictions inquiryRestrictions = KNSServiceLocator.getBusinessObjectAuthorizationService()
160 				.getInquiryRestrictions(bo, GlobalVariables.getUserSession().getPerson());
161 
162 		Collection<InquirySectionDefinition> inquirySections = getBusinessObjectDictionaryService().getInquirySections(
163 				getBusinessObjectClass());
164 		for (Iterator<InquirySectionDefinition> iter = inquirySections.iterator(); iter.hasNext();) {
165 			InquirySectionDefinition inquirySection = iter.next();
166 			if (!inquiryRestrictions.isHiddenSectionId(inquirySection.getId())) {
167 				Section section = SectionBridge.toSection(this, inquirySection, bo, inquiryRestrictions);
168 				sections.add(section);
169 			}
170 		}
171 
172 		return sections;
173 	}
174 
175 	/**
176 	 * Helper method to build an inquiry url for a result field.
177 	 * 
178 	 * @param bo
179 	 *            the business object instance to build the urls for
180 	 * @param propertyName
181 	 *            the property which links to an inquirable
182 	 * @return String url to inquiry
183 	 */
184 	@Deprecated
185 	public HtmlData getInquiryUrl(BusinessObject businessObject, String attributeName, boolean forceInquiry) {
186 		Properties parameters = new Properties();
187 		AnchorHtmlData hRef = new AnchorHtmlData(KRADConstants.EMPTY_STRING, KRADConstants.EMPTY_STRING);
188 		parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, "start");
189 
190 		Class inquiryBusinessObjectClass = null;
191 		String attributeRefName = "";
192 		boolean isPkReference = false;
193 
194 		boolean doesNestedReferenceHaveOwnPrimitiveReference = false;
195 		BusinessObject nestedBusinessObject = null;
196 
197 		Class businessObjectClass = ObjectUtils.materializeClassForProxiedObject(businessObject);
198 		if (attributeName.equals(getBusinessObjectDictionaryService().getTitleAttribute(businessObjectClass))) {
199 			inquiryBusinessObjectClass = businessObjectClass;
200 			isPkReference = true;
201 		}
202 		else {
203 			if (ObjectUtils.isNestedAttribute(attributeName)) {
204 				// if we have a reference object, we should determine if we
205 				// should either provide an inquiry link to
206 				// the reference object itself, or some other nested primitive.
207 
208 				// for example, if the attribute is
209 				// "referenceObject.someAttribute", and there is no primitive
210 				// reference for
211 				// "someAttribute", then an inquiry link is provided to the
212 				// "referenceObject". If it does have a primitive reference,
213 				// then
214 				// the inquiry link is directed towards it instead
215 				String nestedReferenceName = ObjectUtils.getNestedAttributePrefix(attributeName);
216 				Object nestedReferenceObject = ObjectUtils.getNestedValue(businessObject, nestedReferenceName);
217 
218 				if (ObjectUtils.isNotNull(nestedReferenceObject) && nestedReferenceObject instanceof BusinessObject) {
219 					nestedBusinessObject = (BusinessObject) nestedReferenceObject;
220 					String nestedAttributePrimitive = ObjectUtils.getNestedAttributePrimitive(attributeName);
221 					Class nestedBusinessObjectClass = ObjectUtils
222 							.materializeClassForProxiedObject(nestedBusinessObject);
223 
224 					if (nestedAttributePrimitive.equals(getBusinessObjectDictionaryService().getTitleAttribute(
225 							nestedBusinessObjectClass))) {
226 						// we are going to inquiry the record that contains the
227 						// attribute we're rendering an inquiry URL for
228 						inquiryBusinessObjectClass = nestedBusinessObjectClass;
229 						// I know it's already set to false, just to show how
230 						// this variable is set
231 						doesNestedReferenceHaveOwnPrimitiveReference = false;
232 					}
233 					else {
234 						Map primitiveReference = LookupUtils.getPrimitiveReference(nestedBusinessObject,
235 								nestedAttributePrimitive);
236 						if (primitiveReference != null && !primitiveReference.isEmpty()) {
237 							attributeRefName = (String) primitiveReference.keySet().iterator().next();
238 							inquiryBusinessObjectClass = (Class) primitiveReference.get(attributeRefName);
239 							doesNestedReferenceHaveOwnPrimitiveReference = true;
240 						}
241 						else {
242 							// we are going to inquiry the record that contains
243 							// the attribute we're rendering an inquiry URL for
244 							inquiryBusinessObjectClass = ObjectUtils
245 									.materializeClassForProxiedObject(nestedBusinessObject);
246 							// I know it's already set to false, just to show
247 							// how this variable is set
248 							doesNestedReferenceHaveOwnPrimitiveReference = false;
249 						}
250 					}
251 				}
252 			}
253 			else {
254 				Map primitiveReference = LookupUtils.getPrimitiveReference(businessObject, attributeName);
255 				if (primitiveReference != null && !primitiveReference.isEmpty()) {
256 					attributeRefName = (String) primitiveReference.keySet().iterator().next();
257 					inquiryBusinessObjectClass = (Class) primitiveReference.get(attributeRefName);
258 				}
259 			}
260 		}
261 
262 		if (inquiryBusinessObjectClass != null && DocumentHeader.class.isAssignableFrom(inquiryBusinessObjectClass)) {
263 			String documentNumber = (String) ObjectUtils.getPropertyValue(businessObject, attributeName);
264 			if (!StringUtils.isBlank(documentNumber)) {
265 				// if NullPointerException on the following line, maybe the
266 				// Spring bean wasn't injected w/ KualiConfigurationException,
267 				// or if
268 				// instances of a sub-class of this class are not Spring
269 				// created, then override getKualiConfigurationService() in the
270 				// subclass
271 				// to return the configuration service from a Spring service
272 				// locator (or set it).
273 				hRef.setHref(getKualiConfigurationService().getPropertyValueAsString(KRADConstants.WORKFLOW_URL_KEY)
274 						+ KRADConstants.DOCHANDLER_DO_URL + documentNumber + KRADConstants.DOCHANDLER_URL_CHUNK);
275 			}
276 			return hRef;
277 		}
278 
279 		if (inquiryBusinessObjectClass == null
280 				|| getBusinessObjectDictionaryService().isInquirable(inquiryBusinessObjectClass) == null
281 				|| !getBusinessObjectDictionaryService().isInquirable(inquiryBusinessObjectClass).booleanValue()) {
282 			return hRef;
283 		}
284 
285 		synchronized (SUPER_CLASS_TRANSLATOR_LIST) {
286 			for (Class clazz : SUPER_CLASS_TRANSLATOR_LIST) {
287 				if (clazz.isAssignableFrom(inquiryBusinessObjectClass)) {
288 					inquiryBusinessObjectClass = clazz;
289 					break;
290 				}
291 			}
292 		}
293 
294 		if (!inquiryBusinessObjectClass.isInterface()
295 				&& ExternalizableBusinessObject.class.isAssignableFrom(inquiryBusinessObjectClass)) {
296 			inquiryBusinessObjectClass = ExternalizableBusinessObjectUtils
297 					.determineExternalizableBusinessObjectSubInterface(inquiryBusinessObjectClass);
298 		}
299 
300 		parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, inquiryBusinessObjectClass.getName());
301 
302 		// listPrimaryKeyFieldNames returns an unmodifiable list. So a copy is
303 		// necessary.
304 		List<String> keys = new ArrayList<String>(getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(
305 				inquiryBusinessObjectClass));
306 
307 		if (keys == null) {
308 			keys = Collections.emptyList();
309 		}
310 
311 		DataObjectRelationship dataObjectRelationship = null;
312 
313 		if (attributeRefName != null && !"".equals(attributeRefName)) {
314 			dataObjectRelationship = getBusinessObjectMetaDataService().getBusinessObjectRelationship(
315 					businessObject, attributeRefName);
316 
317 			if (dataObjectRelationship != null && dataObjectRelationship.getParentToChildReferences() != null) {
318 				for (String targetNamePrimaryKey : dataObjectRelationship.getParentToChildReferences().values()) {
319 					keys.add(targetNamePrimaryKey);
320 				}
321 			}
322 		}
323 		// build key value url parameters used to retrieve the business object
324 		String keyName = null;
325 		String keyConversion = null;
326 		Map<String, String> fieldList = new HashMap<String, String>();
327 		for (Iterator iter = keys.iterator(); iter.hasNext();) {
328 			keyName = (String) iter.next();
329 			keyConversion = keyName;
330 			if (ObjectUtils.isNestedAttribute(attributeName)) {
331 				if (doesNestedReferenceHaveOwnPrimitiveReference) {
332 					String nestedAttributePrefix = ObjectUtils.getNestedAttributePrefix(attributeName);
333 					// String foreignKeyFieldName =
334 					// getBusinessObjectMetaDataService().getForeignKeyFieldName(
335 					// inquiryBusinessObjectClass.getClass(), attributeRefName,
336 					// keyName);
337 
338 					String foreignKeyFieldName = getBusinessObjectMetaDataService().getForeignKeyFieldName(
339 							nestedBusinessObject.getClass(), attributeRefName, keyName);
340 					keyConversion = nestedAttributePrefix + "." + foreignKeyFieldName;
341 				}
342 				else {
343 					keyConversion = ObjectUtils.getNestedAttributePrefix(attributeName) + "." + keyName;
344 				}
345 			}
346 			else {
347 				if (isPkReference) {
348 					keyConversion = keyName;
349 				}
350 				else if (dataObjectRelationship != null) {
351 					// Using BusinessObjectMetaDataService instead of
352 					// PersistenceStructureService
353 					// since otherwise, relationship information from
354 					// datadictionary is not used at all
355 					// Also, BOMDS.getBusinessObjectRelationship uses
356 					// PersistenceStructureService,
357 					// so both datadictionary and the persistance layer get
358 					// covered
359 					/*
360 					 * DataObjectRelationship dataObjectRelationship =
361 					 * getBusinessObjectMetaDataService
362 					 * ().getBusinessObjectRelationship( businessObject,
363 					 * attributeRefName);
364 					 */
365 					BidiMap bidiMap = new DualHashBidiMap(dataObjectRelationship.getParentToChildReferences());
366 					keyConversion = (String) bidiMap.getKey(keyName);
367 					// keyConversion =
368 					// getPersistenceStructureService().getForeignKeyFieldName(businessObject.getClass(),
369 					// attributeRefName, keyName);
370 				}
371 			}
372 			Object keyValue = null;
373 			if (keyConversion != null) {
374 				keyValue = ObjectUtils.getPropertyValue(businessObject, keyConversion);
375 			}
376 
377 			if (keyValue == null) {
378 				keyValue = "";
379 			}
380 			else if (keyValue instanceof java.sql.Date) { // format the date for
381 															// passing in url
382 				if (Formatter.findFormatter(keyValue.getClass()) != null) {
383 					Formatter formatter = Formatter.getFormatter(keyValue.getClass());
384 					keyValue = (String) formatter.format(keyValue);
385 				}
386 			}
387 			else {
388 				keyValue = keyValue.toString();
389 			}
390 
391 			// Encrypt value if it is a field that has restriction that prevents
392 			// a value from being shown to user,
393 			// because we don't want the browser history to store the restricted
394 			// attribute's value in the URL
395 			AttributeSecurity attributeSecurity = KRADServiceLocatorWeb.getDataDictionaryService().getAttributeSecurity(
396 					businessObject.getClass().getName(), keyName);
397 			if (attributeSecurity != null && attributeSecurity.hasRestrictionThatRemovesValueFromUI()) {
398 				try {
399                     if(CoreApiServiceLocator.getEncryptionService().isEnabled()) {
400 					    keyValue = getEncryptionService().encrypt(keyValue);
401                     }
402 				}
403 				catch (GeneralSecurityException e) {
404 					LOG.error("Exception while trying to encrypted value for inquiry framework.", e);
405 					throw new RuntimeException(e);
406 				}
407 			}
408 
409 			parameters.put(keyName, keyValue);
410 			fieldList.put(keyName, keyValue.toString());
411 		}
412 
413 		return getHyperLink(inquiryBusinessObjectClass, fieldList,
414 				UrlFactory.parameterizeUrl(KRADConstants.INQUIRY_ACTION, parameters));
415 	}
416 
417 	@Deprecated
418 	protected AnchorHtmlData getHyperLink(Class inquiryClass, Map<String, String> fieldList, String inquiryUrl) {
419 		AnchorHtmlData a = new AnchorHtmlData(inquiryUrl, KRADConstants.EMPTY_STRING);
420 		a.setTitle(HtmlData.getTitleText(this.createTitleText(inquiryClass), inquiryClass, fieldList));
421 		return a;
422 	}
423 
424 	/**
425 	 * Gets text to prepend to the inquiry link title
426 	 * 
427 	 * @param dataObjectClass
428 	 *            - data object class being inquired into
429 	 * @return String title prepend text
430 	 */
431 	@Deprecated
432 	protected String createTitleText(Class<?> dataObjectClass) {
433 		String titleText = "";
434 
435 		String titlePrefixProp = getKualiConfigurationService().getPropertyValueAsString(INQUIRY_TITLE_PREFIX);
436 		if (StringUtils.isNotBlank(titlePrefixProp)) {
437 			titleText += titlePrefixProp + " ";
438 		}
439 
440 		String objectLabel = getDataDictionaryService().getDataDictionary()
441 				.getBusinessObjectEntry(dataObjectClass.getName()).getObjectLabel();
442 		if (StringUtils.isNotBlank(objectLabel)) {
443 			titleText += objectLabel + " ";
444 		}
445 
446 		return titleText;
447 	}
448 
449 	@Deprecated
450 	public void addAdditionalSections(List columns, BusinessObject bo) {
451 	}
452 
453 	/**
454 	 * @see Inquirable#getHtmlMenuBar()
455 	 */
456 	@Deprecated
457 	public String getHtmlMenuBar() {
458 		// TODO: replace with inquiry menu bar
459 		return getBusinessObjectDictionaryService().getLookupMenuBar(getBusinessObjectClass());
460 	}
461 
462 	/**
463 	 * @see Inquirable#getTitle()
464 	 */
465 	@Deprecated
466 	public String getTitle() {
467 		return getBusinessObjectDictionaryService().getInquiryTitle(getBusinessObjectClass());
468 	}
469 
470     /**
471 	 * @param businessObjectClass
472 	 *            The dataObjectClass to set.
473 	 */
474 	@Deprecated
475 	public void setBusinessObjectClass(Class businessObjectClass) {
476 		this.dataObjectClass = businessObjectClass;
477 	}
478 
479 	/**
480      * @return Returns the dataObjectClass.
481      */
482     @Deprecated
483     public Class getBusinessObjectClass() {
484         return dataObjectClass;
485     }
486     
487 	/**
488 	 * @see Inquirable#getInactiveRecordDisplay()
489 	 */
490 	@Deprecated
491 	public Map<String, Boolean> getInactiveRecordDisplay() {
492 		return inactiveRecordDisplay;
493 	}
494 
495 	/**
496 	 * @see Inquirable#getShowInactiveRecords(java.lang.String)
497 	 */
498 	@Deprecated
499 	public boolean getShowInactiveRecords(String collectionName) {
500 		return InactiveRecordsHidingUtils.getShowInactiveRecords(inactiveRecordDisplay, collectionName);
501 	}
502 
503 	/**
504 	 * @see Inquirable#setShowInactiveRecords(java.lang.String,
505 	 *      boolean)
506 	 */
507 	@Deprecated
508 	public void setShowInactiveRecords(String collectionName, boolean showInactive) {
509 		InactiveRecordsHidingUtils.setShowInactiveRecords(inactiveRecordDisplay, collectionName, showInactive);
510 	}
511 
512 	protected LookupService getLookupService() {
513 		if (lookupService == null) {
514 			lookupService = KRADServiceLocatorWeb.getLookupService();
515 		}
516 		return lookupService;
517 	}
518 
519 	public void setLookupService(LookupService lookupService) {
520 		this.lookupService = lookupService;
521 	}
522 
523 	protected BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
524 		if (businessObjectDictionaryService == null) {
525 			businessObjectDictionaryService = KNSServiceLocator.getBusinessObjectDictionaryService();
526 		}
527 		return businessObjectDictionaryService;
528 	}
529 
530 	public void setBusinessObjectDictionaryService(BusinessObjectDictionaryService businessObjectDictionaryService) {
531 		this.businessObjectDictionaryService = businessObjectDictionaryService;
532 	}
533 
534 	protected EncryptionService getEncryptionService() {
535 		if (encryptionService == null) {
536 			encryptionService = CoreApiServiceLocator.getEncryptionService();
537 		}
538 		return this.encryptionService;
539 	}
540 
541 	public void setEncryptionService(EncryptionService encryptionService) {
542 		this.encryptionService = encryptionService;
543 	}
544 
545 	protected ConfigurationService getKualiConfigurationService() {
546 		return getConfigurationService();
547 	}
548 
549 	protected BusinessObjectMetaDataService getBusinessObjectMetaDataService() {
550 		if (businessObjectMetaDataService == null) {
551 			businessObjectMetaDataService = KNSServiceLocator.getBusinessObjectMetaDataService();
552 		}
553 		return this.businessObjectMetaDataService;
554 	}
555 
556 	public void setBusinessObjectMetaDataService(BusinessObjectMetaDataService businessObjectMetaDataService) {
557 		this.businessObjectMetaDataService = businessObjectMetaDataService;
558 	}
559 
560 	protected BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
561 		if (this.businessObjectAuthorizationService == null) {
562 			this.businessObjectAuthorizationService = KNSServiceLocator.getBusinessObjectAuthorizationService();
563 		}
564 		return this.businessObjectAuthorizationService;
565 	}
566 
567 	public void setBusinessObjectAuthorizationService(
568 			BusinessObjectAuthorizationService businessObjectAuthorizationService) {
569 		this.businessObjectAuthorizationService = businessObjectAuthorizationService;
570 	}
571 
572 	@Deprecated
573 	protected AnchorHtmlData getInquiryUrlForPrimaryKeys(Class clazz, Object businessObject, List<String> primaryKeys,
574 			String displayText) {
575 		if (businessObject == null)
576 			return new AnchorHtmlData(KRADConstants.EMPTY_STRING, KRADConstants.EMPTY_STRING);
577 
578 		Properties parameters = new Properties();
579 		parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.START_METHOD);
580 		parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, clazz.getName());
581 
582 		String titleAttributeValue;
583 		Map<String, String> fieldList = new HashMap<String, String>();
584 		for (String primaryKey : primaryKeys) {
585 			titleAttributeValue = (String) ObjectUtils.getPropertyValue(businessObject, primaryKey);
586 			parameters.put(primaryKey, titleAttributeValue);
587 			fieldList.put(primaryKey, titleAttributeValue);
588 		}
589 		if (StringUtils.isEmpty(displayText))
590 			return getHyperLink(clazz, fieldList, UrlFactory.parameterizeUrl(KRADConstants.INQUIRY_ACTION, parameters));
591 		else
592 			return getHyperLink(clazz, fieldList, UrlFactory.parameterizeUrl(KRADConstants.INQUIRY_ACTION, parameters),
593 					displayText);
594 	}
595 
596 	@Deprecated
597 	protected AnchorHtmlData getHyperLink(Class inquiryClass, Map<String, String> fieldList, String inquiryUrl,
598 			String displayText) {
599 		AnchorHtmlData a = new AnchorHtmlData(inquiryUrl, KRADConstants.EMPTY_STRING, displayText);
600 		a.setTitle(AnchorHtmlData.getTitleText(getKualiConfigurationService().getPropertyValueAsString(
601                 INQUIRY_TITLE_PREFIX)
602 				+ " "
603 				+ getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(inquiryClass.getName())
604 						.getObjectLabel() + " ", inquiryClass, fieldList));
605 		return a;
606 	}
607 
608 }