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