1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.service.impl;
17
18 import java.beans.PropertyDescriptor;
19 import java.lang.reflect.Method;
20 import java.math.BigDecimal;
21 import java.util.List;
22 import java.util.regex.Pattern;
23
24 import org.apache.commons.beanutils.PropertyUtils;
25 import org.apache.commons.lang.StringUtils;
26 import org.kuali.rice.core.api.CoreApiServiceLocator;
27 import org.kuali.rice.core.api.util.RiceKeyConstants;
28 import org.kuali.rice.core.api.util.type.TypeUtils;
29 import org.kuali.rice.core.framework.persistence.jdbc.sql.SQLUtils;
30 import org.kuali.rice.core.web.format.DateFormatter;
31 import org.kuali.rice.kns.datadictionary.MaintainableFieldDefinition;
32 import org.kuali.rice.kns.datadictionary.MaintainableItemDefinition;
33 import org.kuali.rice.kns.datadictionary.MaintainableSectionDefinition;
34 import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry;
35 import org.kuali.rice.kns.service.DictionaryValidationService;
36 import org.kuali.rice.kns.service.KNSServiceLocator;
37 import org.kuali.rice.kns.service.WorkflowAttributePropertyResolutionService;
38 import org.kuali.rice.krad.bo.BusinessObject;
39 import org.kuali.rice.krad.datadictionary.control.ControlDefinition;
40 import org.kuali.rice.krad.document.Document;
41 import org.kuali.rice.krad.util.GlobalVariables;
42 import org.kuali.rice.krad.util.KRADConstants;
43 import org.kuali.rice.krad.util.ObjectUtils;
44
45
46
47
48
49
50 @Deprecated
51 public class DictionaryValidationServiceImpl extends org.kuali.rice.krad.service.impl.DictionaryValidationServiceImpl implements DictionaryValidationService {
52 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(
53 DictionaryValidationServiceImpl.class);
54
55 protected WorkflowAttributePropertyResolutionService workflowAttributePropertyResolutionService;
56
57
58
59
60
61 @Override
62 @Deprecated
63 public void validateDocumentAndUpdatableReferencesRecursively(Document document, int maxDepth,
64 boolean validateRequired, boolean chompLastLetterSFromCollectionName) {
65
66 validateBusinessObject(document, validateRequired);
67
68 if (maxDepth > 0) {
69 validateUpdatabableReferencesRecursively(document, maxDepth - 1, validateRequired,
70 chompLastLetterSFromCollectionName, newIdentitySet());
71 }
72 }
73
74
75
76
77
78 @Deprecated
79 @Override
80 public void validateDocumentRecursively(Document document, int depth) {
81
82 validateDocument(document);
83
84
85 validateBusinessObjectsFromDescriptors(document, PropertyUtils.getPropertyDescriptors(document.getClass()),
86 depth);
87 }
88
89
90
91
92
93
94 @Deprecated
95 @Override
96 public void validateDocument(Document document) {
97 String documentEntryName = document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName();
98
99 validatePrimitivesFromDescriptors(documentEntryName, document, PropertyUtils.getPropertyDescriptors(document.getClass()), "", true);
100 }
101
102 @Override
103 @Deprecated
104 public void validateBusinessObject(Object businessObject) {
105 validateBusinessObject(businessObject, true);
106 }
107
108 @Override
109 @Deprecated
110 public void validateBusinessObject(Object businessObject, boolean validateRequired) {
111 if (ObjectUtils.isNull(businessObject)) {
112 return;
113 }
114 try {
115
116 validatePrimitivesFromDescriptors(businessObject.getClass().getName(), businessObject,
117 PropertyUtils.getPropertyDescriptors(businessObject.getClass()), "", validateRequired);
118 } catch (RuntimeException e) {
119 LOG.error(String.format("Exception while validating %s", businessObject.getClass().getName()), e);
120 throw e;
121 }
122 }
123
124
125
126
127 @Deprecated
128 @Override
129 public void validateBusinessObjectOnMaintenanceDocument(BusinessObject businessObject, String docTypeName) {
130 MaintenanceDocumentEntry entry =
131 KNSServiceLocator.getMaintenanceDocumentDictionaryService().getMaintenanceDocumentEntry(docTypeName);
132 for (MaintainableSectionDefinition sectionDefinition : entry.getMaintainableSections()) {
133 validateBusinessObjectOnMaintenanceDocumentHelper(businessObject, sectionDefinition.getMaintainableItems(),
134 "");
135 }
136 }
137
138 protected void validateBusinessObjectOnMaintenanceDocumentHelper(BusinessObject businessObject,
139 List<? extends MaintainableItemDefinition> itemDefinitions, String errorPrefix) {
140 for (MaintainableItemDefinition itemDefinition : itemDefinitions) {
141 if (itemDefinition instanceof MaintainableFieldDefinition) {
142 if (getDataDictionaryService().isAttributeDefined(businessObject.getClass(),
143 itemDefinition.getName())) {
144 Object value = ObjectUtils.getPropertyValue(businessObject, itemDefinition.getName());
145 if (value != null && StringUtils.isNotBlank(value.toString())) {
146 Class propertyType = ObjectUtils.getPropertyType(businessObject, itemDefinition.getName(), null);
147 if (TypeUtils.isStringClass(propertyType) ||
148 TypeUtils.isIntegralClass(propertyType) ||
149 TypeUtils.isDecimalClass(propertyType) ||
150 TypeUtils.isTemporalClass(propertyType)) {
151
152 if (!TypeUtils.isTemporalClass(propertyType)) {
153 validateAttributeFormat(businessObject.getClass().getName(), itemDefinition.getName(),
154 value.toString(), errorPrefix + itemDefinition.getName());
155 }
156 }
157 }
158 }
159 }
160 }
161 }
162
163
164
165
166
167
168
169
170
171 @Deprecated
172 protected void validatePrimitivesFromDescriptors(String entryName, Object object,
173 PropertyDescriptor[] propertyDescriptors, String errorPrefix, boolean validateRequired) {
174 for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
175 validatePrimitiveFromDescriptor(entryName, object, propertyDescriptor, errorPrefix, validateRequired);
176 }
177 }
178
179
180
181
182
183
184
185
186
187 @Override
188 @Deprecated
189 public void validatePrimitiveFromDescriptor(String entryName, Object object, PropertyDescriptor propertyDescriptor,
190 String errorPrefix, boolean validateRequired) {
191
192 if (null != propertyDescriptor && getDataDictionaryService().isAttributeDefined(entryName,
193 propertyDescriptor.getName())) {
194 Object value = ObjectUtils.getPropertyValue(object, propertyDescriptor.getName());
195 Class propertyType = propertyDescriptor.getPropertyType();
196
197 if (TypeUtils.isStringClass(propertyType) ||
198 TypeUtils.isIntegralClass(propertyType) ||
199 TypeUtils.isDecimalClass(propertyType) ||
200 TypeUtils.isTemporalClass(propertyType)) {
201
202
203 if (value != null && StringUtils.isNotBlank(value.toString())) {
204 if (!TypeUtils.isTemporalClass(propertyType)) {
205 validateAttributeFormat(entryName, propertyDescriptor.getName(), value.toString(),
206 errorPrefix + propertyDescriptor.getName());
207 }
208 } else if (validateRequired) {
209 validateAttributeRequired(entryName, propertyDescriptor.getName(), value, Boolean.FALSE,
210 errorPrefix + propertyDescriptor.getName());
211 }
212 }
213 }
214 }
215
216
217
218
219
220
221 @Override
222 @Deprecated
223 public void validateAttributeFormat(String objectClassName, String attributeName, String attributeInValue,
224 String errorKey) {
225
226 String attributeDataType = null;
227 try {
228 attributeDataType = getWorkflowAttributePropertyResolutionService().determineFieldDataType(
229 (Class<? extends BusinessObject>) Class.forName(
230 getDataDictionaryService().getDataDictionary().getDictionaryObjectEntry(objectClassName)
231 .getFullClassName()), attributeName);
232 } catch (ClassNotFoundException e) {
233 attributeDataType = KRADConstants.DATA_TYPE_STRING;
234 } catch (NullPointerException e) {
235 attributeDataType = KRADConstants.DATA_TYPE_STRING;
236 }
237
238 validateAttributeFormat(objectClassName, attributeName, attributeInValue, attributeDataType, errorKey);
239 }
240
241
242
243
244
245
246
247
248 @Override
249 @Deprecated
250 public void validateAttributeFormat(String objectClassName, String attributeName, String attributeInValue,
251 String attributeDataType, String errorKey) {
252 boolean checkDateBounds = false;
253 Class<?> formatterClass = null;
254
255 if (LOG.isDebugEnabled()) {
256 LOG.debug("(bo, attributeName, attributeValue) = (" + objectClassName + "," + attributeName + "," +
257 attributeInValue + ")");
258 }
259
260
261
262
263
264
265 final List<String> attributeValues = SQLUtils.getCleanedSearchableValues(attributeInValue, attributeDataType);
266
267 if (attributeValues == null || attributeValues.isEmpty()) {
268 return;
269 }
270
271 for (String attributeValue : attributeValues) {
272
273
274
275
276
277
278 if (StringUtils.isNotBlank(attributeValue)) {
279 Integer minLength = getDataDictionaryService().getAttributeMinLength(objectClassName, attributeName);
280 if ((minLength != null) && (minLength.intValue() > attributeValue.length())) {
281 String errorLabel = getDataDictionaryService().getAttributeErrorLabel(objectClassName,
282 attributeName);
283 GlobalVariables.getMessageMap().putError(errorKey, RiceKeyConstants.ERROR_MIN_LENGTH,
284 new String[]{errorLabel, minLength.toString()});
285 return;
286 }
287 Integer maxLength = getDataDictionaryService().getAttributeMaxLength(objectClassName, attributeName);
288 if ((maxLength != null) && (maxLength.intValue() < attributeValue.length())) {
289 String errorLabel = getDataDictionaryService().getAttributeErrorLabel(objectClassName,
290 attributeName);
291 GlobalVariables.getMessageMap().putError(errorKey, RiceKeyConstants.ERROR_MAX_LENGTH,
292 new String[]{errorLabel, maxLength.toString()});
293 return;
294 }
295 Pattern validationExpression = getDataDictionaryService().getAttributeValidatingExpression(
296 objectClassName, attributeName);
297 if (validationExpression != null && !validationExpression.pattern().equals(".*")) {
298 if (LOG.isDebugEnabled()) {
299 LOG.debug("(bo, attributeName, validationExpression) = (" + objectClassName + "," +
300 attributeName + "," + validationExpression + ")");
301 }
302
303 if (!validationExpression.matcher(attributeValue).matches()) {
304
305 if (formatterClass == null) {
306
307 formatterClass = getDataDictionaryService().getAttributeFormatter(objectClassName,
308 attributeName);
309 }
310
311 if (formatterClass != null) {
312 boolean valuesAreValid = true;
313 boolean isError = true;
314 String errorKeyPrefix = "";
315 try {
316
317
318 if (DateFormatter.class.isAssignableFrom(formatterClass)) {
319 String[] values = attributeInValue.split("\\.\\.");
320 if (values.length == 2 &&
321 attributeValues.size() == 2) {
322 checkDateBounds = true;
323 if (attributeValues.indexOf(attributeValue) ==
324 0) {
325 errorKeyPrefix = KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX;
326 }
327 }
328 }
329
330 Method validatorMethod = formatterClass.getDeclaredMethod(VALIDATE_METHOD,
331 new Class<?>[]{String.class});
332 Object o = validatorMethod.invoke(formatterClass.newInstance(), attributeValue);
333 if (o instanceof Boolean) {
334 isError = !((Boolean) o).booleanValue();
335 }
336 valuesAreValid &= !isError;
337 } catch (Exception e) {
338 if (LOG.isDebugEnabled()) {
339 LOG.debug(e.getMessage(), e);
340 }
341 isError = true;
342 valuesAreValid = false;
343 }
344 if (isError) {
345 checkDateBounds = false;
346 String errorMessageKey =
347 getDataDictionaryService().getAttributeValidatingErrorMessageKey(
348 objectClassName, attributeName);
349 String[] errorMessageParameters =
350 getDataDictionaryService().getAttributeValidatingErrorMessageParameters(
351 objectClassName, attributeName);
352 GlobalVariables.getMessageMap().putError(errorKeyPrefix + errorKey, errorMessageKey,
353 errorMessageParameters);
354 }
355 } else {
356
357 String errorMessageKey = getDataDictionaryService().getAttributeValidatingErrorMessageKey(
358 objectClassName, attributeName);
359 String[] errorMessageParameters =
360 getDataDictionaryService().getAttributeValidatingErrorMessageParameters(
361 objectClassName, attributeName);
362 GlobalVariables.getMessageMap().putError(errorKey, errorMessageKey, errorMessageParameters);
363 }
364 }
365 }
366
367 String exclusiveMin = getDataDictionaryService().getAttributeExclusiveMin(objectClassName,
368 attributeName);
369 if (exclusiveMin != null) {
370 try {
371 BigDecimal exclusiveMinBigDecimal = new BigDecimal(exclusiveMin);
372 if (exclusiveMinBigDecimal.compareTo(new BigDecimal(attributeValue)) >= 0) {
373 String errorLabel = getDataDictionaryService().getAttributeErrorLabel(objectClassName,
374 attributeName);
375 GlobalVariables.getMessageMap().putError(errorKey, RiceKeyConstants.ERROR_EXCLUSIVE_MIN,
376
377 new String[]{errorLabel, exclusiveMin.toString()});
378 return;
379 }
380 } catch (NumberFormatException e) {
381
382 }
383 }
384
385 String inclusiveMax = getDataDictionaryService().getAttributeInclusiveMax(objectClassName,
386 attributeName);
387 if (inclusiveMax != null) {
388 try {
389 BigDecimal inclusiveMaxBigDecimal = new BigDecimal(inclusiveMax);
390 if (inclusiveMaxBigDecimal.compareTo(new BigDecimal(attributeValue)) < 0) {
391 String errorLabel = getDataDictionaryService().getAttributeErrorLabel(objectClassName,
392 attributeName);
393 GlobalVariables.getMessageMap().putError(errorKey, RiceKeyConstants.ERROR_INCLUSIVE_MAX,
394
395 new String[]{errorLabel, inclusiveMax.toString()});
396 return;
397 }
398 } catch (NumberFormatException e) {
399
400 }
401 }
402 }
403 }
404
405 if (checkDateBounds) {
406
407 java.sql.Timestamp lVal = null;
408 java.sql.Timestamp uVal = null;
409 try {
410 lVal = CoreApiServiceLocator.getDateTimeService().convertToSqlTimestamp(attributeValues.get(0));
411 uVal = CoreApiServiceLocator.getDateTimeService().convertToSqlTimestamp(attributeValues.get(1));
412 } catch (Exception ex) {
413
414 String errorMessageKey = getDataDictionaryService().getAttributeValidatingErrorMessageKey(
415 objectClassName, attributeName);
416 String[] errorMessageParameters =
417 getDataDictionaryService().getAttributeValidatingErrorMessageParameters(objectClassName,
418 attributeName);
419 GlobalVariables.getMessageMap().putError(
420 KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX + errorKey, errorMessageKey,
421 errorMessageParameters);
422 }
423
424 if (lVal != null && lVal.compareTo(uVal) > 0) {
425 String errorMessageKey = getDataDictionaryService().getAttributeValidatingErrorMessageKey(
426 objectClassName, attributeName);
427 String[] errorMessageParameters =
428 getDataDictionaryService().getAttributeValidatingErrorMessageParameters(objectClassName,
429 attributeName);
430 GlobalVariables.getMessageMap().putError(
431 KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX + errorKey, errorMessageKey + ".range",
432 errorMessageParameters);
433 }
434 }
435 }
436
437
438
439 @Override
440 @Deprecated
441 public void validateAttributeRequired(String objectClassName, String attributeName, Object attributeValue,
442 Boolean forMaintenance, String errorKey) {
443
444 if (attributeValue == null || (attributeValue instanceof String && StringUtils.isBlank(
445 (String) attributeValue))) {
446 Boolean required = getDataDictionaryService().isAttributeRequired(objectClassName, attributeName);
447 ControlDefinition controlDef = getDataDictionaryService().getAttributeControlDefinition(objectClassName,
448 attributeName);
449
450 if (required != null && required.booleanValue() && !(controlDef != null && controlDef.isHidden())) {
451
452
453 String errorLabel = getDataDictionaryService().getAttributeErrorLabel(objectClassName, attributeName);
454 GlobalVariables.getMessageMap().putError(errorKey, RiceKeyConstants.ERROR_REQUIRED, errorLabel);
455 }
456 }
457 }
458
459
460
461
462
463
464
465
466
467 protected WorkflowAttributePropertyResolutionService getWorkflowAttributePropertyResolutionService() {
468 if (workflowAttributePropertyResolutionService == null) {
469 workflowAttributePropertyResolutionService =
470 KNSServiceLocator.getWorkflowAttributePropertyResolutionService();
471 }
472 return workflowAttributePropertyResolutionService;
473 }
474 }