1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.service.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.config.property.ConfigurationService;
20 import org.kuali.rice.krad.service.KRADServiceLocator;
21 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
22 import org.kuali.rice.krad.service.LookupService;
23 import org.kuali.rice.krad.uif.UifConstants;
24 import org.kuali.rice.krad.uif.view.View;
25 import org.kuali.rice.krad.uif.component.MethodInvokerConfig;
26 import org.kuali.rice.krad.uif.field.InputField;
27 import org.kuali.rice.krad.uif.field.AttributeQuery;
28 import org.kuali.rice.krad.uif.field.AttributeQueryResult;
29 import org.kuali.rice.krad.uif.service.AttributeQueryService;
30 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
31 import org.kuali.rice.krad.uif.widget.Suggest;
32 import org.kuali.rice.krad.util.BeanPropertyComparator;
33
34 import java.text.MessageFormat;
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41
42
43
44
45
46
47
48 public class AttributeQueryServiceImpl implements AttributeQueryService {
49 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(
50 AttributeQueryServiceImpl.class);
51
52 private LookupService lookupService;
53 private ConfigurationService configurationService;
54
55
56
57
58
59
60 @Override
61 public AttributeQueryResult performFieldSuggestQuery(View view, String fieldId, String fieldTerm,
62 Map<String, String> queryParameters) {
63 AttributeQueryResult queryResult = new AttributeQueryResult();
64
65
66 InputField inputField = (InputField) view.getViewIndex().getComponentById(fieldId);
67 if (inputField == null) {
68 throw new RuntimeException("Unable to find attribute field instance for id: " + fieldId);
69 }
70
71 Suggest fieldSuggest = inputField.getSuggest();
72 AttributeQuery suggestQuery = fieldSuggest.getSuggestQuery();
73
74
75 Map<String, String> additionalCriteria = new HashMap<String, String>();
76 additionalCriteria.put(fieldSuggest.getSourcePropertyName(), fieldTerm + "*");
77
78
79 Collection<?> results = null;
80 if (suggestQuery.hasConfiguredMethod()) {
81 Object queryMethodResult = executeAttributeQueryMethod(view, suggestQuery, queryParameters, true,
82 fieldTerm);
83 if ((queryMethodResult != null) && (queryMethodResult instanceof Collection<?>)) {
84 results = (Collection<?>) queryMethodResult;
85 }
86 } else {
87 results = executeAttributeQueryCriteria(suggestQuery, queryParameters, additionalCriteria);
88 }
89
90
91 if (results != null) {
92 if (fieldSuggest.isSourceQueryMethodResults()) {
93 queryResult.setResultData((List<Object>) results);
94 } else {
95 List<Object> suggestData = new ArrayList<Object>();
96 for (Object result : results) {
97 Object suggestFieldValue = ObjectPropertyUtils.getPropertyValue(result,
98 fieldSuggest.getSourcePropertyName());
99 if (suggestFieldValue != null) {
100
101 suggestData.add(suggestFieldValue.toString());
102 }
103 }
104
105 queryResult.setResultData(suggestData);
106 }
107 }
108
109 return queryResult;
110 }
111
112
113
114
115
116 @Override
117 public AttributeQueryResult performFieldQuery(View view, String fieldId, Map<String, String> queryParameters) {
118 AttributeQueryResult queryResult = new AttributeQueryResult();
119
120
121 InputField inputField = (InputField) view.getViewIndex().getComponentById(fieldId);
122 if (inputField == null) {
123 throw new RuntimeException("Unable to find attribute field instance for id: " + fieldId);
124 }
125
126 AttributeQuery fieldQuery = inputField.getAttributeQuery();
127 if (fieldQuery == null) {
128 throw new RuntimeException("Field query not defined for field instance with id: " + fieldId);
129 }
130
131
132 Object resultObject = null;
133 if (fieldQuery.hasConfiguredMethod()) {
134 Object queryMethodResult = executeAttributeQueryMethod(view, fieldQuery, queryParameters, false, null);
135 if (queryMethodResult != null) {
136
137 if (queryMethodResult instanceof AttributeQueryResult) {
138 return (AttributeQueryResult) queryMethodResult;
139 }
140
141
142 if (queryMethodResult instanceof Collection<?>) {
143 Collection<?> methodResultCollection = (Collection<?>) queryMethodResult;
144 if (!methodResultCollection.isEmpty()) {
145 resultObject = methodResultCollection.iterator().next();
146 }
147 } else {
148 resultObject = queryMethodResult;
149 }
150 }
151 } else {
152
153 Collection<?> results = executeAttributeQueryCriteria(fieldQuery, queryParameters, null);
154
155 if ((results != null) && !results.isEmpty()) {
156
157 if (results.size() > 1) {
158
159 resultObject = null;
160 } else {
161 resultObject = results.iterator().next();
162 }
163 }
164 }
165
166 if (resultObject != null) {
167
168 Map<String, String> resultFieldData = new HashMap<String, String>();
169 for (String fromField : fieldQuery.getReturnFieldMapping().keySet()) {
170 String returnField = fieldQuery.getReturnFieldMapping().get(fromField);
171
172 String fieldValueStr = "";
173 Object fieldValue = ObjectPropertyUtils.getPropertyValue(resultObject, fromField);
174 if (fieldValue != null) {
175 fieldValueStr = fieldValue.toString();
176 }
177 resultFieldData.put(returnField, fieldValueStr);
178 }
179 queryResult.setResultFieldData(resultFieldData);
180
181 fieldQuery.setReturnMessageText("");
182 } else {
183
184 if (fieldQuery.isRenderNotFoundMessage()) {
185 String messageTemplate = getConfigurationService().getPropertyValueAsString(
186 UifConstants.MessageKeys.QUERY_DATA_NOT_FOUND);
187 String message = MessageFormat.format(messageTemplate, inputField.getLabel());
188 fieldQuery.setReturnMessageText(message.toLowerCase());
189 }
190 }
191
192
193 queryResult.setResultMessage(fieldQuery.getReturnMessageText());
194 queryResult.setResultMessageStyleClasses(fieldQuery.getReturnMessageStyleClasses());
195
196 return queryResult;
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210 protected Object executeAttributeQueryMethod(View view, AttributeQuery attributeQuery,
211 Map<String, String> queryParameters, boolean isSuggestQuery, String queryTerm) {
212 String queryMethodToCall = attributeQuery.getQueryMethodToCall();
213 MethodInvokerConfig queryMethodInvoker = attributeQuery.getQueryMethodInvokerConfig();
214
215 if (queryMethodInvoker == null) {
216 queryMethodInvoker = new MethodInvokerConfig();
217 }
218
219
220
221 if (StringUtils.isBlank(queryMethodInvoker.getTargetMethod())) {
222 queryMethodInvoker.setTargetMethod(queryMethodToCall);
223 }
224
225
226 if ((queryMethodInvoker.getTargetClass() == null) && (queryMethodInvoker.getTargetObject() == null)) {
227 queryMethodInvoker.setTargetObject(view.getViewHelperService());
228 }
229
230
231 List<Object> arguments = new ArrayList<Object>();
232 if ((attributeQuery.getQueryMethodArgumentFieldList() != null) && (!attributeQuery
233 .getQueryMethodArgumentFieldList().isEmpty())) {
234
235 int numQueryMethodArguments = attributeQuery.getQueryMethodArgumentFieldList().size();
236 if (isSuggestQuery) {
237 numQueryMethodArguments += 1;
238 }
239
240 Class[] argumentTypes = queryMethodInvoker.getArgumentTypes();
241 if ((argumentTypes == null) || (argumentTypes.length != numQueryMethodArguments)) {
242 throw new RuntimeException(
243 "Query method argument field list size does not match found number of method arguments");
244 }
245
246 for (int i = 0; i < attributeQuery.getQueryMethodArgumentFieldList().size(); i++) {
247 String methodArgumentFromField = attributeQuery.getQueryMethodArgumentFieldList().get(i);
248 if (queryParameters.containsKey(methodArgumentFromField)) {
249 arguments.add(queryParameters.get(methodArgumentFromField));
250 } else {
251 arguments.add(null);
252 }
253 }
254 }
255
256 if (isSuggestQuery) {
257 arguments.add(queryTerm);
258 }
259
260 queryMethodInvoker.setArguments(arguments.toArray());
261
262 try {
263 queryMethodInvoker.prepare();
264
265 return queryMethodInvoker.invoke();
266 } catch (Exception e) {
267 throw new RuntimeException("Unable to invoke query method: " + queryMethodInvoker.getTargetMethod(), e);
268 }
269 }
270
271
272
273
274
275
276
277
278
279
280 protected Collection<?> executeAttributeQueryCriteria(AttributeQuery attributeQuery,
281 Map<String, String> queryParameters, Map<String, String> additionalCriteria) {
282 Collection<?> results = null;
283
284
285 Map<String, String> queryCriteria = new HashMap<String, String>();
286 for (String fieldName : attributeQuery.getQueryFieldMapping().values()) {
287 if (queryParameters.containsKey(fieldName) && StringUtils.isNotBlank(queryParameters.get(fieldName))) {
288 queryCriteria.put(fieldName, queryParameters.get(fieldName));
289 }
290 }
291
292
293 for (String fieldName : attributeQuery.getAdditionalCriteria().keySet()) {
294 queryCriteria.put(fieldName, attributeQuery.getAdditionalCriteria().get(fieldName));
295 }
296
297
298 if (additionalCriteria != null) {
299 queryCriteria.putAll(additionalCriteria);
300 }
301
302 Class<?> queryClass = null;
303 try {
304 queryClass = Class.forName(attributeQuery.getDataObjectClassName());
305 } catch (ClassNotFoundException e) {
306 throw new RuntimeException(
307 "Invalid data object class given for suggest query: " + attributeQuery.getDataObjectClassName(), e);
308 }
309
310
311 results = getLookupService().findCollectionBySearchUnbounded(queryClass, queryCriteria);
312
313
314 if (!attributeQuery.getSortPropertyNames().isEmpty() && (results != null) && (results.size() > 1)) {
315 Collections.sort((List<?>) results, new BeanPropertyComparator(attributeQuery.getSortPropertyNames()));
316 }
317
318 return results;
319 }
320
321
322
323
324
325
326 protected LookupService getLookupService() {
327 if (lookupService == null) {
328 lookupService = KRADServiceLocatorWeb.getLookupService();
329 }
330
331 return lookupService;
332 }
333
334
335
336
337
338
339 public void setLookupService(LookupService lookupService) {
340 this.lookupService = lookupService;
341 }
342
343
344
345
346
347
348 protected ConfigurationService getConfigurationService() {
349 if (configurationService == null) {
350 configurationService = KRADServiceLocator.getKualiConfigurationService();
351 }
352
353 return configurationService;
354 }
355
356
357
358
359
360
361 public void setConfigurationService(ConfigurationService configurationService) {
362 this.configurationService = configurationService;
363 }
364 }