1 /*
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Intalio, Inc. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Intalio, Inc. Exolab is a registered
23 * trademark of Intalio, Inc.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2000-2003 (C) Intalio, Inc. All Rights Reserved.
42 *
43 * $Id$
44 * Date Author Changes
45 * 10/26/2000 Arnaud Blandin Created
46 */
47 package org.exolab.castor.xml.validators;
48
49 import org.exolab.castor.xml.ValidationContext;
50 import org.exolab.castor.xml.ValidationException;
51 import org.exolab.castor.xml.TypeValidator;
52 import org.exolab.castor.types.Duration;
53
54 /**
55 * The Duration Validation class. This class handles validation for the Castor
56 * XML Schema duration type.
57 *
58 * @author <a href="mailto:visco@intalio.com">Keith Visco</a>
59 * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
60 * @version $Revision$ $Date: 2003-03-03 02:57:21 -0700 (Mon, 03 Mar 2003) $
61 */
62 public class DurationValidator extends PatternValidator implements TypeValidator {
63
64 /** Maximum allowed value (Inclusive) for a valid instance. (null if not set.) */
65 private Duration _maxInclusive;
66 /** Maximum allowed value (Exclusive) for a valid instance. (null if not set.) */
67 private Duration _maxExclusive;
68 /** Minimum allowed value (Inclusive) for a valid instance. (null if not set.) */
69 private Duration _minInclusive;
70 /** Minimum allowed value (Exclusive) for a valid instance. (null if not set.) */
71 private Duration _minExclusive;
72 /** Fixed value. If not null, a valid duration instance MUST have this value. */
73 private Duration _fixed;
74
75 /**
76 * No-arg constructor.
77 */
78 public DurationValidator() {
79 super();
80 } //-- TimeDurationValidator
81
82 /**
83 * Clears the fixed value for this Duration.
84 */
85 public void clearFixed() {
86 _fixed = null;
87 } // -- clearFixed
88
89 /**
90 * Clears the maximum value for this Duration.
91 */
92 public void clearMax() {
93 _maxInclusive = null;
94 _maxExclusive = null;
95 } // -- clearMax
96
97 /**
98 * Clears the minimum value for this Duration.
99 */
100 public void clearMin() {
101 _minInclusive = null;
102 _minExclusive = null;
103 } // -- clearMin
104
105 /**
106 * Returns the configured fixed value for Duration validation. Returns null
107 * if no fixed value has been configured.
108 *
109 * @return the fixed value to validate against.
110 */
111 public Duration getFixed() {
112 return _fixed;
113 } // -- getFixed
114
115 /**
116 * Returns the configured inclusive maximum value for Duration validation.
117 * Returns null if no inclusive maximum has been configured.
118 *
119 * @return the inclusive maximum value to validate against.
120 */
121 public Duration getMaxInclusive() {
122 return _maxInclusive;
123 } // -- getMaxInclusive
124
125 /**
126 * Returns the configured exclusive maximum value for Duration validation.
127 * Returns null if no exclusive maximum has been configured.
128 *
129 * @return the exclusive maximum value to validate against.
130 */
131 public Duration getMaxExclusive() {
132 return _maxExclusive;
133 } // -- getMaxInclusive
134
135 /**
136 * Returns the configured inclusive minimum value for Duration validation.
137 * Returns null if no inclusive minimum has been configured.
138 *
139 * @return the inclusive minimum value to validate against.
140 */
141 public Duration getMinInclusive() {
142 return _minInclusive;
143 } // -- getMinInclusive
144
145 /**
146 * Returns the configured exclusive minimum value for Duration validation.
147 * Returns null if no exclusive minimum has been configured.
148 *
149 * @return the exclusive minimum value to validate against.
150 */
151 public Duration getMinExclusive() {
152 return _minExclusive;
153 } // -- getMinInclusive
154
155 /**
156 * Returns true if a fixed value to validate against has been set.
157 *
158 * @return true if a fixed value has been set.
159 */
160 public boolean hasFixed() {
161 return _fixed != null;
162 } // -- hasFixed
163
164 /**
165 * Sets the fixed value for Duration validation.
166 * <p>
167 * NOTE: If maximum and/or minimum values have been set and the fixed value
168 * is not within that max/min range, then no Duration will pass
169 * validation. This is as according to the XML Schema spec.
170 *
171 * @param fixedValue
172 * the fixed value that a Duration validated with this
173 * validator must be equal to.
174 */
175 public void setFixed(final Duration fixedValue) {
176 _fixed = fixedValue;
177 }
178
179 /**
180 * Sets the minimum (exclusive) value for Duration validation. To pass
181 * validation, a Duration must be greater than this value.
182 *
183 * @param minValue
184 * the minimum (exclusive) value for Duration validation.
185 */
186 public void setMinExclusive(final Duration minValue) {
187 _minExclusive = minValue;
188 _minInclusive = null;
189 } //-- setMinExclusive
190
191 /**
192 * Sets the minimum (inclusive) value for Duration validation. To pass
193 * validation, a Duration must be greater than or equal to this value.
194 *
195 * @param minValue
196 * the minimum (inclusive) value for Duration validation.
197 */
198 public void setMinInclusive(final Duration minValue) {
199 _minInclusive = minValue;
200 _minExclusive = null;
201 } //-- setMinInclusive
202
203 /**
204 * Sets the maximum (exclusive) value for Duration validation. To pass
205 * validation, a Duration must be less than this value.
206 *
207 * @param maxValue
208 * the maximum (exclusive) value for Duration validation.
209 */
210 public void setMaxExclusive(final Duration maxValue) {
211 _maxExclusive = maxValue;
212 _maxInclusive = null;
213 } //-- setMaxExclusive
214
215 /**
216 * Sets the maximum (inclusive) value for Duration validation. To pass
217 * validation, a Duration must be less than or equal to this value.
218 *
219 * @param maxValue
220 * the maximum (inclusive) value for Duration validation.
221 */
222 public void setMaxInclusive(final Duration maxValue) {
223 _maxInclusive = maxValue;
224 _maxExclusive = null;
225 } //-- setMaxInclusive
226
227 /**
228 * Validate a duration instance.
229 * @param duration the duration to validate
230 * @throws ValidationException if the duration fails validation
231 */
232 public void validate(final Duration duration) throws ValidationException {
233 validate(duration, (ValidationContext) null);
234 }
235
236 /**
237 * Validates a duration instance.
238 * @param duration the duration type to validate
239 * @param context the ValidationContext
240 * @throws ValidationException if the duration fails validation
241 */
242 public void validate(final Duration duration, final ValidationContext context)
243 throws ValidationException {
244 boolean isThereMinInclusive = (_minInclusive != null);
245 boolean isThereMinExclusive = (_minExclusive != null);
246 boolean isThereMaxInclusive = (_maxInclusive != null);
247 boolean isThereMaxExclusive = (_maxExclusive != null);
248
249 if (isThereMinExclusive && isThereMinInclusive) {
250 throw new ValidationException("Both minInclusive and minExclusive are defined");
251 }
252
253 if (isThereMaxExclusive && isThereMaxInclusive) {
254 throw new ValidationException("Both maxInclusive and maxExclusive are defined");
255 }
256
257 if (_fixed != null && !duration.equal(_fixed)) {
258 String err = "Duration " + duration + " is not equal to the fixed value: " + _fixed;
259 throw new ValidationException(err);
260 }
261
262 if (isThereMinInclusive && _minInclusive.isGreater(duration)) {
263 String err = "Duration " + duration + " is less than the minimum allowed value: "
264 + _minInclusive;
265 throw new ValidationException(err);
266 }
267
268 if (isThereMinExclusive && (_minExclusive.isGreater(duration)
269 || duration.equals(_minExclusive))) {
270 String err = "Duration " + duration
271 + " is less than or equal to the minimum exclusive value: " + _minExclusive;
272 throw new ValidationException(err);
273 }
274
275 if (isThereMaxInclusive && duration.isGreater(_maxInclusive)) {
276 String err = "Duration " + duration + " is greater than the maximum allowed value "
277 + _maxInclusive;
278 throw new ValidationException(err);
279 }
280
281 if (isThereMaxExclusive && ((duration.isGreater(_maxExclusive))
282 || duration.equals(_maxExclusive))) {
283 String err = "Duration " + duration
284 + " is greater than or equal to the maximum exclusive value: " + _maxExclusive;
285 throw new ValidationException(err);
286 }
287
288 if (hasPattern()) {
289 super.validate(duration.toString(), context);
290 }
291 } //-- validate
292
293 /**
294 * Validates the given Object.
295 *
296 * @param object the Object to validate
297 * @throws ValidationException if the object fails validation
298 */
299 public void validate(final Object object) throws ValidationException {
300 validate(object, (ValidationContext) null);
301 } //-- validate
302
303 /**
304 * Validates the given Object.
305 *
306 * @param object the Object to validate
307 * @param context the ValidationContext
308 * @throws ValidationException if the object fails validation
309 */
310 public void validate(final Object object, final ValidationContext context)
311 throws ValidationException {
312 if (object == null) {
313 String err = "durationValidator cannot validate a null object.";
314 throw new ValidationException(err);
315 }
316
317 if (object instanceof String) {
318 try {
319 Duration duration = Duration.parseDuration((String) object);
320 validate(duration, context);
321 return;
322 } catch (java.text.ParseException pe) {
323 String err = "String provided fails to parse into a Duration: " + (String) object;
324 throw new ValidationException(err, pe);
325 }
326 }
327
328 Duration value = null;
329 try {
330 value = (Duration) object;
331 } catch (Exception ex) {
332 String err = "Expecting a duration, received instead: " + object.getClass().getName();
333 throw new ValidationException(err);
334 }
335
336 validate(value, context);
337 } //-- validate
338
339 }