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