[Erp5-report] r35819 nicolas - /erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py
nobody at svn.erp5.org
nobody at svn.erp5.org
Mon May 31 18:38:57 CEST 2010
Author: nicolas
Date: Mon May 31 18:38:56 2010
New Revision: 35819
URL: http://svn.erp5.org?rev=35819&view=rev
Log:
ERP5Conduit uses now external tool to apply xupdate document on
XML document, xupdate_processor.
This is usefull to restore data from xml document according xupdate
statements.
Modified:
erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py
Modified: erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py?rev=35819&r1=35818&r2=35819&view=diff
==============================================================================
--- erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py [utf8] (original)
+++ erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py [utf8] Mon May 31 18:38:56 2010
@@ -44,7 +44,8 @@
from lxml import etree
from lxml.etree import Element
parser = etree.XMLParser(remove_blank_text=True)
-from xml.marshal.generic import loads as unmarshaler
+from xml_marshaller.xml_marshaller import load_tree as unmarshaller
+from xupdate_processor import xuproc
from zLOG import LOG, INFO, DEBUG
from base64 import standard_b64decode
from zope.interface import implements
@@ -106,9 +107,8 @@
self.args = {}
security.declareProtected(Permissions.ModifyPortalContent, 'addNode')
- def addNode(self, xml=None, object=None, previous_xml=None,
- object_id=None, sub_object=None, force=0, simulate=0,
- reset=0, **kw):
+ def addNode(self, xml=None, object=None, sub_object=None, reset=None,
+ simulate=None, **kw):
"""
A node is added
@@ -128,119 +128,74 @@
reset_workflow = False
conflict_list = []
xml = self.convertToXml(xml)
- #LOG('ERP5Conduit addNode:',DEBUG,etree.tostring(xml,pretty_print=True))
+ #LOG('ERP5Conduit.addNode', INFO, 'object path:%s' % object.getPath())
+ #LOG('ERP5Conduit.addNode', INFO, '\n%s' % etree.tostring(xml, pretty_print=True))
if xml is None:
return {'conflict_list': conflict_list, 'object': sub_object}
# In the case where this new node is a object to add
- if xml.xpath('name()') in self.XUPDATE_INSERT_OR_ADD and \
- self.getSubObjectDepth(xml) == 0:
- if self.isHistoryAdd(xml) != -1: # bad hack XXX to be removed
- for element in self.getXupdateElementList(xml):
- xml = self.getElementFromXupdate(element)
- conflict_list += self.addNode(
- xml=xml,
- object=object,
- previous_xml=previous_xml,
- force=force,
- simulate=simulate,
- reset=reset, **kw)['conflict_list']
+ xpath_expression = xml.get('select')
+ if xml.xpath('local-name()') == self.history_tag and not reset:
+ conflict_list += self.addWorkflowNode(object, xml, simulate)
+ elif xml.xpath('name()') in self.XUPDATE_INSERT_OR_ADD and\
+ MARSHALLER_NAMESPACE_URI not in xml.nsmap.values():
+ # change the context according select expression
+ context = self.getContextFromXpath(object, xpath_expression)
+ for element in xml.findall('{%s}element' % xml.nsmap['xupdate']):
+ xml = self.getElementFromXupdate(element)
+ conflict_list += self.addNode(xml=xml, object=context, **kw)\
+ ['conflict_list']
elif xml.xpath('local-name()') == self.xml_object_tag:
sub_object = self._createContent(xml=xml,
object=object,
- object_id=object_id,
sub_object=sub_object,
- reset=reset,
reset_local_roles=reset_local_roles,
reset_workflow=reset_workflow,
+ reset=reset,
simulate=simulate,
**kw)
- elif xml.xpath('name()') in self.XUPDATE_INSERT_OR_ADD \
- and self.getSubObjectDepth(xml) >= 1:
- sub_object_id = self.getSubObjectId(xml)
- if previous_xml is not None and sub_object_id is not None:
- # Find the previous xml corresponding to this subobject
- sub_previous_xml = self.getSubObjectXml(sub_object_id, previous_xml)
- #LOG('addNode', DEBUG,'isSubObjectModification sub_previous_xml: %s' % str(sub_previous_xml))
- if sub_previous_xml is not None:
- sub_object = None
- try:
- sub_object = object._getOb(sub_object_id)
- except (AttributeError, KeyError, TypeError):
- pass
- if sub_object is not None:
- #LOG('addNode', DEBUG, 'subobject.id: %s' % sub_object.id)
- # Change the xml in order to directly apply
- # modifications to the subobject
- sub_xml = self.getSubObjectXupdate(xml)
- #LOG('addNode', DEBUG, 'sub_xml: %s' % str(sub_xml))
- # Then do the udpate
- conflict_list += self.addNode(xml=sub_xml, object=sub_object,
- previous_xml=sub_previous_xml, force=force,
- simulate=simulate, reset=reset, **kw)['conflict_list']
- elif (xml.xpath('local-name()') == self.history_tag \
- or self.isHistoryAdd(xml) > 0) and not reset:
- conflict_list += self.addWorkflowNode(object, xml, simulate)
- #elif xml.tag in self.local_role_list or self.isLocalRole(xml)>0 and not simulate:
elif xml.xpath('local-name()') in self.local_role_list:
self.addLocalRoleNode(object, xml)
elif xml.xpath('local-name()') in self.local_permission_list:
conflict_list += self.addLocalPermissionNode(object, xml)
else:
- conflict_list += self.updateNode(xml=xml,object=object, force=force,
- simulate=simulate, reset=reset, **kw)
+ conflict_list += self.updateNode(xml=xml, object=object, reset=reset,
+ simulate=simulate, **kw)
# We must returns the object created
return {'conflict_list':conflict_list, 'object': sub_object}
security.declareProtected(Permissions.ModifyPortalContent, 'deleteNode')
- def deleteNode(self, xml=None, object=None, object_id=None, force=None,
- simulate=0, reset=0, **kw):
+ def deleteNode(self, xml=None, object=None, object_id=None, **kw):
"""
A node is deleted
"""
- # In the case where we have to delete an object
- #LOG('ERP5Conduit.deleteNode', DEBUG, 'deleteNode, object path: %s' % repr(object.getPhysicalPath()))
- #LOG('ERP5Conduit deleteNode', DEBUG,"%s" % object_id)
- #LOG('ERP5Conduit deleteNode', DEBUG,"%s" % xml)
- conflict_list = []
- if xml is not None:
- xml = self.convertToXml(xml)
- #LOG('ERP5Conduit deleteNode', DEBUG,"%s" % etree.tostring(xml,pretty_print=True))
- if object_id is None:
- #LOG('ERP5Conduit.deleteNode', DEBUG, 'deleteNode, SubObjectDepth: %i' % self.getSubObjectDepth(xml))
- if xml.xpath('local-name()') == self.xml_object_tag:
- object_id = self.getAttribute(xml,'id')
- elif self.getSubObjectDepth(xml) == 1:
- object_id = self.getSubObjectId(xml)
- elif self.getSubObjectDepth(xml) == 2:
- # we have to call delete node on a subsubobject
- sub_object_id = self.getSubObjectId(xml)
- try:
- sub_object = object._getOb(sub_object_id)
- sub_xml = self.getSubObjectXupdate(xml)
- conflict_list += self.deleteNode(xml=sub_xml,object=sub_object,
- force=force, simulate=simulate,
- reset=reset, **kw)
- except (KeyError, AttributeError, TypeError):
- #LOG('ERP5Conduit.deleteNode', DEBUG, 'deleteNode, Unable to delete SubObject: %s' % str(sub_object_id))
- pass
- if object_id is not None: # We do have an object_id
+ #LOG('ERP5Conduit.deleteNode', INFO, 'object path:%s' % object.getPath())
+ #LOG('ERP5Conduit deleteNode', INFO, 'object_id:%r' % object_id)
+ if object_id is not None:
self._deleteContent(object=object, object_id=object_id)
- # In the case where we have to delete an user role
- # If we are still there, this means the delete is for this node
- elif xml.xpath('name()') in self.XUPDATE_DEL:
- xml = self.getElementFromXupdate(xml)
- if xml.xpath('local-name()') in self.local_role_list and not simulate:
- # We want to del a local role
- user = self.getAttribute(xml,'id')
- #LOG('ERP5Conduit.deleteNode local_role: ', DEBUG, 'user: %s' % repr(user))
- if xml.xpath('local-name()') == self.local_role_tag:
+ return []
+ xml = self.convertToXml(xml)
+ #LOG('ERP5Conduit deleteNode', INFO, etree.tostring(xml, pretty_print=True))
+ xpath_expression = xml.get('select')
+ context_to_delete = self.getContextFromXpath(object, xpath_expression)
+ if context_to_delete != object:
+ self._deleteContent(object=context_to_delete.getParentValue(),
+ object_id=context_to_delete.getId())
+ else:
+ #same context
+ if [role for role in self.local_role_list if role in xpath_expression]:
+ user = self.extract_id_from_xpath.findall(xpath_expression)[-1][3]
+ #LOG('ERP5Conduit.deleteNode local_role: ', INFO, 'user: %r' % user)
+ if self.local_role_tag in xpath_expression:
object.manage_delLocalRoles([user])
- elif xml.xpath('local-name()') ==self.local_group_tag:
+ elif self.local_group_tag in xpath_expression:
object.manage_delLocalGroupRoles([user])
- if xml.xpath('local-name()') in self.local_permission_list and not simulate:
- permission = self.getAttribute(xml,'id')
+ if [permission for permission in self.local_permission_list if\
+ permission in xpath_expression]:
+ permission = self.extract_id_from_xpath.findall(xpath_expression)[-1][3]
+ #LOG('ERP5Conduit.deleteNode permission: ', INFO,
+ #'permission: %r' % permission)
object.manage_setLocalPermissions(permission)
- return conflict_list
+ return []
security.declareProtected(Permissions.ModifyPortalContent, 'deleteObject')
def deleteObject(self, object, object_id):
@@ -251,8 +206,8 @@
pass
security.declareProtected(Permissions.ModifyPortalContent, 'updateNode')
- def updateNode(self, xml=None, object=None, previous_xml=None, force=0,
- simulate=0, reset=0, **kw):
+ def updateNode(self, xml=None, object=None, previous_xml=None, force=False,
+ simulate=False, reset=False, xpath_expression=None, **kw):
"""
A node is updated with some xupdate
- xml : the xml corresponding to the update, it should be xupdate
@@ -264,14 +219,12 @@
if xml is None:
return {'conflict_list':conflict_list, 'object':object}
xml = self.convertToXml(xml)
- #LOG('ERP5Conduit.updateNode', DEBUG, 'xml.tag: %s' % xml.tag)
- #LOG('ERP5Conduit.updateNode, force: ', DEBUG, force)
- # we have an xupdate xml
- #LOG('ERP5Conduit updateNode', DEBUG, "%s" % etree.tostring(xml,pretty_print=True))
- if xml.xpath('name()') == 'xupdate:modifications':
+ #LOG('ERP5Conduit.updateNode, force: ', INFO, force)
+ #LOG('ERP5Conduit updateNode', INFO, object.getPath())
+ #LOG('ERP5Conduit updateNode', INFO, '\n%s' % etree.tostring(xml, pretty_print=True))
+ if xml.tag == '{%s}modifications' % xml.nsmap.get('xupdate'):
conflict_list += self.applyXupdate(object=object,
xupdate=xml,
- conduit=self,
previous_xml=previous_xml,
force=force,
simulate=simulate,
@@ -286,13 +239,13 @@
if value is not None:
select_list = value.split('/') # Something like:
#('','object[1]','sid[1]')
- new_select_list = ()
+ new_select_list = []
for select_item in select_list:
if select_item.find('[') >= 0:
select_item = select_item[:select_item.find('[')]
- new_select_list += (select_item,)
+ new_select_list.append(select_item)
select_list = new_select_list # Something like : ('','object','sid')
- keyword = select_list[len(select_list)-1] # this will be 'sid'
+ keyword = select_list[-1] # this will be 'sid'
data = None
if xml.xpath('name()') not in self.XUPDATE_INSERT_OR_ADD:
for subnode in xml:
@@ -300,6 +253,7 @@
keyword = subnode.get('name')
data_xml = subnode
else:
+ #XXX find something better than hardcoded prefix
# We can call add node
conflict_list += self.addNode(xml=xml,
object=object,
@@ -308,7 +262,6 @@
reset=reset,
**kw)
return conflict_list
-
if xml.xpath('name()') in self.XUPDATE_DEL:
conflict_list += self.deleteNode(xml=xml,
object=object,
@@ -321,8 +274,10 @@
keyword = xml.xpath('name()')
if not (keyword in self.NOT_EDITABLE_PROPERTY):
# We will look for the data to enter
- data_type = object.getPropertyType(keyword)
- #LOG('ERP5Conduit.updateNode', DEBUG, 'data_type: %s for keyword: %s' % (str(data_type), keyword))
+ xpath_expression = xml.get('select', xpath_expression)
+ context = self.getContextFromXpath(object, xpath_expression)
+ data_type = context.getPropertyType(keyword)
+ #LOG('ERP5Conduit.updateNode', INFO, 'data_type:%r for keyword: %s' % (data_type, keyword))
data = self.convertXmlValue(xml, data_type=data_type)
args[keyword] = data
args = self.getFormatedArgs(args=args)
@@ -335,37 +290,40 @@
isConflict = False
if (previous_xml is not None) and (not force):
# if no previous_xml, no conflict
- old_data = self.getObjectProperty(keyword, previous_xml,
- data_type=data_type)
- #current_data = object.getProperty(keyword)
- current_data = self.getProperty(object, keyword)
- #LOG('ERP5Conduit.updateNode', DEBUG, 'Conflict data: %s' % str(data))
- #LOG('ERP5Conduit.updateNode', DEBUG, 'Conflict old_data: %s' % str(old_data))
- #LOG('ERP5Conduit.updateNode', DEBUG, 'Conflict current_data: %s' % str(current_data))
+ #old_data = self.getObjectProperty(keyword, previous_xml,
+ #data_type=data_type)
+ previous_xml_tree = self.convertToXml(previous_xml)
+ old_result = previous_xml_tree.xpath(xpath_expression)
+ if old_result:
+ old_data = self.convertXmlValue(old_result[0])
+ else:
+ raise ValueError('Xpath expression does not apply on previous'\
+ ' xml:%r' % xpath_expression)
+ current_data = self.getProperty(context, keyword)
+ #LOG('ERP5Conduit.updateNode', INFO, 'Conflict keyword: %s' % keyword)
+ #LOG('ERP5Conduit.updateNode', INFO, 'Conflict data: %s' % str(data))
+ #LOG('ERP5Conduit.updateNode', INFO, 'Conflict old_data: %s' % str(old_data))
+ #LOG('ERP5Conduit.updateNode', INFO, 'Conflict current_data: %s' % str(current_data))
if (old_data != current_data) and (data != current_data) \
and keyword not in self.force_conflict_list:
- #LOG('ERP5Conduit.updateNode', DEBUG, 'Conflict on : %s' % keyword)
- # Hack in order to get the synchronization working for demo
- # XXX this have to be removed after
- #if not (data_type in self.binary_type_list):
- if 1:
- # This is a conflict
- isConflict = 1
- xml_string = etree.tostring(xml, encoding='utf-8')
- conflict = Conflict(object_path=object.getPhysicalPath(),
- keyword=keyword)
- conflict.setXupdate(xml_string)
- if not (data_type in self.binary_type_list):
- conflict.setLocalValue(current_data)
- conflict.setRemoteValue(data)
- conflict_list += [conflict]
+ #LOG('ERP5Conduit.updateNode', INFO, 'Conflict on : %s' % keyword)
+ # This is a conflict
+ isConflict = True
+ xml_string = etree.tostring(xml, encoding='utf-8')
+ conflict = Conflict(object_path=context.getPhysicalPath(),
+ keyword=keyword)
+ conflict.setXupdate(xml_string)
+ if not (data_type in self.binary_type_list):
+ conflict.setLocalValue(current_data)
+ conflict.setRemoteValue(data)
+ conflict_list += [conflict]
# We will now apply the argument with the method edit
if args != {} and (isConflict == 0 or force) and \
(not simulate or reset):
- self._updateContent(object=object, **args)
+ self._updateContent(object=context, **args)
# It is sometimes required to do something after an edit
- if getattr(object, 'manage_afterEdit', None) is not None:
- object.manage_afterEdit()
+ if getattr(context, 'manage_afterEdit', None) is not None:
+ context.manage_afterEdit()
if keyword == 'object':
# This is the case where we have to call addNode
@@ -386,48 +344,9 @@
#user = self.getSubObjectId(xml)
#roles = self.convertXmlValue(data,data_type='tokens')
#object.manage_setLocalRoles(user,roles)
- xml = self.getElementFromXupdate(xml)
conflict_list += self.addNode(xml=xml, object=object,
force=force, simulate=simulate,
reset=reset, **kw)['conflict_list']
- elif self.isSubObjectModification(xml):
- # We should find the object corresponding to
- # this update, so we have to look in the previous_xml
- sub_object_id = self.getSubObjectId(xml)
- #LOG('ERP5Conduit.updateNode', DEBUG,'isSubObjectModification sub_object_id: %s' % sub_object_id)
- if previous_xml is not None and sub_object_id is not None:
- sub_previous_xml = self.getSubObjectXml(sub_object_id, previous_xml)
- #LOG('ERP5Conduit.updateNode', DEBUG, 'isSubObjectModification sub_previous_xml: %s' % str(sub_previous_xml))
- sub_object = None
- try:
- sub_object = object._getOb(sub_object_id)
- except KeyError:
- pass
- if sub_object is not None:
- #LOG('ERP5Conduit.updateNode', DEBUG, 'subobject.id: %s' % sub_object.id)
- # Change the xml in order to directly apply
- # modifications to the subobject
- sub_xml = self.getSubObjectXupdate(xml)
- #LOG('ERP5Conduit.updateNode', DEBUG, 'sub_xml: %s' % str(sub_xml))
- # Then do the udpate
- conflict_list += self.updateNode(xml=sub_xml, object=sub_object,
- force=force,
- previous_xml=sub_previous_xml,
- simulate=simulate, reset=reset, **kw)
- elif previous_xml is None and xml is not None and sub_object_id is not None:
- sub_object = None
- try:
- sub_object = object[sub_object_id]
- except KeyError:
- pass
- if sub_object is not None:
- sub_xml = self.getSubObjectXupdate(xml)
- conflict_list += self.updateNode(xml=sub_xml,
- object=sub_object,
- force=force,
- simulate=simulate,
- reset=reset,
- **kw)
return conflict_list
security.declareProtected(Permissions.AccessContentsInformation,
@@ -466,13 +385,40 @@
Check if it is a simple property
not an attribute @type it's a metadata
"""
- bad_list = (self.sub_object_exp, self.history_exp, self.attribute_type_exp,)
+ bad_list = (self.history_exp, self.attribute_type_exp,)
value = xml.get('select')
if value is not None:
for bad_string in bad_list:
if bad_string.search(value) is not None:
return False
return True
+
+ def getContextFromXpath(self, context, xpath):
+ """Return the last object from xpath expression
+ /object[@gid='foo']/object[@id='bar']/object[@id='freak']/property
+ will return object.getId() == 'freak'
+ - We ignore the first object_block /object[@gid='foo'] intentionaly
+ because the targeted context is already actual context.
+ """
+ if xpath is None:
+ return context
+ result_list = self.extract_id_from_xpath.findall(xpath)
+ first_object = True
+ while result_list:
+ object_block = result_list[0][0]
+ sub_context_id = result_list[0][3]
+ sub_context = context._getOb(sub_context_id, None)
+ if first_object:
+ first_object = False
+ elif sub_context is not None:
+ context = sub_context
+ else:
+ # Ignore non existing objects
+ LOG('ERP5Conduit', INFO, 'sub document of %s not found with id:%r'%\
+ (context.getPath(), sub_context_id))
+ xpath = xpath.replace(object_block, '', 1)
+ result_list = self.extract_id_from_xpath.findall(xpath)
+ return context
security.declareProtected(Permissions.AccessContentsInformation,
'getSubObjectXupdate')
@@ -567,6 +513,7 @@
security.declareProtected(Permissions.AccessContentsInformation,
'getSubObjectId')
+ @deprecated
def getSubObjectId(self, xml):
"""
Return the id of the subobject in an xupdate modification
@@ -870,34 +817,90 @@
data = int(data)
return data
- # XXX is it the right place ? It should be in XupdateUtils, but here we
- # have some specific things to do
+
security.declareProtected(Permissions.ModifyPortalContent, 'applyXupdate')
- def applyXupdate(self, object=None, xupdate=None, conduit=None, force=0,
- simulate=0, reset=0, **kw):
+ 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 xupdate",debug, "%s" % etree.tostring(xupdate,pretty_print=True))
+ #LOG("applyXupdate", INFO, etree.tostring(xupdate, pretty_print=True))
+ xupdate_builded = False
+ xpath_expression_update_dict = {}
for subnode in xupdate:
- sub_xupdate = self.getSubObjectXupdate(subnode)
selection_name = ''
- if subnode.xpath('name()') in self.XUPDATE_INSERT_OR_ADD:
- conflict_list += conduit.addNode(xml=sub_xupdate,object=object,
- force=force, simulate=simulate,
- reset=reset, **kw)['conflict_list']
+ 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
+ context = self.getContextFromXpath(object, xpath_expression)
+ 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
+ context = self.getContextFromXpath(object, xpath_expression)
+ 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 self.XUPDATE_INSERT_OR_ADD:
+ conflict_list += self.addNode(xml=subnode, object=object,
+ previous_xml=previous_xml,
+ **kw)['conflict_list']
elif subnode.xpath('name()') in self.XUPDATE_DEL:
- conflict_list += conduit.deleteNode(xml=sub_xupdate, object=object,
- force=force, simulate=simulate,
- reset=reset, **kw)
+ conflict_list += self.deleteNode(xml=subnode, object=object,
+ previous_xml=previous_xml, **kw)
elif subnode.xpath('name()') in self.XUPDATE_UPDATE:
- conflict_list += conduit.updateNode(xml=sub_xupdate, object=object,
- force=force, simulate=simulate,
- reset=reset, **kw)
-
+ 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
def isWorkflowActionAddable(self, object=None, status=None, wf_tool=None,
@@ -1039,8 +1042,9 @@
"""
return object.getId()
- def _createContent(self, xml=None, object=None, object_id=None, sub_object=None,
- reset=0, reset_local_roles=0, reset_workflow=0, simulate=0, **kw):
+ def _createContent(self, xml=None, object=None, object_id=None,
+ sub_object=None, reset_local_roles=False,
+ reset_workflow=False, simulate=False, **kw):
"""
This is the method calling to create an object
"""
@@ -1056,8 +1060,6 @@
portal_type = ''
if xml.xpath('local-name()') == self.xml_object_tag:
portal_type = self.getObjectType(xml)
- elif xml.xpath('name()') in self.XUPDATE_INSERT_OR_ADD: # Deprecated ???
- portal_type = self.getXupdateObjectType(xml) # Deprecated ???
sub_object, reset_local_roles, reset_workflow = self.constructContent(
object,
object_id,
@@ -1065,7 +1067,6 @@
self.newObject(object=sub_object,
xml=xml,
simulate=simulate,
- reset=reset,
reset_local_roles=reset_local_roles,
reset_workflow=reset_workflow)
return sub_object
More information about the Erp5-report
mailing list