001    /**
002     * Copyright 2005-2014 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kns.service.impl;
017    
018    import java.beans.IndexedPropertyDescriptor;
019    import java.beans.PropertyDescriptor;
020    import java.lang.reflect.InvocationTargetException;
021    import java.util.ArrayList;
022    import java.util.Collection;
023    import java.util.HashSet;
024    import java.util.Iterator;
025    import java.util.List;
026    import java.util.Set;
027    
028    import org.apache.commons.beanutils.PropertyUtils;
029    import org.apache.commons.lang.StringUtils;
030    import org.apache.log4j.Logger;
031    import org.kuali.rice.kew.api.KewApiServiceLocator;
032    import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
033    import org.kuali.rice.kns.datadictionary.FieldDefinition;
034    import org.kuali.rice.kns.datadictionary.InquiryDefinition;
035    import org.kuali.rice.kns.datadictionary.InquirySectionDefinition;
036    import org.kuali.rice.kns.datadictionary.LookupDefinition;
037    import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry;
038    import org.kuali.rice.kns.inquiry.InquiryAuthorizer;
039    import org.kuali.rice.kns.inquiry.InquiryAuthorizerBase;
040    import org.kuali.rice.kns.inquiry.InquiryPresentationController;
041    import org.kuali.rice.kns.inquiry.InquiryPresentationControllerBase;
042    import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
043    import org.kuali.rice.krad.bo.BusinessObject;
044    import org.kuali.rice.krad.bo.PersistableBusinessObject;
045    import org.kuali.rice.krad.exception.IntrospectionException;
046    import org.kuali.rice.krad.service.DataDictionaryService;
047    import org.kuali.rice.krad.service.PersistenceStructureService;
048    import org.kuali.rice.krad.util.ObjectUtils;
049    import org.kuali.rice.krad.valuefinder.ValueFinder;
050    
051    /**
052     * This class is the service implementation for the BusinessObjectDictionary.
053     * This is the default, Kuali delivered implementation which leverages the
054     * DataDictionaryService.
055     */
056    @Deprecated
057    public class BusinessObjectDictionaryServiceImpl implements BusinessObjectDictionaryService {
058            private static Logger LOG = Logger
059                            .getLogger(BusinessObjectDictionaryServiceImpl.class);
060    
061        private DataDictionaryService dataDictionaryService;
062        private PersistenceStructureService persistenceStructureService;
063    
064            public <T extends BusinessObject> InquiryAuthorizer getInquiryAuthorizer(
065                            Class<T> businessObjectClass) {
066                    Class inquiryAuthorizerClass = ((BusinessObjectEntry) getDataDictionaryService()
067                                    .getDataDictionary().getBusinessObjectEntry(
068                                                    businessObjectClass.getName())).getInquiryDefinition()
069                                    .getAuthorizerClass();
070                    if (inquiryAuthorizerClass == null) {
071                            inquiryAuthorizerClass = InquiryAuthorizerBase.class;
072                    }
073                    try {
074                            return (InquiryAuthorizer) inquiryAuthorizerClass.newInstance();
075                    } catch (Exception e) {
076                            throw new RuntimeException(
077                                            "Unable to instantiate InquiryAuthorizer class: "
078                                                            + inquiryAuthorizerClass, e);
079                    }
080            }
081    
082            public <T extends BusinessObject> InquiryPresentationController getInquiryPresentationController(
083                            Class<T> businessObjectClass) {
084                    Class inquiryPresentationControllerClass = ((BusinessObjectEntry) getDataDictionaryService()
085                                    .getDataDictionary().getBusinessObjectEntry(
086                                                    businessObjectClass.getName())).getInquiryDefinition()
087                                    .getPresentationControllerClass();
088                    if (inquiryPresentationControllerClass == null) {
089                            inquiryPresentationControllerClass = InquiryPresentationControllerBase.class;
090                    }
091                    try {
092                            return (InquiryPresentationController) inquiryPresentationControllerClass
093                                            .newInstance();
094                    } catch (Exception e) {
095                            throw new RuntimeException(
096                                            "Unable to instantiate InquiryPresentationController class: "
097                                                            + inquiryPresentationControllerClass, e);
098                    }
099            }
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    }