1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.select.lookup;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.ole.sys.context.SpringContext;
20 import org.kuali.ole.sys.service.NonTransactional;
21 import org.kuali.rice.core.api.config.property.ConfigurationService;
22 import org.kuali.rice.core.api.search.SearchOperator;
23 import org.kuali.rice.kns.service.DataDictionaryService;
24 import org.kuali.rice.kns.service.KNSServiceLocator;
25 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
26 import org.kuali.rice.krad.bo.PersistableBusinessObject;
27 import org.kuali.rice.krad.dao.LookupDao;
28 import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
29 import org.kuali.rice.krad.datadictionary.DataDictionaryEntry;
30 import org.kuali.rice.krad.datadictionary.PrimitiveAttributeDefinition;
31 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
32 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
33 import org.kuali.rice.krad.service.LookupService;
34 import org.kuali.rice.krad.service.ModuleService;
35 import org.kuali.rice.krad.service.PersistenceStructureService;
36
37 import java.lang.reflect.Method;
38 import java.util.*;
39
40 @NonTransactional
41 public class DocLookupServiceImpl implements LookupService {
42 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocLookupServiceImpl.class);
43
44
45 private IDocLookupSearch lookupDao;
46 private LookupDao lookupDaoOjb;
47 private ConfigurationService kualiConfigurationService;
48 private DataDictionaryService dataDictionaryService;
49 private PersistenceStructureService persistenceStructureService;
50
51
52 @Override
53 public Collection findCollectionBySearchUnbounded(Class example, Map formProps) {
54 return findCollectionBySearchHelper(example, formProps, true);
55 }
56
57
58
59
60
61
62
63 @Override
64 public Collection findCollectionBySearch(Class example, Map formProps) {
65 try {
66 return getResult(example, formProps, true);
67 } catch (Exception e) {
68 throw new RuntimeException(e);
69 }
70 }
71
72
73 @Override
74 public Collection findCollectionBySearchHelper(Class example, Map formProps, boolean unbounded) {
75 try {
76 return getResult(example, formProps, true);
77 } catch (Exception e) {
78 throw new RuntimeException(e);
79 }
80 }
81
82
83
84
85
86
87
88 @Override
89 public Object findObjectBySearch(Class example, Map formProps) {
90 if (example == null || formProps == null) {
91 throw new IllegalArgumentException("Object and Map must not be null");
92 }
93
94 PersistableBusinessObject obj = null;
95 try {
96 obj = (PersistableBusinessObject) example.newInstance();
97 } catch (IllegalAccessException e) {
98 throw new RuntimeException("Cannot get new instance of " + example.getName(), e);
99 } catch (InstantiationException e) {
100 throw new RuntimeException("Cannot instantiate " + example.getName(), e);
101 }
102
103 return lookupDaoOjb.findObjectByMap(obj, formProps);
104 }
105
106
107 @Override
108 public boolean allPrimaryKeyValuesPresentAndNotWildcard(Class boClass, Map formProps) {
109 List pkFields = KNSServiceLocator.getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(boClass);
110 Iterator pkIter = pkFields.iterator();
111 boolean returnVal = true;
112 while (returnVal && pkIter.hasNext()) {
113 String pkName = (String) pkIter.next();
114 String pkValue = (String) formProps.get(pkName);
115
116 if (StringUtils.isBlank(pkValue)) {
117 returnVal = false;
118 } else if (StringUtils.indexOfAny(pkValue, SearchOperator.QUERY_CHARACTERS.toArray().toString()) != -1) {
119 returnVal = false;
120 }
121 }
122 return returnVal;
123 }
124
125
126
127
128
129 public IDocLookupSearch getLookupDao() {
130 return lookupDao;
131 }
132
133
134
135
136
137 public void setLookupDao(IDocLookupSearch lookupDao) {
138 this.lookupDao = lookupDao;
139 }
140
141
142 public ConfigurationService getConfigurationService() {
143 return kualiConfigurationService;
144 }
145
146
147 public void setConfigurationService(ConfigurationService kualiConfigurationService) {
148 this.kualiConfigurationService = kualiConfigurationService;
149 }
150
151 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
152 this.dataDictionaryService = dataDictionaryService;
153 }
154
155
156
157
158
159 public LookupDao getLookupDaoOjb() {
160 return lookupDaoOjb;
161 }
162
163
164
165
166
167
168 public void setLookupDaoOjb(LookupDao lookupDaoOjb) {
169 this.lookupDaoOjb = lookupDaoOjb;
170 }
171
172
173 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
174 this.persistenceStructureService = persistenceStructureService;
175 }
176
177
178 private List getResult(Class businessObjectClass, Map criterValues, boolean unbounded) throws Exception {
179 List result = new ArrayList();
180 Map dbCrit = new HashMap();
181 Map docCrit = new HashMap();
182 Map<String, List<String>> docData = getDDRelationship(businessObjectClass);
183 if (docData != null && docData.size() > 0) {
184 for (String key : (java.util.Set<String>) criterValues.keySet()) {
185 boolean found = false;
186 for (String key1 : docData.keySet()) {
187 {
188 if (key.contains(key1) && key.contains(".")) {
189 found = true;
190 String val = key.split("\\.")[key.split("\\.").length - 1];
191 docCrit.put(val, criterValues.get(key));
192 break;
193 }
194 }
195 if (!found) {
196 dbCrit.put(key, criterValues.get(key));
197 }
198 }
199 }
200 }
201 if (ExternalizableBusinessObject.class.isAssignableFrom(businessObjectClass)) {
202
203 ModuleService eboModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(businessObjectClass);
204 BusinessObjectEntry ddEntry = eboModuleService.getExternalizableBusinessObjectDictionaryEntry(businessObjectClass);
205 Map<String, String> filteredFieldValues = new HashMap<String, String>();
206 for (String fieldName : (java.util.Set<String>) dbCrit.keySet()) {
207 if (ddEntry.getAttributeNames().contains(fieldName)) {
208 filteredFieldValues.put(fieldName, (String) dbCrit.get(fieldName));
209 }
210 }
211
212 result = eboModuleService.getExternalizableBusinessObjectsListForLookup(businessObjectClass,
213 (Map) filteredFieldValues, unbounded);
214
215 } else if (!org.kuali.ole.select.lookup.DocStoreData.class.isAssignableFrom(businessObjectClass)) {
216 result = (List) this.getLookupDaoOjb().findCollectionBySearchHelper(businessObjectClass, dbCrit, unbounded,
217 allPrimaryKeyValuesPresentAndNotWildcard(businessObjectClass, dbCrit));
218 }
219 Class cla = null;
220 for (String key : docData.keySet()) {
221 List<String> data = docData.get(key);
222
223 try {
224 cla = Class.forName(data.get(0));
225 } catch (Exception e) {
226 throw new RuntimeException(e);
227 }
228 String attrs = data.get(1);
229 String[] ff = attrs.split(":")[0].split(",");
230 String sourAtt = null, targetAtt = null;
231 if (ff.length == 2) {
232 sourAtt = ff[0];
233 targetAtt = ff[1];
234 }
235 boolean isDBCrit = dbCrit == null || dbCrit.size() < 3;
236 boolean isDocCrit = docCrit == null || docCrit.size() < 1;
237
238 List dbSourceAttrib = getSourceData(result, sourAtt, businessObjectClass);
239
240 List docStoreResult = this.getLookupDao().getResult(cla, targetAtt, dbSourceAttrib, docCrit);
241
242 result = mergeResult(result, sourAtt, businessObjectClass, docStoreResult, targetAtt, cla, docData.keySet().iterator().next(), isDBCrit, isDocCrit);
243 }
244 if (org.kuali.ole.select.lookup.DocStoreData.class.isAssignableFrom(businessObjectClass)) {
245 result = (List) this.getLookupDaoOjb().findCollectionBySearchHelper(businessObjectClass, criterValues, true, true);
246 }
247 return result;
248 }
249
250 private Method getMethod(Class c, String attr, Class[] objectAttributes) throws Exception {
251 Method met = c.getMethod("get" + StringUtils.capitalize(attr), objectAttributes);
252 return met;
253 }
254
255 private Method getSetMethod(Class c, String attr, Class[] objectAttributes) throws Exception {
256 attr = "docData";
257 Method met = c.getMethod("set" + StringUtils.capitalize(attr), objectAttributes);
258 return met;
259 }
260
261 private List mergeResult(List result, String sourAtt, Class sourClass, List dres, String targetAtt, Class targeClass,
262 String attt, boolean isDBCrit, boolean isDocCrit)
263 throws Exception {
264 List resul = new ArrayList();
265 List resut = new ArrayList();
266 Class[] ptyeps = {targeClass};
267 Method srcm = this.getMethod(sourClass, sourAtt, null);
268 Method tcm = this.getMethod(targeClass, targetAtt, null);
269 Method sem = this.getSetMethod(sourClass, attt, ptyeps);
270 for (Object val : result) {
271 for (Object dval : dres) {
272 Object sval = srcm.invoke(val, (Object[]) null);
273 Object dvall = tcm.invoke(dval, (Object[]) null);
274 if ((!isDocCrit && sval != null && sval.equals(dvall)) || (isDocCrit && dvall != null && dvall.equals(sval))) {
275 Object[] arr = {dval};
276 sem.invoke(val, arr);
277 resul.add(val);
278 }
279 }
280 }
281 return resul;
282
283 }
284
285 private List<Object> getSourceData(List result, String objectAttribute, Class clas) throws Exception {
286 List<Object> resul = new ArrayList<Object>(0);
287 Method met = clas.getMethod("get" + StringUtils.capitalize(objectAttribute), (Class[]) null);
288 for (Object data : result) {
289 Object res = met.invoke(data, (Object[]) null);
290 if (res != null) {
291 resul.add(res);
292 }
293 }
294 return resul;
295 }
296
297 public Class getDocClass(Class clas, String objectAttribute) {
298 boolean result = false;
299 Method met = null;
300 try {
301 met = clas.getMethod("get" + StringUtils.capitalize(objectAttribute), (Class[]) null);
302 } catch (Exception e) {
303 return null;
304 }
305 return org.kuali.ole.select.lookup.DocStoreData.class.isAssignableFrom(met.getReturnType()) ?
306 met.getReturnType() : null;
307 }
308
309
310 public Map<String, List<String>> getDDRelationship(Class c) {
311 Map<String, List<String>> result = new HashMap<String, List<String>>(0);
312 DataDictionaryEntry entryBase = SpringContext.getBean(DataDictionaryService.class)
313 .getDataDictionary().getDictionaryObjectEntry(c.getName());
314 if (entryBase == null) {
315 return null;
316 }
317
318 List<RelationshipDefinition> ddRelationships = entryBase
319 .getRelationships();
320 RelationshipDefinition relationship = null;
321 int minKeys = Integer.MAX_VALUE;
322 for (RelationshipDefinition def : ddRelationships) {
323
324 if (def.getPrimitiveAttributes().size() == 1) {
325 for (PrimitiveAttributeDefinition primitive : def
326 .getPrimitiveAttributes()) {
327 if (def.getObjectAttributeName() != null) {
328 List<String> data = new ArrayList<String>(0);
329 Class cc = getDocClass(c, def.getObjectAttributeName());
330 if (cc != null) {
331 data.add(cc.getName());
332 StringBuffer sb = new StringBuffer();
333 List<PrimitiveAttributeDefinition> res = def.getPrimitiveAttributes();
334 for (PrimitiveAttributeDefinition pdef : res) {
335 sb.append(pdef.getSourceName() + "," + pdef.getTargetName() + ":");
336 }
337 sb.deleteCharAt(sb.length() - 1);
338 data.add(sb.toString());
339 result.put(def.getObjectAttributeName(), data);
340 }
341 }
342 }
343 }
344 }
345 return result;
346 }
347
348 @Override
349 public <T> Collection<T> findCollectionBySearchHelper(Class<T> example, Map<String, String> formProperties, boolean unbounded, Integer searchResultsLimit) {
350 return null;
351 }
352 }
353