Example #1
0
 def applyDiff(self, original_data, diff):
   """Use xuproc for computing patched content
   """
   # XXX xuproc does not support passing
   # etree objetcs
   diff = etree.tostring(diff)
   return etree.tostring(xuproc.applyXUpdate(xml_xu_string=diff,
                                             xml_doc_string=original_data), encoding='utf-8')
Example #2
0
 def applyDiff(self, original_data, diff):
   """Use xuproc for computing patched content
   """
   # XXX xuproc does not support passing
   # etree objetcs
   if not isinstance(diff, basestring):
     diff = etree.tostring(diff)
   return etree.tostring(xuproc.applyXUpdate(xml_xu_string=diff,
                                             xml_doc_string=original_data),
                                             encoding='utf-8')
Example #3
0
  def applyXupdate(self, object=None, xupdate=None, previous_xml=None, **kw):
    """
    Parse the xupdate and then it will call the conduit
    """
    conflict_list = []
    if isinstance(xupdate, (str, unicode)):
      xupdate = etree.XML(xupdate, parser=parser)
    #LOG("applyXupdate", INFO, etree.tostring(xupdate, pretty_print=True))
    xupdate_builded = False
    xpath_expression_update_dict = {}
    for subnode in xupdate:
      selection_name = ''
      original_xpath_expression = subnode.get('select', '')
      if not xupdate_builded and\
                            MARSHALLER_NAMESPACE_URI in subnode.nsmap.values()\
                                  or 'block_data' in original_xpath_expression:
        # It means that the xpath expression is targetting
        # marshalled values or data nodes. We need to rebuild the original xml
        # in its own context in order to retrieve original value

        # We are insde a loop build the XUpdated tree only once
        xupdate_builded = True

        # Find the prefix used by marshaller.
        for prefix, namespace_uri in subnode.nsmap.iteritems():
          if namespace_uri == MARSHALLER_NAMESPACE_URI:
            break
        # TODO add support of etree objects for xuproc to avoid
        # serializing tree into string
        if not isinstance(previous_xml, str):
          previous_xml = etree.tostring(previous_xml)
        xupdated_tree = xuproc.applyXUpdate(xml_xu_string=etree.tostring(xupdate),
                                            xml_doc_string=previous_xml)
      if MARSHALLER_NAMESPACE_URI in subnode.nsmap.values():
        xpath_expression = original_xpath_expression
        get_target_parent = subnode.xpath('name()') in XUPDATE_INSERT_LIST
        context = self.getContextFromXpath(object, xpath_expression,
                                           get_target_parent=get_target_parent)
        base_xpath_expression = xpath_expression\
                                            [:xpath_expression.index(prefix)-1]
        xupdated_node_list = xupdated_tree.xpath(base_xpath_expression)
        if xupdated_node_list:
          xupdated_node = xupdated_node_list[0]
        else:
          ValueError('Wrong xpath expression:%r' % base_xpath_expression)
        if base_xpath_expression not in xpath_expression_update_dict:
          xpath_expression_update_dict[base_xpath_expression] = \
                                   dict(xml=xupdated_node,
                                        object=context,
                                        xpath_expression=base_xpath_expression)
      elif 'block_data' in original_xpath_expression:
        """XXX Use Qualified Names for block_data nodes
        to avoid ambiguity
        """
        xpath_expression = original_xpath_expression
        get_target_parent = subnode.xpath('name()') in XUPDATE_INSERT_LIST
        context = self.getContextFromXpath(object, xpath_expression,
                                           get_target_parent=get_target_parent)
        base_xpath_expression = xpath_expression\
                                            [:xpath_expression.index('block_data')-1]
        xupdated_node_list = xupdated_tree.xpath(base_xpath_expression)
        if xupdated_node_list:
          xupdated_node = xupdated_node_list[0]
        else:
          ValueError('Wrong xpath expression:%r' % base_xpath_expression)
        if base_xpath_expression not in xpath_expression_update_dict:
          xpath_expression_update_dict[base_xpath_expression] = \
                                   dict(xml=xupdated_node,
                                        object=context,
                                        xpath_expression=base_xpath_expression)
      elif subnode.xpath('name()') in XUPDATE_INSERT_OR_ADD_LIST:
        conflict_list += self.addNode(xml=subnode, object=object,
                                      previous_xml=previous_xml,
                                      **kw)['conflict_list']
      elif subnode.xpath('name()') == XUPDATE_DEL:
        conflict_list += self.deleteNode(xml=subnode, object=object,
                                         previous_xml=previous_xml, **kw)
      elif subnode.xpath('name()') == XUPDATE_UPDATE:
        conflict_list += self.updateNode(xml=subnode, object=object,
                                         previous_xml=previous_xml, **kw)

    # Now apply collected xupdated_node
    for update_dict in xpath_expression_update_dict.itervalues():
      update_dict.update(kw)
      conflict_list += self.updateNode(previous_xml=previous_xml,
                                       **update_dict)
    return conflict_list
