xmlbuilder: Remove more redundant xml state

We don't need to carry around a separate xml_node. Dropping it simplifies
a few things
This commit is contained in:
Cole Robinson 2018-02-14 09:57:22 -05:00
parent d108bbe143
commit a853387866

View File

@ -47,27 +47,22 @@ _namespaces = {
} }
class _DocCleanupWrapper(object): class _CtxCleanupWrapper(object):
def __init__(self, doc): def __init__(self, ctx, doc):
self._ctx = ctx
self._doc = doc self._doc = doc
def __del__(self): def __del__(self):
self._doc.freeDoc() self._doc.freeDoc()
self._doc = None
class _CtxCleanupWrapper(object):
def __init__(self, ctx):
self._ctx = ctx
def __del__(self):
self._ctx.xpathFreeContext() self._ctx.xpathFreeContext()
self._ctx = None self._ctx = None
def __getattr__(self, attrname): def __getattr__(self, attrname):
return getattr(self._ctx, attrname) return getattr(self._ctx, attrname)
def _make_xml_context(node): def _make_xml_context(doc):
doc = node.doc ctx = _CtxCleanupWrapper(doc.xpathNewContext(), doc)
ctx = _CtxCleanupWrapper(doc.xpathNewContext()) ctx.setContextNode(doc.children)
ctx.setContextNode(node)
ctx.xpathRegisterNs("qemu", _namespaces["qemu"]) ctx.xpathRegisterNs("qemu", _namespaces["qemu"])
return ctx return ctx
@ -663,16 +658,11 @@ class XMLProperty(property):
self._nonxml_fset(xmlbuilder, self._nonxml_fset(xmlbuilder,
self._convert_set_value(xmlbuilder, val)) self._convert_set_value(xmlbuilder, val))
def _set_xml(self, xmlbuilder, setval, root_node=None): def _set_xml(self, xmlbuilder, setval):
""" """
Actually set the passed value in the XML document Actually set the passed value in the XML document
""" """
if root_node is None: ctx = xmlbuilder._xmlstate.xml_ctx
root_node = xmlbuilder._xmlstate.xml_node
ctx = xmlbuilder._xmlstate.xml_ctx
else:
ctx = _make_xml_context(root_node)
xpath = self._make_xpath(xmlbuilder) xpath = self._make_xpath(xmlbuilder)
if setval is None or setval is False: if setval is None or setval is False:
@ -708,8 +698,6 @@ class _XMLState(object):
parentxmlstate and parentxmlstate.get_root_xpath()) or "" parentxmlstate and parentxmlstate.get_root_xpath()) or ""
self.xml_ctx = None self.xml_ctx = None
self.xml_node = None
self._xml_root_doc_ref = None
self.is_build = False self.is_build = False
if not parsexml and not parentxmlstate: if not parsexml and not parentxmlstate:
self.is_build = True self.is_build = True
@ -717,8 +705,6 @@ class _XMLState(object):
def parse(self, parsexml, parentxmlstate): def parse(self, parsexml, parentxmlstate):
if parentxmlstate: if parentxmlstate:
self._xml_root_doc_ref = None
self.xml_node = parentxmlstate.xml_node
self.is_build = parentxmlstate.is_build or self.is_build self.is_build = parentxmlstate.is_build or self.is_build
self.xml_ctx = parentxmlstate.xml_ctx self.xml_ctx = parentxmlstate.xml_ctx
return return
@ -732,14 +718,7 @@ class _XMLState(object):
logging.debug("Error parsing xml=\n%s", parsexml) logging.debug("Error parsing xml=\n%s", parsexml)
raise raise
self.xml_node = doc.children self.xml_ctx = _make_xml_context(doc)
self.xml_ctx = _make_xml_context(self.xml_node)
# This just stores a reference to our root doc wrapper in
# the root node, so the doc is autofree'd only when the node
# and this xmlstate object are free'd
self._xml_root_doc_ref = _DocCleanupWrapper(doc)
self.xml_node.virtinst_root_doc = self._xml_root_doc_ref
def make_xml_stub(self): def make_xml_stub(self):
@ -1125,19 +1104,13 @@ class XMLBuilder(object):
def _do_get_xml_config(self): def _do_get_xml_config(self):
xmlstub = self._xmlstate.make_xml_stub() xmlstub = self._xmlstate.make_xml_stub()
try: ctx = self._xmlstate.xml_ctx
node = None if self._xmlstate.is_build:
ctx = self._xmlstate.xml_ctx newdoc = self._xmlstate.xml_ctx.contextNode().doc.copyDoc(True)
if self._xmlstate.is_build: ctx = _make_xml_context(newdoc)
node = self._xmlstate.xml_node.docCopyNodeList(
self._xmlstate.xml_node.doc)
ctx = node
self._add_parse_bits(node) self._add_parse_bits(ctx)
ret = self._xmlstate.get_node_xml(ctx) ret = self._xmlstate.get_node_xml(ctx)
finally:
if node:
node.freeNode()
if ret == xmlstub: if ret == xmlstub:
ret = "" ret = ""
@ -1148,20 +1121,23 @@ class XMLBuilder(object):
ret += "\n" ret += "\n"
return ret return ret
def _add_parse_bits(self, node): def _add_parse_bits(self, ctx):
""" """
Callback that adds the implicitly tracked XML properties to Callback that adds the implicitly tracked XML properties to
the backing xml. the backing xml.
""" """
origproporder = self._proporder[:] origproporder = self._proporder[:]
origpropstore = self._propstore.copy() origpropstore = self._propstore.copy()
origctx = self._xmlstate.xml_ctx
try: try:
return self._do_add_parse_bits(node) self._xmlstate.xml_ctx = ctx
return self._do_add_parse_bits(ctx)
finally: finally:
self._xmlstate.xml_ctx = origctx
self._proporder = origproporder self._proporder = origproporder
self._propstore = origpropstore self._propstore = origpropstore
def _do_add_parse_bits(self, node): def _do_add_parse_bits(self, ctx):
# Set all defaults if the properties have one registered # Set all defaults if the properties have one registered
xmlprops = self._all_xml_props() xmlprops = self._all_xml_props()
childprops = self._all_child_props() childprops = self._all_child_props()
@ -1188,10 +1164,10 @@ class XMLBuilder(object):
# Alter the XML # Alter the XML
for key in do_order: for key in do_order:
if key in xmlprops: if key in xmlprops:
xmlprops[key]._set_xml(self, self._propstore[key], node) xmlprops[key]._set_xml(self, self._propstore[key])
elif key in childprops: elif key in childprops:
for obj in util.listify(getattr(self, key)): for obj in util.listify(getattr(self, key)):
obj._add_parse_bits(node) obj._add_parse_bits(ctx)
def __repr__(self): def __repr__(self):
return "<%s %s %s>" % (self.__class__.__name__.split(".")[-1], return "<%s %s %s>" % (self.__class__.__name__.split(".")[-1],