xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/xml/dom/domreg.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""Registration facilities for DOM. This module should not be used
2*cda5da8dSAndroid Build Coastguard Workerdirectly. Instead, the functions getDOMImplementation and
3*cda5da8dSAndroid Build Coastguard WorkerregisterDOMImplementation should be imported from xml.dom."""
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard Worker# This is a list of well-known implementations.  Well-known names
6*cda5da8dSAndroid Build Coastguard Worker# should be published by posting to [email protected], and are
7*cda5da8dSAndroid Build Coastguard Worker# subsequently recorded in this file.
8*cda5da8dSAndroid Build Coastguard Worker
9*cda5da8dSAndroid Build Coastguard Workerimport sys
10*cda5da8dSAndroid Build Coastguard Worker
11*cda5da8dSAndroid Build Coastguard Workerwell_known_implementations = {
12*cda5da8dSAndroid Build Coastguard Worker    'minidom':'xml.dom.minidom',
13*cda5da8dSAndroid Build Coastguard Worker    '4DOM': 'xml.dom.DOMImplementation',
14*cda5da8dSAndroid Build Coastguard Worker    }
15*cda5da8dSAndroid Build Coastguard Worker
16*cda5da8dSAndroid Build Coastguard Worker# DOM implementations not officially registered should register
17*cda5da8dSAndroid Build Coastguard Worker# themselves with their
18*cda5da8dSAndroid Build Coastguard Worker
19*cda5da8dSAndroid Build Coastguard Workerregistered = {}
20*cda5da8dSAndroid Build Coastguard Worker
21*cda5da8dSAndroid Build Coastguard Workerdef registerDOMImplementation(name, factory):
22*cda5da8dSAndroid Build Coastguard Worker    """registerDOMImplementation(name, factory)
23*cda5da8dSAndroid Build Coastguard Worker
24*cda5da8dSAndroid Build Coastguard Worker    Register the factory function with the name. The factory function
25*cda5da8dSAndroid Build Coastguard Worker    should return an object which implements the DOMImplementation
26*cda5da8dSAndroid Build Coastguard Worker    interface. The factory function can either return the same object,
27*cda5da8dSAndroid Build Coastguard Worker    or a new one (e.g. if that implementation supports some
28*cda5da8dSAndroid Build Coastguard Worker    customization)."""
29*cda5da8dSAndroid Build Coastguard Worker
30*cda5da8dSAndroid Build Coastguard Worker    registered[name] = factory
31*cda5da8dSAndroid Build Coastguard Worker
32*cda5da8dSAndroid Build Coastguard Workerdef _good_enough(dom, features):
33*cda5da8dSAndroid Build Coastguard Worker    "_good_enough(dom, features) -> Return 1 if the dom offers the features"
34*cda5da8dSAndroid Build Coastguard Worker    for f,v in features:
35*cda5da8dSAndroid Build Coastguard Worker        if not dom.hasFeature(f,v):
36*cda5da8dSAndroid Build Coastguard Worker            return 0
37*cda5da8dSAndroid Build Coastguard Worker    return 1
38*cda5da8dSAndroid Build Coastguard Worker
39*cda5da8dSAndroid Build Coastguard Workerdef getDOMImplementation(name=None, features=()):
40*cda5da8dSAndroid Build Coastguard Worker    """getDOMImplementation(name = None, features = ()) -> DOM implementation.
41*cda5da8dSAndroid Build Coastguard Worker
42*cda5da8dSAndroid Build Coastguard Worker    Return a suitable DOM implementation. The name is either
43*cda5da8dSAndroid Build Coastguard Worker    well-known, the module name of a DOM implementation, or None. If
44*cda5da8dSAndroid Build Coastguard Worker    it is not None, imports the corresponding module and returns
45*cda5da8dSAndroid Build Coastguard Worker    DOMImplementation object if the import succeeds.
46*cda5da8dSAndroid Build Coastguard Worker
47*cda5da8dSAndroid Build Coastguard Worker    If name is not given, consider the available implementations to
48*cda5da8dSAndroid Build Coastguard Worker    find one with the required feature set. If no implementation can
49*cda5da8dSAndroid Build Coastguard Worker    be found, raise an ImportError. The features list must be a sequence
50*cda5da8dSAndroid Build Coastguard Worker    of (feature, version) pairs which are passed to hasFeature."""
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard Worker    import os
53*cda5da8dSAndroid Build Coastguard Worker    creator = None
54*cda5da8dSAndroid Build Coastguard Worker    mod = well_known_implementations.get(name)
55*cda5da8dSAndroid Build Coastguard Worker    if mod:
56*cda5da8dSAndroid Build Coastguard Worker        mod = __import__(mod, {}, {}, ['getDOMImplementation'])
57*cda5da8dSAndroid Build Coastguard Worker        return mod.getDOMImplementation()
58*cda5da8dSAndroid Build Coastguard Worker    elif name:
59*cda5da8dSAndroid Build Coastguard Worker        return registered[name]()
60*cda5da8dSAndroid Build Coastguard Worker    elif not sys.flags.ignore_environment and "PYTHON_DOM" in os.environ:
61*cda5da8dSAndroid Build Coastguard Worker        return getDOMImplementation(name = os.environ["PYTHON_DOM"])
62*cda5da8dSAndroid Build Coastguard Worker
63*cda5da8dSAndroid Build Coastguard Worker    # User did not specify a name, try implementations in arbitrary
64*cda5da8dSAndroid Build Coastguard Worker    # order, returning the one that has the required features
65*cda5da8dSAndroid Build Coastguard Worker    if isinstance(features, str):
66*cda5da8dSAndroid Build Coastguard Worker        features = _parse_feature_string(features)
67*cda5da8dSAndroid Build Coastguard Worker    for creator in registered.values():
68*cda5da8dSAndroid Build Coastguard Worker        dom = creator()
69*cda5da8dSAndroid Build Coastguard Worker        if _good_enough(dom, features):
70*cda5da8dSAndroid Build Coastguard Worker            return dom
71*cda5da8dSAndroid Build Coastguard Worker
72*cda5da8dSAndroid Build Coastguard Worker    for creator in well_known_implementations.keys():
73*cda5da8dSAndroid Build Coastguard Worker        try:
74*cda5da8dSAndroid Build Coastguard Worker            dom = getDOMImplementation(name = creator)
75*cda5da8dSAndroid Build Coastguard Worker        except Exception: # typically ImportError, or AttributeError
76*cda5da8dSAndroid Build Coastguard Worker            continue
77*cda5da8dSAndroid Build Coastguard Worker        if _good_enough(dom, features):
78*cda5da8dSAndroid Build Coastguard Worker            return dom
79*cda5da8dSAndroid Build Coastguard Worker
80*cda5da8dSAndroid Build Coastguard Worker    raise ImportError("no suitable DOM implementation found")
81*cda5da8dSAndroid Build Coastguard Worker
82*cda5da8dSAndroid Build Coastguard Workerdef _parse_feature_string(s):
83*cda5da8dSAndroid Build Coastguard Worker    features = []
84*cda5da8dSAndroid Build Coastguard Worker    parts = s.split()
85*cda5da8dSAndroid Build Coastguard Worker    i = 0
86*cda5da8dSAndroid Build Coastguard Worker    length = len(parts)
87*cda5da8dSAndroid Build Coastguard Worker    while i < length:
88*cda5da8dSAndroid Build Coastguard Worker        feature = parts[i]
89*cda5da8dSAndroid Build Coastguard Worker        if feature[0] in "0123456789":
90*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("bad feature name: %r" % (feature,))
91*cda5da8dSAndroid Build Coastguard Worker        i = i + 1
92*cda5da8dSAndroid Build Coastguard Worker        version = None
93*cda5da8dSAndroid Build Coastguard Worker        if i < length:
94*cda5da8dSAndroid Build Coastguard Worker            v = parts[i]
95*cda5da8dSAndroid Build Coastguard Worker            if v[0] in "0123456789":
96*cda5da8dSAndroid Build Coastguard Worker                i = i + 1
97*cda5da8dSAndroid Build Coastguard Worker                version = v
98*cda5da8dSAndroid Build Coastguard Worker        features.append((feature, version))
99*cda5da8dSAndroid Build Coastguard Worker    return tuple(features)
100