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 1999 (C) Intalio, Inc. All Rights Reserved. 32 * 33 * $Id$ 34 */ 35 package org.exolab.castor.xml.validators; 36 37 import java.lang.reflect.Array; 38 import java.util.Enumeration; 39 import java.util.Vector; 40 41 import org.exolab.castor.xml.TypeValidator; 42 import org.exolab.castor.xml.ValidationContext; 43 import org.exolab.castor.xml.ValidationException; 44 45 /** 46 * A class for defining simple rules used for validating a content model. 47 * 48 * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a> 49 * @version $Revision$ $Date: 2004-10-01 07:25:46 -0600 (Fri, 01 Oct 2004) $ 50 */ 51 public class SimpleTypeValidator implements TypeValidator { 52 53 /** The minimum number of occurences allowed. */ 54 private int _minOccurs = 0; 55 /** The maximum number of occurences allowed. */ 56 private int _maxOccurs = -1; 57 /** The type validate to delegate validation to. */ 58 private TypeValidator _validator = null; 59 60 /** 61 * Creates a default SimpleTypeValidator. 62 */ 63 public SimpleTypeValidator() { 64 super(); 65 } 66 67 /** 68 * Creates a SimpleTypeValidator using the given TypeValidator for delegating validation. 69 * 70 * @param validator The TypeValidator to use 71 */ 72 public SimpleTypeValidator(final TypeValidator validator) { 73 super(); 74 this._validator = validator; 75 } 76 77 /** 78 * Sets the maximum number of times that the described field may occur. 79 * 80 * @param maxOccurs the maximum number of times that the described field may occur. 81 */ 82 public void setMaxOccurs(final int maxOccurs) { 83 this._maxOccurs = maxOccurs; 84 } 85 86 /** 87 * Sets the minimum number of times that the described field may occur. 88 * 89 * @param minOccurs the minimum number of times that the described field may occur. 90 */ 91 public void setMinOccurs(final int minOccurs) { 92 this._minOccurs = minOccurs; 93 } 94 95 /** 96 * Sets the TypeValidator to delegate validation to. 97 * 98 * @param validator the TypeValidator to delegate validation to. 99 */ 100 public void setValidator(final TypeValidator validator) { 101 this._validator = validator; 102 } 103 104 /** 105 * Validates the given Object. 106 * 107 * @param object the Object to validate. 108 * @param context the ValidationContext. 109 * @throws ValidationException if validation fails. 110 */ 111 public void validate(final Object object, final ValidationContext context) 112 throws ValidationException { 113 boolean required = (_minOccurs > 0); 114 115 if (object == null && required) { 116 String err = "This field is required and cannot be null."; 117 throw new ValidationException(err); 118 } 119 120 if (object != null) { 121 Class type = object.getClass(); 122 123 int size = 1; 124 boolean byteArray = false; 125 if (type.isArray()) { 126 byteArray = (type.getComponentType() == Byte.TYPE); 127 if (!byteArray) { 128 size = Array.getLength(object); 129 } 130 } 131 132 // -- check minimum 133 if (size < _minOccurs) { 134 String err = "A minimum of " + _minOccurs + " instance(s) of this field is required."; 135 throw new ValidationException(err); 136 } 137 138 // -- check maximum 139 if (_maxOccurs >= 0 && size > _maxOccurs) { 140 String err = "A maximum of " + _maxOccurs + " instance(s) of this field are allowed."; 141 throw new ValidationException(err); 142 } 143 144 if (_validator == null) { 145 return; 146 } 147 148 // -- check type 149 if (isPrimitive(type) || (type == String.class)) { 150 _validator.validate(object, context); 151 } else if (byteArray) { 152 // -- do nothing for now 153 } else if (type.isArray()) { 154 size = Array.getLength(object); 155 for (int i = 0; i < size; i++) { 156 _validator.validate(Array.get(object, i), context); 157 } 158 } else if (object instanceof java.util.Enumeration) { 159 Enumeration enumeration = (Enumeration) object; 160 while (enumeration.hasMoreElements()) { 161 _validator.validate(enumeration.nextElement(), context); 162 } 163 } else if (object instanceof java.util.Vector) { 164 Vector vector = (Vector) object; 165 for (int i = 0; i < vector.size(); i++) { 166 _validator.validate(vector.elementAt(i), context); 167 } 168 } else { 169 _validator.validate(object, context); 170 } 171 } 172 } 173 174 // -------------------/ 175 // - Private Methods -/ 176 // -------------------/ 177 178 /** 179 * Returns true if the given class type should be treated as a primitive. Wrapper objects such as 180 * java.lang.Integer, and java.lang.Float, will be treated as primitives. 181 * 182 * @param type the Class to check 183 * @return true if the given class should be treated as a primitive type. 184 */ 185 private boolean isPrimitive(final Class type) { 186 if (type.isPrimitive()) { 187 return true; 188 } 189 190 return (type == Boolean.class || type == Byte.class || type == Character.class 191 || type == Double.class || type == Float.class || type == Integer.class 192 || type == Long.class || type == Short.class); 193 } 194 195 }