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