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