1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.lookup;
17
18 import org.apache.commons.beanutils.PropertyUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.search.SearchOperator;
21 import org.kuali.rice.core.web.format.Formatter;
22 import org.kuali.rice.kns.service.KNSServiceLocator;
23 import org.kuali.rice.krad.bo.BusinessObject;
24 import org.kuali.rice.krad.datadictionary.AttributeDefinition;
25 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
26 import org.kuali.rice.krad.service.DataDictionaryService;
27 import org.kuali.rice.krad.service.KRADServiceLocator;
28 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
29
30 import java.lang.reflect.InvocationTargetException;
31 import java.util.ArrayList;
32 import java.util.Collection;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37
38
39
40
41
42
43
44 public class DataDictionaryLookupResultsSupportStrategy implements
45 LookupResultsSupportStrategyService {
46
47 private DataDictionaryService dataDictionaryService;
48
49
50
51
52
53 public String getLookupIdForBusinessObject(BusinessObject businessObject) {
54 final List<String> pkFieldNames = getPrimaryKeyFieldsForBusinessObject(businessObject.getClass());
55 return convertPKFieldMapToLookupId(pkFieldNames, businessObject);
56 }
57
58
59
60
61
62 public boolean qualifiesForStrategy(Class<? extends BusinessObject> boClass) {
63 if (getLookupableForBusinessObject(boClass) == null) {
64 return false;
65 }
66 final List<String> pkFields = getPrimaryKeyFieldsForBusinessObject(boClass);
67 return pkFields != null && pkFields.size() > 0;
68 }
69
70
71
72
73
74 public <T extends BusinessObject> Collection<T> retrieveSelectedResultBOs(Class<T> boClass, Set<String> lookupIds) throws Exception {
75
76 List<T> retrievedBusinessObjects = new ArrayList<T>();
77 final org.kuali.rice.kns.lookup.Lookupable lookupable = getLookupableForBusinessObject(boClass);
78 for (String lookupId : lookupIds) {
79 final Map<String, String> lookupKeys = convertLookupIdToPKFieldMap(lookupId, boClass);
80 List<? extends BusinessObject> bos = lookupable.getSearchResults(lookupKeys);
81
82
83 for (BusinessObject bo : bos) {
84 retrievedBusinessObjects.add((T)bo);
85 }
86 }
87
88 return retrievedBusinessObjects;
89 }
90
91
92
93
94
95
96
97 protected org.kuali.rice.kns.lookup.Lookupable getLookupableForBusinessObject(Class<? extends BusinessObject> businessObjectClass) {
98 final BusinessObjectEntry boEntry = getBusinessObjectEntry(businessObjectClass);
99 if (boEntry == null) {
100 return null;
101 }
102
103 final String lookupableId = boEntry.getLookupDefinition().getLookupableID();
104 return KNSServiceLocator.getLookupable(lookupableId);
105 }
106
107
108
109
110
111
112
113 protected List<String> getPrimaryKeyFieldsForBusinessObject(Class<? extends BusinessObject> businessObjectClass) {
114 final BusinessObjectEntry boEntry = getBusinessObjectEntry(businessObjectClass);
115 if (boEntry == null) {
116 return null;
117 }
118 return boEntry.getPrimaryKeys();
119 }
120
121
122
123
124
125
126
127
128 protected Map<String, String> convertLookupIdToPKFieldMap(String lookupId, Class<? extends BusinessObject> businessObjectClass) {
129 Map<String, String> pkFields = new HashMap<String, String>();
130 if (!StringUtils.isBlank(lookupId)) {
131 final String[] pkValues = lookupId.split("\\|");
132 for (String pkValue : pkValues) {
133 if (!StringUtils.isBlank(pkValue)) {
134 final String[] pkPieces = pkValue.split("-");
135 if (!StringUtils.isBlank(pkPieces[0]) && !StringUtils.isBlank(pkPieces[1])) {
136 pkFields.put(pkPieces[0], pkPieces[1]);
137 }
138 }
139 }
140 }
141 return pkFields;
142 }
143
144
145
146
147
148
149
150 protected String convertPKFieldMapToLookupId(List<String> pkFieldNames, BusinessObject businessObject) {
151 StringBuilder lookupId = new StringBuilder();
152 for (String pkFieldName : pkFieldNames) {
153 try {
154 final Object value = PropertyUtils.getProperty(businessObject, pkFieldName);
155
156 if (value != null) {
157 lookupId.append(pkFieldName);
158 lookupId.append("-");
159 final Formatter formatter = retrieveBestFormatter(pkFieldName, businessObject.getClass());
160 final String formattedValue = (formatter != null) ? formatter.format(value).toString() : value.toString();
161
162 lookupId.append(formattedValue);
163 }
164 lookupId.append(SearchOperator.OR.op());
165 } catch (IllegalAccessException iae) {
166 throw new RuntimeException("Could not retrieve pk field value "+pkFieldName+" from business object "+businessObject.getClass().getName(), iae);
167 } catch (InvocationTargetException ite) {
168 throw new RuntimeException("Could not retrieve pk field value "+pkFieldName+" from business object "+businessObject.getClass().getName(), ite);
169 } catch (NoSuchMethodException nsme) {
170 throw new RuntimeException("Could not retrieve pk field value "+pkFieldName+" from business object "+businessObject.getClass().getName(), nsme);
171 }
172 }
173 return lookupId.substring(0, lookupId.length() - 1);
174 }
175
176
177
178
179
180
181
182
183
184 protected Formatter retrieveBestFormatter(String propertyName, Class<? extends BusinessObject> boClass) {
185 Formatter formatter = null;
186
187 try {
188 Class<? extends Formatter> formatterClass = null;
189
190 final BusinessObjectEntry boEntry = getBusinessObjectEntry(boClass);
191 if (boEntry != null) {
192 final AttributeDefinition attributeDefinition = boEntry.getAttributeDefinition(propertyName);
193 if (attributeDefinition != null && attributeDefinition.hasFormatterClass()) {
194 formatterClass = (Class<? extends Formatter>)Class.forName(attributeDefinition.getFormatterClass());
195 }
196 }
197 if (formatterClass == null) {
198 final java.lang.reflect.Field propertyField = boClass.getDeclaredField(propertyName);
199 if (propertyField != null) {
200 formatterClass = Formatter.findFormatter(propertyField.getType());
201 }
202 }
203
204 if (formatterClass != null) {
205 formatter = formatterClass.newInstance();
206 }
207 } catch (SecurityException se) {
208 throw new RuntimeException("Could not retrieve good formatter", se);
209 } catch (ClassNotFoundException cnfe) {
210 throw new RuntimeException("Could not retrieve good formatter", cnfe);
211 } catch (NoSuchFieldException nsfe) {
212 throw new RuntimeException("Could not retrieve good formatter", nsfe);
213 } catch (IllegalAccessException iae) {
214 throw new RuntimeException("Could not retrieve good formatter", iae);
215 } catch (InstantiationException ie) {
216 throw new RuntimeException("Could not retrieve good formatter", ie);
217 }
218
219 return formatter;
220 }
221
222
223
224
225
226
227
228 protected BusinessObjectEntry getBusinessObjectEntry(Class<? extends BusinessObject> boClass) {
229 return (BusinessObjectEntry) getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(boClass.getName());
230 }
231
232
233
234
235 public DataDictionaryService getDataDictionaryService() {
236 return this.dataDictionaryService;
237 }
238
239
240
241
242 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
243 this.dataDictionaryService = dataDictionaryService;
244 }
245 }