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.schema; 36 37 import java.math.BigDecimal; 38 import java.util.Enumeration; 39 40 import org.exolab.castor.xml.ValidationException; 41 42 /** 43 * Represents the base type for XML Schema Facets 44 * 45 * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a> 46 * @version $Revision$ $Date: 2005-12-13 14:58:48 -0700 (Tue, 13 Dec 2005) $ 47 **/ 48 public class Facet extends Annotated { 49 /** SerialVersionUID */ 50 private static final long serialVersionUID = 7821829275720939922L; 51 52 public static final String ENUMERATION = "enumeration"; 53 public static final String LENGTH = "length"; 54 public static final String PATTERN = "pattern"; 55 public static final String PRECISION = "precision"; 56 public static final String MAX_EXCLUSIVE = "maxExclusive"; 57 public static final String MAX_INCLUSIVE = "maxInclusive"; 58 public static final String MIN_EXCLUSIVE = "minExclusive"; 59 public static final String MIN_INCLUSIVE = "minInclusive"; 60 public static final String MAX_LENGTH = "maxLength"; 61 public static final String MIN_LENGTH = "minLength"; 62 public static final String WHITESPACE = "whiteSpace"; 63 public static final String TOTALDIGITS = "totalDigits"; 64 public static final String FRACTIONDIGITS = "fractionDigits"; 65 66 public static final String WHITESPACE_PRESERVE = "preserve"; 67 public static final String WHITESPACE_REPLACE = "replace"; 68 public static final String WHITESPACE_COLLAPSE = "collapse"; 69 70 private static final String CLASSNAME = Facet.class.getName(); 71 72 private static final String NULL_ARGUMENT = "A null argument was passed to " + CLASSNAME + "#"; 73 74 private static final String ZERO_LENGTH_STRING = 75 "A zero-length String was passed to " + CLASSNAME + "#"; 76 77 /** The name of this Facet. */ 78 private final String _name; 79 /** The character value of this Facet. */ 80 private final String _value; 81 82 /** 83 * The owning {@link SimpleType} instance. 84 */ 85 private SimpleType _owningType; 86 87 /** 88 * Creates a new Facet with the given name. 89 * 90 * @param name the name of the Facet 91 * @param value the value of the Facet 92 **/ 93 public Facet(final String name, final String value) { 94 if (name == null) { 95 String err = NULL_ARGUMENT; 96 err += "Facet: 'name' and 'value' must not be null."; 97 throw new IllegalArgumentException(err); 98 } 99 if (name.length() == 0) { 100 String err = ZERO_LENGTH_STRING; 101 err += "Facet: 'name' and 'value' must not be zero-length."; 102 throw new IllegalArgumentException(err); 103 } 104 this._name = name; 105 this._value = value; 106 } 107 108 /** 109 * Returns the name of this Facet. 110 * 111 * @return the name of this Facet 112 **/ 113 public String getName() { 114 return _name; 115 } 116 117 /** 118 * Returns the character (String) representation of this facet. 119 * 120 * @return the value of this facet 121 **/ 122 public String getValue() { 123 return this._value; 124 } // -- getValue 125 126 /** 127 * Returns true if this Facet can occur more than once, such as the "enumeration" facet. 128 * 129 * @return true if this Facet can occur more than once. 130 **/ 131 public boolean isMultivalued() { 132 return _name.equals(Facet.ENUMERATION) || _name.equals(Facet.PATTERN); 133 } 134 135 /** 136 * Returns an int representation of the value of this facet. 137 * 138 * @return an int representation of the value of this facet 139 * @throws NumberFormatException if the value fails to parse as a int. 140 **/ 141 public int toInt() throws NumberFormatException { 142 return Integer.parseInt(_value); 143 } 144 145 /** 146 * Returns a long representation of the value of this facet. 147 * 148 * @return a long representation of the value of this facet 149 * @throws NumberFormatException if the value fails to parse as a long. 150 **/ 151 public long toLong() throws NumberFormatException { 152 return Long.parseLong(_value); 153 } 154 155 /** 156 * Returns an short representation of the value of this facet. 157 * 158 * @return an short representation of the value of this facet 159 * @throws NumberFormatException if the value fails to parse as a short. 160 **/ 161 public short toShort() throws NumberFormatException { 162 return Short.parseShort(_value); 163 } 164 165 /** 166 * Returns a double representation of the value of this facet. 167 * 168 * @return a double representation of the value of this facet 169 * @throws NumberFormatException if the value fails to parse as a float. 170 */ 171 public float toFloat() throws NumberFormatException { 172 if (_value.equals("INF")) { 173 return Float.POSITIVE_INFINITY; 174 } 175 if (_value.equals("-INF")) { 176 return Float.NEGATIVE_INFINITY; 177 } 178 return Float.valueOf(_value).floatValue(); 179 } 180 181 /** 182 * Returns a double representation of the value of this facet. 183 * 184 * @return a double representation of the value of this facet 185 * @throws NumberFormatException if the value fails to parse as a double. 186 **/ 187 public double toDouble() throws NumberFormatException { 188 return Double.parseDouble(_value); 189 } 190 191 /** 192 * Returns a byte representation of the value of this facet. 193 * 194 * @return a byte representation of the value of this facet 195 * @throws NumberFormatException if the value fails to parse as a byte. 196 **/ 197 public byte toByte() throws NumberFormatException { 198 return Byte.parseByte(_value); 199 } 200 201 /** 202 * Returns a {@link BigDecimal} representation of the value of this facet. 203 * 204 * @return a {@link BigDecimal} representation of the value of this facet 205 * @throws NumberFormatException if the value cannot be parsed as number 206 */ 207 public BigDecimal toBigDecimal() throws NumberFormatException { 208 return new BigDecimal(_value); 209 } 210 211 /** 212 * Returns the type of this Schema Structure. 213 * 214 * @return the type of this Schema Structure 215 **/ 216 public short getStructureType() { 217 return Structure.FACET; 218 } 219 220 /** 221 * Checks the validity of this Schema defintion. 222 * 223 * @exception ValidationException when this Schema definition is invalid. 224 **/ 225 public void validate() throws ValidationException { 226 // TODO: shouldn't this be converted to an abstract method ? 227 // -- do nothing for now 228 } 229 230 /** 231 * Checks whether the current facet overrides a facet of the base data type. This does generally 232 * happen when a data type is derived by restriction and it therefore has facet(s), which are more 233 * restrictive than the ones of the base data type. 234 * 235 * <p> 236 * This method is used for merging facets of the base and derived types, in order to create an 237 * effective set of facets for the derived type. 238 * 239 * <p> 240 * It's important to note that this method does not perform any validity checks. Validation must 241 * be generally performed <b>before</b> trying to merge facets of the base and derived types. 242 * 243 * @param baseFacet a facet of the base data type 244 * @return <code>true</code>, if the current facet overrides <code>baseFacet</code>; 245 * <code>false</code>, otherwise. 246 * 247 * @see #checkConstraints(Enumeration,Enumeration) 248 * @see SimpleType#getEffectiveFacets() 249 */ 250 public boolean overridesBase(final Facet baseFacet) { 251 return getName().equals(baseFacet.getName()); 252 } 253 254 /** 255 * Checks the constraints on the current facet against the other local facets of the same derived 256 * data type and facets of the base data type. Validation is performed according to the rules 257 * defined in "<a href="http://www.w3.org/TR/xmlschema-2/">XML Schema Part 2: Datatypes Second 258 * Edition</a>" document. 259 * 260 * @param localFacets local facets of the data type 261 * @param baseFacets merged facets of the base data type 262 * @throws SchemaException when the current facet does not satisfy schema component validation 263 * constraints 264 */ 265 public void checkConstraints(final Enumeration localFacets, final Enumeration baseFacets) 266 throws SchemaException { 267 // Does nothing by default 268 } 269 270 /** 271 * Sets the owning {@link SimpleType} instance. 272 * 273 * @param owningType The owning {@link SimpleType} instance. 274 */ 275 public void setOwningType(final SimpleType owningType) { 276 _owningType = owningType; 277 } 278 279 /** 280 * Returns the owning {@link SimpleType} instance. 281 * 282 * @return The owning {@link SimpleType} instance. 283 */ 284 public SimpleType getOwningType() { 285 return _owningType; 286 } 287 288 } // -- Facet