1 /*
2 * Copyright 2006 Werner Guttmann
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.exolab.castor.xml.validators;
17
18 import org.exolab.castor.xml.TypeValidator;
19 import org.exolab.castor.xml.ValidationContext;
20 import org.exolab.castor.xml.ValidationException;
21
22 /**
23 * The Int Validation class. This class handles validation for the primitive
24 * <code>int</code> and <code>java.lang.Integer</code> types as well as all
25 * derived types such as unsigned-short.
26 *
27 * @author <a href="mailto:werner DOT guttmann AT gmx DOT net">Werner Guttmann</a>
28 * @version $Revision: 6571 $ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr
29 * 2006) $
30 */
31 public class IntValidator extends PatternValidator implements TypeValidator {
32
33 /** If true, we perform "minimum value" validation. */
34 private boolean _useMin = false;
35 /** If true, we perform "maximum value" validation. */
36 private boolean _useMax = false;
37 /** If true, we perform "fixed" validation. */
38 private boolean _useFixed = false;
39 /** Minimum value (inclusive) for this int. (Not used unless _useMin == true.) */
40 private int _min = 0;
41 /** Maximum value (inclusive) for this int. (Not used unless _useMax == true.) */
42 private int _max = 0;
43 /** Maximum number of digits in this int. (Not applied if < 0.) */
44 private int _totalDigits = -1;
45 /** Fixed value of this int. (Not used unless _useFixed == true.) */
46 private int _fixed = 0;
47
48 /**
49 * Creates a new IntValidator with no restrictions.
50 */
51 public IntValidator() {
52 super();
53 } // -- IntegerValidator
54
55 /**
56 * Clears the fixed value for this IntValidator.
57 */
58 public void clearFixed() {
59 _useFixed = false;
60 } // -- clearFixed
61
62 /**
63 * Clears the maximum value for this IntValidator.
64 */
65 public void clearMax() {
66 _useMax = false;
67 } // -- clearMax
68
69 /**
70 * Clears the minimum value for this IntValidator.
71 */
72 public void clearMin() {
73 _useMin = false;
74 } // -- clearMin
75
76 /**
77 * Returns the configured fixed value for int validation. Returns null if no
78 * fixed value has been configured.
79 *
80 * @return the fixed value to validate against.
81 */
82 public Integer getFixed() {
83 if (_useFixed) {
84 return new Integer(_fixed);
85 }
86 return null;
87 } // -- getFixed
88
89 /**
90 * Returns the configured maximum value for int validation. Returns null if
91 * no maximum has been configured.
92 *
93 * @return the maximum (inclusive) value to validate against.
94 */
95 public Integer getMaxInclusive() {
96 if (_useMax) {
97 return new Integer(_max);
98 }
99 return null;
100 } // -- getMaxInclusive
101
102 /**
103 * Returns the configured minimum value for int validation. Returns null if
104 * no minimum has been configured.
105 *
106 * @return the minimum inclusive value to validate against.
107 */
108 public Integer getMinInclusive() {
109 if (_useMin) {
110 return new Integer(_min);
111 }
112 return null;
113 } // -- getMinInclusive
114
115 /**
116 * Returns the configured maximum number of digits (inclusive) for int
117 * validation. Returns null if no maximum number of digits has been
118 * configured.
119 *
120 * @return the maximum number of digits to validate against.
121 */
122 public Integer getTotalDigits() {
123 if (_totalDigits >= 0) {
124 return new Integer(_totalDigits);
125 }
126 return null;
127 } // -- getTotalDigits
128
129 /**
130 * Returns true if a fixed value to validate against has been set.
131 *
132 * @return true if a fixed value has been set.
133 */
134 public boolean hasFixed() {
135 return _useFixed;
136 } // -- hasFixed
137
138 /**
139 * Sets the fixed value for int validation.
140 * <p>
141 * NOTE: If maximum and/or minimum values have been set and the fixed value
142 * is not within that max/min range, then no int will pass validation. This
143 * is as according to the XML Schema spec.
144 *
145 * @param fixedValue
146 * the fixed value that a int validated with this validator must
147 * be equal to.
148 */
149 public void setFixed(final int fixedValue) {
150 _useFixed = true;
151 this._fixed = fixedValue;
152 } // -- setFixed
153
154 /**
155 * Sets the fixed value for int validation.
156 * <p>
157 * NOTE: If maximum and/or minimum values have been set and the fixed value
158 * is not within that max/min range, then no int will pass validation. This
159 * is as according to the XML Schema spec.
160 *
161 * @param fixedValue
162 * the fixed value that a int validated with this validator must
163 * be equal to.
164 */
165 public void setFixed(final Integer fixedValue) {
166 _useFixed = true;
167 this._fixed = fixedValue.intValue();
168 }
169
170 /**
171 * Sets the minimum (exclusive) value for int validation. To pass
172 * validation, a int must be greater than this value.
173 *
174 * @param minValue
175 * the minimum (exclusive) value for int validation.
176 */
177 public void setMinExclusive(final int minValue) {
178 _useMin = true;
179 _min = minValue + 1;
180 } // -- setMinExclusive
181
182 /**
183 * Sets the minimum (inclusive) value for int validation. To pass
184 * validation, a int must be greater than or equal to this value.
185 *
186 * @param minValue
187 * the minimum (inclusive) value for int validation.
188 */
189 public void setMinInclusive(final int minValue) {
190 _useMin = true;
191 _min = minValue;
192 } // -- setMinInclusive
193
194 /**
195 * Sets the maximum (exclusive) value for int validation. To pass
196 * validation, a int must be less than this value.
197 *
198 * @param maxValue
199 * the maximum (exclusive) value for int validation.
200 */
201 public void setMaxExclusive(final int maxValue) {
202 _useMax = true;
203 _max = maxValue - 1;
204 } // -- setMaxExclusive
205
206 /**
207 * Sets the maximum (inclusive) value for int validation. To pass
208 * validation, a int must be less than or equal to this value.
209 *
210 * @param maxValue
211 * the maximum (inclusive) value for int validation.
212 */
213 public void setMaxInclusive(final int maxValue) {
214 _useMax = true;
215 _max = maxValue;
216 } // -- setMaxInclusive
217
218 /**
219 * Sets the maximum number of digits for int validation. To pass validation,
220 * a int must have this many digits or fewer. Leading zeros are not counted.
221 *
222 * @param totalDig
223 * the maximum (inclusive) number of digits for int validation.
224 * (must be > 0)
225 */
226 public void setTotalDigits(final int totalDig) {
227 if (totalDig <= 0) {
228 throw new IllegalArgumentException(
229 "IntegerValidator: the totalDigits facet must be positive");
230 }
231 _totalDigits = totalDig;
232 }
233
234 /**
235 * Validates the given Object.
236 *
237 * @param i
238 * the long to validate
239 * @param context
240 * the ValidationContext
241 * @throws ValidationException if the object fails validation.
242 */
243 public void validate(final int i, final ValidationContext context)
244 throws ValidationException {
245 if (_useFixed && i != _fixed) {
246 String err = "int " + i + " is not equal to the fixed value: " + _fixed;
247 throw new ValidationException(err);
248 }
249
250 if (_useMin && i < _min) {
251 String err = "int " + i + " is less than the minimum allowed value: " + _min;
252 throw new ValidationException(err);
253 }
254
255 if (_useMax && i > _max) {
256 String err = "int " + i + " is greater than the maximum allowed value: " + _max;
257 throw new ValidationException(err);
258 }
259
260 if (_totalDigits != -1) {
261 int length = Integer.toString(i).length();
262 if (i < 0) {
263 length--;
264 }
265 if (length > _totalDigits) {
266 String err = "int " + i + " has too many digits -- must have "
267 + _totalDigits + " digits or fewer.";
268 throw new ValidationException(err);
269 }
270 }
271
272 if (hasPattern()) {
273 super.validate(Integer.toString(i), context);
274 }
275 } // -- validate
276
277 /**
278 * Validates the given Object.
279 *
280 * @param object
281 * the Object to validate
282 * @throws ValidationException if the object fails validation.
283 */
284 public void validate(final Object object) throws ValidationException {
285 validate(object, (ValidationContext) null);
286 } // -- validate
287
288 /**
289 * Validates the given Object.
290 *
291 * @param object
292 * the Object to validate
293 * @param context
294 * the ValidationContext
295 * @throws ValidationException if the object fails validation.
296 */
297 public void validate(final Object object, final ValidationContext context)
298 throws ValidationException {
299 if (object == null) {
300 String err = "IntValidator cannot validate a null object.";
301 throw new ValidationException(err);
302 }
303
304 int value = 0;
305 try {
306 value = ((Integer) object).intValue();
307 } catch (Exception ex) {
308 String err = "Expecting an Integer, received instead an instance of: ";
309 err += object.getClass().getName();
310 throw new ValidationException(err);
311 }
312 validate(value, context);
313 } //-- validate
314
315 } //-- IntegerValidator