1# -*- coding: utf-8 -*-
2# Copyright 2009-2013, Peter A. Bigot
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain a
6# copy of the License at:
7#
8#            http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16"""Classes related to XMLSchema facets.
17
18The definitions herein are from sections U{4.2<http://www.w3.org/TR/xmlschema-2/index.html#rf-facets>}
19and U{4.3<http://www.w3.org/TR/xmlschema-2/index.html#rf-facets>} of
20U{XML Schema Part 2: Datatypes<http://www.w3.org/TR/xmlschema-2/>}.
21Facets are attributes of a datatype that constrain its lexical and
22value spaces.
23
24"""
25
26import logging
27import re
28import decimal
29import pyxb
30from . import datatypes
31from . import basis
32from pyxb.utils import utility, six
33
34_log = logging.getLogger(__name__)
35
36class Facet (pyxb.cscRoot):
37    """The base class for facets.
38
39    This provides association with STDs, a name, and a value for the facet.
40    """
41
42    _Name = None
43    @classmethod
44    def Name (self):
45        """The name of a facet is a class constant."""
46        return self._Name
47
48    __baseTypeDefinition = None
49    def baseTypeDefinition (self):
50        """The SimpleTypeDefinition component restricted by this facet.
51
52        Note: this is NOT the STD to which the facet belongs, but is
53        usually that STD's base type.  I.e., this jumps us through all
54        the containing restrictions and extensions to get to the core
55        type definition."""
56        return self.__baseTypeDefinition
57
58    __ownerTypeDefinition = None
59    def ownerTypeDefinition (self):
60        """The SimpleTypeDefinition component to which this facet belongs.
61
62        I.e., the one in which the hasFacet specification was found.
63        This value is None if the facet is not associated with an
64        STD."""
65        return self.__ownerTypeDefinition
66
67    # The default valueDatatype to use for instances of this class.
68    # This is overridden in subclasses that do not use late value
69    # datatype bindings.
70    _ValueDatatype = None
71
72    # The datatype used for facet values.
73    __valueDatatype = None
74    def valueDatatype (self):
75        """Get the datatype used to represent values of the facet.
76
77        This usually has nothing to do with the owner datatype; for
78        example, the length facet may apply to any STD but the value
79        of the facet is an integer.  In generated bindings this is
80        usually set explicitly in the facet constructor; when
81        processing a schema, it is derived from the value's type
82        definition.
83        """
84        if self.__valueDatatype is None:
85            assert self.baseTypeDefinition() is not None
86            return self.baseTypeDefinition().pythonSupport()
87        return self.__valueDatatype
88
89    __value = None
90    def _value (self, v): self.__value = v
91    def value (self): return self.__value
92
93    __annotation = None
94    def annotation (self): return self.__annotation
95
96    def __init__ (self, **kw):
97        """Create a facet instance, initializing it from the keyword parameters."""
98        super(Facet, self).__init__(**kw)
99        # Can't create base class instances
100        assert Facet != self.__class__
101        self.setFromKeywords(_reset=True, _constructor=True, **kw)
102
103    def _setFromKeywords_vb (self, **kw):
104        """Configure values of the facet from a set of keywords.
105
106        This method is pre-extended; subclasses should invoke the
107        parent method after setting their local configuration.
108
109        @keyword _reset: If C{False} or missing, existing values will
110                         be retained if they do not appear in the
111                         keywords.  If C{True}, members not defined in
112                         the keywords are set to a default.
113        @keyword base_type_definition:
114        @keyword owner_type_definition:
115        @keyword value_datatype:
116        """
117
118        if not kw.get('_reset', False):
119            kw.setdefault('base_type_definition', self.__baseTypeDefinition)
120            kw.setdefault('owner_type_definition', self.__ownerTypeDefinition)
121            kw.setdefault('value_datatype', self.__valueDatatype)
122        self.__baseTypeDefinition = kw.get('base_type_definition')
123        self.__ownerTypeDefinition = kw.get('owner_type_definition')
124        self.__valueDatatype = kw.get('value_datatype', self._ValueDatatype)
125        # Verify that there's enough information that we should be
126        # able to identify a PST suitable for representing facet
127        # values.
128        assert (self.__valueDatatype is not None) or (self.__baseTypeDefinition is not None)
129        super_fn = getattr(super(Facet, self), '_setFromKeywords_vb', lambda *a,**kw: self)
130        return super_fn(**kw)
131
132    def setFromKeywords (self, **kw):
133        """Public entrypoint to the _setFromKeywords_vb call hierarchy."""
134        return self._setFromKeywords_vb(**kw)
135
136    @classmethod
137    def ClassForFacet (cls, name):
138        """Given the name of a facet, return the Facet subclass that represents it."""
139        assert cls != Facet
140        if 0 <= name.find(':'):
141            name = name.split(':', 1)[1]
142        facet_class = globals().get('%s_%s' % (cls._FacetPrefix, name))
143        if facet_class is None:
144            raise pyxb.LogicError('Unrecognized facet name %s: expect %s' % (name, ','.join([_f._Name for _f in cls.Facets])))
145        assert facet_class is not None
146        return facet_class
147
148    def _valueString (self):
149        if isinstance(self, _CollectionFacet_mixin):
150            return six.u(',').join([ six.text_type(_i) for _i in six.iteritems(self) ])
151        if (self.valueDatatype() is not None) and (self.value() is not None):
152            try:
153                return self.valueDatatype().XsdLiteral(self.value())
154            except Exception:
155                _log.exception('Stringize facet %s produced exception', self.Name())
156                raise
157        return six.text_type(self.value())
158
159    def __str__ (self):
160        rv = []
161        rv.append('%s="%s"' % (self.Name(), self._valueString()))
162        if isinstance(self, _Fixed_mixin) and self.fixed():
163            rv.append('[fixed]')
164        return ''.join(rv)
165
166class ConstrainingFacet (Facet):
167    """One of the facets defined in section 4.3, which provide
168    constraints on the lexical space of a type definition."""
169
170    # The prefix used for Python classes used for a constraining
171    # facet.  Note that this is not the prefix used when generating a
172    # Python class member that specifies a constraining instance, even
173    # if it happens to be the same digraph.
174    _FacetPrefix = 'CF'
175
176    def __init__ (self, **kw):
177        super(ConstrainingFacet, self).__init__(**kw)
178
179    def _validateConstraint_vx (self, value):
180        raise pyxb.LogicError("Facet %s does not implement constraints" % (self.Name(),))
181
182    def validateConstraint (self, value):
183        """Return True iff the given value satisfies the constraint represented by this facet instance.
184
185        The actual test is delegated to the subclasses."""
186        return self._validateConstraint_vx(value)
187
188    def __setFromKeywords(self, **kw):
189        kwv = kw.get('value')
190        if kwv is not None:
191            vdt = self.valueDatatype()
192            if not isinstance(kwv, vdt):
193                kwv = vdt(kwv)
194            self._value(kwv)
195
196    def _setFromKeywords_vb (self, **kw):
197        """Extend base class.
198
199        Additional keywords:
200        * value
201        """
202        # NB: This uses post-extension because it makes reference to the value_data_type
203        super_fn = getattr(super(ConstrainingFacet, self), '_setFromKeywords_vb', lambda *a,**kw: self)
204        rv = super_fn(**kw)
205        self.__setFromKeywords(**kw)
206        return rv
207
208class _LateDatatype_mixin (pyxb.cscRoot):
209    """Marker class to indicate that the facet instance must be told
210    its datatype when it is constructed.
211
212    This is necessary for facets like L{CF_minInclusive} and
213    L{CF_minExclusive}, for which the value is determined by the base
214    type definition of the associated STD.  In some cases the value
215    that must be used in the facet cannot be represented in the Python
216    type used for the facet; see L{LateDatatypeBindsSuperclass}.
217    """
218
219    _LateDatatypeBindsSuperclass = None
220    """The class variable that indicates that the Subclasses must
221    override this variable with a value of C{True} or C{False}.  The
222    value is C{True} iff the value used for the facet is not within
223    the value space of the corresponding value datatype; for example,
224    L{CF_minExclusive}."""
225
226
227    @classmethod
228    def LateDatatypeBindsSuperclass (cls):
229        """Return true if false if the proposed datatype should be
230        used, or True if the base type definition of the proposed
231        datatype should be used."""
232        if cls._LateDatatypeBindsSuperclass is None:
233            raise pyxb.LogicError('Class %s did not set _LateDatatypeBindsSuperclass variable.')
234        return cls._LateDatatypeBindsSuperclass
235
236    @classmethod
237    def BindingValueDatatype (cls, value_type):
238        """Find the datatype for facet values when this facet is bound
239        to the given value_type.
240
241        If the C{value_type} is an STD, the associated Python support
242        datatype from this value_type scanning up through the base
243        type hierarchy is used.
244        """
245
246        import pyxb.xmlschema.structures as structures
247        if isinstance(value_type, structures.SimpleTypeDefinition):
248            # Back up until we find something that actually has a
249            # datatype
250            while not value_type.hasPythonSupport():
251                value_type = value_type.baseTypeDefinition()
252            value_type = value_type.pythonSupport()
253        assert issubclass(value_type, basis.simpleTypeDefinition)
254        if cls.LateDatatypeBindsSuperclass():
255            value_type = value_type.XsdSuperType()
256        return value_type
257
258    def bindValueDatatype (self, value_datatype):
259        self.setFromKeywords(_constructor=True, value_datatype=self.BindingValueDatatype(value_datatype))
260
261class _Fixed_mixin (pyxb.cscRoot):
262    """Mix-in to a constraining facet that adds support for the 'fixed' property."""
263    __fixed = None
264    def fixed (self): return self.__fixed
265
266    def __setFromKeywords (self, **kw):
267        if kw.get('_reset', False):
268            self.__fixed = None
269        kwv = kw.get('fixed')
270        if kwv is not None:
271            self.__fixed = datatypes.boolean(kwv)
272
273    def _setFromKeywords_vb (self, **kw):
274        """Extend base class.
275
276        Additional keywords:
277        * fixed
278        """
279        self.__setFromKeywords(**kw)
280        super_fn = getattr(super(_Fixed_mixin, self), '_setFromKeywords_vb', lambda *a,**kw: self)
281        return super_fn(**kw)
282
283class _CollectionFacet_mixin (pyxb.cscRoot):
284    """Mix-in to handle facets whose values are collections, not scalars.
285
286    For example, the enumeration and pattern facets maintain a list of
287    enumeration values and patterns, respectively, as their value
288    space.
289
290    Subclasses must define a class variable _CollectionFacet_itemType
291    which is a reference to a class that is used to construct members
292    of the collection.
293    """
294
295    __items = None
296    def _setFromKeywords_vb (self, **kw):
297        """Extend base class.
298
299        @keyword _constructor: If C{False} or absent, the object being
300                               set is a member of the collection.  If
301                               C{True}, the object being set is the
302                               collection itself.
303        """
304        if kw.get('_reset', False):
305            self.__items = []
306        if not kw.get('_constructor', False):
307            self.__items.append(self._CollectionFacet_itemType(facet_instance=self, **kw))
308        super_fn = getattr(super(_CollectionFacet_mixin, self), '_setFromKeywords_vb', lambda *a,**kw: self)
309        return super_fn(**kw)
310
311    def _items (self):
312        """The members of the collection, as a reference."""
313        return self.__items
314
315    def items (self):
316        """The members of the collection, as a copy."""
317        return self.__items[:]
318
319    def iteritems (self):
320        """The members of the collection as an iterator"""
321        return iter(self.__items)
322
323class CF_length (ConstrainingFacet, _Fixed_mixin):
324    """A facet that specifies the length of the lexical representation of a value.
325
326    See U{http://www.w3.org/TR/xmlschema-2/#rf-length}
327    """
328    _Name = 'length'
329    _ValueDatatype = datatypes.nonNegativeInteger
330
331    def _validateConstraint_vx (self, value):
332        value_length = value.xsdValueLength()
333        return (value_length is None) or (self.value() is None) or (value_length == self.value())
334
335class CF_minLength (ConstrainingFacet, _Fixed_mixin):
336    """A facet that constrains the length of the lexical representation of a value.
337
338    See U{http://www.w3.org/TR/xmlschema-2/#rf-minLength}
339    """
340    _Name = 'minLength'
341    _ValueDatatype = datatypes.nonNegativeInteger
342
343    def _validateConstraint_vx (self, value):
344        value_length = value.xsdValueLength()
345        return (value_length is None) or (self.value() is None) or (value_length >= self.value())
346
347class CF_maxLength (ConstrainingFacet, _Fixed_mixin):
348    """A facet that constrains the length of the lexical representation of a value.
349
350    See U{http://www.w3.org/TR/xmlschema-2/#rf-minLength}
351    """
352    _Name = 'maxLength'
353    _ValueDatatype = datatypes.nonNegativeInteger
354
355    def _validateConstraint_vx (self, value):
356        value_length = value.xsdValueLength()
357        return (value_length is None) or (self.value() is None) or (value_length <= self.value())
358
359import pyxb.utils.xmlre
360
361class _PatternElement (utility.PrivateTransient_mixin):
362    """This class represents individual patterns that appear within a CF_pattern collection."""
363
364    # The compiled regular expression is marked transient because we
365    # normally do development with Python 2.5, and consequently save
366    # the pickled namespace archives that go into the distribution
367    # with that version.  Compiled regular expressions in Python 2.5
368    # include a reference to the re._compile method, which does not
369    # exist in Python 2.4.  As a result, attempts to load a namespace
370    # which includes types with pattern restrictions fail.
371    __PrivateTransient = set()
372
373    __compiledExpression = None
374    __PrivateTransient.add('compiledExpression')
375
376    __pythonExpression = None
377
378    pattern = None
379    annotation = None
380    def __init__ (self, pattern=None, value=None, annotation=None, **kw):
381        if pattern is None:
382            assert value is not None
383            pattern = value
384        assert isinstance(pattern, six.string_types)
385        self.pattern = pattern
386        if isinstance(annotation, six.string_types):
387            self.annotation = annotation
388        self.__pythonExpression = pyxb.utils.xmlre.XMLToPython(pattern)
389        super(_PatternElement, self).__init__()
390
391    def __str__ (self): return self.pattern
392
393    def matches (self, text):
394        if self.__compiledExpression is None:
395            self.__compiledExpression = re.compile(self.__pythonExpression)
396        return self.__compiledExpression.match(text)
397
398class CF_pattern (ConstrainingFacet, _CollectionFacet_mixin):
399    """A facet that constrains the lexical representation of a value
400    to match one of a set of patterns.
401
402    See U{http://www.w3.org/TR/xmlschema-2/#rf-pattern}
403
404    @note: In PyXB, pattern constraints are ignored for any type with
405    a Python representation that does not derive from a string type.
406    This is due to the difficulty in reconstructing the lexical
407    representation of a non-string type after it has been converted to
408    its value space.
409
410    @todo: On creating new instances of non-string simple types from
411    string representations, we could apply pattern constraints.  That
412    would mean checking them prior to invoking the Factory method.
413    """
414    _Name = 'pattern'
415    _CollectionFacet_itemType = _PatternElement
416    _ValueDatatype = datatypes.string
417
418    __patternElements = None
419    def patternElements (self): return self.__patternElements
420
421    def __init__ (self, **kw):
422        super(CF_pattern, self).__init__(**kw)
423        self.__patternElements = []
424
425    def addPattern (self, **kw):
426        pattern = self._CollectionFacet_itemType(**kw)
427        self.__patternElements.append(pattern)
428        return pattern
429
430    def _validateConstraint_vx (self, value):
431        # If validation is inhibited, or if the facet hasn't had any
432        # restrictions applied yet, return True.
433        if 0 == len(self.__patternElements):
434            return True
435        if not isinstance(value, six.string_types):
436            # Ignore pattern constraint when value space and lexical
437            # space differ.
438            return True
439        for pe in self.__patternElements:
440            if pe.matches(value):
441                return True
442        return False
443
444@six.python_2_unicode_compatible
445class _EnumerationElement (object):
446    """This class represents individual values that appear within a
447    L{CF_enumeration} collection."""
448
449    __value = None
450    def value (self):
451        """The Python value that is used for equality testing
452        against this enumeration.
453
454        This is an instance of L{enumeration.valueDatatype()<CF_enumeration.valueDatatype>},
455        initialized from the unicodeValue."""
456        return self.__value
457
458    __tag = None
459    def tag (self):
460        """The Python identifier used for the named constant representing
461        the enumeration value.
462
463        This should include any desired prefix, since it must be
464        unique within its binding class.  If C{None}, no enumeration
465        constant will be generated."""
466        return self.__tag
467    def _setTag (self, tag):
468        """Set the tag to be used for this enumeration."""
469        self.__tag = tag
470
471    __enumeration = None
472    def enumeration (self):
473        """A reference to the L{CF_enumeration} instance that owns this element."""
474        return self.__enumeration
475
476    __unicodeValue = None
477    def unicodeValue (self):
478        """The unicode string that defines the enumeration value."""
479        return self.__unicodeValue
480
481    def __init__ (self, enumeration=None, unicode_value=None,
482                  description=None, annotation=None, tag=None,
483                  **kw):
484        # The preferred keyword is "unicode_value", but when being
485        # generically applied by
486        # structures.SimpleTypeDefinition.__updateFacets, the unicode
487        # value comes in through the keyword "value".  Similarly for
488        # "enumeration" and "facet_instance".
489        value = kw.get('value', unicode_value)
490        if unicode_value is None:
491            unicode_value = value
492        if enumeration is None:
493            enumeration = kw['facet_instance']
494        self.__unicodeValue = unicode_value
495        self.__enumeration = enumeration
496        self.__description = description
497        self.__annotation = annotation
498        self.__tag = tag
499
500        assert self.__enumeration is not None
501
502        value_datatype = self.enumeration().valueDatatype()
503        self.__value = value_datatype.Factory(value, _validate_constraints=False, _from_xml=True)
504
505        if (self.__description is None) and (self.__annotation is not None):
506            self.__description = six.text_type(self.__annotation)
507
508    def __str__ (self):
509        return utility.QuotedEscaped(self.unicodeValue())
510
511class CF_enumeration (ConstrainingFacet, _CollectionFacet_mixin, _LateDatatype_mixin):
512    """Capture a constraint that restricts valid values to a fixed set.
513
514    A STD that has an enumeration restriction should mix-in
515    L{pyxb.binding.basis.enumeration_mixin}, and should have a class
516    variable titled C{_CF_enumeration} that is an instance of this
517    class.
518
519    "unicode" refers to the Unicode string by which the value is
520    represented in XML.
521
522    "tag" refers to the Python member reference associated with the
523    enumeration.  The value is derived from the unicode value of the
524    enumeration element and an optional prefix that identifies the
525    owning simple type when the tag is promoted to module-level
526    visibility.
527
528    "value" refers to the Python value held in the tag
529
530    See U{http://www.w3.org/TR/xmlschema-2/#rf-enumeration}
531    """
532    _Name = 'enumeration'
533    _CollectionFacet_itemType = _EnumerationElement
534    _LateDatatypeBindsSuperclass = False
535
536    __tagToElement = None
537    __valueToElement = None
538    __unicodeToElement = None
539
540    # The prefix to be used when making enumeration tags visible at
541    # the module level.  If None, tags are not made visible.
542    __enumPrefix = None
543
544    def __init__ (self, **kw):
545        super(CF_enumeration, self).__init__(**kw)
546        self.__enumPrefix = kw.get('enum_prefix', self.__enumPrefix)
547        self.__tagToElement = { }
548        self.__valueToElement = { }
549        self.__unicodeToElement = { }
550
551    def enumPrefix (self):
552        return self.__enumPrefix
553
554    def elements (self):
555        """@deprecated: Use L{items} or L{iteritems} instead."""
556        return list(six.iteritems(self))
557
558    def values (self):
559        """Return a list of enumeration values."""
560        return [ _ee.value() for _ee in six.iteritems(self) ]
561
562    def itervalues (self):
563        """Generate the enumeration values."""
564        for ee in six.iteritems(self):
565            yield ee.value()
566
567    def addEnumeration (self, **kw):
568        kw['enumeration'] = self
569        ee = _EnumerationElement(**kw)
570        assert not (ee.tag in self.__tagToElement)
571        self.__tagToElement[ee.tag()] = ee
572        self.__unicodeToElement[ee.unicodeValue()] = ee
573        value = ee.value()
574        # Not just issubclass(self.valueDatatype(), basis.STD_list);
575        # this may be a union with one of those as a member type.
576        if isinstance(value, list):
577            value = ' '.join([ _v.xsdLiteral() for _v in value ])
578        self.__valueToElement[value] = ee
579        self._items().append(ee)
580        return value
581
582    def elementForValue (self, value):
583        """Return the L{_EnumerationElement} instance that has the given value.
584
585        @raise KeyError: the value is not valid for the enumeration."""
586        return self.__valueToElement[value]
587
588    def valueForUnicode (self, ustr):
589        """Return the enumeration value corresponding to the given unicode string.
590
591        If ustr is not a valid option for this enumeration, return None."""
592        rv = self.__unicodeToElement.get(ustr)
593        if rv is not None:
594            rv = rv.value()
595        return rv
596
597    def _validateConstraint_vx (self, value):
598        # If validation is inhibited, or if the facet hasn't had any
599        # restrictions applied yet, return True.
600        if 0 == len(self._items()):
601            return True
602        for ee in six.iteritems(self):
603            if ee.value() == value:
604                return True
605        return False
606
607class _Enumeration_mixin (pyxb.cscRoot):
608    """Marker class to indicate that the generated binding has enumeration members."""
609    @classmethod
610    def valueForUnicode (cls, ustr):
611        return cls._CF_enumeration.valueForUnicode(ustr)
612
613class _WhiteSpace_enum (datatypes.NMTOKEN, _Enumeration_mixin):
614    """The enumeration used to constrain the whiteSpace facet"""
615    pass
616_WhiteSpace_enum._CF_enumeration = CF_enumeration(value_datatype=_WhiteSpace_enum)
617_WhiteSpace_enum.preserve = _WhiteSpace_enum._CF_enumeration.addEnumeration(unicode_value=six.u('preserve'), tag='preserve')
618_WhiteSpace_enum.replace = _WhiteSpace_enum._CF_enumeration.addEnumeration(unicode_value=six.u('replace'), tag='replace')
619_WhiteSpace_enum.collapse = _WhiteSpace_enum._CF_enumeration.addEnumeration(unicode_value=six.u('collapse'), tag='collapse')
620# NOTE: For correctness we really need to initialize the facet map for
621# WhiteSpace_enum, even though at the moment it isn't necessary.  We
622# can't right now, because its parent datatypes.NMTOKEN hasn't been
623# initialized yet
624_WhiteSpace_enum._InitializeFacetMap(_WhiteSpace_enum._CF_enumeration)
625
626class CF_whiteSpace (ConstrainingFacet, _Fixed_mixin):
627    """Specify the value-space interpretation of whitespace.
628
629    See U{http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace}
630    """
631    _Name = 'whiteSpace'
632    _ValueDatatype = _WhiteSpace_enum
633
634    __TabCRLF_re = re.compile("[\t\n\r]")
635    __MultiSpace_re = re.compile(" +")
636    def normalizeString (self, value):
637        """Normalize the given string in accordance with the configured whitespace interpretation."""
638        if self.value() is None:
639            return value
640        if self.value() == _WhiteSpace_enum.preserve:
641            return utility.NormalizeWhitespace(value, preserve=True)
642        if self.value() == _WhiteSpace_enum.replace:
643            return utility.NormalizeWhitespace(value, replace=True)
644        assert self.value() == _WhiteSpace_enum.collapse, 'Unexpected value "%s" for whiteSpace facet' % (self.value(),)
645        return utility.NormalizeWhitespace(value, collapse=True)
646
647    def _validateConstraint_vx (self, value):
648        """No validation rules for whitespace facet."""
649        return True
650
651class CF_minInclusive (ConstrainingFacet, _Fixed_mixin, _LateDatatype_mixin):
652    """Specify the minimum legal value for the constrained type.
653
654    See U{http://www.w3.org/TR/xmlschema-2/#rf-minInclusive}
655    """
656    _Name = 'minInclusive'
657    _LateDatatypeBindsSuperclass = False
658
659    def _validateConstraint_vx (self, value):
660        return (self.value() is None) or (self.value() <= value)
661
662
663class CF_maxInclusive (ConstrainingFacet, _Fixed_mixin, _LateDatatype_mixin):
664    """Specify the maximum legal value for the constrained type.
665
666    See U{http://www.w3.org/TR/xmlschema-2/#rf-maxInclusive}
667    """
668    _Name = 'maxInclusive'
669    _LateDatatypeBindsSuperclass = False
670
671    def _validateConstraint_vx (self, value):
672        return (self.value() is None) or (self.value() >= value)
673
674class CF_minExclusive (ConstrainingFacet, _Fixed_mixin, _LateDatatype_mixin):
675    """Specify the exclusive lower bound of legal values for the constrained type.
676
677    See U{http://www.w3.org/TR/xmlschema-2/#rf-minExclusive}
678    """
679    _Name = 'minExclusive'
680    _LateDatatypeBindsSuperclass = True
681
682    def _validateConstraint_vx (self, value):
683        return (self.value() is None) or (self.value() < value)
684
685class CF_maxExclusive (ConstrainingFacet, _Fixed_mixin, _LateDatatype_mixin):
686    """Specify the exclusive upper bound of legal values for the constrained type.
687
688    See U{http://www.w3.org/TR/xmlschema-2/#rf-maxExclusive}
689    """
690    _Name = 'maxExclusive'
691    _LateDatatypeBindsSuperclass = True
692
693    def _validateConstraint_vx (self, value):
694        return (self.value() is None) or (self.value() > value)
695
696class CF_totalDigits (ConstrainingFacet, _Fixed_mixin):
697    """Specify the number of digits in the *value* space of the type.
698
699    See U{http://www.w3.org/TR/xmlschema-2/#rf-totalDigits}
700    """
701    _Name = 'totalDigits'
702    _ValueDatatype = datatypes.positiveInteger
703
704    def _validateConstraint_vx (self, value):
705        if self.value() is None:
706            return True
707        if isinstance(value, datatypes.decimal):
708            (sign, digits, exponent) = value.normalize().as_tuple()
709            if len(digits) > self.value():
710                return False
711            if 0 > exponent:
712                return -exponent <= self.value()
713            return (exponent + len(digits)) <= self.value()
714        n = 0
715        scale = 1
716        match = False
717        v = None
718        while (n <= self.value()) and (not match):
719            v = six.long_type(value * scale)
720            match = ((value * scale) == v)
721            if self.value() == n:
722                break
723            n += 1
724            scale *= 10
725        while n < self.value():
726            n += 1
727            scale *= 10
728        return match and (v is not None) and (abs(v) < scale)
729
730class CF_fractionDigits (ConstrainingFacet, _Fixed_mixin):
731    """Specify the number of sub-unit digits in the *value* space of the type.
732
733    See U{http://www.w3.org/TR/xmlschema-2/#rf-fractionDigits}
734    """
735    _Name = 'fractionDigits'
736    _ValueDatatype = datatypes.nonNegativeInteger
737
738    def _validateConstraint_vx (self, value):
739        if self.value() is None:
740            return True
741        if isinstance(value, datatypes.decimal):
742            (sign, digits, exponent) = value.normalize().as_tuple()
743            return (0 <= exponent) or (-exponent <= self.value())
744        n = 0
745        scale = 1
746        while n <= self.value():
747            if ((value * scale) == six.long_type(value * scale)):
748                return True
749            n += 1
750            scale *= 10
751        return False
752
753class FundamentalFacet (Facet):
754    """A fundamental facet provides information on the value space of the associated type."""
755
756    _FacetPrefix = 'FF'
757
758    @classmethod
759    def CreateFromDOM (cls, node, owner_type_definition, base_type_definition=None):
760        facet_class = cls.ClassForFacet(node.getAttribute('name'))
761        rv = facet_class(base_type_definition=base_type_definition,
762                         owner_type_definition=owner_type_definition)
763        rv.updateFromDOM(node)
764
765    def updateFromDOM (self, node):
766        if not node.hasAttribute('name'):
767            raise pyxb.SchemaValidationError('No name attribute in facet')
768        assert node.getAttribute('name') == self.Name()
769        self._updateFromDOM(node)
770
771    def _updateFromDOM (self, node):
772        try:
773            super(FundamentalFacet, self)._updateFromDOM(node)
774        except AttributeError:
775            pass
776        if (self.valueDatatype() is not None) and node.hasAttribute('value'):
777            self._value(self.valueDatatype()(node.getAttribute('value')))
778        # @todo
779        self.__annotation = None
780        return self
781
782class FF_equal (FundamentalFacet):
783    """Specifies that the associated type supports a notion of equality.
784
785    See U{http://www.w3.org/TR/xmlschema-2/#equal}
786    """
787
788    _Name = 'equal'
789
790class FF_ordered (FundamentalFacet):
791    """Specifies that the associated type supports a notion of order.
792
793    See U{http://www.w3.org/TR/xmlschema-2/#rf-ordered}
794    """
795
796    _LegalValues = ( 'false', 'partial', 'total' )
797    _Name = 'ordered'
798    _ValueDatatype = datatypes.string
799
800    def __init__ (self, **kw):
801        # @todo: correct value type definition
802        super(FF_ordered, self).__init__(**kw)
803
804class FF_bounded (FundamentalFacet):
805    """Specifies that the associated type supports a notion of bounds.
806
807    See U{http://www.w3.org/TR/xmlschema-2/#rf-bounded}
808    """
809
810    _Name = 'bounded'
811    _ValueDatatype = datatypes.boolean
812
813class FF_cardinality (FundamentalFacet):
814    """Specifies that the associated type supports a notion of length.
815
816    See U{http://www.w3.org/TR/xmlschema-2/#rf-cardinality}
817    """
818
819    _LegalValues = ( 'finite', 'countably infinite' )
820    _Name = 'cardinality'
821    _ValueDatatype = datatypes.string
822    def __init__ (self, **kw):
823        # @todo correct value type definition
824        super(FF_cardinality, self).__init__(value_datatype=datatypes.string, **kw)
825
826class FF_numeric (FundamentalFacet):
827    """Specifies that the associated type represents a number.
828
829    See U{http://www.w3.org/TR/xmlschema-2/#rf-numeric}
830    """
831
832    _Name = 'numeric'
833    _ValueDatatype = datatypes.boolean
834
835# The fixed set of expected facets
836ConstrainingFacet.Facets = [
837    CF_length, CF_minLength, CF_maxLength, CF_pattern, CF_enumeration,
838    CF_whiteSpace, CF_minInclusive, CF_maxInclusive, CF_minExclusive,
839    CF_maxExclusive, CF_totalDigits, CF_fractionDigits ]
840
841FundamentalFacet.Facets = [
842    FF_equal, FF_ordered, FF_bounded, FF_cardinality, FF_numeric ]
843
844Facet.Facets = []
845Facet.Facets.extend(ConstrainingFacet.Facets)
846Facet.Facets.extend(FundamentalFacet.Facets)
847
848# Facet details from a hacked generator reading the normative schema
849# and only printing the facet-related code.
850datatypes.ENTITIES._CF_pattern = CF_pattern()
851datatypes.ENTITIES._CF_maxLength = CF_maxLength()
852datatypes.ENTITIES._CF_enumeration = CF_enumeration(value_datatype=datatypes.ENTITIES)
853datatypes.ENTITIES._CF_minLength = CF_minLength(value=datatypes.nonNegativeInteger(1))
854datatypes.ENTITIES._CF_whiteSpace = CF_whiteSpace()
855datatypes.ENTITIES._CF_length = CF_length()
856datatypes.ENTITIES._InitializeFacetMap(datatypes.ENTITIES._CF_pattern,
857   datatypes.ENTITIES._CF_maxLength,
858   datatypes.ENTITIES._CF_enumeration,
859   datatypes.ENTITIES._CF_minLength,
860   datatypes.ENTITIES._CF_whiteSpace,
861   datatypes.ENTITIES._CF_length)
862datatypes.ENTITY._InitializeFacetMap()
863datatypes.ID._InitializeFacetMap()
864datatypes.IDREF._InitializeFacetMap()
865datatypes.IDREFS._CF_pattern = CF_pattern()
866datatypes.IDREFS._CF_maxLength = CF_maxLength()
867datatypes.IDREFS._CF_enumeration = CF_enumeration(value_datatype=datatypes.IDREFS)
868datatypes.IDREFS._CF_minLength = CF_minLength(value=datatypes.nonNegativeInteger(1))
869datatypes.IDREFS._CF_whiteSpace = CF_whiteSpace()
870datatypes.IDREFS._CF_length = CF_length()
871datatypes.IDREFS._InitializeFacetMap(datatypes.IDREFS._CF_pattern,
872   datatypes.IDREFS._CF_maxLength,
873   datatypes.IDREFS._CF_enumeration,
874   datatypes.IDREFS._CF_minLength,
875   datatypes.IDREFS._CF_whiteSpace,
876   datatypes.IDREFS._CF_length)
877datatypes.NCName._CF_pattern = CF_pattern()
878datatypes.NCName._CF_pattern.addPattern(pattern=six.u('[\\i-[:]][\\c-[:]]*'))
879datatypes.NCName._InitializeFacetMap(datatypes.NCName._CF_pattern)
880datatypes.NMTOKEN._CF_pattern = CF_pattern()
881datatypes.NMTOKEN._CF_pattern.addPattern(pattern=six.u('\\c+'))
882datatypes.NMTOKEN._InitializeFacetMap(datatypes.NMTOKEN._CF_pattern)
883datatypes.NMTOKENS._CF_pattern = CF_pattern()
884datatypes.NMTOKENS._CF_maxLength = CF_maxLength()
885datatypes.NMTOKENS._CF_enumeration = CF_enumeration(value_datatype=datatypes.NMTOKENS)
886datatypes.NMTOKENS._CF_minLength = CF_minLength(value=datatypes.nonNegativeInteger(1))
887datatypes.NMTOKENS._CF_whiteSpace = CF_whiteSpace()
888datatypes.NMTOKENS._CF_length = CF_length()
889datatypes.NMTOKENS._InitializeFacetMap(datatypes.NMTOKENS._CF_pattern,
890   datatypes.NMTOKENS._CF_maxLength,
891   datatypes.NMTOKENS._CF_enumeration,
892   datatypes.NMTOKENS._CF_minLength,
893   datatypes.NMTOKENS._CF_whiteSpace,
894   datatypes.NMTOKENS._CF_length)
895datatypes.NOTATION._CF_minLength = CF_minLength()
896datatypes.NOTATION._CF_maxLength = CF_maxLength()
897datatypes.NOTATION._CF_enumeration = CF_enumeration(value_datatype=datatypes.NOTATION)
898datatypes.NOTATION._CF_pattern = CF_pattern()
899datatypes.NOTATION._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
900datatypes.NOTATION._CF_length = CF_length()
901datatypes.NOTATION._InitializeFacetMap(datatypes.NOTATION._CF_minLength,
902   datatypes.NOTATION._CF_maxLength,
903   datatypes.NOTATION._CF_enumeration,
904   datatypes.NOTATION._CF_pattern,
905   datatypes.NOTATION._CF_whiteSpace,
906   datatypes.NOTATION._CF_length)
907datatypes.Name._CF_pattern = CF_pattern()
908datatypes.Name._CF_pattern.addPattern(pattern=six.u('\\i\\c*'))
909datatypes.Name._InitializeFacetMap(datatypes.Name._CF_pattern)
910datatypes.QName._CF_minLength = CF_minLength()
911datatypes.QName._CF_maxLength = CF_maxLength()
912datatypes.QName._CF_enumeration = CF_enumeration(value_datatype=datatypes.QName)
913datatypes.QName._CF_pattern = CF_pattern()
914datatypes.QName._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
915datatypes.QName._CF_length = CF_length()
916datatypes.QName._InitializeFacetMap(datatypes.QName._CF_minLength,
917   datatypes.QName._CF_maxLength,
918   datatypes.QName._CF_enumeration,
919   datatypes.QName._CF_pattern,
920   datatypes.QName._CF_whiteSpace,
921   datatypes.QName._CF_length)
922datatypes.anyURI._CF_minLength = CF_minLength()
923datatypes.anyURI._CF_maxLength = CF_maxLength()
924datatypes.anyURI._CF_enumeration = CF_enumeration(value_datatype=datatypes.anyURI)
925datatypes.anyURI._CF_pattern = CF_pattern()
926datatypes.anyURI._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
927datatypes.anyURI._CF_length = CF_length()
928datatypes.anyURI._InitializeFacetMap(datatypes.anyURI._CF_minLength,
929   datatypes.anyURI._CF_maxLength,
930   datatypes.anyURI._CF_enumeration,
931   datatypes.anyURI._CF_pattern,
932   datatypes.anyURI._CF_whiteSpace,
933   datatypes.anyURI._CF_length)
934datatypes.base64Binary._CF_minLength = CF_minLength()
935datatypes.base64Binary._CF_maxLength = CF_maxLength()
936datatypes.base64Binary._CF_enumeration = CF_enumeration(value_datatype=datatypes.base64Binary)
937datatypes.base64Binary._CF_pattern = CF_pattern()
938datatypes.base64Binary._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
939datatypes.base64Binary._CF_length = CF_length()
940datatypes.base64Binary._InitializeFacetMap(datatypes.base64Binary._CF_minLength,
941   datatypes.base64Binary._CF_maxLength,
942   datatypes.base64Binary._CF_enumeration,
943   datatypes.base64Binary._CF_pattern,
944   datatypes.base64Binary._CF_whiteSpace,
945   datatypes.base64Binary._CF_length)
946datatypes.boolean._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
947datatypes.boolean._CF_pattern = CF_pattern()
948datatypes.boolean._InitializeFacetMap(datatypes.boolean._CF_whiteSpace,
949   datatypes.boolean._CF_pattern)
950datatypes.byte._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.byte, value=datatypes.anySimpleType(six.u('-128')))
951datatypes.byte._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.byte, value=datatypes.anySimpleType(six.u('127')))
952datatypes.byte._InitializeFacetMap(datatypes.byte._CF_minInclusive,
953   datatypes.byte._CF_maxInclusive)
954datatypes.date._CF_pattern = CF_pattern()
955datatypes.date._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.date)
956datatypes.date._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
957datatypes.date._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
958datatypes.date._CF_enumeration = CF_enumeration(value_datatype=datatypes.date)
959datatypes.date._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
960datatypes.date._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.date)
961datatypes.date._InitializeFacetMap(datatypes.date._CF_pattern,
962   datatypes.date._CF_minInclusive,
963   datatypes.date._CF_maxExclusive,
964   datatypes.date._CF_minExclusive,
965   datatypes.date._CF_enumeration,
966   datatypes.date._CF_whiteSpace,
967   datatypes.date._CF_maxInclusive)
968datatypes.dateTime._CF_pattern = CF_pattern()
969datatypes.dateTime._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.dateTime)
970datatypes.dateTime._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
971datatypes.dateTime._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
972datatypes.dateTime._CF_enumeration = CF_enumeration(value_datatype=datatypes.dateTime)
973datatypes.dateTime._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
974datatypes.dateTime._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.dateTime)
975datatypes.dateTime._InitializeFacetMap(datatypes.dateTime._CF_pattern,
976   datatypes.dateTime._CF_minInclusive,
977   datatypes.dateTime._CF_maxExclusive,
978   datatypes.dateTime._CF_minExclusive,
979   datatypes.dateTime._CF_enumeration,
980   datatypes.dateTime._CF_whiteSpace,
981   datatypes.dateTime._CF_maxInclusive)
982datatypes.decimal._CF_totalDigits = CF_totalDigits()
983datatypes.decimal._CF_pattern = CF_pattern()
984datatypes.decimal._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.decimal)
985datatypes.decimal._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
986datatypes.decimal._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
987datatypes.decimal._CF_enumeration = CF_enumeration(value_datatype=datatypes.decimal)
988datatypes.decimal._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
989datatypes.decimal._CF_fractionDigits = CF_fractionDigits()
990datatypes.decimal._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.decimal)
991datatypes.decimal._InitializeFacetMap(datatypes.decimal._CF_totalDigits,
992   datatypes.decimal._CF_pattern,
993   datatypes.decimal._CF_minInclusive,
994   datatypes.decimal._CF_maxExclusive,
995   datatypes.decimal._CF_minExclusive,
996   datatypes.decimal._CF_enumeration,
997   datatypes.decimal._CF_whiteSpace,
998   datatypes.decimal._CF_fractionDigits,
999   datatypes.decimal._CF_maxInclusive)
1000datatypes.double._CF_pattern = CF_pattern()
1001datatypes.double._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.double)
1002datatypes.double._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1003datatypes.double._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1004datatypes.double._CF_enumeration = CF_enumeration(value_datatype=datatypes.double)
1005datatypes.double._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1006datatypes.double._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.double)
1007datatypes.double._InitializeFacetMap(datatypes.double._CF_pattern,
1008   datatypes.double._CF_minInclusive,
1009   datatypes.double._CF_maxExclusive,
1010   datatypes.double._CF_minExclusive,
1011   datatypes.double._CF_enumeration,
1012   datatypes.double._CF_whiteSpace,
1013   datatypes.double._CF_maxInclusive)
1014datatypes.duration._CF_pattern = CF_pattern()
1015datatypes.duration._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.duration)
1016datatypes.duration._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1017datatypes.duration._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1018datatypes.duration._CF_enumeration = CF_enumeration(value_datatype=datatypes.duration)
1019datatypes.duration._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1020datatypes.duration._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.duration)
1021datatypes.duration._InitializeFacetMap(datatypes.duration._CF_pattern,
1022   datatypes.duration._CF_minInclusive,
1023   datatypes.duration._CF_maxExclusive,
1024   datatypes.duration._CF_minExclusive,
1025   datatypes.duration._CF_enumeration,
1026   datatypes.duration._CF_whiteSpace,
1027   datatypes.duration._CF_maxInclusive)
1028datatypes.float._CF_pattern = CF_pattern()
1029datatypes.float._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.float)
1030datatypes.float._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1031datatypes.float._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1032datatypes.float._CF_enumeration = CF_enumeration(value_datatype=datatypes.float)
1033datatypes.float._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1034datatypes.float._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.float)
1035datatypes.float._InitializeFacetMap(datatypes.float._CF_pattern,
1036   datatypes.float._CF_minInclusive,
1037   datatypes.float._CF_maxExclusive,
1038   datatypes.float._CF_minExclusive,
1039   datatypes.float._CF_enumeration,
1040   datatypes.float._CF_whiteSpace,
1041   datatypes.float._CF_maxInclusive)
1042datatypes.gDay._CF_pattern = CF_pattern()
1043datatypes.gDay._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.gDay)
1044datatypes.gDay._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1045datatypes.gDay._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1046datatypes.gDay._CF_enumeration = CF_enumeration(value_datatype=datatypes.gDay)
1047datatypes.gDay._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1048datatypes.gDay._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.gDay)
1049datatypes.gDay._InitializeFacetMap(datatypes.gDay._CF_pattern,
1050   datatypes.gDay._CF_minInclusive,
1051   datatypes.gDay._CF_maxExclusive,
1052   datatypes.gDay._CF_minExclusive,
1053   datatypes.gDay._CF_enumeration,
1054   datatypes.gDay._CF_whiteSpace,
1055   datatypes.gDay._CF_maxInclusive)
1056datatypes.gMonth._CF_pattern = CF_pattern()
1057datatypes.gMonth._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.gMonth)
1058datatypes.gMonth._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1059datatypes.gMonth._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1060datatypes.gMonth._CF_enumeration = CF_enumeration(value_datatype=datatypes.gMonth)
1061datatypes.gMonth._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1062datatypes.gMonth._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.gMonth)
1063datatypes.gMonth._InitializeFacetMap(datatypes.gMonth._CF_pattern,
1064   datatypes.gMonth._CF_minInclusive,
1065   datatypes.gMonth._CF_maxExclusive,
1066   datatypes.gMonth._CF_minExclusive,
1067   datatypes.gMonth._CF_enumeration,
1068   datatypes.gMonth._CF_whiteSpace,
1069   datatypes.gMonth._CF_maxInclusive)
1070datatypes.gMonthDay._CF_pattern = CF_pattern()
1071datatypes.gMonthDay._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.gMonthDay)
1072datatypes.gMonthDay._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1073datatypes.gMonthDay._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1074datatypes.gMonthDay._CF_enumeration = CF_enumeration(value_datatype=datatypes.gMonthDay)
1075datatypes.gMonthDay._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1076datatypes.gMonthDay._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.gMonthDay)
1077datatypes.gMonthDay._InitializeFacetMap(datatypes.gMonthDay._CF_pattern,
1078   datatypes.gMonthDay._CF_minInclusive,
1079   datatypes.gMonthDay._CF_maxExclusive,
1080   datatypes.gMonthDay._CF_minExclusive,
1081   datatypes.gMonthDay._CF_enumeration,
1082   datatypes.gMonthDay._CF_whiteSpace,
1083   datatypes.gMonthDay._CF_maxInclusive)
1084datatypes.gYear._CF_pattern = CF_pattern()
1085datatypes.gYear._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.gYear)
1086datatypes.gYear._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1087datatypes.gYear._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1088datatypes.gYear._CF_enumeration = CF_enumeration(value_datatype=datatypes.gYear)
1089datatypes.gYear._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1090datatypes.gYear._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.gYear)
1091datatypes.gYear._InitializeFacetMap(datatypes.gYear._CF_pattern,
1092   datatypes.gYear._CF_minInclusive,
1093   datatypes.gYear._CF_maxExclusive,
1094   datatypes.gYear._CF_minExclusive,
1095   datatypes.gYear._CF_enumeration,
1096   datatypes.gYear._CF_whiteSpace,
1097   datatypes.gYear._CF_maxInclusive)
1098datatypes.gYearMonth._CF_pattern = CF_pattern()
1099datatypes.gYearMonth._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.gYearMonth)
1100datatypes.gYearMonth._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1101datatypes.gYearMonth._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1102datatypes.gYearMonth._CF_enumeration = CF_enumeration(value_datatype=datatypes.gYearMonth)
1103datatypes.gYearMonth._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1104datatypes.gYearMonth._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.gYearMonth)
1105datatypes.gYearMonth._InitializeFacetMap(datatypes.gYearMonth._CF_pattern,
1106   datatypes.gYearMonth._CF_minInclusive,
1107   datatypes.gYearMonth._CF_maxExclusive,
1108   datatypes.gYearMonth._CF_minExclusive,
1109   datatypes.gYearMonth._CF_enumeration,
1110   datatypes.gYearMonth._CF_whiteSpace,
1111   datatypes.gYearMonth._CF_maxInclusive)
1112datatypes.hexBinary._CF_minLength = CF_minLength()
1113datatypes.hexBinary._CF_maxLength = CF_maxLength()
1114datatypes.hexBinary._CF_enumeration = CF_enumeration(value_datatype=datatypes.hexBinary)
1115datatypes.hexBinary._CF_pattern = CF_pattern()
1116datatypes.hexBinary._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1117datatypes.hexBinary._CF_length = CF_length()
1118datatypes.hexBinary._InitializeFacetMap(datatypes.hexBinary._CF_minLength,
1119   datatypes.hexBinary._CF_maxLength,
1120   datatypes.hexBinary._CF_enumeration,
1121   datatypes.hexBinary._CF_pattern,
1122   datatypes.hexBinary._CF_whiteSpace,
1123   datatypes.hexBinary._CF_length)
1124datatypes.int._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.int, value=datatypes.anySimpleType(six.u('-2147483648')))
1125datatypes.int._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.int, value=datatypes.anySimpleType(six.u('2147483647')))
1126datatypes.int._InitializeFacetMap(datatypes.int._CF_minInclusive,
1127   datatypes.int._CF_maxInclusive)
1128datatypes.integer._CF_pattern = CF_pattern()
1129datatypes.integer._CF_pattern.addPattern(pattern=six.u('[\\-+]?[0-9]+'))
1130datatypes.integer._CF_fractionDigits = CF_fractionDigits(value=datatypes.nonNegativeInteger(0))
1131datatypes.integer._InitializeFacetMap(datatypes.integer._CF_pattern,
1132   datatypes.integer._CF_fractionDigits)
1133datatypes.language._CF_pattern = CF_pattern()
1134datatypes.language._CF_pattern.addPattern(pattern=six.u('[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*'))
1135datatypes.language._InitializeFacetMap(datatypes.language._CF_pattern)
1136datatypes.long._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.long, value=datatypes.anySimpleType(six.u('-9223372036854775808')))
1137datatypes.long._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.long, value=datatypes.anySimpleType(six.u('9223372036854775807')))
1138datatypes.long._InitializeFacetMap(datatypes.long._CF_minInclusive,
1139   datatypes.long._CF_maxInclusive)
1140datatypes.negativeInteger._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.negativeInteger, value=datatypes.anySimpleType(six.u('-1')))
1141datatypes.negativeInteger._InitializeFacetMap(datatypes.negativeInteger._CF_maxInclusive)
1142datatypes.nonNegativeInteger._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.nonNegativeInteger, value=datatypes.anySimpleType(six.u('0')))
1143datatypes.nonNegativeInteger._InitializeFacetMap(datatypes.nonNegativeInteger._CF_minInclusive)
1144datatypes.nonPositiveInteger._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.nonPositiveInteger, value=datatypes.anySimpleType(six.u('0')))
1145datatypes.nonPositiveInteger._InitializeFacetMap(datatypes.nonPositiveInteger._CF_maxInclusive)
1146datatypes.normalizedString._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.replace)
1147datatypes.normalizedString._InitializeFacetMap(datatypes.normalizedString._CF_whiteSpace)
1148datatypes.positiveInteger._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.positiveInteger, value=datatypes.anySimpleType(six.u('1')))
1149datatypes.positiveInteger._InitializeFacetMap(datatypes.positiveInteger._CF_minInclusive)
1150datatypes.short._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.short, value=datatypes.anySimpleType(six.u('-32768')))
1151datatypes.short._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.short, value=datatypes.anySimpleType(six.u('32767')))
1152datatypes.short._InitializeFacetMap(datatypes.short._CF_minInclusive,
1153   datatypes.short._CF_maxInclusive)
1154datatypes.string._CF_minLength = CF_minLength()
1155datatypes.string._CF_maxLength = CF_maxLength()
1156datatypes.string._CF_enumeration = CF_enumeration(value_datatype=datatypes.string)
1157datatypes.string._CF_pattern = CF_pattern()
1158datatypes.string._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.preserve)
1159datatypes.string._CF_length = CF_length()
1160datatypes.string._InitializeFacetMap(datatypes.string._CF_minLength,
1161   datatypes.string._CF_maxLength,
1162   datatypes.string._CF_enumeration,
1163   datatypes.string._CF_pattern,
1164   datatypes.string._CF_whiteSpace,
1165   datatypes.string._CF_length)
1166datatypes.time._CF_pattern = CF_pattern()
1167datatypes.time._CF_minInclusive = CF_minInclusive(value_datatype=datatypes.time)
1168datatypes.time._CF_maxExclusive = CF_maxExclusive(value_datatype=datatypes.anySimpleType)
1169datatypes.time._CF_minExclusive = CF_minExclusive(value_datatype=datatypes.anySimpleType)
1170datatypes.time._CF_enumeration = CF_enumeration(value_datatype=datatypes.time)
1171datatypes.time._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1172datatypes.time._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.time)
1173datatypes.time._InitializeFacetMap(datatypes.time._CF_pattern,
1174   datatypes.time._CF_minInclusive,
1175   datatypes.time._CF_maxExclusive,
1176   datatypes.time._CF_minExclusive,
1177   datatypes.time._CF_enumeration,
1178   datatypes.time._CF_whiteSpace,
1179   datatypes.time._CF_maxInclusive)
1180datatypes.token._CF_whiteSpace = CF_whiteSpace(value=_WhiteSpace_enum.collapse)
1181datatypes.token._InitializeFacetMap(datatypes.token._CF_whiteSpace)
1182datatypes.unsignedByte._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.unsignedByte, value=datatypes.anySimpleType(six.u('255')))
1183datatypes.unsignedByte._InitializeFacetMap(datatypes.unsignedByte._CF_maxInclusive)
1184datatypes.unsignedInt._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.unsignedInt, value=datatypes.anySimpleType(six.u('4294967295')))
1185datatypes.unsignedInt._InitializeFacetMap(datatypes.unsignedInt._CF_maxInclusive)
1186datatypes.unsignedLong._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.unsignedLong, value=datatypes.anySimpleType(six.u('18446744073709551615')))
1187datatypes.unsignedLong._InitializeFacetMap(datatypes.unsignedLong._CF_maxInclusive)
1188datatypes.unsignedShort._CF_maxInclusive = CF_maxInclusive(value_datatype=datatypes.unsignedShort, value=datatypes.anySimpleType(six.u('65535')))
1189datatypes.unsignedShort._InitializeFacetMap(datatypes.unsignedShort._CF_maxInclusive)
1190