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