1 package org.apache.fulcrum.intake.validator;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Locale;
25 import java.util.Map;
26
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.fulcrum.intake.model.Field;
29 import org.apache.fulcrum.intake.model.Group;
30 import org.apache.fulcrum.intake.validator.FieldReference.Comparison;
31
32 /**
33 * Validates an int field in dependency on another int field.
34 *
35 * <table>
36 * <caption>Validation rules</caption>
37 * <tr>
38 * <th>Name</th><th>Valid Values</th><th>Default Value</th>
39 * </tr>
40 * <tr>
41 * <td>less-than</td>
42 * <td><name of other field></td>
43 * <td> </td>
44 * </tr>
45 * <tr>
46 * <td>greater-than</td>
47 * <td><name of other field></td>
48 * <td> </td>
49 * </tr>
50 * <tr>
51 * <td>less-than-or-equal</td>
52 * <td><name of other field></td>
53 * <td> </td>
54 * </tr>
55 * <tr>
56 * <td>greater-than-or-equal</td>
57 * <td><name of other field></td>
58 * <td> </td>
59 * </tr>
60 * </table>
61 *
62 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
63 * @version $Id$
64 */
65 public class IntegerRangeValidator
66 extends IntegerValidator
67 {
68 /** List of FieldReferences for multiple comparisons */
69 List<FieldReference> fieldReferences;
70
71 /** Callback for the actual compare operation */
72 CompareCallback<Integer> compareCallback;
73
74 /**
75 * Default constructor
76 */
77 public IntegerRangeValidator()
78 {
79 super();
80 }
81
82 /**
83 * Constructor to use when initializing Object
84 *
85 * @param paramMap a map of parameters
86 * @throws InvalidMaskException one of the mask rules is invalid
87 */
88 @Override
89 public void init(Map<String, ? extends Constraint> paramMap)
90 throws InvalidMaskException
91 {
92 super.init(paramMap);
93
94 compareCallback = new CompareCallback<Integer>()
95 {
96 /**
97 * Compare the given values using the compare operation provided
98 *
99 * @param compare type of compare operation
100 * @param thisValue value of this field
101 * @param refValue value of the reference field
102 *
103 * @return the result of the comparison
104 */
105 @Override
106 public boolean compareValues(Comparison compare, Integer thisValue, Integer refValue)
107 {
108 boolean result = true;
109
110 switch (compare)
111 {
112 case LT:
113 result = thisValue.compareTo(refValue) < 0;
114 break;
115
116 case LTE:
117 result = thisValue.compareTo(refValue) <= 0;
118 break;
119
120 case GT:
121 result = thisValue.compareTo(refValue) > 0;
122 break;
123
124 case GTE:
125 result = thisValue.compareTo(refValue) >= 0;
126 break;
127 }
128
129 return result;
130 }
131 };
132
133 fieldReferences = new ArrayList<FieldReference>(10);
134
135 for (Map.Entry<String, ? extends Constraint> entry : paramMap.entrySet())
136 {
137 String key = entry.getKey();
138 Constraint constraint = entry.getValue();
139
140 Comparison compare = FieldReference.getComparisonType(key);
141
142 if (compare != null)
143 {
144 // found matching constraint
145 FieldReference/FieldReference.html#FieldReference">FieldReference fieldref = new FieldReference();
146 fieldref.setComparison(compare);
147 fieldref.setFieldName(constraint.getValue());
148 fieldref.setMessage(constraint.getMessage());
149
150 fieldReferences.add(fieldref);
151 }
152 }
153
154 if (fieldReferences.isEmpty())
155 {
156 log.warn("No reference field rules have been found.");
157 }
158 }
159
160 /**
161 * Determine whether a testValue meets the criteria specified
162 * in the constraints defined for this validator
163 *
164 * @param testField a <code>Field</code> to be tested
165 * @throws ValidationException containing an error message if the
166 * testValue did not pass the validation tests.
167 */
168 @Override
169 public void assertValidity(final Field<Integer> testField)
170 throws ValidationException
171 {
172 super.assertValidity(testField);
173
174 Group thisGroup = testField.getGroup();
175 Locale locale = testField.getLocale();
176
177 if (testField.isMultiValued())
178 {
179 String[] stringValues = (String[])testField.getTestValue();
180
181 for (int i = 0; i < stringValues.length; i++)
182 {
183 assertValidity(stringValues[i], thisGroup, locale);
184 }
185 }
186 else
187 {
188 String testValue = (String)testField.getTestValue();
189
190 assertValidity(testValue, thisGroup, locale);
191 }
192 }
193
194 /**
195 * Determine whether a testValue meets the criteria specified
196 * in the constraints defined for this validator
197 *
198 * @param testValue a <code>String</code> to be tested
199 * @param group the group this field belongs to
200 * @param locale the locale for this field
201 *
202 * @throws ValidationException containing an error message if the
203 * testValue did not pass the validation tests.
204 */
205 public void assertValidity(final String testValue, final Group group, final Locale locale)
206 throws ValidationException
207 {
208 if (required || StringUtils.isNotEmpty(testValue))
209 {
210 Integer testInt;
211
212 try
213 {
214 testInt = parseNumber(testValue, locale);
215 }
216 catch (NumberFormatException e)
217 {
218 errorMessage = invalidNumberMessage;
219 throw new ValidationException(invalidNumberMessage);
220 }
221
222 try
223 {
224 FieldReference.checkReferences(fieldReferences, compareCallback,
225 testInt, group);
226 }
227 catch (ValidationException e)
228 {
229 errorMessage = e.getMessage();
230 throw e;
231 }
232 }
233 }
234 }