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 }