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
42
43 public class RangeConstraintProcessor extends MandatoryElementConstraintProcessor<RangeConstraint> {
44
45 private static final String CONSTRAINT_NAME = "range constraint";
46 private static final String MIN_EXCLUSIVE_KEY = "validation.minExclusive";
47 private static final String MAX_INCLUSIVE_KEY = "validation.maxInclusive";
48 private static final String RANGE_KEY = "validation.range";
49
50
51
52
53 @Override
54 public ProcessorResult process(DictionaryValidationResult result, Object value, RangeConstraint constraint, AttributeValueReader attributeValueReader) throws AttributeValidationException {
55
56
57 return new ProcessorResult(processSingleRangeConstraint(result, value, constraint, attributeValueReader));
58 }
59
60 @Override
61 public String getName() {
62 return CONSTRAINT_NAME;
63 }
64
65
66
67
68 @Override
69 public Class<? extends Constraint> getConstraintType() {
70 return RangeConstraint.class;
71 }
72
73
74
75
76
77
78
79
80
81
82 protected ConstraintValidationResult processSingleRangeConstraint(DictionaryValidationResult result, Object value, RangeConstraint constraint, AttributeValueReader attributeValueReader) throws AttributeValidationException {
83
84 if (ValidationUtils.isNullOrEmpty(value) ||
85 (constraint.getExclusiveMin() == null && constraint.getInclusiveMax() == null)){
86 return result.addSkipped(attributeValueReader, CONSTRAINT_NAME);
87 }
88
89
90
91 DataType dataType = constraint.getDataType();
92 Object typedValue = value;
93
94 if (dataType != null) {
95 typedValue = ValidationUtils.convertToDataType(value, dataType, dateTimeService);
96 }
97 else if(value instanceof String){
98
99 try{
100 Double d = Double.parseDouble((String)value);
101 typedValue = d;
102 }
103 catch(NumberFormatException n){
104
105 }
106 }
107
108
109 if (typedValue instanceof Date)
110 return validateRange(result, (Date)typedValue, constraint, attributeValueReader);
111 else if (typedValue instanceof Number)
112 return validateRange(result, (Number)typedValue, constraint, attributeValueReader);
113
114 return result.addSkipped(attributeValueReader, CONSTRAINT_NAME);
115 }
116
117
118
119
120
121
122
123
124
125
126
127 protected ConstraintValidationResult validateRange(DictionaryValidationResult result, Date value, RangeConstraint constraint, AttributeValueReader attributeValueReader) throws IllegalArgumentException {
128
129 Date date = value != null ? ValidationUtils.getDate(value, dateTimeService) : null;
130
131 String inclusiveMaxText = constraint.getInclusiveMax();
132 String exclusiveMinText = constraint.getExclusiveMin();
133
134 Date inclusiveMax = inclusiveMaxText != null ? ValidationUtils.getDate(inclusiveMaxText, dateTimeService) : null;
135 Date exclusiveMin = exclusiveMinText != null ? ValidationUtils.getDate(exclusiveMinText, dateTimeService) : null;
136
137 return isInRange(result, date, inclusiveMax, inclusiveMaxText, exclusiveMin, exclusiveMinText, attributeValueReader);
138 }
139
140
141
142
143
144
145
146
147
148
149
150 protected ConstraintValidationResult validateRange(DictionaryValidationResult result, Number value, RangeConstraint constraint, AttributeValueReader attributeValueReader) throws IllegalArgumentException {
151
152
153
154
155 BigDecimal number = value != null ? new BigDecimal(value.toString()) : null;
156
157 String inclusiveMaxText = constraint.getInclusiveMax();
158 String exclusiveMinText = constraint.getExclusiveMin();
159
160 BigDecimal inclusiveMax = inclusiveMaxText != null ? new BigDecimal(inclusiveMaxText) : null;
161 BigDecimal exclusiveMin = exclusiveMinText != null ? new BigDecimal(exclusiveMinText) : null;
162
163 return isInRange(result, number, inclusiveMax, inclusiveMaxText, exclusiveMin, exclusiveMinText, attributeValueReader);
164 }
165
166
167
168
169
170
171
172
173
174
175
176
177
178 private <T> ConstraintValidationResult isInRange(DictionaryValidationResult result, T value, Comparable<T> inclusiveMax, String inclusiveMaxText, Comparable<T> exclusiveMin, String exclusiveMinText, AttributeValueReader attributeValueReader) {
179
180 Result lessThanMax = ValidationUtils.isLessThanOrEqual(value, inclusiveMax);
181
182 Result greaterThanMin = ValidationUtils.isGreaterThan(value, exclusiveMin);
183
184
185 if (lessThanMax != Result.INVALID && greaterThanMin != Result.INVALID) {
186
187 if (lessThanMax == Result.UNDEFINED && greaterThanMin == Result.UNDEFINED)
188 return result.addNoConstraint(attributeValueReader, CONSTRAINT_NAME);
189
190
191 return result.addSuccess(attributeValueReader, CONSTRAINT_NAME);
192 }
193
194
195 if (lessThanMax != Result.UNDEFINED && greaterThanMin != Result.UNDEFINED)
196 return result.addError(RANGE_KEY, attributeValueReader, CONSTRAINT_NAME, RiceKeyConstants.ERROR_OUT_OF_RANGE, exclusiveMinText, inclusiveMaxText);
197
198 else if (lessThanMax == Result.INVALID)
199 return result.addError(MAX_INCLUSIVE_KEY, attributeValueReader, CONSTRAINT_NAME, RiceKeyConstants.ERROR_INCLUSIVE_MAX, inclusiveMaxText);
200
201 else
202 return result.addError(MIN_EXCLUSIVE_KEY, attributeValueReader, CONSTRAINT_NAME, RiceKeyConstants.ERROR_EXCLUSIVE_MIN, exclusiveMinText);
203 }
204
205 }