001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.kns.service.impl;
017
018import java.beans.IndexedPropertyDescriptor;
019import java.beans.PropertyDescriptor;
020import java.lang.reflect.InvocationTargetException;
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.HashSet;
024import java.util.Iterator;
025import java.util.List;
026import java.util.Set;
027
028import org.apache.commons.beanutils.PropertyUtils;
029import org.apache.commons.lang.StringUtils;
030import org.apache.log4j.Logger;
031import org.kuali.rice.kew.api.KewApiServiceLocator;
032import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
033import org.kuali.rice.kns.datadictionary.FieldDefinition;
034import org.kuali.rice.kns.datadictionary.InquiryDefinition;
035import org.kuali.rice.kns.datadictionary.InquirySectionDefinition;
036import org.kuali.rice.kns.datadictionary.LookupDefinition;
037import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry;
038import org.kuali.rice.kns.inquiry.InquiryAuthorizer;
039import org.kuali.rice.kns.inquiry.InquiryAuthorizerBase;
040import org.kuali.rice.kns.inquiry.InquiryPresentationController;
041import org.kuali.rice.kns.inquiry.InquiryPresentationControllerBase;
042import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
043import org.kuali.rice.krad.bo.BusinessObject;
044import org.kuali.rice.krad.bo.PersistableBusinessObject;
045import org.kuali.rice.krad.exception.IntrospectionException;
046import org.kuali.rice.krad.service.DataDictionaryService;
047import org.kuali.rice.krad.service.PersistenceStructureService;
048import org.kuali.rice.krad.util.ObjectUtils;
049import 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
057public 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}