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