diff --git a/product/ERP5SyncML/Signature.py b/product/ERP5SyncML/Signature.py index e5c7b3fc86fbaa6be9ba4c1bbfffa8ad542f14a9..d9c1a54cf64f57dc3cfe32c4c9530861c8126c8a 100644 --- a/product/ERP5SyncML/Signature.py +++ b/product/ERP5SyncML/Signature.py @@ -65,10 +65,10 @@ class Signature(Folder, SyncCode, File): id=None, rid=None, status=None, - xml_string='', + xml_string=None, object=None): Folder.__init__(self, id) - File.__init__(self, id, '', xml_string) + File.__init__(self, id, '', '') if object is not None: self.setPath(object.getPhysicalPath()) self.setObjectId(object.getId()) @@ -188,7 +188,7 @@ class Signature(Folder, SyncCode, File): if xml is not None: # convert the string to Pdata if the big size file = cStringIO.StringIO(xml) - self.xml, size = self._read_data(file) + self.xml, size = self.getParentValue()._read_data(file) self.setTempXML(None) # We make sure that the xml will not be erased self.setMD5(xml) else: @@ -223,7 +223,7 @@ class Signature(Folder, SyncCode, File): """ if xml is not None: file = cStringIO.StringIO(xml) - self.temp_xml, size = self._read_data(file) + self.temp_xml, size = self.getParentValue()._read_data(file) else: self.temp_xml = None @@ -353,7 +353,7 @@ class Signature(Folder, SyncCode, File): xml = xml.decode('utf-8').encode('ascii','xmlcharrefreplace') # convert the string to Pdata if the big size file = cStringIO.StringIO(xml) - self.partial_xml, size = self._read_data(file) + self.partial_xml, size = self.getParentValue()._read_data(file) if not isinstance(self.partial_xml, Pdata): self.partial_xml = Pdata(self.partial_xml) self.last_data_partial_xml = self.partial_xml.getLastPdata() @@ -372,7 +372,7 @@ class Signature(Folder, SyncCode, File): xml = xml.decode('utf-8').encode('ascii','xmlcharrefreplace') file = cStringIO.StringIO(xml) - xml_append, size = self._read_data(file) + xml_append, size = self.getParentValue()._read_data(file) if not isinstance(xml_append, Pdata): xml_append = Pdata(xml_append) last_data = xml_append.getLastPdata() @@ -381,7 +381,36 @@ class Signature(Folder, SyncCode, File): else: self.partial_xml = xml_append self.last_data_partial_xml = last_data - + + def getFirstChunkPdata(self, size_lines): + """ + """ + chunk = list() + chunk.append(self.partial_xml.data) + size = chunk[0].count('\n') + index = 0 + Pdata = next = self.partial_xml.next + while size < size_lines: + Pdata = next + size += Pdata.data.count('\n') + chunk.append(Pdata.data) + index += 1 + next = Pdata.next + + if size == size_lines: + self.partial_xml = next + elif size > size_lines: + data_list = chunk[index].split('\n') + chunk[index] = '\n'.join(data_list[:size_lines]) + if Pdata is not None: + Pdata.data = '\n'.join(data_list[size_lines:]) + self.partial_xml = Pdata + else: + self.partial_xml.data = '\n'.join(data_list[size_lines:]) + + return ''.join(chunk) + + def getPartialXML(self): """ Set the partial string we will have to diff --git a/product/ERP5SyncML/Subscription.py b/product/ERP5SyncML/Subscription.py index eac52831fe6af5172335076fec52013e28d2431d..296de7a69fe8166ec224e1a3af857380b2841bb3 100644 --- a/product/ERP5SyncML/Subscription.py +++ b/product/ERP5SyncML/Subscription.py @@ -36,6 +36,7 @@ from Products.ERP5Type.Core.Folder import Folder from Products.ERP5Type.Base import Base from Products.ERP5Type import Permissions from Products.ERP5Type import PropertySheet +from OFS.Image import File from DateTime import DateTime from zLOG import LOG, DEBUG, INFO import md5 @@ -55,7 +56,7 @@ def addSubscription( self, id, title='', REQUEST=None ): #class Subscription(Folder, SyncCode, Implicit, Folder, Impli): from XMLSyncUtils import XMLSyncUtils -class Subscription(Folder, XMLSyncUtils): +class Subscription(Folder, XMLSyncUtils, File): """ Subscription hold the definition of a master ODB from/to which a selection of objects will be synchronised @@ -88,8 +89,11 @@ class Subscription(Folder, XMLSyncUtils): last_anchor - it defines the id of the last synchronisation next_anchor - it defines the id of the current synchronisation - - """ + + Subscription inherit of File because the Signature use method _read_data + which have the need of a __r_jar not None. + During the initialization of a Signature this __p_jar is None + """ meta_type = 'ERP5 Subscription' portal_type = 'SyncML Subscription' # may be useful in the future... diff --git a/product/ERP5SyncML/XMLSyncUtils.py b/product/ERP5SyncML/XMLSyncUtils.py index c330679a20887f17076f158ebf6ce784bd75f4d0..5194ea4f37f497a12e7ac55dc327ae0d34a4fe97 100644 --- a/product/ERP5SyncML/XMLSyncUtils.py +++ b/product/ERP5SyncML/XMLSyncUtils.py @@ -781,8 +781,8 @@ class XMLSyncUtilsMixin(SyncCode): signature = Signature(id=gid, object=object).__of__(subscriber) signature.setTempXML(xml_string) if xml_string.count('\n') > self.MAX_LINES: - xml_string, rest_string = self.cutXML(xml_string) more_data = 1 + xml_string, rest_string = self.cutXML(xml_string) signature.setPartialXML(rest_string) status = self.PARTIAL signature.setAction('Add') @@ -822,8 +822,8 @@ class XMLSyncUtilsMixin(SyncCode): xml_string = self.getXupdateObject(xml_object, signature.getXML()) if xml_string.count('\n') > self.MAX_LINES: # This make comment fails, so we need to replace - xml_string, rest_string = self.cutXML(xml_string) more_data = 1 + xml_string, rest_string = self.cutXML(xml_string) signature.setPartialXML(rest_string) status = self.PARTIAL signature.setAction('Replace') @@ -876,19 +876,23 @@ class XMLSyncUtilsMixin(SyncCode): signature.setStatus(self.SYNCHRONIZED) elif signature.getStatus() == self.PARTIAL: xml_string = signature.getPartialXML() - xml_to_send = Element('Partial') - xml_to_send.text = etree.CDATA(xml_string.decode('utf-8')) if(subscriber.getMediaType() != self.MEDIA_TYPE['TEXT_XML']): xml_to_send = conduit.getXMLFromObjectWithId(object,\ xml_mapping=domain.getXMLMapping()) elif xml_string.count('\n') > self.MAX_LINES: - xml_to_send, rest_string = self.cutXML(xml_string) more_data = 1 - signature.setPartialXML(rest_string) + # Receive the chunk of partial xml + short_string = signature.getFirstChunkPdata(self.MAX_LINES) + xml_to_send = etree.Element('Partial') + xml_to_send.text = etree.CDATA(short_string.decode('utf-8')) status = self.PARTIAL + else: + xml_to_send = Element('Partial') + xml_to_send.text = etree.CDATA(xml_string.decode('utf-8')) signature.setStatus(status) if signature.getAction() == 'Replace': - rid = signature.getRid()#in fisrt, we try with rid if there is one + rid = signature.getRid() + # In first, we try with rid if there is one gid = signature.getGid() syncml_data_list.append(self.replaceXMLObject( cmd_id=cmd_id,