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