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>maxInclusive</b> constraining facet, defined in section "<a href="
23   * http://www.w3.org/TR/xmlschema-2/#rf-maxInclusive">4.3.7 maxInclusive</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>maxInclusive</b> is the <i>inclusive upper bound</i> of the <i>value space</i>
28   * for a datatype with the <i>ordered</i> property. The value of <b>maxInclusive</b> <i>must</i> be
29   * in the <i>value space</i> of the <i>base type</i>.
30   *
31   * @author <a href="mailto:sergei.ivanov@mail.ru">Sergei Ivanov</a>
32   * @version $Revision: 6465 $ $Date: 2006-04-13 06:47:36 -0600 (Thu, 13 Apr 2006) $
33   */
34  public final class MaxInclusive extends Facet {
35  
36    /**
37     * Serial version UID.
38     */
39    private static final long serialVersionUID = 2826634377769846916L;
40  
41    /**
42     * Creates an instance of this class.
43     * 
44     * @param value A value for this {@link Facet}.
45     */
46    public MaxInclusive(final String value) {
47      super(Facet.MAX_INCLUSIVE, value);
48    }
49  
50    /**
51     * Checks whether the current facet overrides a facet of the base data type.
52     *
53     * <p>
54     * <i>maxInclusive</i> can override the following facets of the base data type:
55     *
56     * <ul>
57     * <li><i>maxExclusive</i></li>
58     * <li>or <i>maxInclusive</i></li>
59     * </ul>
60     *
61     * @param baseFacet a facet of the base data type
62     * @return <code>true</code>, if the current facet overrides <code>baseFacet</code>;
63     *         <code>false</code>, otherwise.
64     * @see #checkConstraints(Enumeration, Enumeration)
65     */
66    public boolean overridesBase(final Facet baseFacet) {
67      final String otherName = baseFacet.getName();
68      return otherName.equals(Facet.MAX_EXCLUSIVE) || otherName.equals(Facet.MAX_INCLUSIVE);
69    }
70  
71    /**
72     * Validation is performed according to section "<a href="
73     * http://www.w3.org/TR/xmlschema-2/#maxInclusive-coss">4.3.7.4 Constraints on maxInclusive Schema
74     * Components</a>" of "<a href="http://www.w3.org/TR/xmlschema-2/">XML Schema Part 2: Datatypes
75     * Second Edition</a>" document.
76     *
77     * @param localFacets local facets of the data type
78     * @param baseFacets merged facets of the base data type
79     * @throws SchemaException when the current facet does not satisfy schema component validation
80     *         constraints
81     */
82    public void checkConstraints(final Enumeration localFacets, final Enumeration baseFacets)
83        throws SchemaException {
84  
85      while (localFacets.hasMoreElements()) {
86        final Facet other = (Facet) localFacets.nextElement();
87        if (this == other) {
88          continue; // do not check against self
89        }
90        final String otherName = other.getName();
91        if (otherName.equals(Facet.MIN_INCLUSIVE) && getOwningType().isNumericType()
92            && other.toBigDecimal().compareTo(this.toBigDecimal()) > 0) {
93          // Schema Component Constraint: minInclusive <= maxInclusive
94          throw new SchemaException(
95              "It is an error for the value specified " + "for minInclusive to be greater than "
96                  + "the value specified for maxInclusive " + "for the same datatype.");
97        }
98      }
99      if (baseFacets != null) {
100       while (baseFacets.hasMoreElements()) {
101         final Facet other = (Facet) baseFacets.nextElement();
102         final String otherName = other.getName();
103 
104         // Schema Component Constraint: maxInclusive valid restriction
105         // It is an error if any of the following conditions is true:
106         if (otherName.equals(Facet.MAX_INCLUSIVE) && getOwningType().isNumericType()
107             && this.toBigDecimal().compareTo(other.toBigDecimal()) > 0) {
108           // [1]
109           throw new SchemaException("It is an error if the following condition is true: "
110               + "maxInclusive is among the members of {facets} "
111               + "of {base type definition} and {value} is greater than "
112               + "the {value} of the parent maxInclusive.");
113         } else if (otherName.equals(Facet.MAX_EXCLUSIVE) && getOwningType().isNumericType()
114             && this.toBigDecimal().compareTo(other.toBigDecimal()) >= 0) {
115           // [2]
116           throw new SchemaException("It is an error if the following condition is true: "
117               + "maxExclusive is among the members of {facets} "
118               + "of {base type definition} and {value} is greater than "
119               + "or equal to the {value} of the parent maxExclusive.");
120         } else if (otherName.equals(Facet.MIN_INCLUSIVE) && getOwningType().isNumericType()
121             && this.toBigDecimal().compareTo(other.toBigDecimal()) < 0) {
122           // [3]
123           throw new SchemaException("It is an error if the following condition is true: "
124               + "minInclusive is among the members of {facets} "
125               + "of {base type definition} and {value} is less than "
126               + "the {value} of the parent minInclusive.");
127         } else if (otherName.equals(Facet.MIN_EXCLUSIVE) && getOwningType().isNumericType()
128             && this.toBigDecimal().compareTo(other.toBigDecimal()) <= 0) {
129           // [4]
130           throw new SchemaException("It is an error if the following condition is true: "
131               + "minExclusive is among the members of {facets} "
132               + "of {base type definition} and {value} is less than "
133               + "or equal to the {value} of the parent minExclusive.");
134         }
135       }
136     }
137   }
138 }