Example #4
0
  def applyXupdate(self, object=None, xupdate=None, previous_xml=None, **kw): # pylint: disable=redefined-builtin
    """
    Parse the xupdate and then it will call the conduit
    """
    conflict_list = []
    if isinstance(xupdate, (str, unicode)):
      xupdate = etree.XML(xupdate, parser=parser)
    #LOG("applyXupdate", INFO, etree.tostring(xupdate, pretty_print=True))
    xupdate_builded = False
    xpath_expression_update_dict = {}
    for subnode in xupdate:
      original_xpath_expression = subnode.get('select', '')
      if not xupdate_builded and \
          MARSHALLER_NAMESPACE_URI in subnode.nsmap.values() \
          or 'block_data' in original_xpath_expression:
        # It means that the xpath expression is targetting
        # marshalled values or data nodes. We need to rebuild the original xml
        # in its own context in order to retrieve original value

        # We are insde a loop build the XUpdated tree only once
        xupdate_builded = True

        # Find the prefix used by marshaller.
        for prefix, namespace_uri in subnode.nsmap.iteritems():
          if namespace_uri == MARSHALLER_NAMESPACE_URI:
            break
        # TODO add support of etree objects for xuproc to avoid
        # serializing tree into string
        if not isinstance(previous_xml, str):
          previous_xml = etree.tostring(previous_xml)
        xupdated_tree = xuproc.applyXUpdate(xml_xu_string=etree.tostring(xupdate),
                                            xml_doc_string=previous_xml)
      if MARSHALLER_NAMESPACE_URI in subnode.nsmap.values():
        xpath_expression = original_xpath_expression
        get_target_parent = subnode.xpath('name()') in XUPDATE_INSERT_LIST
        context = self.getContextFromXpath(object, xpath_expression,
                                           get_target_parent=get_target_parent)
        base_xpath_expression = xpath_expression\
                                            [:xpath_expression.index(prefix)-1]
        xupdated_node_list = xupdated_tree.xpath(base_xpath_expression)
        if xupdated_node_list:
          xupdated_node = xupdated_node_list[0]
        else:
          ValueError('Wrong xpath expression:%r' % base_xpath_expression)
        if base_xpath_expression not in xpath_expression_update_dict:
          xpath_expression_update_dict[base_xpath_expression] = \
                                   dict(xml=xupdated_node,
                                        object=context,
                                        xpath_expression=base_xpath_expression)
      elif 'block_data' in original_xpath_expression:
        """XXX Use Qualified Names for block_data nodes
        to avoid ambiguity
        """
        xpath_expression = original_xpath_expression
        get_target_parent = subnode.xpath('name()') in XUPDATE_INSERT_LIST
        context = self.getContextFromXpath(object, xpath_expression,
                                           get_target_parent=get_target_parent)
        base_xpath_expression = xpath_expression\
                                            [:xpath_expression.index('block_data')-1]
        xupdated_node_list = xupdated_tree.xpath(base_xpath_expression)
        if xupdated_node_list:
          xupdated_node = xupdated_node_list[0]
        else:
          ValueError('Wrong xpath expression:%r' % base_xpath_expression)
        if base_xpath_expression not in xpath_expression_update_dict:
          xpath_expression_update_dict[base_xpath_expression] = \
                                   dict(xml=xupdated_node,
                                        object=context,
                                        xpath_expression=base_xpath_expression)
      elif subnode.xpath('name()') in XUPDATE_INSERT_OR_ADD_LIST:
        conflict_list += self.addNode(xml=subnode, object=object,
                                      previous_xml=previous_xml,
                                      **kw)['conflict_list']
      elif subnode.xpath('name()') == XUPDATE_DEL:
        conflict_list += self.deleteNode(xml=subnode, object=object,
                                         previous_xml=previous_xml, **kw)
      elif subnode.xpath('name()') == XUPDATE_UPDATE:
        conflict_list += self.updateNode(xml=subnode, object=object,
                                         previous_xml=previous_xml, **kw)

    # Now apply collected xupdated_node
    for update_dict in xpath_expression_update_dict.itervalues():
      update_dict.update(kw)
      conflict_list += self.updateNode(previous_xml=previous_xml,
                                       **update_dict)
    return conflict_list