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 }