001    /**
002     * Copyright 2005-2012 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.krad.keyvalues;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.apache.log4j.Logger;
020    import org.kuali.rice.core.api.util.ClassLoaderUtils;
021    import org.kuali.rice.core.api.util.ConcreteKeyValue;
022    import org.kuali.rice.core.api.util.KeyValue;
023    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
024    import org.kuali.rice.kim.api.type.KimType;
025    import org.kuali.rice.kim.api.type.KimTypeAttribute;
026    import org.kuali.rice.kim.framework.services.KimFrameworkServiceLocator;
027    import org.kuali.rice.kim.framework.type.KimTypeService;
028    import org.kuali.rice.krad.datadictionary.AttributeDefinition;
029    import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
030    import org.kuali.rice.krad.service.DataDictionaryService;
031    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
032    
033    import java.util.ArrayList;
034    import java.util.Collections;
035    import java.util.List;
036    
037    /**
038     * @author Kuali Rice Team (rice.collab@kuali.org)
039     */
040    public class KimAttributeValuesFinder extends KeyValuesBase {
041    
042            private static final Logger LOG = Logger.getLogger( KimAttributeValuesFinder.class );
043    
044            protected String kimTypeId;
045            protected String kimAttributeName;
046        private DataDictionaryService dataDictionaryService;
047    
048        protected DataDictionaryService getDataDictionaryService() {
049                    if ( dataDictionaryService == null ) {
050                            dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
051                    }
052                    return this.dataDictionaryService;
053            }
054    
055            /**
056             * @see KeyValuesFinder#getKeyValues()
057             */
058            @Override
059            public List<KeyValue> getKeyValues() {
060            KimType kimType = KimApiServiceLocator.getKimTypeInfoService().getKimType(kimTypeId);
061            if ( kimType != null ) {
062                    KimTypeService service = KimFrameworkServiceLocator.getKimTypeService(kimType);
063                    if ( service != null ) {
064                                    return getAttributeValidValues(kimTypeId,kimAttributeName);
065                    }
066                    LOG.error( "Unable to get type service " + kimType.getServiceName() );
067            } else {
068                    LOG.error( "Unable to obtain KIM type for kimTypeId=" + kimTypeId );
069            }
070            return Collections.emptyList();
071            }
072    
073        private List<KeyValue> getAttributeValidValues(String kimTypeId, String attributeName) {
074                    if ( LOG.isDebugEnabled() ) {
075                            LOG.debug( "getAttributeValidValues(" + kimTypeId + "," + attributeName + ")");
076                    }
077                    KimTypeAttribute attrib = KimApiServiceLocator.getKimTypeInfoService().getKimType(kimTypeId).getAttributeDefinitionByName(attributeName);
078                    if ( LOG.isDebugEnabled() ) {
079                            LOG.debug( "Found Attribute definition: " + attrib );
080                    }
081                    List<KeyValue> pairs = null;
082                    if ( StringUtils.isNotBlank(attrib.getKimAttribute().getComponentName()) ) {
083                            try {
084                                    Class.forName(attrib.getKimAttribute().getComponentName());
085                                    try {
086                                            pairs = getLocalDataDictionaryAttributeValues(attrib);
087                                    } catch ( ClassNotFoundException ex ) {
088                                            LOG.error( "Got a ClassNotFoundException resolving a values finder - since this should have been executing in the context of the host system - this should not happen.");
089                                            return Collections.emptyList();
090                                    }
091                            } catch ( ClassNotFoundException ex ) {
092                                    LOG.error( "Got a ClassNotFoundException resolving a component name (" + attrib.getKimAttribute().getComponentName() + ") - since this should have been executing in the context of the host system - this should not happen.");
093                            }
094                    } else {
095                            pairs = getCustomValueFinderValues(attrib);
096                    }
097            return pairs;
098            }
099    
100        protected List<KeyValue> getCustomValueFinderValues(KimTypeAttribute attrib) {
101                    return Collections.emptyList();
102            }
103    
104        protected List<KeyValue> getLocalDataDictionaryAttributeValues(KimTypeAttribute attr) throws ClassNotFoundException {
105    
106                    BusinessObjectEntry entry = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(attr.getKimAttribute().getComponentName());
107                    if ( entry == null ) {
108                            LOG.warn( "Unable to obtain BusinessObjectEntry for component name: " + attr.getKimAttribute().getComponentName() );
109                            return Collections.emptyList();
110                    }
111                    AttributeDefinition definition = entry.getAttributeDefinition(attr.getKimAttribute().getAttributeName());
112                    if ( definition == null ) {
113                            LOG.warn( "No attribute named " + attr.getKimAttribute().getAttributeName() + " found on BusinessObjectEntry for: " + attr.getKimAttribute().getComponentName() );
114                            return Collections.emptyList();
115                    }
116    
117            List<KeyValue> pairs = new ArrayList<KeyValue>();
118                    String keyValuesFinderName = definition.getControl().getValuesFinderClass();
119                    if ( StringUtils.isNotBlank(keyValuesFinderName)) {
120                            try {
121                                    KeyValuesFinder finder = (KeyValuesFinder)Class.forName(keyValuesFinderName).newInstance();
122                                    if (finder instanceof PersistableBusinessObjectValuesFinder) {
123                            ((PersistableBusinessObjectValuesFinder) finder).setBusinessObjectClass(
124                                ClassLoaderUtils.getClass(definition.getControl().getBusinessObjectClass()));
125                            ((PersistableBusinessObjectValuesFinder) finder).setKeyAttributeName(definition.getControl().getKeyAttribute());
126                            ((PersistableBusinessObjectValuesFinder) finder).setLabelAttributeName(definition.getControl().getLabelAttribute());
127                            if (definition.getControl().getIncludeBlankRow() != null) {
128                                    ((PersistableBusinessObjectValuesFinder) finder).setIncludeBlankRow(definition.getControl().getIncludeBlankRow());
129                            }
130                            ((PersistableBusinessObjectValuesFinder) finder).setIncludeKeyInDescription(definition.getControl().getIncludeKeyInLabel());
131                                    }
132    
133                    for (KeyValue pair : finder.getKeyValues()) {
134                        pairs.add(new ConcreteKeyValue(pair));
135                    }
136    
137                            } catch ( ClassNotFoundException ex ) {
138                                    LOG.info( "Unable to find class: " + keyValuesFinderName + " in the current context." );
139                                    throw ex;
140                            } catch (Exception e) {
141                                    LOG.error("Unable to build a KeyValuesFinder for " + attr.getKimAttribute().getAttributeName(), e);
142                            }
143                    } else {
144                            LOG.warn( "No values finder class defined on the control definition (" + definition.getControl() + ") on BO / attr = " + attr.getKimAttribute().getComponentName() + " / " + attr.getKimAttribute().getAttributeName() );
145                    }
146                    return pairs;
147            }
148    
149            /**
150             * @return the kimAttributeName
151             */
152            public String getKimAttributeName() {
153                    return this.kimAttributeName;
154            }
155    
156            /**
157             * @param kimAttributeName the kimAttributeName to set
158             */
159            public void setKimAttributeName(String kimAttributeName) {
160                    this.kimAttributeName = kimAttributeName;
161            }
162    
163            /**
164             * @return the kimTypeId
165             */
166            public String getKimTypeId() {
167                    return this.kimTypeId;
168            }
169    
170            /**
171             * @param kimTypeId the kimTypeId to set
172             */
173            public void setKimTypeId(String kimTypeId) {
174                    this.kimTypeId = kimTypeId;
175            }
176    
177    }