10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""Registration facilities for DOM. This module should not be used 20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidirectly. Instead, the functions getDOMImplementation and 30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiregisterDOMImplementation should be imported from xml.dom.""" 40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom xml.dom.minicompat import * # isinstance, StringTypes 60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# This is a list of well-known implementations. Well-known names 80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# should be published by posting to xml-sig@python.org, and are 90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# subsequently recorded in this file. 100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiwell_known_implementations = { 120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'minidom':'xml.dom.minidom', 130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '4DOM': 'xml.dom.DOMImplementation', 140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi } 150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# DOM implementations not officially registered should register 170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# themselves with their 180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiregistered = {} 200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef registerDOMImplementation(name, factory): 220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """registerDOMImplementation(name, factory) 230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Register the factory function with the name. The factory function 250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi should return an object which implements the DOMImplementation 260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi interface. The factory function can either return the same object, 270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi or a new one (e.g. if that implementation supports some 280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi customization).""" 290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi registered[name] = factory 310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _good_enough(dom, features): 330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "_good_enough(dom, features) -> Return 1 if the dom offers the features" 340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for f,v in features: 350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if not dom.hasFeature(f,v): 360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 0 370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return 1 380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef getDOMImplementation(name = None, features = ()): 400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """getDOMImplementation(name = None, features = ()) -> DOM implementation. 410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Return a suitable DOM implementation. The name is either 430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi well-known, the module name of a DOM implementation, or None. If 440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi it is not None, imports the corresponding module and returns 450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi DOMImplementation object if the import succeeds. 460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If name is not given, consider the available implementations to 480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi find one with the required feature set. If no implementation can 490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi be found, raise an ImportError. The features list must be a sequence 500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi of (feature, version) pairs which are passed to hasFeature.""" 510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi import os 530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi creator = None 540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi mod = well_known_implementations.get(name) 550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if mod: 560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi mod = __import__(mod, {}, {}, ['getDOMImplementation']) 570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return mod.getDOMImplementation() 580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif name: 590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return registered[name]() 600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif "PYTHON_DOM" in os.environ: 610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return getDOMImplementation(name = os.environ["PYTHON_DOM"]) 620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # User did not specify a name, try implementations in arbitrary 640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # order, returning the one that has the required features 650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(features, StringTypes): 660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi features = _parse_feature_string(features) 670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for creator in registered.values(): 680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dom = creator() 690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _good_enough(dom, features): 700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return dom 710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for creator in well_known_implementations.keys(): 730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dom = getDOMImplementation(name = creator) 750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except StandardError: # typically ImportError, or AttributeError 760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi continue 770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if _good_enough(dom, features): 780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return dom 790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ImportError,"no suitable DOM implementation found" 810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _parse_feature_string(s): 830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi features = [] 840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parts = s.split() 850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i = 0 860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi length = len(parts) 870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi while i < length: 880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi feature = parts[i] 890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if feature[0] in "0123456789": 900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise ValueError, "bad feature name: %r" % (feature,) 910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i = i + 1 920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi version = None 930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if i < length: 940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi v = parts[i] 950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if v[0] in "0123456789": 960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i = i + 1 970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi version = v 980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi features.append((feature, version)) 990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return tuple(features) 100