View Javadoc

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