def __init__(self, parent=None): super(LnstParser, self).__init__() if parent: self._data = parent._data self._template_proc = parent._template_proc self._include_root = parent._include_root self._events_enabled = parent._events_enabled self._event_handlers = parent._event_handlers else: self._data = {} self._template_proc = XmlTemplates() self._include_root = os.getcwd() self._events_enabled = True self._event_handlers = {}
class LnstParser(XmlParser): """ Enhanced XmlParser This class enhances XmlParser with advanced features that are used in parsing LNST XML files. All (sub)parsers should use this as their base class. """ _data = None _template_proc = None _include_root = None _events_enabled = None _event_handlers = None def __init__(self, parent=None): super(LnstParser, self).__init__() if parent: self._data = parent._data self._template_proc = parent._template_proc self._include_root = parent._include_root self._events_enabled = parent._events_enabled self._event_handlers = parent._event_handlers else: self._data = {} self._template_proc = XmlTemplates() self._include_root = os.getcwd() self._events_enabled = True self._event_handlers = {} def set_target(self, data_dict): self._data = data_dict def set_machines(self, machines): self._template_proc.set_machines(machines) def set_definitions(self, defs): self._template_proc.set_definitions(defs) def set_include_root(self, include_root_path): self._include_root = include_root_path def enable_events(self): self._events_enabled = True def disable_events(self): self._events_enabled = False def register_event_handler(self, event_id, handler): self._event_handlers[event_id] = handler def _trigger_event(self, event_id, args): if not self._events_enabled: return try: handler = self._event_handlers[event_id] except KeyError as err: logging.warn("No handler found for %s event, ignoring", event_id) return handler(**args) def _process_child_nodes(self, node, scheme, params=None, default_handler=None, new_ns_level=True): scheme["define"] = self._define_handler if not params: params = {} if new_ns_level: self._template_proc.add_namespace_level() parent = super(LnstParser, self) result = parent._process_child_nodes(node, scheme, params, default_handler) if new_ns_level: self._template_proc.drop_namespace_level() return result def _process_node(self, node, handler, params): old_include_root = None if self._has_attribute(node, "source"): source = self._get_attribute(node, "source") source_rp = RecipePath(self._include_root, source) old_include_root = self._include_root self._include_root = source_rp.get_root() xmlstr = source_rp.to_str() dom_init = XmlDomTreeInit() try: dom = dom_init.parse_string(xmlstr, filename=source_rp.abs_path()) except IOError as err: msg = "Unable to resolve include: %s" % str(err) raise XmlProcessingError(msg, node) loaded_node = None try: loaded_node = dom.getElementsByTagName(node.nodeName)[0] except Exception: msg = ("No '%s' element present in included file '%s'." % (node.nodeName, source_rp.abs_path())) raise XmlProcessingError(msg, node) old_attrs = self._get_all_attributes(node) parent = node.parentNode parent.replaceChild(loaded_node, node) node = loaded_node # copy all of the original attributes to the sourced node for name, value in old_attrs.iteritems(): # do not overwrite sourced attributes if not node.hasAttribute(name): node.setAttribute(name, value) parent = super(LnstParser, self) parent._process_node(node, handler, params) if old_include_root: self._include_root = old_include_root def _get_attribute(self, node, attr_name, conversion_cb=None): parent = super(LnstParser, self) raw_attr_val = parent._get_attribute(node, attr_name) try: attr_val = self._template_proc.expand_string(raw_attr_val) except XmlTemplateError as err: raise XmlProcessingError(str(err), node) return self._convert_string(node, attr_val, conversion_cb) def _get_text_content(self, node, conversion_cb=None): parent = super(LnstParser, self) raw_content = parent._get_text_content(node) try: content = self._template_proc.expand_string(raw_content) except XmlTemplateError as err: raise XmlProcessingError(str(err), node) return self._convert_string(node, content, conversion_cb) def _define_handler(self, node, params): scheme = {"alias": self._alias_handler} self._process_child_nodes(node, scheme, new_ns_level=False) def _alias_handler(self, node, params): if self._has_attribute(node, "name"): name = self._get_attribute(node, "name") else: msg = "Alias tag must have the 'name' attribute" raise XmlProcessingError(msg, node) if self._has_attribute(node, "value"): value = self._get_attribute(node, "value") else: value = self._get_text_content(node) try: self._template_proc.define_alias(name, value) except XmlTemplateError as err: raise XmlProcessingError(str(err), node)