View Javadoc

1   /*
2    * Copyright 2005-2007 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.krad.service.impl;
17  
18  import java.beans.IndexedPropertyDescriptor;
19  import java.beans.PropertyDescriptor;
20  import java.lang.reflect.InvocationTargetException;
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Set;
27  
28  import org.apache.commons.beanutils.PropertyUtils;
29  import org.apache.commons.lang.StringUtils;
30  import org.apache.log4j.Logger;
31  import org.kuali.rice.kew.api.KewApiServiceLocator;
32  import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
33  import org.kuali.rice.kns.datadictionary.FieldDefinition;
34  import org.kuali.rice.kns.datadictionary.InquiryDefinition;
35  import org.kuali.rice.kns.datadictionary.InquirySectionDefinition;
36  import org.kuali.rice.kns.datadictionary.LookupDefinition;
37  import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry;
38  import org.kuali.rice.krad.bo.BusinessObject;
39  import org.kuali.rice.krad.bo.PersistableBusinessObject;
40  import org.kuali.rice.krad.exception.IntrospectionException;
41  import org.kuali.rice.krad.inquiry.InquiryAuthorizer;
42  import org.kuali.rice.krad.inquiry.InquiryAuthorizerBase;
43  import org.kuali.rice.krad.inquiry.InquiryPresentationController;
44  import org.kuali.rice.krad.inquiry.InquiryPresentationControllerBase;
45  import org.kuali.rice.krad.service.BusinessObjectDictionaryService;
46  import org.kuali.rice.krad.service.DataDictionaryService;
47  import org.kuali.rice.krad.service.PersistenceStructureService;
48  import org.kuali.rice.krad.util.ObjectUtils;
49  import org.kuali.rice.krad.valuefinder.ValueFinder;
50  
51  /**
52   * This class is the service implementation for the BusinessObjectDictionary.
53   * This is the default, Kuali delivered implementation which leverages the
54   * DataDictionaryService.
55   */
56  @Deprecated
57  public class BusinessObjectDictionaryServiceImpl implements
58  		BusinessObjectDictionaryService {
59  	private static Logger LOG = Logger
60  			.getLogger(BusinessObjectDictionaryServiceImpl.class);
61  
62      private DataDictionaryService dataDictionaryService;
63      private PersistenceStructureService persistenceStructureService;
64  
65  	public <T extends BusinessObject> InquiryAuthorizer getInquiryAuthorizer(
66  			Class<T> businessObjectClass) {
67  		Class inquiryAuthorizerClass = ((BusinessObjectEntry) getDataDictionaryService()
68  				.getDataDictionary().getBusinessObjectEntry(
69  						businessObjectClass.getName())).getInquiryDefinition()
70  				.getAuthorizerClass();
71  		if (inquiryAuthorizerClass == null) {
72  			inquiryAuthorizerClass = InquiryAuthorizerBase.class;
73  		}
74  		try {
75  			return (InquiryAuthorizer) inquiryAuthorizerClass.newInstance();
76  		} catch (Exception e) {
77  			throw new RuntimeException(
78  					"Unable to instantiate InquiryAuthorizer class: "
79  							+ inquiryAuthorizerClass, e);
80  		}
81  	}
82  
83  	public <T extends BusinessObject> InquiryPresentationController getInquiryPresentationController(
84  			Class<T> businessObjectClass) {
85  		Class inquiryPresentationControllerClass = ((BusinessObjectEntry) getDataDictionaryService()
86  				.getDataDictionary().getBusinessObjectEntry(
87  						businessObjectClass.getName())).getInquiryDefinition()
88  				.getPresentationControllerClass();
89  		if (inquiryPresentationControllerClass == null) {
90  			inquiryPresentationControllerClass = InquiryPresentationControllerBase.class;
91  		}
92  		try {
93  			return (InquiryPresentationController) inquiryPresentationControllerClass
94  					.newInstance();
95  		} catch (Exception e) {
96  			throw new RuntimeException(
97  					"Unable to instantiate InquiryPresentationController class: "
98  							+ inquiryPresentationControllerClass, e);
99  		}
100 	}
101 
102     /**
103      * Uses the DataDictionaryService.
104      *
105      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getBusinessObjectEntries()
106      */
107     public List getBusinessObjectClassnames() {
108 		return getDataDictionaryService().getDataDictionary()
109 				.getBusinessObjectClassNames();
110     }
111 
112     /**
113      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#isLookupable(java.lang.Class)
114      */
115     public Boolean isLookupable(Class businessObjectClass) {
116         Boolean isLookupable = Boolean.FALSE;
117 
118         BusinessObjectEntry entry = getBusinessObjectEntry(businessObjectClass);
119         if (entry != null) {
120             isLookupable = Boolean.valueOf(entry.hasLookupDefinition());
121         }
122 
123         return isLookupable;
124     }
125 
126     /**
127      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#isInquirable(java.lang.Class)
128      */
129     public Boolean isInquirable(Class businessObjectClass) {
130         Boolean isInquirable = Boolean.FALSE;
131 
132         BusinessObjectEntry entry = getBusinessObjectEntry(businessObjectClass);
133         if (entry != null) {
134             isInquirable = Boolean.valueOf(entry.hasInquiryDefinition());
135         }
136 
137         return isInquirable;
138     }
139 
140     /**
141      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#isMaintainable(java.lang.Class)
142      */
143     public Boolean isMaintainable(Class businessObjectClass) {
144         Boolean isMaintainable = Boolean.FALSE;
145 
146         BusinessObjectEntry entry = getBusinessObjectEntry(businessObjectClass);
147         if (entry != null) {
148 			isMaintainable = Boolean
149 					.valueOf(getMaintenanceDocumentEntry(businessObjectClass) != null);
150         }
151 
152         return isMaintainable;
153     }
154     
155 
156     /**
157 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#isExportable(java.lang.Class)
158 	 */
159 	public Boolean isExportable(Class businessObjectClass) {
160 		Boolean isExportable = Boolean.FALSE;
161 		
162 		BusinessObjectEntry entry = getBusinessObjectEntry(businessObjectClass);
163         if (entry != null) {
164             isExportable = entry.getExporterClass() != null;
165         }
166 
167         return isExportable;
168 	}
169 
170 	/**
171      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupFieldNames(java.lang.Class)
172      */
173     public List getLookupFieldNames(Class businessObjectClass) {
174         List results = null;
175 
176         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
177         if (lookupDefinition != null) {
178             results = lookupDefinition.getLookupFieldNames();
179         }
180 
181         return results;
182     }
183 
184 
185     /**
186      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupTitle(java.lang.Class)
187      */
188     public String getLookupTitle(Class businessObjectClass) {
189         String lookupTitle = "";
190 
191         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
192         if (lookupDefinition != null) {
193             lookupTitle = lookupDefinition.getTitle();
194         }
195 
196         return lookupTitle;
197     }
198 
199     /**
200      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupMenuBar(java.lang.Class)
201      */
202     public String getLookupMenuBar(Class businessObjectClass) {
203         String menubar = "";
204 
205         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
206         if (lookupDefinition != null) {
207             if (lookupDefinition.hasMenubar()) {
208                 menubar = lookupDefinition.getMenubar();
209             }
210         }
211 
212         return menubar;
213     }
214 
215 
216     /**
217      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getExtraButtonSource(java.lang.Class)
218      */
219     public String getExtraButtonSource(Class businessObjectClass) {
220         String buttonSource = "";
221 
222         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
223         if (lookupDefinition != null) {
224             if (lookupDefinition.hasExtraButtonSource()) {
225                 buttonSource = lookupDefinition.getExtraButtonSource();
226             }
227         }
228 
229         return buttonSource;
230     }
231 
232     /**
233      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getExtraButtonParams(java.lang.Class)
234      */
235     public String getExtraButtonParams(Class businessObjectClass) {
236         String buttonParams = "";
237 
238         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
239         if (lookupDefinition != null) {
240             if (lookupDefinition.hasExtraButtonParams()) {
241                 buttonParams = lookupDefinition.getExtraButtonParams();
242             }
243         }
244 
245         return buttonParams;
246     }
247 
248     
249     /**
250      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getSearchIconOverride(java.lang.Class)
251      */
252     public String getSearchIconOverride(Class businessObjectClass) {
253         String iconUrl = "";
254 
255         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
256         if (lookupDefinition != null) {
257             if (lookupDefinition.hasSearchIconOverride()) {
258                 iconUrl = lookupDefinition.getSearchIconOverride();
259             }
260         }
261 
262         return iconUrl;
263     }
264 
265     
266     /**
267      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupDefaultSortFieldName(java.lang.Class)
268      */
269     public List getLookupDefaultSortFieldNames(Class businessObjectClass) {
270         List defaultSort = null;
271 
272         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
273         if (lookupDefinition != null) {
274             if (lookupDefinition.hasDefaultSort()) {
275 				defaultSort = lookupDefinition.getDefaultSort()
276 						.getAttributeNames();
277             }
278         }
279         if (defaultSort == null) {
280             defaultSort = new ArrayList();
281         }
282 
283         return defaultSort;
284     }
285 
286     /**
287      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupResultFieldNames(java.lang.Class)
288      */
289     public List<String> getLookupResultFieldNames(Class businessObjectClass) {
290         List<String> results = null;
291 
292         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
293         if (lookupDefinition != null) {
294             results = lookupDefinition.getResultFieldNames();
295         }
296 
297         return results;
298     }
299 
300 
301     /**
302 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupResultFieldMaxLength(java.lang.Class,
303 	 *      java.lang.String)
304      */
305 	public Integer getLookupResultFieldMaxLength(Class businessObjectClass,
306 			String resultFieldName) {
307 		Integer resultFieldMaxLength = null;
308 
309 		LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
310 		if (lookupDefinition != null) {
311 			FieldDefinition field = lookupDefinition.getResultField(resultFieldName);
312 			if (field != null) {
313 				resultFieldMaxLength = field.getMaxLength();
314 			}
315 		}
316 
317 		return resultFieldMaxLength;
318     }
319 
320     /**
321      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupResultSetLimit(java.lang.Class)
322      */
323     public Integer getLookupResultSetLimit(Class businessObjectClass) {
324         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
325         if ( lookupDefinition != null ) {
326 			return lookupDefinition.getResultSetLimit(); // TODO: stupid, change
327 															// to return int
328         } else {
329             return null;
330         }
331     }
332 
333 	/**
334 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupNumberOfColumns(java.lang.Class)
335 	 */
336 	public Integer getLookupNumberOfColumns(Class businessObjectClass) {
337 		// default to 1
338 		int numberOfColumns = 1;
339 
340 		LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
341 		if (lookupDefinition != null) {
342 			if (lookupDefinition.getNumOfColumns() > 1) {
343 				numberOfColumns = lookupDefinition.getNumOfColumns();
344 			}
345 		}
346 
347 		return numberOfColumns;
348 	}
349 
350 	/**
351 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupAttributeRequired(java.lang.Class,
352 	 *      java.lang.String)
353      */
354 	public Boolean getLookupAttributeRequired(Class businessObjectClass,
355 			String attributeName) {
356         Boolean isRequired = null;
357 
358 		FieldDefinition definition = getLookupFieldDefinition(
359 				businessObjectClass, attributeName);
360         if (definition != null) {
361             isRequired = Boolean.valueOf(definition.isRequired());
362         }
363 
364         return isRequired;
365     }
366 
367 	/**
368 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupAttributeReadOnly(java.lang.Class,
369 	 *      java.lang.String)
370 	 */
371 	public Boolean getLookupAttributeReadOnly(Class businessObjectClass, String attributeName) {
372 		Boolean readOnly = null;
373 
374 		FieldDefinition definition = getLookupFieldDefinition(businessObjectClass, attributeName);
375 		if (definition != null) {
376 			readOnly = Boolean.valueOf(definition.isReadOnly());
377 		}
378 
379 		return readOnly;
380 	}
381 
382 	/**
383 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getInquiryFieldNames(java.lang.Class,
384 	 *      java.lang.String)
385      */
386 	public List getInquiryFieldNames(Class businessObjectClass,
387 			String sectionTitle) {
388         List results = null;
389 
390 		InquirySectionDefinition inquirySection = getInquiryDefinition(
391 				businessObjectClass).getInquirySection(sectionTitle);
392         if (inquirySection != null) {
393             results = inquirySection.getInquiryFieldNames();
394         }
395 
396         return results;
397     }
398 
399     /**
400      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getInquirySections(java.lang.Class)
401      */
402     public List<InquirySectionDefinition> getInquirySections(Class businessObjectClass) {
403         List<InquirySectionDefinition> results = null;
404 
405 		results = getInquiryDefinition(businessObjectClass)
406 				.getInquirySections();
407 
408         return results;
409     }
410 
411     /**
412      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getInquiryTitle(java.lang.Class)
413      */
414     public String getInquiryTitle(Class businessObjectClass) {
415         String title = "";
416 
417         InquiryDefinition inquiryDefinition = getInquiryDefinition(businessObjectClass);
418         if (inquiryDefinition != null) {
419             title = inquiryDefinition.getTitle();
420         }
421 
422         return title;
423     }
424 
425     /**
426      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getInquirableClass(java.lang.Class)
427      */
428     public Class getInquirableClass(Class businessObjectClass) {
429         Class clazz = null;
430 
431         InquiryDefinition inquiryDefinition = getInquiryDefinition(businessObjectClass);
432         if (inquiryDefinition != null) {
433             clazz = inquiryDefinition.getInquirableClass();
434         }
435 
436         return clazz;
437     }
438 
439     /**
440      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getMaintainableTitle(java.lang.Class)
441      */
442     public String getMaintainableLabel(Class businessObjectClass) {
443         String label = "";
444 
445         MaintenanceDocumentEntry entry = getMaintenanceDocumentEntry(businessObjectClass);
446         if (entry != null) {
447             label = KewApiServiceLocator.getDocumentTypeService().getDocumentTypeByName(entry.getDocumentTypeName()).getLabel();
448         }
449 
450         return label;
451     }
452 
453     /**
454      *
455      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupableID(java.lang.Class)
456      */
457     public String getLookupableID(Class businessObjectClass) {
458         String lookupableID = null;
459 
460         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
461         if (lookupDefinition != null) {
462             lookupableID = lookupDefinition.getLookupableID();
463         }
464 
465         return lookupableID;
466     }
467 
468 
469     /**
470 	 * Recurses down the updatable references and collections of a BO,
471 	 * uppercasing those attributes which are marked as needing to be uppercased
472 	 * in the data dictionary. Updatability of a reference or collection is
473 	 * defined by the PersistenceStructureService
474      *
475 	 * @param bo
476 	 *            the BO to uppercase
477      *
478      * @see PersistenceStructureService#isCollectionUpdatable(Class, String)
479      * @see PersistenceStructureService#isReferenceUpdatable(Class, String)
480      * @see DataDictionaryService#getAttributeForceUppercase(Class, String)
481      */
482     public void performForceUppercase(BusinessObject bo) {
483     	performForceUppercaseCycleSafe(bo, new HashSet<BusinessObject>());
484     }
485     
486     /**
487      * Handles recursion for performForceUppercase in a cycle-safe manner,
488      * keeping track of visited BusinessObjects to prevent infinite recursion.
489      */
490     protected void performForceUppercaseCycleSafe(BusinessObject bo, Set<BusinessObject> visited) {
491     	if (visited.contains(bo)) {
492     		return;
493     	} else {
494     		visited.add(bo);
495     	}
496 		PropertyDescriptor descriptors[] = PropertyUtils
497 				.getPropertyDescriptors(bo);
498         for (int i = 0; i < descriptors.length; ++i) {
499             try {
500                 if (descriptors[i] instanceof IndexedPropertyDescriptor) {
501 					// Skip this case because PropertyUtils.getProperty(bo,
502 					// descriptors[i].getName()) will throw a
503                     // NoSuchMethodException on those. These
504 					// fields are usually convenience methods in the BO and in
505 					// the below code we anyway wouldn't know which index
506                     // .toUpperCase().
507 				} else {
508 					Object nestedObject = ObjectUtils.getPropertyValue(bo,
509 							descriptors[i].getName());
510 					if (ObjectUtils.isNotNull(nestedObject)
511 							&& nestedObject instanceof BusinessObject) {
512 						if (persistenceStructureService
513 								.isPersistable(nestedObject.getClass())) {
514                                 try {
515 								if (persistenceStructureService.hasReference(bo
516 										.getClass(), descriptors[i].getName())) {
517 									if (persistenceStructureService
518 											.isReferenceUpdatable(
519 													bo.getClass(),
520 													descriptors[i].getName())) {
521 										if (persistenceStructureService
522 												.getForeignKeyFieldsPopulationState(
523 														(PersistableBusinessObject) bo,
524 														descriptors[i]
525 																.getName())
526 												.isAllFieldsPopulated()) {
527 											// check FKs to prevent probs caused
528 											// by referential integrity problems
529                                             performForceUppercaseCycleSafe((BusinessObject) nestedObject, visited);
530                                     }
531                                     }
532                                 }
533                                 } catch (org.kuali.rice.krad.exception.ReferenceAttributeNotAnOjbReferenceException ranaore) {
534 								LOG.debug("Propery " + descriptors[i].getName()
535 										+ " is not a foreign key reference.");
536                                 }
537                             }
538                     } else if (nestedObject instanceof String) {
539 						if (dataDictionaryService.isAttributeDefined(
540 								bo.getClass(), descriptors[i].getName())
541 								.booleanValue()
542 								&& dataDictionaryService
543 										.getAttributeForceUppercase(
544 												bo.getClass(),
545 												descriptors[i].getName())
546 										.booleanValue()) {
547                             String curValue = (String) nestedObject;
548 							PropertyUtils.setProperty(bo, descriptors[i]
549 									.getName(), curValue.toUpperCase());
550                         }
551 					} else {
552 						if (ObjectUtils.isNotNull(nestedObject)
553 								&& nestedObject instanceof Collection) {
554 							if (persistenceStructureService.hasCollection(bo
555 									.getClass(), descriptors[i].getName())) {
556 								if (persistenceStructureService
557 										.isCollectionUpdatable(bo.getClass(),
558 												descriptors[i].getName())) {
559 									Iterator iter = ((Collection) nestedObject)
560 											.iterator();
561                             while (iter.hasNext()) {
562                                 Object collElem = iter.next();
563                                 if (collElem instanceof BusinessObject) {
564 											if (persistenceStructureService
565 													.isPersistable(collElem
566 															.getClass())) {
567                                                 performForceUppercaseCycleSafe((BusinessObject) collElem, visited);
568                                             }
569                                         }
570                                     }
571                                 }
572                             }
573                         }
574                     }
575                 }
576 			} catch (IllegalAccessException e) {
577 				throw new IntrospectionException(
578 						"unable to performForceUppercase", e);
579 			} catch (InvocationTargetException e) {
580 				throw new IntrospectionException(
581 						"unable to performForceUppercase", e);
582 			} catch (NoSuchMethodException e) {
583                 // if the getter/setter does not exist, just skip over
584 				// throw new
585 				// IntrospectionException("unable to performForceUppercase", e);
586             }
587         }
588     }
589 
590     /**
591      * Sets the instance of the data dictionary service.
592      *
593      * @param dataDictionaryService
594      */
595 	public void setDataDictionaryService(
596 			DataDictionaryService dataDictionaryService) {
597         this.dataDictionaryService = dataDictionaryService;
598     }
599 
600     /**
601      * This method retrieves the instance of the data dictionary service.
602      *
603      * @return An instance of the DataDictionaryService.
604      */
605     public DataDictionaryService getDataDictionaryService() {
606         return this.dataDictionaryService;
607     }
608 
609     /**
610      * @param businessObjectClass
611 	 * @return BusinessObjectEntry for the given dataObjectClass, or null if
612 	 *         there is none
613 	 * @throws IllegalArgumentException
614 	 *             if the given Class is null or is not a BusinessObject class
615      */
616     private BusinessObjectEntry getBusinessObjectEntry(Class businessObjectClass) {
617         validateBusinessObjectClass(businessObjectClass);
618 
619 		BusinessObjectEntry entry = (BusinessObjectEntry) getDataDictionaryService()
620 				.getDataDictionary().getBusinessObjectEntry(
621 						businessObjectClass.getName());
622         return entry;
623     }
624 
625     /**
626      * @param businessObjectClass
627 	 * @return MaintenanceDocumentEntry for the given dataObjectClass, or
628 	 *         null if there is none
629 	 * @throws IllegalArgumentException
630 	 *             if the given Class is null or is not a BusinessObject class
631      */
632 	private MaintenanceDocumentEntry getMaintenanceDocumentEntry(
633 			Class businessObjectClass) {
634         validateBusinessObjectClass(businessObjectClass);
635 
636 		MaintenanceDocumentEntry entry = (MaintenanceDocumentEntry) getDataDictionaryService()
637 				.getDataDictionary()
638 				.getMaintenanceDocumentEntryForBusinessObjectClass(
639 						businessObjectClass);
640         return entry;
641     }
642 
643     /**
644      * @param businessObjectClass
645 	 * @return LookupDefinition for the given dataObjectClass, or null if
646 	 *         there is none
647 	 * @throws IllegalArgumentException
648 	 *             if the given Class is null or is not a BusinessObject class
649      */
650     private LookupDefinition getLookupDefinition(Class businessObjectClass) {
651         LookupDefinition lookupDefinition = null;
652 
653         BusinessObjectEntry entry = getBusinessObjectEntry(businessObjectClass);
654         if (entry != null) {
655             if (entry.hasLookupDefinition()) {
656                 lookupDefinition = entry.getLookupDefinition();
657             }
658         }
659 
660         return lookupDefinition;
661     }
662 
663     /**
664      * @param businessObjectClass
665      * @param attributeName
666 	 * @return FieldDefinition for the given dataObjectClass and lookup
667 	 *         field name, or null if there is none
668 	 * @throws IllegalArgumentException
669 	 *             if the given Class is null or is not a BusinessObject class
670      */
671 	private FieldDefinition getLookupFieldDefinition(Class businessObjectClass,
672 			String lookupFieldName) {
673         if (StringUtils.isBlank(lookupFieldName)) {
674 			throw new IllegalArgumentException(
675 					"invalid (blank) lookupFieldName");
676         }
677 
678         FieldDefinition fieldDefinition = null;
679 
680         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
681         if (lookupDefinition != null) {
682             fieldDefinition = lookupDefinition.getLookupField(lookupFieldName);
683         }
684 
685         return fieldDefinition;
686     }
687 
688     /**
689      * @param businessObjectClass
690      * @param attributeName
691 	 * @return FieldDefinition for the given dataObjectClass and lookup
692 	 *         result field name, or null if there is none
693 	 * @throws IllegalArgumentException
694 	 *             if the given Class is null or is not a BusinessObject class
695      */
696 	private FieldDefinition getLookupResultFieldDefinition(
697 			Class businessObjectClass, String lookupFieldName) {
698         if (StringUtils.isBlank(lookupFieldName)) {
699 			throw new IllegalArgumentException(
700 					"invalid (blank) lookupFieldName");
701         }
702 
703         FieldDefinition fieldDefinition = null;
704 
705         LookupDefinition lookupDefinition = getLookupDefinition(businessObjectClass);
706         if (lookupDefinition != null) {
707             fieldDefinition = lookupDefinition.getResultField(lookupFieldName);
708         }
709 
710         return fieldDefinition;
711     }
712 
713     /**
714      * @param businessObjectClass
715 	 * @return InquiryDefinition for the given dataObjectClass, or null if
716 	 *         there is none
717 	 * @throws IllegalArgumentException
718 	 *             if the given Class is null or is not a BusinessObject class
719      */
720     private InquiryDefinition getInquiryDefinition(Class businessObjectClass) {
721         InquiryDefinition inquiryDefinition = null;
722 
723         BusinessObjectEntry entry = getBusinessObjectEntry(businessObjectClass);
724         if (entry != null) {
725             if (entry.hasInquiryDefinition()) {
726                 inquiryDefinition = entry.getInquiryDefinition();
727             }
728         }
729 
730         return inquiryDefinition;
731     }
732 
733 
734     /**
735      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getTitleAttribute(java.lang.Class)
736      */
737     public String getTitleAttribute(Class businessObjectClass) {
738         String titleAttribute = null;
739 
740         BusinessObjectEntry entry = getBusinessObjectEntry(businessObjectClass);
741         if (entry != null) {
742             titleAttribute = entry.getTitleAttribute();
743         }
744 
745         return titleAttribute;
746     }
747 
748     /**
749      * @param businessObjectClass
750      * @param attributeName
751 	 * @return FieldDefinition for the given dataObjectClass and field name,
752 	 *         or null if there is none
753 	 * @throws IllegalArgumentException
754 	 *             if the given Class is null or is not a BusinessObject class
755      */
756 	private FieldDefinition getInquiryFieldDefinition(
757 			Class businessObjectClass, String fieldName) {
758         if (StringUtils.isBlank(fieldName)) {
759             throw new IllegalArgumentException("invalid (blank) fieldName");
760         }
761 
762         FieldDefinition fieldDefinition = null;
763 
764         InquiryDefinition inquiryDefinition = getInquiryDefinition(businessObjectClass);
765         if (inquiryDefinition != null) {
766             fieldDefinition = inquiryDefinition.getFieldDefinition(fieldName);
767         }
768 
769         return fieldDefinition;
770     }
771 
772     /**
773      * @param businessObjectClass
774 	 * @throws IllegalArgumentException
775 	 *             if the given Class is null or is not a BusinessObject class
776      */
777     private void validateBusinessObjectClass(Class businessObjectClass) {
778         if (businessObjectClass == null) {
779 			throw new IllegalArgumentException(
780 					"invalid (null) dataObjectClass");
781         }
782         if (!BusinessObject.class.isAssignableFrom(businessObjectClass)) {
783 			throw new IllegalArgumentException("class '"
784 					+ businessObjectClass.getName()
785 					+ "' is not a descendent of BusinessObject");
786         }
787     }
788 
789     /**
790 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#forceLookupResultFieldInquiry(java.lang.Class,
791 	 *      java.lang.String)
792      */
793 	public Boolean forceLookupResultFieldInquiry(Class businessObjectClass,
794 			String attributeName) {
795         Boolean forceLookup = null;
796         if (getLookupResultFieldDefinition(businessObjectClass, attributeName) != null) {
797 			forceLookup = Boolean.valueOf(getLookupResultFieldDefinition(
798 					businessObjectClass, attributeName).isForceInquiry());
799         }
800 
801         return forceLookup;
802     }
803 
804     /**
805 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#noLookupResultFieldInquiry(java.lang.Class,
806 	 *      java.lang.String)
807      */
808 	public Boolean noLookupResultFieldInquiry(Class businessObjectClass,
809 			String attributeName) {
810         Boolean noLookup = null;
811         if (getLookupResultFieldDefinition(businessObjectClass, attributeName) != null) {
812 			noLookup = Boolean.valueOf(getLookupResultFieldDefinition(
813 					businessObjectClass, attributeName).isNoInquiry());
814         }
815 
816         return noLookup;
817     }
818 
819     /**
820 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#forceLookupFieldLookup(java.lang.Class,
821 	 *      java.lang.String)
822      */
823 	public Boolean forceLookupFieldLookup(Class businessObjectClass,
824 			String attributeName) {
825         Boolean forceLookup = null;
826         if (getLookupFieldDefinition(businessObjectClass, attributeName) != null) {
827 			forceLookup = Boolean.valueOf(getLookupFieldDefinition(
828 					businessObjectClass, attributeName).isForceLookup());
829         }
830 
831         return forceLookup;
832     }
833 
834 	public Boolean forceInquiryFieldLookup(Class businessObjectClass,
835 			String attributeName) {
836         Boolean forceInquiry = null;
837         if (getLookupFieldDefinition(businessObjectClass, attributeName) != null) {
838 			forceInquiry = Boolean.valueOf(getLookupFieldDefinition(
839 					businessObjectClass, attributeName).isForceInquiry());
840         }
841 
842         return forceInquiry;
843     }
844 
845     /**
846 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#noLookupFieldLookup(java.lang.Class,
847 	 *      java.lang.String)
848      */
849 	public Boolean noLookupFieldLookup(Class businessObjectClass,
850 			String attributeName) {
851         Boolean noLookup = null;
852         if (getLookupFieldDefinition(businessObjectClass, attributeName) != null) {
853 			noLookup = Boolean.valueOf(getLookupFieldDefinition(
854 					businessObjectClass, attributeName).isNoLookup());
855         }
856 
857         return noLookup;
858     }
859 
860     /**
861 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#noLookupFieldLookup(java.lang.Class,
862 	 *      java.lang.String)
863      */
864 	public Boolean noDirectInquiryFieldLookup(Class businessObjectClass,
865 			String attributeName) {
866         Boolean noDirectInquiry = null;
867         if (getLookupFieldDefinition(businessObjectClass, attributeName) != null) {
868 			noDirectInquiry = Boolean.valueOf(getLookupFieldDefinition(
869 					businessObjectClass, attributeName).isNoDirectInquiry());
870         }
871 
872         return noDirectInquiry;
873     }
874 
875     /**
876 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupResultFieldUseShortLabel(java.lang.Class,
877 	 *      java.lang.String)
878 	 */
879 	public Boolean getLookupResultFieldUseShortLabel(Class businessObjectClass,
880 			String attributeName) {
881         Boolean useShortLabel = null;
882         if (getLookupResultFieldDefinition(businessObjectClass, attributeName) != null) {
883 			useShortLabel = Boolean.valueOf(getLookupResultFieldDefinition(
884 					businessObjectClass, attributeName).isUseShortLabel());
885         }
886 
887         return useShortLabel;
888 	}
889 
890 	/**
891 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupResultFieldTotal(java.lang.Class,
892 	 *      java.lang.String)
893 	 */
894 	public Boolean getLookupResultFieldTotal(Class businessObjectClass, String attributeName) {
895 		Boolean total = false;
896 
897 		if (getLookupResultFieldDefinition(businessObjectClass, attributeName) != null) {
898 			total = Boolean.valueOf(getLookupResultFieldDefinition(
899 					businessObjectClass, attributeName).isTotal());
900 		}
901 
902 		return total;
903 	}
904 
905 	/**
906 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#forceInquiryFieldInquiry(java.lang.Class,
907 	 *      java.lang.String)
908      */
909 	public Boolean forceInquiryFieldInquiry(Class businessObjectClass,
910 			String attributeName) {
911         Boolean forceInquiry = null;
912         if (getInquiryFieldDefinition(businessObjectClass, attributeName) != null) {
913 			forceInquiry = Boolean.valueOf(getInquiryFieldDefinition(
914 					businessObjectClass, attributeName).isForceInquiry());
915         }
916 
917         return forceInquiry;
918     }
919 
920     /**
921 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#noInquiryFieldInquiry(java.lang.Class,
922 	 *      java.lang.String)
923      */
924 	public Boolean noInquiryFieldInquiry(Class businessObjectClass,
925 			String attributeName) {
926         Boolean noInquiry = null;
927         if (getInquiryFieldDefinition(businessObjectClass, attributeName) != null) {
928 			noInquiry = Boolean.valueOf(getInquiryFieldDefinition(
929 					businessObjectClass, attributeName).isNoInquiry());
930         }
931 
932         return noInquiry;
933     }
934 
935     /**
936 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupFieldDefaultValue(java.lang.Class,
937 	 *      java.lang.String)
938      */
939 	public String getLookupFieldDefaultValue(Class businessObjectClass,
940 			String attributeName) {
941 		return getLookupFieldDefinition(businessObjectClass, attributeName)
942 				.getDefaultValue();
943     }
944 
945     /**
946      * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupFieldDefaultValueFinderClass(java.lang.Class,
947      *      java.lang.String)
948      */
949 	public Class<? extends ValueFinder> getLookupFieldDefaultValueFinderClass(
950 			Class businessObjectClass, String attributeName) {
951 		return getLookupFieldDefinition(businessObjectClass, attributeName)
952 				.getDefaultValueFinderClass();
953     }
954 
955 	/** {@inheritDoc} */
956 	public String getLookupFieldQuickfinderParameterString(Class businessObjectClass, String attributeName) {
957 		return getLookupFieldDefinition(businessObjectClass, attributeName).getQuickfinderParameterString();
958 	}
959 
960 	/** {@inheritDoc} */
961 	public Class<? extends ValueFinder> getLookupFieldQuickfinderParameterStringBuilderClass(Class businessObjectClass, String attributeName) {
962 		return getLookupFieldDefinition(businessObjectClass, attributeName).getQuickfinderParameterStringBuilderClass();
963 	}
964 
965 	public void setPersistenceStructureService(
966 			PersistenceStructureService persistenceStructureService) {
967         this.persistenceStructureService = persistenceStructureService;
968     }
969 
970 	/**
971 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#isLookupFieldTreatWildcardsAndOperatorsAsLiteral(java.lang.Class, java.lang.String)
972 	 */
973 	public boolean isLookupFieldTreatWildcardsAndOperatorsAsLiteral(Class businessObjectClass, String attributeName) {
974 		FieldDefinition lookupFieldDefinition = getLookupFieldDefinition(businessObjectClass, attributeName);
975 		return lookupFieldDefinition != null && lookupFieldDefinition.isTreatWildcardsAndOperatorsAsLiteral();
976 	}
977 	
978 	/**
979 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getInquiryFieldAdditionalDisplayAttributeName(java.lang.Class,
980 	 *      java.lang.String)
981 	 */
982 	public String getInquiryFieldAdditionalDisplayAttributeName(Class businessObjectClass, String attributeName) {
983 		String additionalDisplayAttributeName = null;
984 
985 		if (getInquiryFieldDefinition(businessObjectClass, attributeName) != null) {
986 			additionalDisplayAttributeName = getInquiryFieldDefinition(businessObjectClass, attributeName)
987 					.getAdditionalDisplayAttributeName();
988 		}
989 
990 		return additionalDisplayAttributeName;
991 	}
992 
993 	/**
994 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getInquiryFieldAlternateDisplayAttributeName(java.lang.Class,
995 	 *      java.lang.String)
996 	 */
997 	public String getInquiryFieldAlternateDisplayAttributeName(Class businessObjectClass, String attributeName) {
998 		String alternateDisplayAttributeName = null;
999 
1000 		if (getInquiryFieldDefinition(businessObjectClass, attributeName) != null) {
1001 			alternateDisplayAttributeName = getInquiryFieldDefinition(businessObjectClass, attributeName)
1002 					.getAlternateDisplayAttributeName();
1003 		}
1004 
1005 		return alternateDisplayAttributeName;
1006 	}
1007 
1008 	/**
1009 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupFieldAdditionalDisplayAttributeName(java.lang.Class,
1010 	 *      java.lang.String)
1011 	 */
1012 	public String getLookupFieldAdditionalDisplayAttributeName(Class businessObjectClass, String attributeName) {
1013 		String additionalDisplayAttributeName = null;
1014 
1015 		if (getLookupResultFieldDefinition(businessObjectClass, attributeName) != null) {
1016 			additionalDisplayAttributeName = getLookupResultFieldDefinition(businessObjectClass, attributeName)
1017 					.getAdditionalDisplayAttributeName();
1018 		}
1019 
1020 		return additionalDisplayAttributeName;
1021 	}
1022 
1023 	/**
1024 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#getLookupFieldAlternateDisplayAttributeName(java.lang.Class,
1025 	 *      java.lang.String)
1026 	 */
1027 	public String getLookupFieldAlternateDisplayAttributeName(Class businessObjectClass, String attributeName) {
1028 		String alternateDisplayAttributeName = null;
1029 
1030 		if (getLookupResultFieldDefinition(businessObjectClass, attributeName) != null) {
1031 			alternateDisplayAttributeName = getLookupResultFieldDefinition(businessObjectClass, attributeName)
1032 					.getAlternateDisplayAttributeName();
1033 		}
1034 
1035 		return alternateDisplayAttributeName;
1036 	}
1037 	
1038 	/**
1039 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#tranlateCodesInLookup(java.lang.Class)
1040 	 */
1041 	public Boolean tranlateCodesInLookup(Class businessObjectClass) {
1042 		boolean translateCodes = false;
1043 
1044 		if (getLookupDefinition(businessObjectClass) != null) {
1045 			translateCodes = getLookupDefinition(businessObjectClass).isTranslateCodes();
1046 		}
1047 
1048 		return translateCodes;
1049 	}
1050 
1051 	/**
1052 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#tranlateCodesInInquiry(java.lang.Class)
1053 	 */
1054 	public Boolean tranlateCodesInInquiry(Class businessObjectClass) {
1055 		boolean translateCodes = false;
1056 
1057 		if (getInquiryDefinition(businessObjectClass) != null) {
1058 			translateCodes = getInquiryDefinition(businessObjectClass).isTranslateCodes();
1059 		}
1060 
1061 		return translateCodes;
1062 	}
1063 
1064 	/**
1065 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#isLookupFieldTriggerOnChange(java.lang.Class,
1066 	 *      java.lang.String)
1067 	 */
1068 	public boolean isLookupFieldTriggerOnChange(Class businessObjectClass, String attributeName) {
1069 		boolean triggerOnChange = false;
1070 		if (getLookupFieldDefinition(businessObjectClass, attributeName) != null) {
1071 			triggerOnChange = getLookupFieldDefinition(businessObjectClass, attributeName).isTriggerOnChange();
1072 		}
1073 
1074 		return triggerOnChange;
1075 	}
1076 
1077 	/**
1078 	 * @see org.kuali.rice.krad.service.BusinessObjectDictionaryService#disableSearchButtonsInLookup(java.lang.Class)
1079 	 */
1080 	public boolean disableSearchButtonsInLookup(Class businessObjectClass) {
1081 		boolean disableSearchButtons = false;
1082 
1083 		if (getLookupDefinition(businessObjectClass) != null) {
1084 			disableSearchButtons = getLookupDefinition(businessObjectClass).isDisableSearchButtons();
1085 		}
1086 
1087 		return disableSearchButtons;
1088 	}
1089 
1090 
1091 	
1092 }