1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
package org.kuali.rice.kew.impl.document.search; |
17 | |
|
18 | |
import org.apache.commons.beanutils.PropertyUtils; |
19 | |
import org.apache.commons.lang.ObjectUtils; |
20 | |
import org.apache.commons.lang.StringUtils; |
21 | |
import org.apache.log4j.Logger; |
22 | |
import org.joda.time.DateTime; |
23 | |
import org.kuali.rice.kew.api.KEWPropertyConstants; |
24 | |
import org.kuali.rice.kew.api.document.DocumentStatus; |
25 | |
import org.kuali.rice.kew.api.document.DocumentStatusCategory; |
26 | |
import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria; |
27 | |
import org.kuali.rice.kew.api.document.search.RouteNodeLookupLogic; |
28 | |
import org.kuali.rice.kew.docsearch.DocumentSearchInternalUtils; |
29 | |
import org.kuali.rice.kew.api.KewApiConstants; |
30 | |
|
31 | |
import java.lang.reflect.InvocationTargetException; |
32 | |
import java.util.ArrayList; |
33 | |
import java.util.Arrays; |
34 | |
import java.util.Collection; |
35 | |
import java.util.HashMap; |
36 | |
import java.util.HashSet; |
37 | |
import java.util.List; |
38 | |
import java.util.Map; |
39 | |
import java.util.Set; |
40 | |
|
41 | |
|
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | 0 | public class DocumentSearchCriteriaTranslatorImpl implements DocumentSearchCriteriaTranslator { |
47 | |
|
48 | 0 | private static final Logger LOG = Logger.getLogger(DocumentSearchCriteriaTranslatorImpl.class); |
49 | |
|
50 | |
private static final String DOCUMENT_STATUSES = "documentStatuses"; |
51 | |
private static final String ROUTE_NODE_LOOKUP_LOGIC = "routeNodeLookupLogic"; |
52 | |
|
53 | |
|
54 | |
|
55 | |
|
56 | 0 | private static final String[] DIRECT_TRANSLATE_FIELD_NAMES = { |
57 | |
"documentId", |
58 | |
"applicationDocumentId", |
59 | |
"applicationDocumentStatus", |
60 | |
"initiatorPrincipalName", |
61 | |
"viewerPrincipalName", |
62 | |
"approverPrincipalName", |
63 | |
"routeNodeName", |
64 | |
"documentTypeName", |
65 | |
"saveName" |
66 | |
}; |
67 | 0 | private static final Set<String> DIRECT_TRANSLATE_FIELD_NAMES_SET = |
68 | |
new HashSet<String>(Arrays.asList(DIRECT_TRANSLATE_FIELD_NAMES)); |
69 | |
|
70 | 0 | private static final String[] DATE_RANGE_TRANSLATE_FIELD_NAMES = { |
71 | |
"dateCreated", |
72 | |
"dateLastModified", |
73 | |
"dateApproved", |
74 | |
"dateFinalized" |
75 | |
}; |
76 | 0 | private static final Set<String> DATE_RANGE_TRANSLATE_FIELD_NAMES_SET = |
77 | |
new HashSet<String>(Arrays.asList(DATE_RANGE_TRANSLATE_FIELD_NAMES)); |
78 | |
|
79 | |
@Override |
80 | |
public DocumentSearchCriteria translateFieldsToCriteria(Map<String, String> fieldValues) { |
81 | |
|
82 | 0 | DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create(); |
83 | 0 | for (Map.Entry<String, String> field : fieldValues.entrySet()) { |
84 | |
try { |
85 | 0 | if (StringUtils.isNotBlank(field.getValue())) { |
86 | 0 | if (DIRECT_TRANSLATE_FIELD_NAMES_SET.contains(field.getKey())) { |
87 | 0 | PropertyUtils.setNestedProperty(criteria, field.getKey(), field.getValue()); |
88 | 0 | } else if (DATE_RANGE_TRANSLATE_FIELD_NAMES_SET.contains(field.getKey())) { |
89 | 0 | applyDateRangeField(criteria, field.getKey(), field.getValue()); |
90 | 0 | } else if (field.getKey().startsWith(KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX)) { |
91 | 0 | String documentAttributeName = field.getKey().substring(KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX.length()); |
92 | 0 | applyDocumentAttribute(criteria, documentAttributeName, field.getValue()); |
93 | |
} |
94 | |
|
95 | |
} |
96 | 0 | } catch (Exception e) { |
97 | 0 | throw new IllegalStateException("Failed to set document search criteria field: " + field.getKey(), e); |
98 | 0 | } |
99 | |
} |
100 | |
|
101 | 0 | String routeNodeLookupLogic = fieldValues.get(ROUTE_NODE_LOOKUP_LOGIC); |
102 | 0 | if (StringUtils.isNotBlank(routeNodeLookupLogic)) { |
103 | 0 | criteria.setRouteNodeLookupLogic(RouteNodeLookupLogic.valueOf(routeNodeLookupLogic)); |
104 | |
} |
105 | |
|
106 | 0 | String documentStatusesValue = fieldValues.get(KEWPropertyConstants.DOC_SEARCH_RESULT_PROPERTY_NAME_STATUS_CODE); |
107 | 0 | if (StringUtils.isNotBlank(documentStatusesValue)) { |
108 | 0 | String[] documentStatuses = documentStatusesValue.split(","); |
109 | 0 | for (String documentStatus : documentStatuses) { |
110 | 0 | if (documentStatus.startsWith("category:")) { |
111 | 0 | String categoryCode = StringUtils.remove(documentStatus, "category:"); |
112 | 0 | criteria.getDocumentStatusCategories().add(DocumentStatusCategory.fromCode(categoryCode)); |
113 | 0 | } else { |
114 | 0 | criteria.getDocumentStatuses().add(DocumentStatus.fromCode(documentStatus)); |
115 | |
} |
116 | |
} |
117 | |
} |
118 | |
|
119 | 0 | return criteria.build(); |
120 | |
} |
121 | |
|
122 | |
|
123 | |
|
124 | |
|
125 | |
|
126 | |
|
127 | |
public Map<String, String[]> translateCriteriaToFields(DocumentSearchCriteria criteria) { |
128 | 0 | Map<String, String[]> values = new HashMap<String, String[]>(); |
129 | |
|
130 | 0 | for (String property: DIRECT_TRANSLATE_FIELD_NAMES) { |
131 | 0 | convertCriteriaPropertyToField(criteria, property, values); |
132 | |
} |
133 | |
|
134 | 0 | for (String property: DATE_RANGE_TRANSLATE_FIELD_NAMES) { |
135 | 0 | convertCriteriaPropertyToField(criteria, property + "From", values); |
136 | 0 | convertCriteriaPropertyToField(criteria, property + "To", values); |
137 | |
} |
138 | |
|
139 | 0 | Map<String, List<String>> docAttrValues = criteria.getDocumentAttributeValues(); |
140 | 0 | for (Map.Entry<String, List<String>> entry: docAttrValues.entrySet()) { |
141 | 0 | values.put(KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX + entry.getKey(), entry.getValue().toArray(new String[0])); |
142 | |
} |
143 | |
|
144 | 0 | RouteNodeLookupLogic lookupLogic = criteria.getRouteNodeLookupLogic(); |
145 | 0 | if (lookupLogic != null) { |
146 | 0 | values.put(ROUTE_NODE_LOOKUP_LOGIC, new String[]{lookupLogic.name()}); |
147 | |
} |
148 | |
|
149 | 0 | Collection<String> statuses = new ArrayList<String>(); |
150 | 0 | for (DocumentStatus status: criteria.getDocumentStatuses()) { |
151 | 0 | statuses.add(status.getCode()); |
152 | |
} |
153 | 0 | for (DocumentStatusCategory category: criteria.getDocumentStatusCategories()) { |
154 | 0 | statuses.add("category:" + category.getCode()); |
155 | |
} |
156 | 0 | values.put(KEWPropertyConstants.DOC_SEARCH_RESULT_PROPERTY_NAME_STATUS_CODE, statuses.toArray(new String[0])); |
157 | |
|
158 | 0 | return values; |
159 | |
} |
160 | |
|
161 | |
|
162 | |
|
163 | |
|
164 | |
|
165 | |
|
166 | |
|
167 | |
protected static void convertCriteriaPropertyToField(DocumentSearchCriteria criteria, String property, Map<String, String[]> values) { |
168 | |
try { |
169 | 0 | Object val = PropertyUtils.getProperty(criteria, property); |
170 | 0 | if (val != null) { |
171 | 0 | values.put(property, new String[] { ObjectUtils.toString(val) }); |
172 | |
} |
173 | 0 | } catch (NoSuchMethodException nsme) { |
174 | 0 | LOG.error("Error reading property '" + property + "' of criteria", nsme); |
175 | 0 | } catch (InvocationTargetException ite) { |
176 | 0 | LOG.error("Error reading property '" + property + "' of criteria", ite); |
177 | 0 | } catch (IllegalAccessException iae) { |
178 | 0 | LOG.error("Error reading property '" + property + "' of criteria", iae); |
179 | |
|
180 | 0 | } |
181 | 0 | } |
182 | |
|
183 | |
protected void applyDateRangeField(DocumentSearchCriteria.Builder criteria, String fieldName, String fieldValue) throws Exception { |
184 | 0 | DateTime lowerDateTime = DocumentSearchInternalUtils.getLowerDateTimeBound(fieldValue); |
185 | 0 | DateTime upperDateTime = DocumentSearchInternalUtils.getUpperDateTimeBound(fieldValue); |
186 | 0 | if (lowerDateTime != null) { |
187 | 0 | PropertyUtils.setNestedProperty(criteria, fieldName + "From", lowerDateTime); |
188 | |
} |
189 | 0 | if (upperDateTime != null) { |
190 | 0 | PropertyUtils.setNestedProperty(criteria, fieldName + "To", upperDateTime); |
191 | |
} |
192 | 0 | } |
193 | |
|
194 | |
protected void applyDocumentAttribute(DocumentSearchCriteria.Builder criteria, String documentAttributeName, String attributeValue) { |
195 | 0 | criteria.addDocumentAttributeValue(documentAttributeName, attributeValue); |
196 | 0 | } |
197 | |
|
198 | |
} |