Commit 9b22e41d authored by Sebastien Robin's avatar Sebastien Robin

by Fabien, use the library Ft.Xml instead of xml.dom.minidom in order to make...

by Fabien, use the library Ft.Xml instead of xml.dom.minidom in order to make synchronization faster, and use xpath exression, this make the code much more cleaner

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@14478 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent c08f67d8
...@@ -33,8 +33,7 @@ from Products.CMFCore.utils import getToolByName ...@@ -33,8 +33,7 @@ from Products.CMFCore.utils import getToolByName
from Products.ERP5SyncML.XupdateUtils import XupdateUtils from Products.ERP5SyncML.XupdateUtils import XupdateUtils
from Products.ERP5Type.Utils import convertToUpperCase from Products.ERP5Type.Utils import convertToUpperCase
from Products.ERP5Type.Accessor.TypeDefinition import list_types from Products.ERP5Type.Accessor.TypeDefinition import list_types
from xml.dom.ext.reader.Sax2 import FromXml from Ft.Xml import Parse
from xml.dom.minidom import parse, parseString
from DateTime.DateTime import DateTime from DateTime.DateTime import DateTime
from email.MIMEBase import MIMEBase from email.MIMEBase import MIMEBase
from email import Encoders from email import Encoders
...@@ -44,10 +43,12 @@ from Products.ERP5Type import Permissions ...@@ -44,10 +43,12 @@ from Products.ERP5Type import Permissions
from Globals import PersistentMapping from Globals import PersistentMapping
import pickle import pickle
import string import string
from xml.dom.ext import PrettyPrint
from cStringIO import StringIO from cStringIO import StringIO
from xml.sax.saxutils import escape, unescape from xml.sax.saxutils import escape, unescape
import re, copy import re, copy
import cStringIO
from Ft.Xml.Domlette import Print, PrettyPrint
from zLOG import LOG from zLOG import LOG
...@@ -132,7 +133,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -132,7 +133,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
return {'conflict_list':conflict_list, 'object':sub_object} return {'conflict_list':conflict_list, 'object':sub_object}
LOG('addNode',0,'xml_reconstitued: %s' % str(xml)) LOG('addNode',0,'xml_reconstitued: %s' % str(xml))
# In the case where this new node is a object to add # In the case where this new node is a object to add
if xml.nodeName in self.XUPDATE_INSERT_OR_ADD and self.getSubObjectDepth(xml)==0: if xml.nodeName in self.XUPDATE_INSERT_OR_ADD and \
self.getSubObjectDepth(xml)==0:
if self.isHistoryAdd(xml)!=-1: # bad hack XXX to be removed if self.isHistoryAdd(xml)!=-1: # bad hack XXX to be removed
for element in self.getXupdateElementList(xml): for element in self.getXupdateElementList(xml):
xml = self.getElementFromXupdate(element) xml = self.getElementFromXupdate(element)
...@@ -160,7 +162,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -160,7 +162,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
portal_type = self.getObjectType(xml) portal_type = self.getObjectType(xml)
elif xml.nodeName in self.XUPDATE_INSERT_OR_ADD: # Deprecated ??? elif xml.nodeName in self.XUPDATE_INSERT_OR_ADD: # Deprecated ???
portal_type = self.getXupdateObjectType(xml) # Deprecated ??? portal_type = self.getXupdateObjectType(xml) # Deprecated ???
sub_object = self.constructContent(object, object_id, docid, portal_type) sub_object = self.constructContent(object, object_id, docid,
portal_type)
self.newObject( self.newObject(
object=sub_object, object=sub_object,
xml=xml, xml=xml,
...@@ -274,9 +277,9 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -274,9 +277,9 @@ class ERP5Conduit(XMLSyncUtilsMixin):
LOG('updateNode, force: ',0,force) LOG('updateNode, force: ',0,force)
# we have an xupdate xml # we have an xupdate xml
if xml.nodeName == 'xupdate:modifications': if xml.nodeName == 'xupdate:modifications':
conflict_list += self.applyXupdate(object=object,xupdate=xml,conduit=self, conflict_list += self.applyXupdate(object=object, xupdate=xml,
previous_xml=previous_xml, force=force, simulate=simulate, conduit=self,previous_xml=previous_xml, force=force,
**kw) simulate=simulate, **kw)
# we may have only the part of an xupdate # we may have only the part of an xupdate
else: else:
args = {} args = {}
...@@ -342,7 +345,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -342,7 +345,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
# - current_data : the data actually on this box # - current_data : the data actually on this box
isConflict = 0 isConflict = 0
if (previous_xml is not None) and (not force): # if no previous_xml, no conflict 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) old_data = self.getObjectProperty(keyword, previous_xml,
data_type=data_type)
#current_data = object.getProperty(keyword) #current_data = object.getProperty(keyword)
current_data = self.getProperty(object, keyword) current_data = self.getProperty(object, keyword)
LOG('updateNode',0,'Conflict data: %s' % str(data)) LOG('updateNode',0,'Conflict data: %s' % str(data))
...@@ -383,8 +387,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -383,8 +387,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if keyword == 'object': if keyword == 'object':
# This is the case where we have to call addNode # This is the case where we have to call addNode
LOG('updateNode',0,'we will add sub-object') LOG('updateNode',0,'we will add sub-object')
conflict_list += self.addNode(xml=xml,object=object,force=force, conflict_list += self.addNode(xml=xml, object=object, force=force, simulate=simulate, **kw)['conflict_list']
simulate=simulate, **kw)['conflict_list']
elif keyword == self.history_tag and not simulate: elif keyword == self.history_tag and not simulate:
# This is the case where we have to call addNode # This is the case where we have to call addNode
LOG('updateNode',0,'we will add history') LOG('updateNode',0,'we will add history')
...@@ -397,8 +400,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -397,8 +400,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
#roles = self.convertXmlValue(data,data_type='tokens') #roles = self.convertXmlValue(data,data_type='tokens')
#object.manage_setLocalRoles(user,roles) #object.manage_setLocalRoles(user,roles)
xml = self.getElementFromXupdate(xml) xml = self.getElementFromXupdate(xml)
conflict_list += self.addNode(xml=xml,object=object,force=force, conflict_list += self.addNode(xml=xml, object=object, force=force,
simulate=simulate,**kw)['conflict_list'] simulate=simulate,**kw)['conflict_list']
elif self.isSubObjectModification(xml): elif self.isSubObjectModification(xml):
# We should find the object corresponding to # We should find the object corresponding to
# this update, so we have to look in the previous_xml # this update, so we have to look in the previous_xml
...@@ -421,8 +424,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -421,8 +424,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
sub_xml = self.getSubObjectXupdate(xml) sub_xml = self.getSubObjectXupdate(xml)
LOG('updateNode',0,'sub_xml: %s' % str(sub_xml)) LOG('updateNode',0,'sub_xml: %s' % str(sub_xml))
# Then do the udpate # Then do the udpate
conflict_list += self.updateNode(xml=sub_xml,object=sub_object, force=force, conflict_list += self.updateNode(xml=sub_xml, object=sub_object, force=force,
previous_xml=sub_previous_xml,simulate=simulate, **kw) previous_xml=sub_previous_xml, simulate=simulate, **kw)
elif previous_xml is None and xml is not None and sub_object_id is not None: elif previous_xml is None and xml is not None and sub_object_id is not None:
sub_object = None sub_object = None
try: try:
...@@ -438,7 +441,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -438,7 +441,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
**kw) **kw)
return conflict_list return conflict_list
security.declareProtected(Permissions.AccessContentsInformation,'getFormatedArgs') security.declareProtected(Permissions.AccessContentsInformation,
'getFormatedArgs')
def getFormatedArgs(self, args=None): def getFormatedArgs(self, args=None):
""" """
This lookd inside the args dictionnary and then This lookd inside the args dictionnary and then
...@@ -484,19 +488,21 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -484,19 +488,21 @@ class ERP5Conduit(XMLSyncUtilsMixin):
return 0 return 0
return 1 return 1
security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectXupdate') security.declareProtected(Permissions.AccessContentsInformation,
'getSubObjectXupdate')
def getSubObjectXupdate(self, xml): def getSubObjectXupdate(self, xml):
""" """
This will change the xml in order to change the update This will change the xml in order to change the update
from the object to the subobject from the object to the subobject
""" """
xml = copy.deepcopy(xml) xml_copy = xml.cloneNode(True) #make a deepcopy of the node xml
for subnode in self.getAttributeNodeList(xml): for subnode in self.getAttributeNodeList(xml_copy):
if subnode.nodeName=='select': if subnode.nodeName=='select':
subnode.nodeValue = self.getSubObjectSelect(subnode.nodeValue) subnode.nodeValue = self.getSubObjectSelect(subnode.nodeValue)
return xml return xml_copy
security.declareProtected(Permissions.AccessContentsInformation,'isHistoryAdd') security.declareProtected(Permissions.AccessContentsInformation,
'isHistoryAdd')
def isHistoryAdd(self, xml): def isHistoryAdd(self, xml):
bad_list = (self.history_exp,) bad_list = (self.history_exp,)
for subnode in self.getAttributeNodeList(xml): for subnode in self.getAttributeNodeList(xml):
...@@ -510,7 +516,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -510,7 +516,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
return -1 return -1
return 0 return 0
security.declareProtected(Permissions.AccessContentsInformation,'isSubObjectModification') security.declareProtected(Permissions.AccessContentsInformation,
'isSubObjectModification')
def isSubObjectModification(self, xml): def isSubObjectModification(self, xml):
""" """
Check if it is a modification from an subobject Check if it is a modification from an subobject
...@@ -524,7 +531,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -524,7 +531,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
return 1 return 1
return 0 return 0
security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectDepth') security.declareProtected(Permissions.AccessContentsInformation,
'getSubObjectDepth')
def getSubObjectDepth(self, xml): def getSubObjectDepth(self, xml):
""" """
Give the Depth of a subobject modification Give the Depth of a subobject modification
...@@ -555,7 +563,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -555,7 +563,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
return (1 - i) return (1 - i)
return 0 return 0
security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectSelect') security.declareProtected(Permissions.AccessContentsInformation,
'getSubObjectSelect')
def getSubObjectSelect(self, select): def getSubObjectSelect(self, select):
""" """
Return a string wich is the selection for the subobject Return a string wich is the selection for the subobject
...@@ -571,7 +580,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -571,7 +580,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
select = new_value select = new_value
return select return select
security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectId') security.declareProtected(Permissions.AccessContentsInformation,
'getSubObjectId')
def getSubObjectId(self, xml): def getSubObjectId(self, xml):
""" """
Return the id of the subobject in an xupdate modification Return the id of the subobject in an xupdate modification
...@@ -587,7 +597,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -587,7 +597,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
return object_id return object_id
return object_id return object_id
security.declareProtected(Permissions.AccessContentsInformation,'getHistoryIdFromSelect') security.declareProtected(Permissions.AccessContentsInformation,
'getHistoryIdFromSelect')
def getHistoryIdFromSelect(self, xml): def getHistoryIdFromSelect(self, xml):
""" """
Return the id of the subobject in an xupdate modification Return the id of the subobject in an xupdate modification
...@@ -604,7 +615,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -604,7 +615,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
return object_id return object_id
return object_id return object_id
security.declareProtected(Permissions.AccessContentsInformation,'getSubObjectXml') security.declareProtected(Permissions.AccessContentsInformation,
'getSubObjectXml')
def getSubObjectXml(self, object_id, xml): def getSubObjectXml(self, object_id, xml):
""" """
Return the xml of the subobject which as the id object_id Return the xml of the subobject which as the id object_id
...@@ -624,7 +636,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -624,7 +636,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
""" """
for attribute in self.getAttributeNodeList(xml): for attribute in self.getAttributeNodeList(xml):
if attribute.nodeName == param: if attribute.nodeName == param:
data = attribute.childNodes[0].data data = attribute.value
return self.convertXmlValue(data,data_type='string') return self.convertXmlValue(data,data_type='string')
return None return None
...@@ -635,7 +647,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -635,7 +647,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
""" """
for subnode in self.getElementNodeList(xml): for subnode in self.getElementNodeList(xml):
if subnode.nodeName == 'docid': if subnode.nodeName == 'docid':
data = subnode.childNodes[0].data data = subnode.childNodes[0].value
return self.convertXmlValue(data) return self.convertXmlValue(data)
return None return None
...@@ -669,7 +681,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -669,7 +681,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
LOG('Conduit.convertToXml xml',0,repr(xml)) LOG('Conduit.convertToXml xml',0,repr(xml))
if type(xml) is type(u'a'): if type(xml) is type(u'a'):
xml = xml.encode('utf-8') xml = xml.encode('utf-8')
xml = parseString(xml) xml = Parse(xml)
LOG('Conduit.convertToXml not failed',0,'ok') LOG('Conduit.convertToXml not failed',0,'ok')
xml = xml.childNodes[0] # Because we just created a new xml xml = xml.childNodes[0] # Because we just created a new xml
# If we have the xml from the node erp5, we just take the subnode # If we have the xml from the node erp5, we just take the subnode
...@@ -811,7 +823,8 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -811,7 +823,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
#PrettyPrint(xml,xml_string) #PrettyPrint(xml,xml_string)
#xml_string = xml_string.getvalue() #xml_string = xml_string.getvalue()
#xml_string = unicode(xml_string,encoding='utf-8') #xml_string = unicode(xml_string,encoding='utf-8')
xml_string = xml.toxml(encoding='utf-8') xml_string = self.nodeToString(xml)
#xml_string = xml.toxml(encoding='utf-8')
xml_string = unicode(xml_string,encoding='utf-8') xml_string = unicode(xml_string,encoding='utf-8')
#if type(xml_string) is type (u'a'): #if type(xml_string) is type (u'a'):
# xml_string = xml_string.encode('utf-8') # xml_string = xml_string.encode('utf-8')
...@@ -845,7 +858,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -845,7 +858,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
#PrettyPrint(xml,xml_string) #PrettyPrint(xml,xml_string)
#xml_string = xml_string.getvalue() #xml_string = xml_string.getvalue()
#xml_string = unicode(xml_string,encoding='utf-8') #xml_string = unicode(xml_string,encoding='utf-8')
xml_string = xml.toxml(encoding='utf-8') xml_string = self.nodeToString(xml)
xml_string = unicode(xml_string,encoding='utf-8') xml_string = unicode(xml_string,encoding='utf-8')
maxi = xml_string.find('>')+1 maxi = xml_string.find('>')+1
result += xml_string[maxi:xml_string.find('</%s>' % xml.nodeName)] result += xml_string[maxi:xml_string.find('</%s>' % xml.nodeName)]
...@@ -929,7 +942,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -929,7 +942,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
""" """
conflict_list = [] conflict_list = []
if type(xupdate) in (type('a'),type(u'a')): if type(xupdate) in (type('a'),type(u'a')):
xupdate = parseString(xupdate) xupdate = Parse(xupdate)
#When xupdate mix different object, (like object and his subobject) we need to treat them separatly #When xupdate mix different object, (like object and his subobject) we need to treat them separatly
if self.isMixedXupdate(xupdate): if self.isMixedXupdate(xupdate):
#return to updateNode with only one line #return to updateNode with only one line
...@@ -967,7 +980,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -967,7 +980,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
nb_sub = len(subnode_list) nb_sub = len(subnode_list)
comp = 0 comp = 0
for subnode in subnode_list: for subnode in subnode_list:
value = subnode.getAttribute('select') value = self.getAttribute(subnode, 'select')
if re.search(self.object_exp, value): if re.search(self.object_exp, value):
comp += 1 comp += 1
if nb_sub == comp: if nb_sub == comp:
...@@ -1043,7 +1056,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -1043,7 +1056,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if wf_id is None: # History added by xupdate if wf_id is None: # History added by xupdate
wf_id = self.getHistoryIdFromSelect(xml) wf_id = self.getHistoryIdFromSelect(xml)
LOG('addNode, workflow_history id:',0,wf_id) LOG('addNode, workflow_history id:',0,wf_id)
LOG('addNode, workflow_history xml:',0,xml.toxml()) #LOG('addNode, workflow_history xml:',0,xml.toxml())#toxml isn't in 4Suite
LOG('addNode, workflow_history xml.getElmentNodeList:',0,self.getElementNodeList(xml)) LOG('addNode, workflow_history xml.getElmentNodeList:',0,self.getElementNodeList(xml))
xml = self.getElementNodeList(xml)[0] xml = self.getElementNodeList(xml)[0]
LOG('addNode, workflow_history id:',0,wf_id) LOG('addNode, workflow_history id:',0,wf_id)
...@@ -1152,3 +1165,13 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -1152,3 +1165,13 @@ class ERP5Conduit(XMLSyncUtilsMixin):
# conflict.setRemoteValue(status) # conflict.setRemoteValue(status)
# conflict_list += [conflict] # conflict_list += [conflict]
# return conflict_list # return conflict_list
def nodeToString(self, node):
"""
return an xml string corresponding to the node
"""
buf = cStringIO.StringIO()
Print(node, stream=buf, encoding='utf-8')
xml_string = buf.getvalue()
buf.close()
return xml_string
...@@ -29,8 +29,7 @@ ...@@ -29,8 +29,7 @@
import smtplib # to send emails import smtplib # to send emails
from Publication import Publication,Subscriber from Publication import Publication,Subscriber
from Subscription import Signature from Subscription import Signature
from xml.dom.ext.reader.Sax2 import FromXmlStream, FromXml from Ft.Xml import Parse
from xml.dom.minidom import parse, parseString
from XMLSyncUtils import XMLSyncUtils from XMLSyncUtils import XMLSyncUtils
from Conduit.ERP5Conduit import ERP5Conduit from Conduit.ERP5Conduit import ERP5Conduit
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
...@@ -221,7 +220,7 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -221,7 +220,7 @@ class PublicationSynchronization(XMLSyncUtils):
if xml_client is not None: if xml_client is not None:
if isinstance(xml_client, str) or isinstance(xml_client, unicode): if isinstance(xml_client, str) or isinstance(xml_client, unicode):
xml_client = parseString(xml_client) xml_client = Parse(xml_client)
first_node = xml_client.childNodes[0] first_node = xml_client.childNodes[0]
if first_node.nodeName != "SyncML": if first_node.nodeName != "SyncML":
......
...@@ -28,9 +28,7 @@ ...@@ -28,9 +28,7 @@
import smtplib # to send emails import smtplib # to send emails
from Subscription import Subscription,Signature from Subscription import Subscription,Signature
from xml.dom.ext.reader.Sax2 import FromXmlStream, FromXml from Ft.Xml import Parse
from xml.dom.minidom import parse, parseString
from xml.dom.ext import PrettyPrint
from XMLSyncUtils import XMLSyncUtils from XMLSyncUtils import XMLSyncUtils
import commands import commands
from Conduit.ERP5Conduit import ERP5Conduit from Conduit.ERP5Conduit import ERP5Conduit
...@@ -99,7 +97,7 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -99,7 +97,7 @@ class SubscriptionSynchronization(XMLSyncUtils):
else: else:
xml_client = msg xml_client = msg
if isinstance(xml_client, str) or isinstance(xml_client, unicode): if isinstance(xml_client, str) or isinstance(xml_client, unicode):
xml_client = parseString(xml_client) xml_client = Parse(xml_client)
next_status = self.getNextSyncBodyStatus(xml_client, None) next_status = self.getNextSyncBodyStatus(xml_client, None)
#LOG('readResponse, next status :',0,next_status) #LOG('readResponse, next status :',0,next_status)
if next_status is not None: if next_status is not None:
......
...@@ -40,8 +40,7 @@ from Products.ERP5SyncML import Conduit ...@@ -40,8 +40,7 @@ from Products.ERP5SyncML import Conduit
from Publication import Publication,Subscriber from Publication import Publication,Subscriber
from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2 from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2
from Subscription import Subscription,Signature from Subscription import Subscription,Signature
from xml.dom.ext.reader.Sax2 import FromXmlStream, FromXml from Ft.Xml import Parse
from xml.dom.minidom import parse, parseString
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from PublicationSynchronization import PublicationSynchronization from PublicationSynchronization import PublicationSynchronization
from SubscriptionSynchronization import SubscriptionSynchronization from SubscriptionSynchronization import SubscriptionSynchronization
...@@ -50,7 +49,6 @@ from AccessControl.SecurityManagement import newSecurityManager ...@@ -50,7 +49,6 @@ from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.User import UnrestrictedUser from AccessControl.User import UnrestrictedUser
from Acquisition import aq_base from Acquisition import aq_base
from xml.parsers.expat import ExpatError # parseString error
import urllib import urllib
import urllib2 import urllib2
import socket import socket
...@@ -974,7 +972,7 @@ class SynchronizationTool( SubscriptionSynchronization, ...@@ -974,7 +972,7 @@ class SynchronizationTool( SubscriptionSynchronization,
commands.getstatusoutput('rm -f /tmp/%s.gz.gpg' % filename) commands.getstatusoutput('rm -f /tmp/%s.gz.gpg' % filename)
# Get the target and then find the corresponding publication or # Get the target and then find the corresponding publication or
# Subscription # Subscription
xml = parseString(text) xml = Parse(text)
#XXX this function is not very optimized and should be improved #XXX this function is not very optimized and should be improved
url = self.getTarget(xml) url = self.getTarget(xml)
for publication in self.getPublicationList(): for publication in self.getPublicationList():
......
...@@ -29,8 +29,7 @@ ...@@ -29,8 +29,7 @@
import smtplib import smtplib
from Products.ERP5SyncML.SyncCode import SyncCode from Products.ERP5SyncML.SyncCode import SyncCode
from Products.ERP5SyncML.Subscription import Signature from Products.ERP5SyncML.Subscription import Signature
from xml.dom.ext.reader.Sax2 import FromXml from Ft.Xml import Parse
from xml.dom.minidom import parse, parseString
from DateTime import DateTime from DateTime import DateTime
from cStringIO import StringIO from cStringIO import StringIO
from xml.dom.ext import PrettyPrint from xml.dom.ext import PrettyPrint
...@@ -301,28 +300,17 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -301,28 +300,17 @@ class XMLSyncUtilsMixin(SyncCode):
We will retrieve the session id of the message We will retrieve the session id of the message
""" """
session_id = 0 session_id = 0
for subnode in self.getElementNodeList(xml): session_id = xml.xpath('string(/SyncML/SyncHdr/SessionID)')
if subnode.nodeName == 'SyncML': session_id = int(session_id)
for subnode1 in self.getElementNodeList(subnode):
if subnode1.nodeName == 'SyncHdr':
for subnode2 in self.getElementNodeList(subnode1):
if subnode2.nodeName == 'SessionID':
session_id = int(subnode2.childNodes[0].data)
return session_id return session_id
def getMessageId(self, xml): def getMessageId(self, xml):
""" """
We will retrieve the message id of the message We will retrieve the message id of the message
""" """
message_id = 0 message_id = 0
for subnode in self.getElementNodeList(xml): message_id = xml.xpath('string(/SyncML/SyncHdr/MsgID)')
if subnode.nodeName == 'SyncML': message_id = int(message_id)
for subnode1 in self.getElementNodeList(subnode):
if subnode1.nodeName == 'SyncHdr':
for subnode2 in self.getElementNodeList(subnode1):
if subnode2.nodeName == 'MsgID':
message_id = int(subnode2.childNodes[0].data)
return message_id return message_id
def getTarget(self, xml): def getTarget(self, xml):
...@@ -330,18 +318,10 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -330,18 +318,10 @@ class XMLSyncUtilsMixin(SyncCode):
return the target in the SyncHdr section return the target in the SyncHdr section
""" """
url = '' url = ''
for subnode in self.getElementNodeList(xml): url = xml.xpath('string(/SyncML/SyncHdr/Target/LocURI)')
if subnode.nodeName == 'SyncML': url = url.encode('utf-8')
for subnode1 in self.getElementNodeList(subnode):
if subnode1.nodeName == 'SyncHdr':
for subnode2 in self.getElementNodeList(subnode1):
if subnode2.nodeName == 'Target':
for subnode3 in self.getElementNodeList(subnode2):
if subnode3.nodeName == 'LocURI':
url = subnode3.childNodes[0].data
return url return url
def getAlertLastAnchor(self, xml_stream): def getAlertLastAnchor(self, xml_stream):
""" """
Return the value of the last anchor, in the Return the value of the last anchor, in the
...@@ -351,23 +331,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -351,23 +331,8 @@ class XMLSyncUtilsMixin(SyncCode):
# Get informations from the body # Get informations from the body
client_body = first_node.childNodes[3] client_body = first_node.childNodes[3]
for subnode in client_body.childNodes: last_anchor = client_body.xpath('string(/Alert/Item/Meta/Anchor/Last)')
if subnode.nodeType == subnode.ELEMENT_NODE and \ last_anchor = last_anchor.encode('utf-8')
subnode.nodeName == "Alert":
for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == "Item":
for subnode3 in subnode2.childNodes:
if subnode3.nodeType == subnode3.ELEMENT_NODE and \
subnode3.nodeName == "Meta":
for subnode4 in subnode3.childNodes:
if subnode4.nodeType == subnode4.ELEMENT_NODE and \
subnode4.nodeName == "Anchor":
for subnode5 in subnode4.childNodes:
# Get the last time we had a synchronization
if subnode5.nodeType == subnode5.ELEMENT_NODE and \
subnode5.nodeName == "Last":
last_anchor = subnode5.childNodes[0].data
return last_anchor return last_anchor
def getAlertNextAnchor(self, xml_stream): def getAlertNextAnchor(self, xml_stream):
...@@ -381,61 +346,33 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -381,61 +346,33 @@ class XMLSyncUtilsMixin(SyncCode):
# Get informations from the body # Get informations from the body
client_body = first_node.childNodes[3] client_body = first_node.childNodes[3]
if client_body.nodeName != "SyncBody": next_anchor = client_body.xpath('string(/Alert/Item/Meta/Anchor/Next)')
print "This is not a SyncML Body" next_anchor = next_anchor.encode('utf-8')
for subnode in client_body.childNodes: return next_anchor
if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == "Alert":
for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == "Item":
for subnode3 in subnode2.childNodes:
if subnode3.nodeType == subnode3.ELEMENT_NODE and \
subnode3.nodeName == "Meta":
for subnode4 in subnode3.childNodes:
if subnode4.nodeType == subnode4.ELEMENT_NODE and \
subnode4.nodeName == "Anchor":
for subnode5 in subnode4.childNodes:
# Get the last time we had a synchronization
if subnode5.nodeType == subnode5.ELEMENT_NODE and \
subnode5.nodeName == "Next":
next_anchor = subnode5.childNodes[0].data
return next_anchor
def getStatusTarget(self, xml): def getStatusTarget(self, xml):
""" """
Return the value of the alert code inside the xml_stream Return the value of the alert code inside the xml_stream
""" """
# Get informations from the body return xml.xpath('string(TargetRef)')
if xml.nodeName=='Status':
for subnode in xml.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == 'TargetRef':
return subnode.childNodes[0].data
return None
def getStatusCode(self, xml): def getStatusCode(self, xml):
""" """
Return the value of the alert code inside the xml_stream Return the value of the alert code inside the xml_stream
""" """
# Get informations from the body status_code = xml.xpath('string(Data)')
if xml.nodeName=='Status': if status_code not in ('', None, []):
for subnode in xml.childNodes: return int(status_code)
if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == 'Data':
return int(subnode.childNodes[0].data)
return None return None
def getStatusCommand(self, xml): def getStatusCommand(self, xml):
""" """
Return the value of the command inside the xml_stream Return the value of the command inside the xml_stream
""" """
# Get informations from the body
if xml.nodeName=='Status': if xml.nodeName=='Status':
for subnode in xml.childNodes: return xml.xpath('string(//Status/Cmd)')
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Cmd': else:
return subnode.childNodes[0].data return None
return None
def getCred(self, xml): def getCred(self, xml):
""" """
...@@ -444,111 +381,61 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -444,111 +381,61 @@ class XMLSyncUtilsMixin(SyncCode):
format='' format=''
type='' type=''
data='' data=''
first_node = xml.childNodes[0] first_node = xml.childNodes[0]
if first_node.nodeName != "SyncML": format = first_node.xpath('string(/SyncML/SyncHdr/Cred/Meta/Format)')
print "This is not a SyncML message" type = first_node.xpath('string(/SyncML/SyncHdr/Cred/Meta/Type)')
# Get informations from the header data = first_node.xpath('string(/SyncML/SyncHdr/Cred/Data)')
xml_header = first_node.childNodes[1]
if xml_header.nodeName != "SyncHdr":
LOG('PubSyncModif',0,'This is not a SyncML Header')
raise ValueError, "Sorry, This is not a SyncML Header"
for subnode in xml_header.childNodes: format = format.encode('utf-8')
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName=='Cred': type = type.encode('utf-8')
for subnode2 in subnode.childNodes: data = data.encode('utf-8')
if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == 'Meta':
for subnode3 in subnode2.childNodes:
if subnode3.nodeType == subnode3.ELEMENT_NODE and \
subnode3.nodeName == 'Format':
if len(subnode3.childNodes) > 0:
format=subnode3.childNodes[0].data
if subnode3.nodeType == subnode3.ELEMENT_NODE and \
subnode3.nodeName == 'Type':
if len(subnode3.childNodes) > 0:
type=subnode3.childNodes[0].data
if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == 'Data':
if len(subnode2.childNodes) > 0:
data=subnode2.childNodes[0].data
return (format, type, data) return (format, type, data)
def getAlertCode(self, xml_stream): def getAlertCode(self, xml_stream):
""" """
Return the value of the alert code inside the full syncml message Return the value of the alert code inside the full syncml message
""" """
# Get informations from the body alert_code = xml_stream.xpath('string(SyncML/SyncBody/Alert/Data)')
first_node = xml_stream.childNodes[0] if alert_code not in (None, ''):
client_body = first_node.childNodes[3] return int(alert_code)
if client_body.nodeName != "SyncBody": else:
LOG('XMLSyncUtils.getAlertCode',0,"This is not a SyncML Body") return None
raise ValueError, "Sorry, This is not a SyncML Body"
alert = 0
for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName=='Alert':
for subnode1 in subnode.childNodes:
if subnode1.nodeType == subnode1.ELEMENT_NODE and subnode1.nodeName == 'Data':
return int(subnode1.childNodes[0].data)
return None
def checkCred(self, xml_stream): def checkCred(self, xml_stream):
""" """
Check if there's a Cred section in the xml_stream Check if there's a Cred section in the xml_stream
""" """
first_node = xml_stream.childNodes[0] cred = False
# Get informations from the header if xml_stream.xpath('string(SyncML/SyncHdr/Cred)') not in ('', None, []):
xml_header = first_node.childNodes[1] cred = True
if xml_header.nodeName != "SyncHdr":
LOG('PubSyncModif',0,'This is not a SyncML Header')
raise ValueError, "Sorry, This is not a SyncML Header"
cred = 0
for subnode in xml_header.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Cred":
cred=1
return cred return cred
def checkAlert(self, xml_stream): def checkAlert(self, xml_stream):
""" """
Check if there's an Alert section in the xml_stream Check if there's an Alert section in the xml_stream
""" """
first_node = xml_stream.childNodes[0] alert = False
client_body = first_node.childNodes[3] if xml_stream.xpath('string(SyncML/SyncBody/Alert)') not in ('', None, []):
if client_body.nodeName != "SyncBody": alert = True
print "This is not a SyncML Body"
alert = 0
for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Alert":
alert = 1
return alert return alert
def checkSync(self, xml_stream): def checkSync(self, xml_stream):
""" """
Check if there's an Sync section in the xml_xtream Check if there's an Sync section in the xml_xtream
""" """
first_node = xml_stream.childNodes[0] sync = False
client_body = first_node.childNodes[3] if xml_stream.xpath('string(SyncML/SyncBody/Sync)') not in ('', None, []):
if client_body.nodeName != "SyncBody": sync = True
LOG('checkSync',0,"This is not a SyncML Body") return sync
raise ValueError, "Sorry, This is not a SyncML Body"
for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Sync":
return 1
return 0
def CheckStatus(self, xml_stream): def CheckStatus(self, xml_stream):
""" """
Check if there's a Status section in the xml_xtream Check if there's a Status section in the xml_xtream
""" """
first_node = xml_stream.childNodes[0] status = False
client_body = first_node.childNodes[3] if xml_stream.xpath('string(SyncML/SyncBody/Status)') not in ('', None, []):
if client_body.nodeName != "SyncBody": status = True
print "This is not a SyncML Body"
status = None
for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Status":
status = "1"
return status return status
def getNextSyncAction(self, xml_stream, last_action): def getNextSyncAction(self, xml_stream, last_action):
...@@ -563,18 +450,22 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -563,18 +450,22 @@ class XMLSyncUtilsMixin(SyncCode):
print "This is not a SyncML Body" print "This is not a SyncML Body"
next_action = None next_action = None
for subnode in client_body.childNodes: for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Sync": if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == "Sync":
# if we didn't use this method before # if we didn't use this method before
if last_action == None and len(subnode.childNodes) > 1: if last_action == None and len(subnode.childNodes) > 1:
next_action = subnode.childNodes[1] next_action = subnode.childNodes[1]
else: else:
found = None found = None
for subnode2 in subnode.childNodes: for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode.ELEMENT_NODE and subnode2 != last_action and found is None: if subnode2.nodeType == subnode.ELEMENT_NODE and \
subnode2 != last_action and found is None:
pass pass
elif subnode2.nodeType == subnode.ELEMENT_NODE and subnode2 == last_action and found is None: elif subnode2.nodeType == subnode.ELEMENT_NODE and \
subnode2 == last_action and found is None:
found = 1 found = 1
elif subnode2.nodeType == subnode.ELEMENT_NODE and found is not None: elif subnode2.nodeType == subnode.ELEMENT_NODE and \
found is not None:
next_action = subnode2 next_action = subnode2
break break
return next_action return next_action
...@@ -593,7 +484,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -593,7 +484,8 @@ class XMLSyncUtilsMixin(SyncCode):
next_status = None next_status = None
found = None found = None
for subnode in client_body.childNodes: for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Status": if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == "Status":
# if we didn't use this method before # if we didn't use this method before
if last_status == None: if last_status == None:
next_status = subnode next_status = subnode
...@@ -609,9 +501,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -609,9 +501,11 @@ class XMLSyncUtilsMixin(SyncCode):
Return the node starting with <object....> of the action Return the node starting with <object....> of the action
""" """
for subnode in action.childNodes: for subnode in action.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item': if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == 'Item':
for subnode2 in subnode.childNodes: for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Data': if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == 'Data':
for subnode3 in subnode2.childNodes: for subnode3 in subnode2.childNodes:
#if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'object': #if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'object':
if subnode3.nodeType == subnode3.ELEMENT_NODE: if subnode3.nodeType == subnode3.ELEMENT_NODE:
...@@ -622,9 +516,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -622,9 +516,11 @@ class XMLSyncUtilsMixin(SyncCode):
Return the node starting with <object....> of the action Return the node starting with <object....> of the action
""" """
for subnode in action.childNodes: for subnode in action.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item': if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == 'Item':
for subnode2 in subnode.childNodes: for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Data': if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == 'Data':
for subnode3 in subnode2.childNodes: for subnode3 in subnode2.childNodes:
#if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'object': #if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'object':
if subnode3.nodeType == subnode3.COMMENT_NODE: if subnode3.nodeType == subnode3.COMMENT_NODE:
...@@ -639,60 +535,40 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -639,60 +535,40 @@ class XMLSyncUtilsMixin(SyncCode):
return None return None
def getAttributeNodeList(self, node):
"""
Return attributesNodes that are ElementNode XXX may be not needed at all
"""
subnode_list = []
for subnode in node.attributes:
if subnode.nodeType == subnode.ATTRIBUTE_NODE:
subnode_list += [subnode]
return subnode_list
def getActionId(self, action): def getActionId(self, action):
""" """
Return the rid of the object described by the action Return the rid of the object described by the action
""" """
for subnode in action.childNodes: for subnode in action.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item': if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == 'Item':
for subnode2 in subnode.childNodes: for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Source': if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == 'Source':
for subnode3 in subnode2.childNodes: for subnode3 in subnode2.childNodes:
if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'LocURI': if subnode3.nodeType == subnode3.ELEMENT_NODE and \
subnode3.nodeName == 'LocURI':
return str(subnode3.childNodes[0].data) return str(subnode3.childNodes[0].data)
def checkActionMoreData(self, action): def checkActionMoreData(self, action):
""" """
Return the rid of the object described by the action Return the rid of the object described by the action
""" """
for subnode in action.childNodes: if action.xpath('Item/MoreData'):
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item': return True
for subnode2 in subnode.childNodes: return False
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'MoreData':
return 1
return 0
def getActionType(self, action): def getActionType(self, action):
""" """
Return the type of the object described by the action Return the type of the object described by the action
""" """
for subnode in action.childNodes: return action.xpath('string(Meta/Type)')
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Meta':
for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Type':
return str(subnode2.childNodes[0].data)
def getElementNodeList(self, node): def getElementNodeList(self, node):
""" """
Return childNodes that are ElementNode Return childNodes that are ElementNode
""" """
#return node.getElementsByTagName('*') return node.xpath('*')
subnode_list = []
for subnode in node.childNodes or []:
if subnode.nodeType == subnode.ELEMENT_NODE:
subnode_list += [subnode]
return subnode_list
def getTextNodeList(self, node): def getTextNodeList(self, node):
""" """
...@@ -703,16 +579,12 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -703,16 +579,12 @@ class XMLSyncUtilsMixin(SyncCode):
if subnode.nodeType == subnode.TEXT_NODE: if subnode.nodeType == subnode.TEXT_NODE:
subnode_list += [subnode] subnode_list += [subnode]
return subnode_list return subnode_list
def getAttributeNodeList(self, node): def getAttributeNodeList(self, node):
""" """
Return childNodes that are ElementNode Return childNodes that are ElementNode
""" """
attribute_list = [] return node.xpath('@*')
for subnode in node.attributes.values() or []:
if subnode.nodeType == subnode.ATTRIBUTE_NODE:
attribute_list += [subnode]
return attribute_list
def getSyncMLData(self, domain=None,remote_xml=None,cmd_id=0, def getSyncMLData(self, domain=None,remote_xml=None,cmd_id=0,
subscriber=None,destination_path=None, subscriber=None,destination_path=None,
...@@ -765,7 +637,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -765,7 +637,8 @@ class XMLSyncUtilsMixin(SyncCode):
#if gid_generator is not None: #if gid_generator is not None:
# object_gid = gid_generator() # object_gid = gid_generator()
force = 0 force = 0
if syncml_data.count('\n') < self.MAX_LINES and not object.id.startswith('.'): # If not we have to cut if syncml_data.count('\n') < self.MAX_LINES and not \
object.id.startswith('.'): # If not we have to cut
#LOG('getSyncMLData',0,'xml_mapping: %s' % str(domain.xml_mapping)) #LOG('getSyncMLData',0,'xml_mapping: %s' % str(domain.xml_mapping))
#LOG('getSyncMLData',0,'code: %s' % str(self.getAlertCode(remote_xml))) #LOG('getSyncMLData',0,'code: %s' % str(self.getAlertCode(remote_xml)))
#LOG('getSyncMLData',0,'gid_list: %s' % str(local_gid_list)) #LOG('getSyncMLData',0,'gid_list: %s' % str(local_gid_list))
...@@ -781,11 +654,13 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -781,11 +654,13 @@ class XMLSyncUtilsMixin(SyncCode):
# For the case it was never synchronized, we have to send everything # For the case it was never synchronized, we have to send everything
if signature is not None and signature.getXMLMapping()==None: if signature is not None and signature.getXMLMapping()==None:
pass pass
elif signature==None or (signature.getXML()==None and signature.getStatus()!=self.PARTIAL) or \ elif signature == None or (signature.getXML() == None and \
self.getAlertCode(remote_xml)==self.SLOW_SYNC: signature.getStatus() != self.PARTIAL) or \
self.getAlertCode(remote_xml) == self.SLOW_SYNC:
#LOG('PubSyncModif',0,'Current object.getPath: %s' % object.getPath()) #LOG('PubSyncModif',0,'Current object.getPath: %s' % object.getPath())
LOG('getSyncMLData',0,'no signature for gid: %s' % object_gid) LOG('getSyncMLData',0,'no signature for gid: %s' % object_gid)
xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping) xml_object = self.getXMLObject(object=object,
xml_mapping=domain.xml_mapping)
xml_string = xml_object xml_string = xml_object
signature = Signature(gid=object_gid,id=object.getId(),object=object) signature = Signature(gid=object_gid,id=object.getId(),object=object)
signature.setTempXML(xml_object) signature.setTempXML(xml_object)
...@@ -806,14 +681,15 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -806,14 +681,15 @@ class XMLSyncUtilsMixin(SyncCode):
status =self.PARTIAL status =self.PARTIAL
signature.setAction('Add') signature.setAction('Add')
xml_string = '<!--' + short_string + '-->' xml_string = '<!--' + short_string + '-->'
syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object,gid=object_gid, syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object,
xml_string=xml_string, more_data=more_data) gid=object_gid, xml_string=xml_string, more_data=more_data)
cmd_id += 1 cmd_id += 1
signature.setStatus(status) signature.setStatus(status)
subscriber.addSignature(signature) subscriber.addSignature(signature)
elif signature.getStatus()==self.NOT_SYNCHRONIZED \ elif signature.getStatus()==self.NOT_SYNCHRONIZED \
or signature.getStatus()==self.PUB_CONFLICT_MERGE: # We don't have synchronized this object yet or signature.getStatus()==self.PUB_CONFLICT_MERGE: # We don't have synchronized this object yet
xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping) xml_object = self.getXMLObject(object=object,
xml_mapping=domain.xml_mapping)
#LOG('getSyncMLData',0,'checkMD5: %s' % str(signature.checkMD5(xml_object))) #LOG('getSyncMLData',0,'checkMD5: %s' % str(signature.checkMD5(xml_object)))
#LOG('getSyncMLData',0,'getStatus: %s' % str(signature.getStatus())) #LOG('getSyncMLData',0,'getStatus: %s' % str(signature.getStatus()))
if signature.getStatus()==self.PUB_CONFLICT_MERGE: if signature.getStatus()==self.PUB_CONFLICT_MERGE:
...@@ -842,8 +718,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -842,8 +718,8 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setAction('Replace') signature.setAction('Replace')
xml_string = '<!--' + short_string + '-->' xml_string = '<!--' + short_string + '-->'
signature.setStatus(status) signature.setStatus(status)
syncml_data += self.replaceXMLObject(cmd_id=cmd_id,object=object,gid=object_gid, syncml_data += self.replaceXMLObject(cmd_id=cmd_id, object=object,
xml_string=xml_string, more_data=more_data) gid=object_gid, xml_string=xml_string, more_data=more_data)
cmd_id += 1 cmd_id += 1
signature.setTempXML(xml_object) signature.setTempXML(xml_object)
# Now we can apply the xupdate from the subscriber # Now we can apply the xupdate from the subscriber
...@@ -851,10 +727,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -851,10 +727,11 @@ class XMLSyncUtilsMixin(SyncCode):
#LOG('getSyncMLData subscriber_xupdate',0,subscriber_xupdate) #LOG('getSyncMLData subscriber_xupdate',0,subscriber_xupdate)
if subscriber_xupdate is not None: if subscriber_xupdate is not None:
old_xml = signature.getXML() old_xml = signature.getXML()
conduit.updateNode(xml=subscriber_xupdate, object=object, conduit.updateNode(xml=subscriber_xupdate, object=object,
previous_xml=old_xml,force=(domain.getDomainType==self.SUB), previous_xml=old_xml, force=(domain.getDomainType==self.SUB),
simulate=0) simulate=0)
xml_object = self.getXMLObject(object=object,xml_mapping=domain.xml_mapping) xml_object = self.getXMLObject(object=object,
xml_mapping=domain.xml_mapping)
signature.setTempXML(xml_object) signature.setTempXML(xml_object)
if set_synchronized: # We have to do that after this previous update if set_synchronized: # We have to do that after this previous update
# We should not have this case when we are in CONFLICT_MERGE # We should not have this case when we are in CONFLICT_MERGE
...@@ -890,11 +767,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -890,11 +767,11 @@ class XMLSyncUtilsMixin(SyncCode):
xml_string = '<!--' + xml_string + '-->' xml_string = '<!--' + xml_string + '-->'
signature.setStatus(status) signature.setStatus(status)
if signature.getAction()=='Replace': if signature.getAction()=='Replace':
syncml_data += self.replaceXMLObject(cmd_id=cmd_id,object=object,gid=object_gid, syncml_data += self.replaceXMLObject(cmd_id=cmd_id, object=object,
xml_string=xml_string, more_data=more_data) gid=object_gid, xml_string=xml_string, more_data=more_data)
elif signature.getAction()=='Add': elif signature.getAction()=='Add':
syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object,gid=object_gid, syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object,
xml_string=xml_string, more_data=more_data) gid=object_gid, xml_string=xml_string, more_data=more_data)
return (syncml_data,xml_confirmation,cmd_id) return (syncml_data,xml_confirmation,cmd_id)
def applyActionList(self, domain=None, subscriber=None,destination_path=None, def applyActionList(self, domain=None, subscriber=None,destination_path=None,
...@@ -918,7 +795,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -918,7 +795,8 @@ class XMLSyncUtilsMixin(SyncCode):
object = domain.getObjectFromGid(object_gid) object = domain.getObjectFromGid(object_gid)
if signature == None: if signature == None:
LOG('applyActionList, signature is None',0,signature) LOG('applyActionList, signature is None',0,signature)
signature = Signature(gid=object_gid,status=self.NOT_SYNCHRONIZED,object=object).__of__(subscriber) signature = Signature(gid=object_gid, status=self.NOT_SYNCHRONIZED,
object=object).__of__(subscriber)
subscriber.addSignature(signature) subscriber.addSignature(signature)
force = signature.getForce() force = signature.getForce()
LOG('applyActionList',0,'object: %s' % repr(object)) LOG('applyActionList',0,'object: %s' % repr(object))
...@@ -932,7 +810,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -932,7 +810,7 @@ class XMLSyncUtilsMixin(SyncCode):
data_subnode = partial_data data_subnode = partial_data
LOG('SyncModif',0,'data_subnode: %s' % data_subnode) LOG('SyncModif',0,'data_subnode: %s' % data_subnode)
#data_subnode = FromXml(data_subnode) #data_subnode = FromXml(data_subnode)
data_subnode = parseString(data_subnode) data_subnode = Parse(data_subnode)
data_subnode = data_subnode.childNodes[0] # Because we just created a new xml data_subnode = data_subnode.childNodes[0] # Because we just created a new xml
# document, with childNodes[0] a DocumentType and childNodes[1] the Element Node # document, with childNodes[0] a DocumentType and childNodes[1] the Element Node
else: else:
...@@ -942,12 +820,13 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -942,12 +820,13 @@ class XMLSyncUtilsMixin(SyncCode):
if object is None: if object is None:
object_id = domain.generateNewIdWithGenerator(object=destination_path,gid=object_gid) object_id = domain.generateNewIdWithGenerator(object=destination_path,gid=object_gid)
#if object_id is not None: #if object_id is not None:
add_data = conduit.addNode(xml=data_subnode, object=destination_path, add_data = conduit.addNode(xml=data_subnode,
object_id=object_id) object=destination_path, object_id=object_id)
conflict_list += add_data['conflict_list'] conflict_list += add_data['conflict_list']
# Retrieve directly the object from addNode # Retrieve directly the object from addNode
object = add_data['object'] object = add_data['object']
LOG('XMLSyncUtils, in ADD add_data',0,add_data) LOG('XMLSyncUtils, in ADD add_data',0,add_data)
signature.setPath(object.getPhysicalPath())
LOG('applyActionList',0,'object after add: %s' % repr(object)) LOG('applyActionList',0,'object after add: %s' % repr(object))
else: else:
#Object was retrieve but need to be updated without recreated #Object was retrieve but need to be updated without recreated
...@@ -1012,11 +891,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -1012,11 +891,11 @@ class XMLSyncUtilsMixin(SyncCode):
elif next_action.nodeName == 'Delete': elif next_action.nodeName == 'Delete':
object_id = signature.getId() object_id = signature.getId()
conduit.deleteNode(xml=self.getDataSubNode(next_action), object=destination_path, conduit.deleteNode(xml=self.getDataSubNode(next_action),
object_id=object_id) object=destination_path, object_id=object_id)
subscriber.delSignature(object_gid) subscriber.delSignature(object_gid)
xml_confirmation += self.SyncMLConfirmation(cmd_id, xml_confirmation += self.SyncMLConfirmation(cmd_id,
object_gid,status_code,'Delete') object_gid,status_code,'Delete')
else: # We want to retrieve more data else: # We want to retrieve more data
signature.setStatus(self.PARTIAL) signature.setStatus(self.PARTIAL)
#LOG('SyncModif',0,'setPartialXML: %s' % str(previous_partial)) #LOG('SyncModif',0,'setPartialXML: %s' % str(previous_partial))
...@@ -1026,8 +905,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -1026,8 +905,8 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setPartialXML(previous_partial) signature.setPartialXML(previous_partial)
#LOG('SyncModif',0,'previous_partial: %s' % str(previous_partial)) #LOG('SyncModif',0,'previous_partial: %s' % str(previous_partial))
LOG('SyncModif',0,'waiting more data for :%s' % signature.getId()) LOG('SyncModif',0,'waiting more data for :%s' % signature.getId())
xml_confirmation += self.SyncMLConfirmation(cmd_id,object_gid, xml_confirmation += self.SyncMLConfirmation(cmd_id, object_gid,
self.WAITING_DATA,next_action.nodeName) self.WAITING_DATA, next_action.nodeName)
if conflict_list != [] and signature is not None: if conflict_list != [] and signature is not None:
# We had a conflict # We had a conflict
signature.setStatus(self.CONFLICT) signature.setStatus(self.CONFLICT)
...@@ -1121,11 +1000,13 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1121,11 +1000,13 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
if domain.domain_type == self.PUB: if domain.domain_type == self.PUB:
simulate = 1 simulate = 1
for subnode in xml_header.childNodes: for subnode in xml_header.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Source": if subnode.nodeType == subnode.ELEMENT_NODE and \
for subnode2 in subnode.childNodes: subnode.nodeName == "Source":
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'LocURI': for subnode2 in subnode.childNodes:
subscription_url = str(subnode2.childNodes[0].data) if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subscriber = domain.getSubscriber(subscription_url) subnode2.nodeName == 'LocURI':
subscription_url = str(subnode2.childNodes[0].data)
subscriber = domain.getSubscriber(subscription_url)
# We have to check if this message was not already, this can be dangerous # We have to check if this message was not already, this can be dangerous
# to update two times the same object # to update two times the same object
...@@ -1142,7 +1023,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1142,7 +1023,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
xml=last_xml,domain=domain) xml=last_xml,domain=domain)
elif domain.domain_type == self.SUB: elif domain.domain_type == self.SUB:
self.sendResponse(from_url=domain.subscription_url, self.sendResponse(from_url=domain.subscription_url,
to_url=domain.publication_url, sync_id=domain.getTitle(), xml=last_xml,domain=domain) to_url=domain.publication_url, sync_id=domain.getTitle(),
xml=last_xml, domain=domain)
return {'has_response':has_response,'xml':last_xml} return {'has_response':has_response,'xml':last_xml}
subscriber.setLastSentMessage('') subscriber.setLastSentMessage('')
...@@ -1164,7 +1046,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1164,7 +1046,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
globals(), locals(), ['']) globals(), locals(), [''])
conduit = getattr(conduit_module, conduit_name)() conduit = getattr(conduit_module, conduit_name)()
# Then apply the list of actions # Then apply the list of actions
(xml_confirmation,has_next_action,cmd_id) = self.applyActionList(cmd_id=cmd_id, (xml_confirmation,has_next_action,cmd_id) = self.applyActionList(
cmd_id=cmd_id,
domain=domain, domain=domain,
destination_path=destination_path, destination_path=destination_path,
subscriber=subscriber, subscriber=subscriber,
...@@ -1178,8 +1061,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1178,8 +1061,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
# syncml header # syncml header
if domain.domain_type == self.PUB: if domain.domain_type == self.PUB:
xml(self.SyncMLHeader(subscriber.getSessionId(), subscriber.incrementMessageId(), xml(self.SyncMLHeader(subscriber.getSessionId(),
subscriber.getSubscriptionUrl(), domain.getPublicationUrl())) subscriber.incrementMessageId(), subscriber.getSubscriptionUrl(),
domain.getPublicationUrl()))
elif domain.domain_type == self.SUB: elif domain.domain_type == self.SUB:
xml(self.SyncMLHeader(domain.getSessionId(), domain.incrementMessageId(), xml(self.SyncMLHeader(domain.getSessionId(), domain.incrementMessageId(),
domain.getPublicationUrl(), domain.getSubscriptionUrl())) domain.getPublicationUrl(), domain.getSubscriptionUrl()))
...@@ -1192,11 +1076,11 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1192,11 +1076,11 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
if has_next_action == 0 and not \ if has_next_action == 0 and not \
(domain.domain_type==self.SUB and alert_code==self.SLOW_SYNC): (domain.domain_type==self.SUB and alert_code==self.SLOW_SYNC):
(syncml_data,xml_confirmation,cmd_id) = self.getSyncMLData(domain=domain, (syncml_data,xml_confirmation,cmd_id) = self.getSyncMLData(domain=domain,
remote_xml=remote_xml, remote_xml=remote_xml,
subscriber=subscriber, subscriber=subscriber,
destination_path=destination_path, destination_path=destination_path,
cmd_id=cmd_id,xml_confirmation=xml_confirmation, cmd_id=cmd_id,xml_confirmation=xml_confirmation,
conduit=conduit) conduit=conduit)
# syncml body # syncml body
xml(' <SyncBody>\n') xml(' <SyncBody>\n')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment