1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.workflow.attribute;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.kuali.rice.core.api.config.module.RunMode;
22 import org.kuali.rice.core.api.config.property.ConfigContext;
23 import org.kuali.rice.core.api.CoreApiServiceLocator;
24 import org.kuali.rice.core.api.config.property.ConfigurationService;
25 import org.kuali.rice.core.api.uif.RemotableAttributeError;
26 import org.kuali.rice.core.api.uif.RemotableAttributeField;
27 import org.kuali.rice.core.api.util.io.SerializationUtils;
28 import org.kuali.rice.kew.api.KewApiConstants;
29 import org.kuali.rice.kew.api.document.DocumentWithContent;
30 import org.kuali.rice.kew.api.document.attribute.DocumentAttribute;
31 import org.kuali.rice.kew.api.document.attribute.DocumentAttributeFactory;
32 import org.kuali.rice.kew.api.document.attribute.DocumentAttributeString;
33 import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
34 import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
35 import org.kuali.rice.kew.api.exception.WorkflowException;
36 import org.kuali.rice.kew.api.extension.ExtensionDefinition;
37 import org.kuali.rice.kew.framework.document.attribute.SearchableAttribute;
38 import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry;
39 import org.kuali.rice.kns.document.MaintenanceDocument;
40 import org.kuali.rice.kns.lookup.LookupUtils;
41 import org.kuali.rice.kns.maintenance.KualiGlobalMaintainableImpl;
42 import org.kuali.rice.kns.maintenance.Maintainable;
43 import org.kuali.rice.kns.service.DictionaryValidationService;
44 import org.kuali.rice.kns.service.KNSServiceLocator;
45 import org.kuali.rice.kns.service.WorkflowAttributePropertyResolutionService;
46 import org.kuali.rice.kns.util.FieldUtils;
47 import org.kuali.rice.kns.web.ui.Field;
48 import org.kuali.rice.kns.web.ui.Row;
49 import org.kuali.rice.krad.bo.BusinessObject;
50 import org.kuali.rice.krad.bo.DocumentHeader;
51 import org.kuali.rice.kns.bo.GlobalBusinessObject;
52 import org.kuali.rice.krad.bo.PersistableBusinessObject;
53 import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
54 import org.kuali.rice.krad.datadictionary.DocumentEntry;
55 import org.kuali.rice.krad.datadictionary.SearchingAttribute;
56 import org.kuali.rice.krad.datadictionary.SearchingTypeDefinition;
57 import org.kuali.rice.krad.datadictionary.WorkflowAttributes;
58 import org.kuali.rice.krad.document.Document;
59 import org.kuali.rice.krad.service.DocumentService;
60 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
61 import org.kuali.rice.krad.util.ErrorMessage;
62 import org.kuali.rice.krad.util.GlobalVariables;
63 import org.kuali.rice.krad.util.KRADPropertyConstants;
64 import org.kuali.rice.krad.util.MessageMap;
65 import org.kuali.rice.krad.util.ObjectUtils;
66
67 import java.text.MessageFormat;
68 import java.util.ArrayList;
69 import java.util.LinkedHashMap;
70 import java.util.List;
71 import java.util.Map;
72
73
74
75
76 @Deprecated
77 public class DataDictionarySearchableAttribute implements SearchableAttribute {
78
79 private static final long serialVersionUID = 173059488280366451L;
80 private static final Logger LOG = Logger.getLogger(DataDictionarySearchableAttribute.class);
81 public static final String DATA_TYPE_BOOLEAN = "boolean";
82 public static final String KEW_RUN_MODE_PROPERTY = "kew.mode";
83
84 @Override
85 public String generateSearchContent(ExtensionDefinition extensionDefinition,
86 String documentTypeName,
87 WorkflowAttributeDefinition attributeDefinition) {
88 return "";
89 }
90
91 @Override
92 public List<DocumentAttribute> extractDocumentAttributes(ExtensionDefinition extensionDefinition,
93 DocumentWithContent documentWithContent) {
94 List<DocumentAttribute> attributes = new ArrayList<DocumentAttribute>();
95
96 String docId = documentWithContent.getDocument().getDocumentId();
97
98 DocumentService docService = KRADServiceLocatorWeb.getDocumentService();
99 Document doc = null;
100 try {
101 doc = docService.getByDocumentHeaderIdSessionless(docId);
102 } catch (WorkflowException we) {
103 LOG.error( "Unable to retrieve document " + docId + " in getSearchStorageValues()", we);
104 }
105
106 String attributeValue = "";
107 if ( doc != null ) {
108 if ( doc.getDocumentHeader() != null ) {
109 attributeValue = doc.getDocumentHeader().getDocumentDescription();
110 } else {
111 attributeValue = "null document header";
112 }
113 } else {
114 attributeValue = "null document";
115 }
116 DocumentAttributeString attribute = DocumentAttributeFactory.createStringAttribute("documentDescription", attributeValue);
117 attributes.add(attribute);
118
119 attributeValue = "";
120 if ( doc != null ) {
121 if ( doc.getDocumentHeader() != null ) {
122 attributeValue = doc.getDocumentHeader().getOrganizationDocumentNumber();
123 } else {
124 attributeValue = "null document header";
125 }
126 } else {
127 attributeValue = "null document";
128 }
129 attribute = DocumentAttributeFactory.createStringAttribute("organizationDocumentNumber", attributeValue);
130 attributes.add(attribute);
131
132 if ( doc != null && doc instanceof MaintenanceDocument) {
133 final Class<? extends BusinessObject> businessObjectClass = getBusinessObjectClass(
134 documentWithContent.getDocument().getDocumentTypeName());
135 if (businessObjectClass != null) {
136 if (GlobalBusinessObject.class.isAssignableFrom(businessObjectClass)) {
137 final GlobalBusinessObject globalBO = retrieveGlobalBusinessObject(docId, businessObjectClass);
138
139 if (globalBO != null) {
140 attributes.addAll(findAllDocumentAttributesForGlobalBusinessObject(globalBO));
141 }
142 } else {
143 attributes.addAll(parsePrimaryKeyValuesFromDocument(businessObjectClass, (MaintenanceDocument)doc));
144 }
145
146 }
147 }
148 if ( doc != null ) {
149 DocumentEntry docEntry = KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(
150 documentWithContent.getDocument().getDocumentTypeName());
151 if ( docEntry != null ) {
152 WorkflowAttributes workflowAttributes = docEntry.getWorkflowAttributes();
153 WorkflowAttributePropertyResolutionService waprs = KNSServiceLocator
154 .getWorkflowAttributePropertyResolutionService();
155 attributes.addAll(waprs.resolveSearchableAttributeValues(doc, workflowAttributes));
156 } else {
157 LOG.error("Unable to find DD document entry for document type: " + documentWithContent.getDocument()
158 .getDocumentTypeName());
159 }
160 }
161 return attributes;
162 }
163
164 @Override
165 public List<RemotableAttributeField> getSearchFields(ExtensionDefinition extensionDefinition, String documentTypeName) {
166 List<Row> searchRows = getSearchingRows(documentTypeName);
167 return FieldUtils.convertRowsToAttributeFields(searchRows);
168 }
169
170
171
172
173
174 protected List<Row> getSearchingRows(String documentTypeName) {
175
176 List<Row> docSearchRows = new ArrayList<Row>();
177
178 Class boClass = DocumentHeader.class;
179
180 Field descriptionField = FieldUtils.getPropertyField(boClass, "documentDescription", true);
181 descriptionField.setFieldDataType(KewApiConstants.SearchableAttributeConstants.DATA_TYPE_STRING);
182
183 Field orgDocNumberField = FieldUtils.getPropertyField(boClass, "organizationDocumentNumber", true);
184 orgDocNumberField.setFieldDataType(KewApiConstants.SearchableAttributeConstants.DATA_TYPE_STRING);
185
186 List<Field> fieldList = new ArrayList<Field>();
187 fieldList.add(descriptionField);
188 docSearchRows.add(new Row(fieldList));
189
190 fieldList = new ArrayList<Field>();
191 fieldList.add(orgDocNumberField);
192 docSearchRows.add(new Row(fieldList));
193
194
195 DocumentEntry entry =
196 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(documentTypeName);
197 if (entry == null)
198 return docSearchRows;
199 if (entry instanceof MaintenanceDocumentEntry) {
200 Class<? extends BusinessObject> businessObjectClass = getBusinessObjectClass(documentTypeName);
201 Class<? extends Maintainable> maintainableClass = getMaintainableClass(documentTypeName);
202
203 KualiGlobalMaintainableImpl globalMaintainable = null;
204 try {
205 globalMaintainable = (KualiGlobalMaintainableImpl)maintainableClass.newInstance();
206 businessObjectClass = globalMaintainable.getPrimaryEditedBusinessObjectClass();
207 } catch (Exception ie) {
208
209 }
210
211 if (businessObjectClass != null)
212 docSearchRows.addAll(createFieldRowsForBusinessObject(businessObjectClass));
213 }
214
215 WorkflowAttributes workflowAttributes = entry.getWorkflowAttributes();
216 if (workflowAttributes != null)
217 docSearchRows.addAll(createFieldRowsForWorkflowAttributes(workflowAttributes));
218
219 return docSearchRows;
220 }
221
222 @Override
223 public List<RemotableAttributeError> validateDocumentAttributeCriteria(ExtensionDefinition extensionDefinition,
224 DocumentSearchCriteria documentSearchCriteria) {
225 List<RemotableAttributeError> validationErrors = new ArrayList<RemotableAttributeError>();
226 DictionaryValidationService validationService = KNSServiceLocator.getKNSDictionaryValidationService();
227 RunMode kewRunMode = RunMode.valueOf(ConfigContext.getCurrentContextConfig().getProperty(KEW_RUN_MODE_PROPERTY));
228 if (kewRunMode != RunMode.LOCAL) {
229 GlobalVariables.getMessageMap().clearErrorMessages();
230 }
231
232 Map<String, List<String>> documentAttributeValues = documentSearchCriteria.getDocumentAttributeValues();
233 for (String key : documentAttributeValues.keySet()) {
234 List<String> values = documentAttributeValues.get(key);
235 if (CollectionUtils.isNotEmpty(values)) {
236 for (String value : values) {
237 if (StringUtils.isNotBlank(value)) {
238 validationService.validateAttributeFormat(documentSearchCriteria.getDocumentTypeName(), key, value, key);
239 }
240 }
241 }
242 }
243
244 retrieveValidationErrorsFromGlobalVariables(validationErrors);
245
246 return validationErrors;
247 }
248
249
250
251
252
253 protected void retrieveValidationErrorsFromGlobalVariables(List<RemotableAttributeError> validationErrors) {
254
255 ConfigurationService configurationService = CoreApiServiceLocator.getKualiConfigurationService();
256
257 if(GlobalVariables.getMessageMap().hasErrors()){
258 MessageMap deepCopy = (MessageMap) SerializationUtils.deepCopy(GlobalVariables.getMessageMap());
259 for (String errorKey : deepCopy.getErrorMessages().keySet()) {
260 List<ErrorMessage> errorMessages = deepCopy.getErrorMessages().get(errorKey);
261 if (CollectionUtils.isNotEmpty(errorMessages)) {
262 List<String> errors = new ArrayList<String>();
263 for (ErrorMessage errorMessage : errorMessages) {
264
265 String error = MessageFormat.format(configurationService.getPropertyValueAsString(errorMessage.getErrorKey()), errorMessage.getMessageParameters());
266 errors.add(error);
267 }
268 RemotableAttributeError remotableAttributeError = RemotableAttributeError.Builder.create(errorKey, errors).build();
269 validationErrors.add(remotableAttributeError);
270 }
271 }
272
273 GlobalVariables.getMessageMap().clearErrorMessages();
274 }
275 }
276
277 protected List<Row> createFieldRowsForWorkflowAttributes(WorkflowAttributes attrs) {
278 List<Row> searchFields = new ArrayList<Row>();
279
280 List<SearchingTypeDefinition> searchingTypeDefinitions = attrs.getSearchingTypeDefinitions();
281 final WorkflowAttributePropertyResolutionService propertyResolutionService = KNSServiceLocator
282 .getWorkflowAttributePropertyResolutionService();
283 for (SearchingTypeDefinition definition: searchingTypeDefinitions) {
284 SearchingAttribute attr = definition.getSearchingAttribute();
285
286 final String attributeName = attr.getAttributeName();
287 final String businessObjectClassName = attr.getBusinessObjectClassName();
288 Class boClass = null;
289 Object businessObject = null;
290 try {
291 boClass = Class.forName(businessObjectClassName);
292 businessObject = (Object)boClass.newInstance();
293 } catch (Exception e) {
294 throw new RuntimeException(e);
295 }
296
297 Field searchField = FieldUtils.getPropertyField(boClass, attributeName, false);
298
299
300 searchField.setColumnVisible(attr.isShowAttributeInResultSet());
301
302
303
304 if (!attr.isShowAttributeInSearchCriteria()){
305 searchField.setFieldType(Field.HIDDEN);
306 }
307 String fieldDataType = propertyResolutionService.determineFieldDataType(boClass, attributeName);
308 if (fieldDataType.equals(DataDictionarySearchableAttribute.DATA_TYPE_BOOLEAN)) {
309 fieldDataType = KewApiConstants.SearchableAttributeConstants.DATA_TYPE_STRING;
310 }
311
312
313 if (fieldDataType.equals(KewApiConstants.SearchableAttributeConstants.DATA_TYPE_FLOAT) ||
314 fieldDataType.equals(KewApiConstants.SearchableAttributeConstants.DATA_TYPE_LONG) ||
315 fieldDataType.equals(KewApiConstants.SearchableAttributeConstants.DATA_TYPE_DATE)) {
316
317 searchField.setAllowInlineRange(true);
318 }
319 searchField.setFieldDataType(fieldDataType);
320 List displayedFieldNames = new ArrayList();
321 displayedFieldNames.add(attributeName);
322 LookupUtils.setFieldQuickfinder(businessObject, attributeName, searchField, displayedFieldNames);
323
324 List<Field> fieldList = new ArrayList<Field>();
325 fieldList.add(searchField);
326
327 Row row = new Row(fieldList);
328 if (!attr.isShowAttributeInSearchCriteria()) {
329 row.setHidden(true);
330 }
331 searchFields.add(row);
332 }
333
334 return searchFields;
335 }
336
337 protected List<DocumentAttribute> parsePrimaryKeyValuesFromDocument(Class<? extends BusinessObject> businessObjectClass, MaintenanceDocument document) {
338 List<DocumentAttribute> values = new ArrayList<DocumentAttribute>();
339
340 final List primaryKeyNames = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(businessObjectClass);
341
342 for (Object primaryKeyNameAsObj : primaryKeyNames) {
343 final String primaryKeyName = (String)primaryKeyNameAsObj;
344 final DocumentAttribute searchableValue = parseSearchableAttributeValueForPrimaryKey(primaryKeyName, businessObjectClass, document);
345 if (searchableValue != null) {
346 values.add(searchableValue);
347 }
348 }
349 return values;
350 }
351
352
353
354
355
356
357
358
359 protected DocumentAttribute parseSearchableAttributeValueForPrimaryKey(String propertyName, Class<? extends BusinessObject> businessObjectClass, MaintenanceDocument document) {
360
361 Maintainable maintainable = document.getNewMaintainableObject();
362 PersistableBusinessObject bo = maintainable.getBusinessObject();
363
364 final Object propertyValue = ObjectUtils.getPropertyValue(bo, propertyName);
365 if (propertyValue == null) return null;
366
367 final WorkflowAttributePropertyResolutionService propertyResolutionService = KNSServiceLocator
368 .getWorkflowAttributePropertyResolutionService();
369 DocumentAttribute value = propertyResolutionService.buildSearchableAttribute(businessObjectClass, propertyName, propertyValue);
370 return value;
371 }
372
373
374
375
376
377
378 protected Class<? extends BusinessObject> getBusinessObjectClass(String documentTypeName) {
379 MaintenanceDocumentEntry entry = retrieveMaintenanceDocumentEntry(documentTypeName);
380 return (entry == null ? null : (Class<? extends BusinessObject>) entry.getDataObjectClass());
381 }
382
383
384
385
386
387
388 protected Class<? extends Maintainable> getMaintainableClass(String documentTypeName) {
389 MaintenanceDocumentEntry entry = retrieveMaintenanceDocumentEntry(documentTypeName);
390 return (entry == null ? null : entry.getMaintainableClass());
391 }
392
393
394
395
396
397
398
399 protected MaintenanceDocumentEntry retrieveMaintenanceDocumentEntry(String documentTypeName) {
400 return (MaintenanceDocumentEntry) KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(documentTypeName);
401 }
402
403 protected GlobalBusinessObject retrieveGlobalBusinessObject(String documentNumber, Class<? extends BusinessObject> businessObjectClass) {
404 GlobalBusinessObject globalBO = null;
405
406 Map pkMap = new LinkedHashMap();
407 pkMap.put(KRADPropertyConstants.DOCUMENT_NUMBER, documentNumber);
408
409 List returnedBOs = (List) KNSServiceLocator.getBusinessObjectService().findMatching(businessObjectClass, pkMap);
410 if (returnedBOs.size() > 0) {
411 globalBO = (GlobalBusinessObject)returnedBOs.get(0);
412 }
413
414 return globalBO;
415 }
416
417 protected List<DocumentAttribute> findAllDocumentAttributesForGlobalBusinessObject(GlobalBusinessObject globalBO) {
418 List<DocumentAttribute> searchValues = new ArrayList<DocumentAttribute>();
419
420 for (Object bo : globalBO.generateGlobalChangesToPersist()) {
421 DocumentAttribute value = generateSearchableAttributeFromChange(bo);
422 if (value != null) {
423 searchValues.add(value);
424 }
425 }
426
427 return searchValues;
428 }
429
430 protected DocumentAttribute generateSearchableAttributeFromChange(Object changeToPersist) {
431 List<String> primaryKeyNames = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(changeToPersist.getClass());
432
433 for (Object primaryKeyNameAsObject : primaryKeyNames) {
434 String primaryKeyName = (String)primaryKeyNameAsObject;
435 Object value = ObjectUtils.getPropertyValue(changeToPersist, primaryKeyName);
436
437 if (value != null) {
438 final WorkflowAttributePropertyResolutionService propertyResolutionService = KNSServiceLocator
439 .getWorkflowAttributePropertyResolutionService();
440 DocumentAttribute saValue = propertyResolutionService.buildSearchableAttribute((Class)changeToPersist.getClass(), primaryKeyName, value);
441 return saValue;
442 }
443 }
444 return null;
445 }
446
447
448
449
450
451
452 protected List<Row> createFieldRowsForBusinessObject(Class<? extends BusinessObject> businessObjectClass) {
453 List<Row> searchFields = new ArrayList<Row>();
454
455 final List primaryKeyNamesAsObjects = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(businessObjectClass);
456 final BusinessObjectEntry boEntry = KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(businessObjectClass.getName());
457 final WorkflowAttributePropertyResolutionService propertyResolutionService = KNSServiceLocator
458 .getWorkflowAttributePropertyResolutionService();
459 for (Object primaryKeyNameAsObject : primaryKeyNamesAsObjects) {
460
461 String attributeName = (String)primaryKeyNameAsObject;
462 BusinessObject businessObject = null;
463 try {
464 businessObject = businessObjectClass.newInstance();
465 } catch (Exception e) {
466 throw new RuntimeException(e);
467 }
468
469 Field searchField = FieldUtils.getPropertyField(businessObjectClass, attributeName, false);
470 String dataType = propertyResolutionService.determineFieldDataType(businessObjectClass, attributeName);
471 searchField.setFieldDataType(dataType);
472 List<Field> fieldList = new ArrayList<Field>();
473
474 List displayedFieldNames = new ArrayList();
475 displayedFieldNames.add(attributeName);
476 LookupUtils.setFieldQuickfinder(businessObject, attributeName, searchField, displayedFieldNames);
477
478 fieldList.add(searchField);
479 searchFields.add(new Row(fieldList));
480 }
481
482 return searchFields;
483 }
484
485 }