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