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