1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.docsearch;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.uif.RemotableAttributeField;
20 import org.kuali.rice.core.api.util.ConcreteKeyValue;
21 import org.kuali.rice.core.api.util.KeyValue;
22 import org.kuali.rice.kew.api.KewApiConstants;
23 import org.kuali.rice.kew.doctype.ApplicationDocumentStatus;
24 import org.kuali.rice.kew.doctype.bo.DocumentType;
25 import org.kuali.rice.kew.engine.node.RouteNode;
26 import org.kuali.rice.kew.framework.document.search.DocumentSearchCriteriaConfiguration;
27 import org.kuali.rice.kew.service.KEWServiceLocator;
28 import org.kuali.rice.kns.util.FieldUtils;
29 import org.kuali.rice.kns.web.ui.Field;
30 import org.kuali.rice.kns.web.ui.Row;
31 import org.kuali.rice.krad.util.KRADConstants;
32
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.List;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class DocumentSearchCriteriaProcessorKEWAdapter implements DocumentSearchCriteriaProcessor {
65
66
67
68 public static final String ADVANCED_SEARCH_FIELD = "isAdvancedSearch";
69
70
71
72 public static final String SUPERUSER_SEARCH_FIELD = "superUserSearch";
73
74
75
76 public static final String CLEARSAVED_SEARCH_FIELD = "resetSavedSearch";
77
78
79
80
81 private static final String DOCUMENT_ATTRIBUTE_FIELD_MARKER = "DOCUMENT_ATTRIBUTE_FIELD_MARKER";
82
83 private static final String APPLICATION_DOCUMENT_STATUS = "applicationDocumentStatus";
84 private static final String DATE_APP_DOC_STATUS_CHANGED_FROM = "rangeLowerBoundKeyPrefix_dateApplicationDocumentStatusChanged";
85 private static final String DATE_APP_DOC_STATUS_CHANGED = "dateApplicationDocumentStatusChanged";
86 private static final String ROUTE_NODE_NAME = "routeNodeName";
87 private static final String ROUTE_NODE_LOGIC = "routeNodeLogic";
88
89 private static final String[] BASIC_FIELD_NAMES = {
90 "documentTypeName",
91 "initiatorPrincipalName",
92 "documentId",
93 "groupViewerId",
94 "dateCreated",
95 DOCUMENT_ATTRIBUTE_FIELD_MARKER,
96 "saveName"
97 };
98
99 private static final String[] ADVANCED_FIELD_NAMES = {
100 "documentTypeName",
101 "initiatorPrincipalName",
102 "approverPrincipalName",
103 "viewerPrincipalName",
104 "groupViewerName",
105 "groupViewerId",
106 "documentId",
107 "applicationDocumentId",
108 "statusCode",
109 APPLICATION_DOCUMENT_STATUS,
110 DATE_APP_DOC_STATUS_CHANGED,
111 ROUTE_NODE_NAME,
112 ROUTE_NODE_LOGIC,
113 "dateCreated",
114 "dateApproved",
115 "dateLastModified",
116 "dateFinalized",
117 "title",
118 DOCUMENT_ATTRIBUTE_FIELD_MARKER,
119 "saveName"
120 };
121
122
123
124
125 private static final Collection<String> DOCUMENTTYPE_DEPENDENT_FIELDS = Arrays.asList(new String[] { DOCUMENT_ATTRIBUTE_FIELD_MARKER, APPLICATION_DOCUMENT_STATUS, DATE_APP_DOC_STATUS_CHANGED_FROM, DATE_APP_DOC_STATUS_CHANGED, ROUTE_NODE_NAME, ROUTE_NODE_LOGIC });
126
127
128
129 private static final Collection<String> DOCSTATUS_DEPENDENT_FIELDS = Arrays.asList(new String[] { APPLICATION_DOCUMENT_STATUS, DATE_APP_DOC_STATUS_CHANGED_FROM, DATE_APP_DOC_STATUS_CHANGED });
130
131
132 @Override
133 public List<Row> getRows(DocumentType documentType, List<Row> defaultRows, boolean advancedSearch, boolean superUserSearch) {
134 List<Row> rows = null;
135 if(advancedSearch) {
136 rows = loadRowsForAdvancedSearch(defaultRows, documentType);
137 } else {
138 rows = loadRowsForBasicSearch(defaultRows, documentType);
139 }
140 addHiddenFields(rows, advancedSearch, superUserSearch);
141 return rows;
142 }
143
144 protected List<Row> loadRowsForAdvancedSearch(List<Row> defaultRows, DocumentType documentType) {
145 List<Row> rows = new ArrayList<Row>();
146 loadRowsWithFields(rows, defaultRows, ADVANCED_FIELD_NAMES, documentType);
147 return rows;
148 }
149
150 protected List<Row> loadRowsForBasicSearch(List<Row> defaultRows, DocumentType documentType) {
151 List<Row> rows = new ArrayList<Row>();
152 loadRowsWithFields(rows, defaultRows, BASIC_FIELD_NAMES, documentType);
153 return rows;
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167
168 protected void loadRowsWithFields(List<Row> rowsToLoad, List<Row> defaultRows, String[] fieldNames,
169 DocumentType documentType) {
170
171 for (String fieldName : fieldNames) {
172 if (DOCUMENTTYPE_DEPENDENT_FIELDS.contains(fieldName) && documentType == null) {
173 continue;
174 }
175
176 if (DOCSTATUS_DEPENDENT_FIELDS.contains(fieldName) && !documentType.isAppDocStatusInUse()) {
177 continue;
178 }
179 if (fieldName.equals(DOCUMENT_ATTRIBUTE_FIELD_MARKER)) {
180 rowsToLoad.addAll(getDocumentAttributeRows(documentType));
181 continue;
182 }
183
184
185
186
187 for (Row row : defaultRows) {
188 boolean matched = false;
189
190
191 for (Field field : row.getFields()) {
192
193
194 if (field.getPropertyName().equals(fieldName) || field.getPropertyName().endsWith("_" + fieldName)) {
195 matched = true;
196 if (APPLICATION_DOCUMENT_STATUS.equals(field.getPropertyName())) {
197
198
199
200 applyApplicationDocumentStatusCustomizations(field, documentType);
201 break;
202 } else if (ROUTE_NODE_NAME.equals(field.getPropertyName())) {
203
204 applyRouteNodeNameCustomizations(field, documentType);
205 }
206 }
207 }
208 if (matched) {
209 rowsToLoad.add(row);
210 }
211 }
212 }
213 }
214
215
216
217
218 protected List<Row> getDocumentAttributeRows(DocumentType documentType) {
219 List<Row> documentAttributeRows = new ArrayList<Row>();
220 DocumentSearchCriteriaConfiguration configuration =
221 KEWServiceLocator.getDocumentSearchCustomizationMediator().
222 getDocumentSearchCriteriaConfiguration(documentType);
223 if (configuration != null) {
224 List<RemotableAttributeField> remotableAttributeFields = configuration.getFlattenedSearchAttributeFields();
225 if (remotableAttributeFields != null && !remotableAttributeFields.isEmpty()) {
226 documentAttributeRows.addAll(FieldUtils.convertRemotableAttributeFields(remotableAttributeFields));
227 }
228 }
229 List<Row> fixedDocumentAttributeRows = new ArrayList<Row>();
230 for (Row row : documentAttributeRows) {
231 List<Field> fields = row.getFields();
232 for (Field field : fields) {
233
234 if(field.getMaxLength() == 0) {
235 field.setMaxLength(100);
236 }
237 if(field.isDatePicker() && field.isRanged()) {
238 Field newDate = FieldUtils.createRangeDateField(field);
239 List<Field> newFields = new ArrayList<Field>();
240 newFields.add(newDate);
241 fixedDocumentAttributeRows.addAll(FieldUtils.wrapFields(newFields));
242 }
243
244 field.setPropertyName(KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX + field.getPropertyName());
245 if (StringUtils.isNotBlank(field.getLookupParameters())) {
246 field.setLookupParameters(prefixLookupParameters(field.getLookupParameters()));
247 }
248 if (StringUtils.isNotBlank(field.getFieldConversions())) {
249 field.setFieldConversions(prefixFieldConversions(field.getFieldConversions()));
250 }
251 }
252 fixedDocumentAttributeRows.add(row);
253 }
254
255 return fixedDocumentAttributeRows;
256 }
257
258
259
260
261
262
263
264
265
266 protected void applyApplicationDocumentStatusCustomizations(Field field, DocumentType documentType) {
267 List<ApplicationDocumentStatus> validStatuses = documentType.getValidApplicationStatuses();
268 if (validStatuses == null || validStatuses.size() == 0){
269
270
271
272
273 field.setFieldType(Field.TEXT);
274 } else {
275
276
277 field.setFieldType(Field.DROPDOWN);
278 List<KeyValue> validValues = new ArrayList<KeyValue>();
279 for (ApplicationDocumentStatus status: validStatuses) {
280 validValues.add(new ConcreteKeyValue(status.getStatusName(), status.getStatusName()));
281 }
282 field.setFieldValidValues(validValues);
283
284
285
286
287 }
288 }
289
290 protected void applyRouteNodeNameCustomizations(Field field, DocumentType documentType) {
291 List<RouteNode> nodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(documentType, true);
292 List<KeyValue> values = new ArrayList<KeyValue>(nodes.size());
293 for (RouteNode node: nodes) {
294 values.add(new ConcreteKeyValue(node.getName(), node.getName()));
295 }
296 field.setFieldValidValues(values);
297 }
298
299 protected void addHiddenFields(List<Row> rows, boolean advancedSearch, boolean superUserSearch) {
300 Row hiddenRow = new Row();
301 hiddenRow.setHidden(true);
302
303 Field detailedField = new Field();
304 detailedField.setPropertyName(ADVANCED_SEARCH_FIELD);
305 detailedField.setPropertyValue(advancedSearch ? "YES" : "NO");
306 detailedField.setFieldType(Field.HIDDEN);
307
308 Field superUserSearchField = new Field();
309 superUserSearchField.setPropertyName(SUPERUSER_SEARCH_FIELD);
310 superUserSearchField.setPropertyValue(superUserSearch ? "YES" : "NO");
311 superUserSearchField.setFieldType(Field.HIDDEN);
312
313 Field clearSavedSearchField = new Field();
314 clearSavedSearchField .setPropertyName(CLEARSAVED_SEARCH_FIELD);
315 clearSavedSearchField .setPropertyValue(superUserSearch ? "YES" : "NO");
316 clearSavedSearchField .setFieldType(Field.HIDDEN);
317
318 List<Field> hiddenFields = new ArrayList<Field>();
319 hiddenFields.add(detailedField);
320 hiddenFields.add(superUserSearchField);
321 hiddenFields.add(clearSavedSearchField);
322 hiddenRow.setFields(hiddenFields);
323 rows.add(hiddenRow);
324
325 }
326
327 private String prefixLookupParameters(String lookupParameters) {
328 StringBuilder newLookupParameters = new StringBuilder(KRADConstants.EMPTY_STRING);
329 String[] conversions = StringUtils.split(lookupParameters, KRADConstants.FIELD_CONVERSIONS_SEPARATOR);
330
331 for (int m = 0; m < conversions.length; m++) {
332 String conversion = conversions[m];
333 String[] conversionPair = StringUtils.split(conversion, KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR, 2);
334 String conversionFrom = conversionPair[0];
335 String conversionTo = conversionPair[1];
336 conversionFrom = KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX + conversionFrom;
337 newLookupParameters.append(conversionFrom)
338 .append(KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR)
339 .append(conversionTo);
340
341 if (m < conversions.length) {
342 newLookupParameters.append(KRADConstants.FIELD_CONVERSIONS_SEPARATOR);
343 }
344 }
345 return newLookupParameters.toString();
346 }
347
348 private String prefixFieldConversions(String fieldConversions) {
349 StringBuilder newFieldConversions = new StringBuilder(KRADConstants.EMPTY_STRING);
350 String[] conversions = StringUtils.split(fieldConversions, KRADConstants.FIELD_CONVERSIONS_SEPARATOR);
351
352 for (int l = 0; l < conversions.length; l++) {
353 String conversion = conversions[l];
354
355 String[] conversionPair = StringUtils.split(conversion, KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR, 2);
356 String conversionFrom = conversionPair[0];
357 String conversionTo = conversionPair[1];
358 conversionTo = KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX + conversionTo;
359 newFieldConversions.append(conversionFrom)
360 .append(KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR)
361 .append(conversionTo);
362
363 if (l < conversions.length) {
364 newFieldConversions.append(KRADConstants.FIELD_CONVERSIONS_SEPARATOR);
365 }
366 }
367
368 return newFieldConversions.toString();
369 }
370
371 }