View Javadoc
1   /*
2    * Copyright 2008 Werner Guttmann
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  package org.exolab.castor.xml.schema.facets;
15  
16  import java.util.Enumeration;
17  
18  import org.exolab.castor.xml.schema.Facet;
19  import org.exolab.castor.xml.schema.SchemaException;
20  
21  /**
22   * An implementation of <b>minExclusive</b> constraining facet, defined in section "<a href="
23   * http://www.w3.org/TR/xmlschema-2/#rf-minExclusive">4.3.9 minExclusive</a>" of "<a href="
24   * http://www.w3.org/TR/xmlschema-2/">XML Schema Part 2: Datatypes Second Edition</a>" document.
25   *
26   * <p>
27   * [Definition:] <b>minExclusive</b> is the <i>exclusive lower bound</i> of the <i>value space</i>
28   * for a datatype with the <i>ordered</i> property. The value of <b>minExclusive</b> <i>must</i> be
29   * in the <i>value space</i> of the <i>base type</i> or be equal to {value} in {base type
30   * definition}.
31   *
32   * @author <a href="mailto:sergei.ivanov@mail.ru">Sergei Ivanov</a>
33   * @version $Revision: 6465 $ $Date: 2006-04-13 06:47:36 -0600 (Thu, 13 Apr 2006) $
34   */
35  public final class MinExclusive extends Facet {
36  
37    /**
38     * Serial version UID.
39     */
40    private static final long serialVersionUID = 9164023814934394681L;
41  
42    /**
43     * Creates an instance of this class.
44     * 
45     * @param value A value for this {@link Facet}.
46     */
47    public MinExclusive(final String value) {
48      super(Facet.MIN_EXCLUSIVE, value);
49    }
50  
51    /**
52     * Checks whether the current facet overrides a facet of the base data type.
53     *
54     * <p>
55     * <i>minExclusive</i> can override the following facets of the base data type:
56     *
57     * <ul>
58     * <li><i>minExclusive</i></li>
59     * <li>or <i>minInclusive</i></li>
60     * </ul>
61     *
62     * @param baseFacet a facet of the base data type
63     * @return <code>true</code>, if the current facet overrides <code>baseFacet</code>;
64     *         <code>false</code>, otherwise.
65     * @see #checkConstraints(Enumeration, Enumeration)
66     */
67    public boolean overridesBase(final Facet baseFacet) {
68      final String otherName = baseFacet.getName();
69      return otherName.equals(Facet.MIN_EXCLUSIVE) || otherName.equals(Facet.MIN_INCLUSIVE);
70    }
71  
72    /**
73     * Validation is performed according to section "<a href="
74     * http://www.w3.org/TR/xmlschema-2/#minExclusive-coss">4.3.9.4 Constraints on minExclusive Schema
75     * Components</a>" of "<a href="http://www.w3.org/TR/xmlschema-2/">XML Schema Part 2: Datatypes
76     * Second Edition</a>" document.
77     *
78     * @param localFacets local facets of the data type
79     * @param baseFacets merged facets of the base data type
80     * @throws SchemaException when the current facet does not satisfy schema component validation
81     *         constraints
82     */
83    public void checkConstraints(final Enumeration localFacets, final Enumeration baseFacets)
84        throws SchemaException {
85  
86      while (localFacets.hasMoreElements()) {
87        final Facet other = (Facet) localFacets.nextElement();
88        if (this == other) {
89          continue; // do not check against self
90        }
91        final String otherName = other.getName();
92        if (otherName.equals(Facet.MIN_INCLUSIVE)) {
93          // Schema Component Constraint: minInclusive and minExclusive
94          throw new SchemaException("It is an error for both minInclusive and minExclusive "
95              + "to be specified for the same datatype.");
96        } else if (otherName.equals(Facet.MAX_INCLUSIVE) && getOwningType().isNumericType()
97            && this.toBigDecimal().compareTo(other.toBigDecimal()) >= 0) {
98          // Schema Component Constraint: minExclusive < maxInclusive
99          throw new SchemaException(
100             "It is an error for the value specified " + "for minExclusive to be greater than "
101                 + "or equal to the value specified for " + "maxInclusive for the same datatype.");
102       }
103     }
104     if (baseFacets != null) {
105       while (baseFacets.hasMoreElements()) {
106         final Facet other = (Facet) baseFacets.nextElement();
107         final String otherName = other.getName();
108 
109         // Schema Component Constraint: minExclusive valid restriction
110         // It is an error if any of the following conditions is true:
111         if (otherName.equals(Facet.MIN_EXCLUSIVE) && getOwningType().isNumericType()
112             && this.toBigDecimal().compareTo(other.toBigDecimal()) < 0) {
113           // [1]
114           throw new SchemaException("It is an error if the following condition is true: "
115               + "minExclusive is among the members of {facets} of "
116               + "{base type definition} and {value} is less than "
117               + "the {value} of the parent minExclusive.");
118         } else if (otherName.equals(Facet.MAX_INCLUSIVE) && getOwningType().isNumericType()
119             && this.toBigDecimal().compareTo(other.toBigDecimal()) > 0) {
120           // [2]
121           throw new SchemaException("It is an error if the following condition is true: "
122               + "maxInclusive is among the members of {facets} of "
123               + "{base type definition} and {value} is greater than "
124               + "the {value} of the parent maxInclusive.");
125         } else if (otherName.equals(Facet.MIN_INCLUSIVE) && getOwningType().isNumericType()
126             && this.toBigDecimal().compareTo(other.toBigDecimal()) < 0) {
127           // [3]
128           throw new SchemaException("It is an error if the following condition is true: "
129               + "minInclusive is among the members of {facets} of "
130               + "{base type definition} and {value} is less than "
131               + "the {value} of the parent minInclusive.");
132         } else if (otherName.equals(Facet.MAX_EXCLUSIVE) && getOwningType().isNumericType()
133             && this.toBigDecimal().compareTo(other.toBigDecimal()) >= 0) {
134           // [4]
135           throw new SchemaException("It is an error if the following condition is true: "
136               + "maxExclusive is among the members of {facets} of "
137               + "{base type definition} and {value} is greater than "
138               + "or equal to the {value} of the parent maxExclusive.");
139         }
140       }
141     }
142   }
143 }