1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary.validation.processor;
17
18 import org.kuali.rice.core.api.uif.DataType;
19 import org.kuali.rice.core.api.util.RiceKeyConstants;
20 import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
21 import org.kuali.rice.krad.datadictionary.validation.AttributeValueReader;
22 import org.kuali.rice.krad.datadictionary.validation.ValidationUtils;
23 import org.kuali.rice.krad.datadictionary.validation.ValidationUtils.Result;
24 import org.kuali.rice.krad.datadictionary.validation.capability.RangeConstrainable;
25 import org.kuali.rice.krad.datadictionary.validation.constraint.Constraint;
26 import org.kuali.rice.krad.datadictionary.validation.constraint.RangeConstraint;
27 import org.kuali.rice.krad.datadictionary.validation.result.ConstraintValidationResult;
28 import org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult;
29 import org.kuali.rice.krad.datadictionary.validation.result.ProcessorResult;
30
31 import java.math.BigDecimal;
32 import java.util.Date;
33
34
35
36
37
38
39
40
41 public class RangeConstraintProcessor extends MandatoryElementConstraintProcessor<RangeConstraint> {
42
43 private static final String CONSTRAINT_NAME = "range constraint";
44
45
46
47
48 @Override
49 public ProcessorResult process(DictionaryValidationResult result, Object value, RangeConstraint constraint, AttributeValueReader attributeValueReader) throws AttributeValidationException {
50
51
52 return new ProcessorResult(processSingleRangeConstraint(result, value, constraint, attributeValueReader));
53 }
54
55 @Override
56 public String getName() {
57 return CONSTRAINT_NAME;
58 }
59
60
61
62
63 @Override
64 public Class<? extends Constraint> getConstraintType() {
65 return RangeConstraint.class;
66 }
67
68 protected ConstraintValidationResult processSingleRangeConstraint(DictionaryValidationResult result, Object value, RangeConstraint constraint, AttributeValueReader attributeValueReader) throws AttributeValidationException {
69
70 if (ValidationUtils.isNullOrEmpty(value))
71 return result.addSkipped(attributeValueReader, CONSTRAINT_NAME);
72
73
74
75 DataType dataType = constraint.getDataType();
76 Object typedValue = value;
77
78 if (dataType != null) {
79 typedValue = ValidationUtils.convertToDataType(value, dataType, dateTimeService);
80 }
81
82
83 if (typedValue instanceof Date)
84 return validateRange(result, (Date)typedValue, constraint, attributeValueReader);
85 else if (typedValue instanceof Number)
86 return validateRange(result, (Number)typedValue, constraint, attributeValueReader);
87
88 return result.addSkipped(attributeValueReader, CONSTRAINT_NAME);
89 }
90
91 protected ConstraintValidationResult validateRange(DictionaryValidationResult result, Date value, RangeConstraint constraint, AttributeValueReader attributeValueReader) throws IllegalArgumentException {
92
93 Date date = value != null ? ValidationUtils.getDate(value, dateTimeService) : null;
94
95 String inclusiveMaxText = constraint.getInclusiveMax();
96 String exclusiveMinText = constraint.getExclusiveMin();
97
98 Date inclusiveMax = inclusiveMaxText != null ? ValidationUtils.getDate(inclusiveMaxText, dateTimeService) : null;
99 Date exclusiveMin = exclusiveMinText != null ? ValidationUtils.getDate(exclusiveMinText, dateTimeService) : null;
100
101 return isInRange(result, date, inclusiveMax, inclusiveMaxText, exclusiveMin, exclusiveMinText, attributeValueReader);
102 }
103
104 protected ConstraintValidationResult validateRange(DictionaryValidationResult result, Number value, RangeConstraint constraint, AttributeValueReader attributeValueReader) throws IllegalArgumentException {
105
106
107
108 BigDecimal number = value != null ? new BigDecimal(value.toString()) : null;
109
110 String inclusiveMaxText = constraint.getInclusiveMax();
111 String exclusiveMinText = constraint.getExclusiveMin();
112
113 BigDecimal inclusiveMax = inclusiveMaxText != null ? new BigDecimal(inclusiveMaxText) : null;
114 BigDecimal exclusiveMin = exclusiveMinText != null ? new BigDecimal(exclusiveMinText) : null;
115
116 return isInRange(result, number, inclusiveMax, inclusiveMaxText, exclusiveMin, exclusiveMinText, attributeValueReader);
117 }
118
119 private <T> ConstraintValidationResult isInRange(DictionaryValidationResult result, T value, Comparable<T> inclusiveMax, String inclusiveMaxText, Comparable<T> exclusiveMin, String exclusiveMinText, AttributeValueReader attributeValueReader) {
120
121 Result lessThanMax = ValidationUtils.isLessThanOrEqual(value, inclusiveMax);
122
123 Result greaterThanMin = ValidationUtils.isGreaterThan(value, exclusiveMin);
124
125
126 if (lessThanMax != Result.INVALID && greaterThanMin != Result.INVALID) {
127
128 if (lessThanMax == Result.UNDEFINED && greaterThanMin == Result.UNDEFINED)
129 return result.addNoConstraint(attributeValueReader, CONSTRAINT_NAME);
130
131
132 return result.addSuccess(attributeValueReader, CONSTRAINT_NAME);
133 }
134
135
136 if (lessThanMax != Result.UNDEFINED && greaterThanMin != Result.UNDEFINED)
137 return result.addError(attributeValueReader, CONSTRAINT_NAME, RiceKeyConstants.ERROR_OUT_OF_RANGE, exclusiveMinText, inclusiveMaxText);
138
139 else if (lessThanMax == Result.INVALID)
140 return result.addError(attributeValueReader, CONSTRAINT_NAME, RiceKeyConstants.ERROR_INCLUSIVE_MAX, inclusiveMaxText);
141
142 else
143 return result.addError(attributeValueReader, CONSTRAINT_NAME, RiceKeyConstants.ERROR_EXCLUSIVE_MIN, exclusiveMinText);
144 }
145
146 }