1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """Classes and global objects related to U{XML Namespaces<http://www.w3.org/TR/2006/REC-xml-names-20060816/index.html>}.
16
17 Since namespaces hold all referenceable objects, this module also defines the
18 infrastructure for resolving named object references, such as schema
19 components.
20 """
21
22 import pyxb
23 import os
24 import fnmatch
25 import pyxb.utils.utility
26 import xml.dom
29
30 """Represent an U{expanded name
31 <http://www.w3.org/TR/REC-xml-names/#dt-expname>}, which pairs a
32 namespace with a local name.
33
34 Because a large number of local elements, and most attributes, have no
35 namespace associated with them, this is optimized for representing names
36 with an absent namespace. The hash and equality test methods are set so
37 that a plain string is equivalent to a tuple of C{None} and that string.
38
39 Note that absent namespaces can be represented in two ways: with a
40 namespace of C{None} (the name "has no namespace"), and with a namespace
41 that is an L{absent namespace <Namespace.CreateAbsentNamespace>} (the name
42 "has an absent namespace"). Hash code calculations are done so that the
43 two alternatives produce the same hash; however, comparison is done so
44 that the two are distinguished. The latter is the intended behavior; the
45 former should not be counted upon.
46
47 This class allows direct lookup of the named object within a category by
48 using the category name as an accessor function. That is, if the
49 namespace of the expanded name C{en} has a category 'typeDefinition', then
50 the following two expressions are equivalent::
51
52 en.typeDefinition()
53 en.namespace().categoryMap('typeDefinition').get(en.localName())
54
55 This class descends from C{tuple} so that its values can be used as
56 dictionary keys without concern for pointer equivalence.
57 """
59 """The L{Namespace} part of the expanded name."""
60 return self.__namespace
61 __namespace = None
62
64 """Return the URI of the namespace, or C{None} if the namespace is absent."""
65 return self.__namespaceURI
66 __namespaceURI = None
67
69 """The local part of the expanded name."""
70 return self.__localName
71 __localName = None
72
73
74 __expandedName = None
75
79
81 """Return a tuple consisting of the namespace URI and the local name.
82
83 This presents the expanded name as base Python types for persistent
84 storage. Be aware, though, that it will lose the association of the
85 name with an absent namespace, if that matters to you."""
86 return ( self.__namespaceURI, self.__localName )
87
88
98
100 """Return a new expanded name in the namespace of this name.
101
102 @param local_name: The local name portion of an expanded name.
103 @return: An instance of L{ExpandedName}.
104 """
105 return ExpandedName(self.namespace(), local_name)
106
108 """Return the input name, except if the input name has no namespace,
109 return a name that uses the namespace from this name with the local
110 name from the input name.
111
112 Use this when the XML document has an unqualified name and we're
113 processing using an absent default namespace.
114
115 @warning: Be careful when using a global name to adopt a name from a
116 local element: if the local element (with no namespace) has the same
117 localName as but is different from the global element (with a
118 namespace), this will improperly provide a namespace when one should
119 not be present. See the comments in
120 L{pyxb.binding.basis.element.elementForName}.
121 """
122
123 if not isinstance(name, ExpandedName):
124 name = ExpandedName(name)
125 if name.namespace() is None:
126 name = self.createName(name.localName())
127 return name
128
130 """Create an expanded name.
131
132 Expected argument patterns are:
133
134 ( C{str} ) -- the local name in an absent namespace
135 ( L{ExpandedName} ) -- a copy of the given expanded name
136 ( C{xml.dom.Node} ) -- The name extracted from node.namespaceURI and node.localName
137 ( C{str}, C{str} ) -- the namespace URI and the local name
138 ( L{Namespace}, C{str} ) -- the namespace and the local name
139 ( L{ExpandedName}, C{str}) -- the namespace from the expanded name, and the local name
140
141 Wherever C{str} occurs C{unicode} is also permitted.
142
143 @keyword fallback_namespace: Optional Namespace instance to use if the
144 namespace would otherwise be None. This is only used if it is an
145 absent namespace.
146
147 """
148 fallback_namespace = kw.get('fallback_namespace')
149 if 0 == len(args):
150 raise pyxb.LogicError('Too few arguments to ExpandedName constructor')
151 if 2 < len(args):
152 raise pyxb.LogicError('Too many arguments to ExpandedName constructor')
153 if 2 == len(args):
154
155 ( ns, ln ) = args
156 else:
157
158 assert 1 == len(args)
159 ln = args[0]
160 ns = None
161 if isinstance(ln, basestring):
162 pass
163 elif isinstance(ln, tuple) and (2 == len(ln)):
164 (ns, ln) = ln
165 elif isinstance(ln, ExpandedName):
166 ns = ln.namespace()
167 ln = ln.localName()
168 elif isinstance(ln, xml.dom.Node):
169 if not(ln.nodeType in (xml.dom.Node.ELEMENT_NODE, xml.dom.Node.ATTRIBUTE_NODE)):
170 raise pyxb.LogicError('Cannot create expanded name from non-element DOM node %s' % (ln.nodeType,))
171 ns = ln.namespaceURI
172 ln = ln.localName
173 else:
174 raise pyxb.LogicError('Unrecognized argument type %s' % (type(ln),))
175 if (ns is None) and (fallback_namespace is not None):
176 if fallback_namespace.isAbsentNamespace():
177 ns = fallback_namespace
178 if isinstance(ns, (str, unicode)):
179 ns = NamespaceForURI(ns, create_if_missing=True)
180 if isinstance(ns, ExpandedName):
181 ns = ns.namespace()
182 if (ns is not None) and not isinstance(ns, Namespace):
183 raise pyxb.LogicError('ExpandedName must include a valid (perhaps absent) namespace, or None.')
184 self.__namespace = ns
185 if self.__namespace is not None:
186 self.__namespaceURI = self.__namespace.uri()
187 self.__localName = ln
188 assert self.__localName is not None
189 self.__expandedName = ( self.__namespace, self.__localName )
190 self.__uriTuple = ( self.__namespaceURI, self.__localName )
191
192
198
204
206 if other is None:
207 return cmp(1, -1)
208 if isinstance(other, (str, unicode)):
209 other = ( None, other )
210 if not isinstance(other, tuple):
211 other = other.__uriTuple
212 if isinstance(other[0], Namespace):
213 other = ( other[0].uri(), other[1] )
214 return cmp(self.__uriTuple, other)
215
225
229
231 """An extended dictionary intended to assist with QName resolution.
232
233 These dictionaries have an attribute that identifies a category of named
234 objects within a Namespace; the specifications for various documents
235 require that certain groups of objects must be unique, while uniqueness is
236 not required between groups. The dictionary also retains a pointer to the
237 Namespace instance for which it holds objects."""
239 """The namespace to which the object map belongs."""
240 return self.__namespace
241 __namespace = None
242
244 """The category of objects (e.g., typeDefinition, elementDeclaration)."""
245 return self.__category
246 __category = None
247
248 - def __init__ (self, category, namespace, *args, **kw):
252
254 """Mix-in that aggregates those aspects of XMLNamespaces that hold
255 references to categories of named objects.
256
257 Arbitrary groups of named objects, each requiring unique names within
258 themselves, can be saved. Unless configured otherwise, the Namespace
259 instance is extended with accessors that provide direct access to
260 individual category maps. The name of the method is the category name
261 with a suffix of "s"; e.g., if a category "typeDefinition" exists, it can
262 be accessed from the namespace using the syntax C{ns.typeDefinitions()}.
263
264 Note that the returned value from the accessor is a live reference to
265 the category map; changes made to the map are reflected in the
266 namespace.
267 """
268
269
270
271 __categoryMap = None
272
274 """CSC extension to reset fields of a Namespace.
275
276 This one handles category-related data."""
277 getattr(super(_NamespaceCategory_mixin, self), '_reset', lambda *args, **kw: None)()
278 self.__categoryMap = { }
279
281 """The list of individual categories held in this namespace."""
282 return self.__categoryMap.keys()
283
285 """Return the whole map from categories to named objects."""
286 return self.__categoryMap
287
294
296 """Define public methods on the Namespace which provide access to
297 individual NamedObjectMaps based on their category.
298
299 """
300 for category in self.categories():
301 accessor_name = category + 's'
302 setattr(self, accessor_name, lambda _map=self.categoryMap(category): _map)
303
320
322 """Allow access to the named_object by looking up the local_name in
323 the given category.
324
325 Raises pyxb.NamespaceUniquenessError if an object with the same name
326 already exists in the category."""
327 name_map = self.categoryMap(category)
328 old_object = name_map.get(local_name)
329 if (old_object is not None) and (old_object != named_object):
330 raise pyxb.NamespaceUniquenessError(self, '%s: name %s used for multiple values in %s' % (self, local_name, category))
331 name_map[local_name] = named_object
332 return named_object
333
335 """Replace the referenced object in the category.
336
337 The new object will be added only if the old_object matches the
338 current entry for local_name in the category."""
339 name_map = self.categoryMap(category)
340 if old_object == name_map.get(local_name):
341 name_map[local_name] = new_object
342 return name_map[local_name]
343
345 """Replace a component definition where present in the category maps.
346
347 @note: This is a high-cost operation, as every item in every category
348 map must be examined to see whether its value field matches
349 C{existing_def}."""
350 for (cat, registry) in self.__categoryMap.items():
351 for (k, v) in registry.items():
352 if v == existing_def:
353 print 'Replacing value for %s in %s' % (k, cat)
354 del registry[k]
355 if replacement_def is not None:
356 registry[k] = replacement_def
357 return getattr(super(_NamespaceCategory_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
358
359
360
361
362
363
374
380
382 """Add the named objects from the given map into the set held by this namespace.
383 It is an error to name something which is already present."""
384 self.configureCategories(category_map.keys())
385 for category in category_map.keys():
386 current_map = self.categoryMap(category)
387 new_map = category_map[category]
388 for (local_name, component) in new_map.iteritems():
389 existing_component = current_map.get(local_name)
390 if existing_component is None:
391 current_map[local_name] = component
392 elif existing_component._allowUpdateFromOther(component):
393 existing_component._updateFromOther(component)
394 else:
395 raise pyxb.NamespaceError(self, 'Load attempted to override %s %s in %s' % (category, ln, self.uri()))
396 self.__defineCategoryAccessors()
397
399 """Return C{True} iff schema components have been associated with this namespace.
400
401 This only checks whether the corresponding categories have been added,
402 not whether there are any entries in those categories. It is useful
403 for identifying namespaces that were incorporated through a
404 declaration but never actually referenced."""
405 return 'typeDefinition' in self.__categoryMap
406
416
418 """Mix-in for components that can depend on other components."""
419
420 __PrivateTransient = set()
421
422
423 __bindingRequires = None
424 __PrivateTransient.add('bindingRequires')
425
427 """CSC extension to reset fields of a component. This one clears
428 dependency-related data, since the clone will have to revise its
429 dependencies.
430 @rtype: C{None}"""
431 getattr(super(_ComponentDependency_mixin, self), '_resetClone_csc', lambda *_args, **_kw: None)(**kw)
432 self.__bindingRequires = None
433
435 """Return a set of components upon whose bindings this component's
436 bindings depend.
437
438 For example, bindings that are extensions or restrictions depend on
439 their base types. Complex type definition bindings require that the
440 types of their attribute declarations be available at the class
441 definition, and the types of their element declarations in the
442 postscript.
443
444 @keyword include_lax: if C{False} (default), only the requirements of
445 the class itself are returned. If C{True}, all requirements are
446 returned.
447 @rtype: C{set(L{pyxb.xmlschema.structures._SchemaComponent_mixin})}
448 """
449 if reset or (self.__bindingRequires is None):
450 if isinstance(self, resolution._Resolvable_mixin) and not (self.isResolved()):
451 raise pyxb.LogicError('Unresolved %s in %s: %s' % (self.__class__.__name__, self._namespaceContext().targetNamespace(), self.name()))
452 self.__bindingRequires = self._bindingRequires_vx(include_lax)
453 return self.__bindingRequires
454
456 """Placeholder for subclass method that identifies the necessary components.
457
458 @note: Override in subclasses.
459
460 @return: The component instances on which this component depends
461 @rtype: C{frozenset}
462 @raise LogicError: A subclass failed to implement this method
463 """
464 raise pyxb.LogicError('%s does not implement _bindingRequires_vx' % (type(self),))
465
467 """Mix-in for managing components defined within this namespace.
468
469 The component set includes not only top-level named components (such as
470 those accessible through category maps), but internal anonymous
471 components, such as those involved in representing the content model of a
472 complex type definition. We need to be able to get a list of these
473 components, sorted in dependency order, so that generated bindings do not
474 attempt to refer to a binding that has not yet been generated."""
475
476
477
478 __components = None
479
481 """CSC extension to reset fields of a Namespace.
482
483 This one handles data related to component association with a
484 namespace."""
485 getattr(super(_NamespaceComponentAssociation_mixin, self), '_reset', lambda *args, **kw: None)()
486 self.__components = set()
487 self.__origins = set()
488 self.__schemaMap = { }
489
497
499 """Replace a component definition in the set of associated components.
500
501 @raise KeyError: C{existing_def} is not in the set of components."""
502
503 self.__components.remove(existing_def)
504 if replacement_def is not None:
505 self.__components.add(replacement_def)
506 return getattr(super(_NamespaceComponentAssociation_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
507
517
526
533
534 __origins = None
535
537 """Return a frozenset of all components, named or unnamed, belonging
538 to this namespace."""
539 return frozenset(self.__components)
540
544
545 import archive
546 import resolution
547
548 from utility import *
549
550 -class Namespace (_NamespaceCategory_mixin, resolution._NamespaceResolution_mixin, _NamespaceComponentAssociation_mixin, archive._NamespaceArchivable_mixin):
551 """Represents an XML namespace (a URI).
552
553 There is at most one L{Namespace} class instance per namespace (URI). The
554 instance also supports associating arbitrary L{maps<NamedObjectMap>} from
555 names to objects, in separate categories. The default categories are
556 configured externally; for example, the
557 L{Schema<pyxb.xmlschema.structures.Schema>} component defines a category
558 for each named component in XMLSchema, and the customizing subclass for
559 WSDL definitions adds categories for the service bindings, messages, etc.
560
561 Namespaces can be written to and loaded from pickled files. See
562 L{NamespaceArchive} for information.
563 """
564
565
566
567 __uri = None
568
569
570
571
572
573
574
575 __absentNamespaceID = 0
576
577
578
579 __boundPrefix = None
580
581
582
583 __prefix = None
584
585
586
587 __Registry = { }
588
589
590 __AbsentNamespaces = set()
591
592
593 __description = None
594
595
596 __isBuiltinNamespace = False
597
598
599 __isUndeclaredNamespace = False
600
601
602 __isLoadedNamespace = False
603
604
605
606 __namespaceArchive = None
607
608
609 __hasBeenArchived = False
610
611
612
613 __builtinModulePath = None
614
615
616
617
618 __bindingConfiguration = None
619
620
621
622
623
624
625 __initialNamespaceContext = None
626
627
628
629 __contextDefaultNamespace = None
630
631
632
633 __contextInScopeNamespaces = None
634
635 @classmethod
637 """If a Namespace instance for the given URI exists, return it; otherwise return None.
638
639 Note; Absent namespaces are not stored in the registry. If you use
640 one (e.g., for a schema with no target namespace), don't lose hold of
641 it."""
642 assert uri is not None
643 return cls.__Registry.get(uri, None)
644
645
647 """Pickling support.
648
649 To ensure that unpickled Namespace instances are unique per
650 URI, we ensure that the routine that creates unpickled
651 instances knows what it's supposed to return."""
652 if self.uri() is None:
653 raise pyxb.LogicError('Illegal to serialize absent namespaces')
654 return (self.uri(),)
655
657 """Pickling and singleton support.
658
659 This ensures that no more than one Namespace instance exists
660 for any given URI. We could do this up in __init__, but that
661 doesn't normally get called when unpickling instances; this
662 does. See also __getnewargs__()."""
663 (uri,) = args
664 if not (uri in cls.__Registry):
665 instance = object.__new__(cls)
666
667 instance.__uri = uri
668 instance._reset()
669
670 if uri is None:
671 cls.__AbsentNamespaces.add(instance)
672 return instance
673 cls.__Registry[uri] = instance
674 return cls.__Registry[uri]
675
676 @classmethod
680
681 - def __init__ (self, uri,
682 description=None,
683 builtin_namespace=None,
684 builtin_module_path=None,
685 is_undeclared_namespace=False,
686 is_loaded_namespace=False,
687 bound_prefix=None,
688 default_namespace=None,
689 in_scope_namespaces=None):
727
732
734 """Return the URI for the namespace represented by this instance.
735
736 If the URI is None, this is an absent namespace, used to hold
737 declarations not associated with a namespace (e.g., from schema with
738 no target namespace)."""
739 return self.__uri
740
748
753
755 """Return True iff this namespace is an absent namespace.
756
757 Absent namespaces have no namespace URI; they exist only to
758 hold components created from schemas with no target
759 namespace."""
760 return self.__uri is None
761
763 """When known to be operating in this namespace, provide the Namespace
764 instance to be used when names are associated with no namespace."""
765 if self.isAbsentNamespace():
766 return self
767 return None
768
769 @classmethod
780
784
786 """Return the standard prefix to be used for this namespace.
787
788 Only a few namespace prefixes are bound to namespaces: xml and xmlns
789 are two. In all other cases, this method should return None. The
790 infrastructure attempts to prevent user creation of Namespace
791 instances that have bound prefixes."""
792 return self.__boundPrefix
793
795 """Return True iff this namespace was defined by the infrastructure.
796
797 That is the case for all namespaces in the Namespace module."""
798 return self.__isBuiltinNamespace
799
801 assert self.__builtinNamespaceVariable is not None
802 return 'pyxb.namespace.%s' % (self.__builtinNamespaceVariable,)
803
811
813 """Return True iff this namespace is always available
814 regardless of whether there is a declaration for it.
815
816 This is the case only for the
817 xml(http://www.w3.org/XML/1998/namespace) and
818 xmlns(http://www.w3.org/2000/xmlns/) namespaces."""
819 return self.__isUndeclaredNamespace
820
822 """Return C{True} iff this namespace was loaded from a namespace archive."""
823 return self.__isLoadedNamespace
824
826 """Return C{True} iff this namespace has been saved to a namespace archive.
827 See also L{isLoadedNamespace}."""
828 return self.__hasBeenArchived
829
835
838
841
843 """Support pickling.
844
845 Well, no, not really. Because namespace instances must be unique, we
846 represent them as their URI, and that's done by __getnewargs__
847 above. All the interesting information is in the ModuleRecords."""
848 return {}
849
852
853 __definedBuiltins = False
862
864 """Attempts to load the named objects held in this namespace.
865
866 The base class implementation looks at the set of available archived
867 namespaces, and if one contains this namespace unserializes its named
868 object maps.
869
870 Sub-classes may choose to look elsewhere, if this version fails or
871 before attempting it.
872
873 There is no guarantee that any particular category of named object has
874 been located when this returns. Caller must check.
875 """
876 for mr in self.moduleRecords():
877 if mr.isLoadable():
878 if mr.isPublic():
879 print 'Load %s from %s' % (mr, mr.archive())
880 try:
881 mr.archive().readNamespaces()
882 except pyxb.NamespaceArchiveError, e:
883 print e
884 else:
885 print 'Ignoring private module %s in validation' % (mr,)
886 self._activate()
887
888 __didValidation = False
889 __inValidation = False
909
911 """Replace the existing definition with another.
912
913 This is used in a situation where building the component model
914 resulted in a new component instance being created and registered, but
915 for which an existing component is to be preferred. An example is
916 when parsing the schema for XMLSchema itself: the built-in datatype
917 components should be retained instead of the simple type definition
918 components dynamically created from the schema.
919
920 By providing the value C{None} as the replacement definition, this can
921 also be used to remove components.
922
923 @note: Invoking this requires scans of every item in every category
924 map in the namespace.
925
926 @return: C{replacement_def}
927 """
928
929
930 return self._replaceComponent_csc(existing_def, replacement_def)
931
933 """Obtain the namespace context to be used when creating components in this namespace.
934
935 Usually applies only to built-in namespaces, but is also used in the
936 autotests when creating a namespace without a xs:schema element. .
937 Note that we must create the instance dynamically, since the
938 information that goes into it has cross-dependencies that can't be
939 resolved until this module has been completely loaded."""
940
941 if self.__initialNamespaceContext is None:
942 isn = { }
943 if self.__contextInScopeNamespaces is not None:
944 for (k, v) in self.__contextInScopeNamespaces.items():
945 isn[k] = self.__identifyNamespace(v)
946 kw = { 'target_namespace' : self
947 , 'default_namespace' : self.__identifyNamespace(self.__contextDefaultNamespace)
948 , 'in_scope_namespaces' : isn }
949 self.__initialNamespaceContext = resolution.NamespaceContext(None, **kw)
950 return self.__initialNamespaceContext
951
952
954 """Identify the specified namespace, which should be a built-in.
955
956 Normally we can just use a reference to the Namespace module instance,
957 but when creating those instances we sometimes need to refer to ones
958 for which the instance has not yet been created. In that case, we use
959 the name of the instance, and resolve the namespace when we need to
960 create the initial context."""
961 if nsval is None:
962 return self
963 if isinstance(nsval, (str, unicode)):
964 nsval = globals().get(nsval)
965 if isinstance(nsval, Namespace):
966 return nsval
967 raise pyxb.LogicError('Cannot identify namespace from %s' % (nsval,))
968
978
979 from builtin import *
980
981 resolution.NamespaceContext._AddTargetNamespaceAttribute(XMLSchema.createExpandedName('schema'), ExpandedName('targetNamespace'))
982
983
984
985
986