Commit 337a2213 authored by Sebastien Robin's avatar Sebastien Robin

many updates made when the cvs was down


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@118 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent b374861f
This diff is collapsed.
...@@ -160,7 +160,7 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -160,7 +160,7 @@ class PublicationSynchronization(XMLSyncUtils):
# FIXME: Why can't we use the method addSubscriber ?? # FIXME: Why can't we use the method addSubscriber ??
self.list_publications[id].addSubscriber(subscriber) self.list_publications[id].addSubscriber(subscriber)
# first synchronization # first synchronization
self.PubSyncInit(self.list_publications[id],xml_client) self.PubSyncInit(self.list_publications[id],xml_client,subscriber=subscriber)
elif self.checkAlert(xml_client) and self.getAlertCode(xml_client) in (self.TWO_WAY,self.SLOW_SYNC): elif self.checkAlert(xml_client) and self.getAlertCode(xml_client) in (self.TWO_WAY,self.SLOW_SYNC):
self.PubSyncInit(publication=self.list_publications[id], self.PubSyncInit(publication=self.list_publications[id],
......
...@@ -45,8 +45,8 @@ class Conflict(SyncCode): ...@@ -45,8 +45,8 @@ class Conflict(SyncCode):
remote_value=None, domain=None, domain_id=None): remote_value=None, domain=None, domain_id=None):
self.object_path=object_path self.object_path=object_path
self.keyword = keyword self.keyword = keyword
self.local_value=local_value self.setLocalValue(local_value)
self.remote_value=remote_value self.setRemoteValue(remote_value)
self.domain = domain self.domain = domain
self.domain_id = domain_id self.domain_id = domain_id
...@@ -56,6 +56,36 @@ class Conflict(SyncCode): ...@@ -56,6 +56,36 @@ class Conflict(SyncCode):
""" """
return self.object_path return self.object_path
def getLocalValue(self):
"""
get the domain
"""
return self.local_value
def setLocalValue(self, value):
"""
get the domain
"""
try:
self.local_value = value
except TypeError: # It happens when we try to store StringIO
self.local_value = None
def getRemoteValue(self):
"""
get the domain
"""
return self.remote_value
def setRemoteValue(self, value):
"""
get the domain
"""
try:
self.remote_value = value
except TypeError: # It happens when we try to store StringIO
self.remote_value = None
def setDomain(self, domain): def setDomain(self, domain):
""" """
set the domain set the domain
...@@ -68,6 +98,12 @@ class Conflict(SyncCode): ...@@ -68,6 +98,12 @@ class Conflict(SyncCode):
""" """
return self.domain return self.domain
def getKeyword(self):
"""
get the domain
"""
return self.keyword
def getDomainId(self): def getDomainId(self):
""" """
get the domain id get the domain id
...@@ -80,6 +116,17 @@ class Conflict(SyncCode): ...@@ -80,6 +116,17 @@ class Conflict(SyncCode):
""" """
self.domain_id = domain_id self.domain_id = domain_id
def applyRemoteValue():
"""
We will take the remote value for this conflict
"""
pass
def applyLocalValue():
"""
We will take the local value for this conflict
"""
pass
class Signature(SyncCode): class Signature(SyncCode):
""" """
...@@ -102,6 +149,7 @@ class Signature(SyncCode): ...@@ -102,6 +149,7 @@ class Signature(SyncCode):
self.setTempXML(None) self.setTempXML(None)
self.setTempXML(None) self.setTempXML(None)
self.resetConflictList() self.resetConflictList()
self.md5_string = None
self.force = 0 self.force = 0
#def __init__(self,object=None, status=None, xml_string=None): #def __init__(self,object=None, status=None, xml_string=None):
...@@ -125,6 +173,9 @@ class Signature(SyncCode): ...@@ -125,6 +173,9 @@ class Signature(SyncCode):
self.setTempXML(None) self.setTempXML(None)
if len(self.getConflictList())>0: if len(self.getConflictList())>0:
self.resetConflictList() self.resetConflictList()
elif status in (self.PUB_CONFLICT_MERGE,self.SENT):
# We have a solution for the conflict, don't need to keep the list
self.resetConflictList()
def getStatus(self): def getStatus(self):
""" """
...@@ -151,7 +202,7 @@ class Signature(SyncCode): ...@@ -151,7 +202,7 @@ class Signature(SyncCode):
self.xml = xml self.xml = xml
if self.xml != None: if self.xml != None:
self.setTempXML(None) # We make sure that the xml will not be erased self.setTempXML(None) # We make sure that the xml will not be erased
self.md5_string = md5.new(xml).digest() self.setMD5(xml)
def getXML(self): def getXML(self):
""" """
...@@ -183,7 +234,7 @@ class Signature(SyncCode): ...@@ -183,7 +234,7 @@ class Signature(SyncCode):
""" """
get the MD5 object of this signature get the MD5 object of this signature
""" """
return self.md5_object return self.md5_string
def checkMD5(self, xml_string): def checkMD5(self, xml_string):
""" """
...@@ -192,7 +243,7 @@ class Signature(SyncCode): ...@@ -192,7 +243,7 @@ class Signature(SyncCode):
if we want to know if an objects has changed or not if we want to know if an objects has changed or not
Returns 1 if MD5 are equals, else it returns 0 Returns 1 if MD5 are equals, else it returns 0
""" """
return md5.new(xml_string).digest() == self.md5_string return ((md5.new(xml_string).digest()) == self.getMD5())
def setRid(self, rid): def setRid(self, rid):
""" """
...@@ -223,14 +274,16 @@ class Signature(SyncCode): ...@@ -223,14 +274,16 @@ class Signature(SyncCode):
Set the partial string we will have to Set the partial string we will have to
deliver in the future deliver in the future
""" """
#LOG('Subscriber.setPartialXML before',0,'partial_xml: %s' % str(self.partial_xml))
self.partial_xml = xml self.partial_xml = xml
#LOG('Subscriber.setPartialXML after',0,'partial_xml: %s' % str(self.partial_xml))
def getPartialXML(self): def getPartialXML(self):
""" """
Set the partial string we will have to Set the partial string we will have to
deliver in the future deliver in the future
""" """
LOG('Subscriber.getPartialXML',0,'partial_xml: %s' % str(self.partial_xml)) #LOG('Subscriber.getPartialXML',0,'partial_xml: %s' % str(self.partial_xml))
return self.partial_xml return self.partial_xml
def getAction(self): def getAction(self):
...@@ -339,6 +392,13 @@ class Subscription(SyncCode): ...@@ -339,6 +392,13 @@ class Subscription(SyncCode):
def getSynchronizationType(self, default=None): def getSynchronizationType(self, default=None):
""" """
""" """
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# XXX for debugging only, to be removed
dict_sign = {}
for object_id in self.signatures.keys():
dict_sign[object_id] = self.signatures[object_id].getStatus()
LOG('getSignature',0,'signatures_status: %s' % str(dict_sign))
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
code = self.SLOW_SYNC code = self.SLOW_SYNC
if len(self.signatures.keys()) > 0: if len(self.signatures.keys()) > 0:
code = self.TWO_WAY code = self.TWO_WAY
...@@ -562,7 +622,7 @@ class Subscription(SyncCode): ...@@ -562,7 +622,7 @@ class Subscription(SyncCode):
for object_id in self.signatures.keys(): for object_id in self.signatures.keys():
# Change the status only if we are not in a conflict mode # Change the status only if we are not in a conflict mode
if not(self.signatures[object_id].getStatus() in (self.CONFLICT,self.PUB_CONFLICT_MERGE, if not(self.signatures[object_id].getStatus() in (self.CONFLICT,self.PUB_CONFLICT_MERGE,
self.SUB_CONFLICT_MERGE)): self.PUB_CONFLICT_CLIENT_WIN)):
self.signatures[object_id].setStatus(self.NOT_SYNCHRONIZED) self.signatures[object_id].setStatus(self.NOT_SYNCHRONIZED)
self.signatures[object_id].setPartialXML(None) self.signatures[object_id].setPartialXML(None)
self.signatures[object_id].setTempXML(None) self.signatures[object_id].setTempXML(None)
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
# #
############################################################################## ##############################################################################
from Products.ERP5Type.Accessor.TypeDefinition import list_types
from Globals import Persistent from Globals import Persistent
class SyncCode(Persistent): class SyncCode(Persistent):
...@@ -60,10 +61,28 @@ class SyncCode(Persistent): ...@@ -60,10 +61,28 @@ class SyncCode(Persistent):
PARTIAL = 4 PARTIAL = 4
NOT_SYNCHRONIZED = 5 NOT_SYNCHRONIZED = 5
PUB_CONFLICT_MERGE = 6 PUB_CONFLICT_MERGE = 6
SUB_CONFLICT_MERGE = 7 #SUB_CONFLICT_MERGE = 7
PUB_CONFLICT_CLIENT_WIN = 8 PUB_CONFLICT_CLIENT_WIN = 8
SUB_CONFLICT_CLIENT_WIN = 9 #SUB_CONFLICT_CLIENT_WIN = 9
MAX_LINES = 1000 MAX_LINES = 1000
#ENCODING='iso-8859-1' #ENCODING='iso-8859-1'
NOT_EDITABLE_PROPERTY = ('id','object','workflow_history','security_info','uid'
'xupdate:element','xupdate:attribute')
XUPDATE_INSERT = ('xupdate:insert-after','xupdate:insert-before')
XUPDATE_ADD = ('xupdate:append',)
XUPDATE_DEL = ('xupdate:remove',)
XUPDATE_UPDATE = ('xupdate:update',)
XUPDATE_INSERT_OR_ADD = tuple(XUPDATE_INSERT) + tuple(XUPDATE_ADD)
XUPDATE_TAG = tuple(XUPDATE_INSERT) + tuple(XUPDATE_ADD) + \
tuple(XUPDATE_UPDATE) + tuple(XUPDATE_DEL)
text_type_list = ('text','string')
list_type_list = list_types
binary_type_list = ('image','file','document')
date_type_list = ('date',)
dict_type_list = ('dict',)
xml_object_tag = 'object'
sub_object_exp = "/object\[@id='.*'\]/object\[@id='.*'\]"
This diff is collapsed.
...@@ -26,11 +26,12 @@ ...@@ -26,11 +26,12 @@
# #
############################################################################## ##############################################################################
from Products.ERP5SyncML.XMLSyncUtils import * from Products.ERP5SyncML.XMLSyncUtils import XMLSyncUtilsMixin
from xml.dom.ext.reader.Sax2 import FromXml from xml.dom.ext.reader.Sax2 import FromXml
from Products.ERP5SyncML.SyncCode import SyncCode
from zLOG import LOG from zLOG import LOG
class XupdateUtils: class XupdateUtils(XMLSyncUtilsMixin):
""" """
This class contains method specific to xupdate xml, This class contains method specific to xupdate xml,
this is the place where we should parse xupdate data. this is the place where we should parse xupdate data.
...@@ -41,155 +42,25 @@ class XupdateUtils: ...@@ -41,155 +42,25 @@ class XupdateUtils:
Parse the xupdate and then it will call the conduit Parse the xupdate and then it will call the conduit
""" """
conflict_list = [] conflict_list = []
if type(xupdate) is type('a'): if type(xupdate) in (type('a'),type(u'a')):
xupdate = FromXml(xupdate) xupdate = FromXml(xupdate)
# This is a list of selection with a fake tag for subnode in self.getElementNodeList(xupdate):
fake_tag_list = ()
for subnode in xupdate.childNodes:
to_continue = 0
selection_name = '' selection_name = ''
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'xupdate:append': if subnode.nodeName in self.XUPDATE_ADD:
# Check if we do not have a fake tag somewhere # Check if we do not have a fake tag somewhere
for subnode1 in subnode.attributes: for subnode1 in self.getElementNodeList(subnode):
if subnode1.nodeType == subnode1.ATTRIBUTE_NODE and subnode1.nodeName=='select': if subnode1.nodeName == 'xupdate:element':
selection_name = subnode1.nodeValue conflict_list += conduit.addNode(xml=subnode, object=object, force=force, **kw)
LOG('applyXupdate',0,'selection_name: %s' % str(selection_name)) elif subnode1.nodeName == 'xupdate:text':
for subnode1 in subnode.childNodes:
if subnode1.nodeType == subnode1.ELEMENT_NODE and subnode1.nodeName == 'xupdate:element':
for subnode2 in subnode1.attributes:
if subnode2.nodeName=='name' and subnode2.nodeValue == 'LogilabXMLDIFFFAKETag':
fake_tag_list += (selection_name,)
to_continue = 1
if not to_continue:
conduit.addNode(xml=subnode, object=object, force=force, **kw)
if subnode1.nodeType == subnode.ELEMENT_NODE and subnode1.nodeName == 'xupdate:text':
if selection_name in fake_tag_list: # This is the case where xmldiff do the crazy thing :
# Adding a fake tag, modify and delete,
# so we should only update.
conflict_list += conduit.updateNode(xml=subnode, object=object, force=force, **kw)
else:
conflict_list += conduit.addNode(xml=subnode,object=object, force=force, **kw) conflict_list += conduit.addNode(xml=subnode,object=object, force=force, **kw)
#if to_continue: elif subnode.nodeName in self.XUPDATE_DEL:
# continue conflict_list += conduit.deleteNode(xml=subnode, object=object, force=force, **kw)
elif subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'xupdate:remove': elif subnode.nodeName in self.XUPDATE_UPDATE:
for subnode1 in subnode.attributes:
if subnode1.nodeType == subnode1.ATTRIBUTE_NODE and subnode1.nodeName=='select':
selection_name = subnode1.nodeValue
LOG('applyXupdate',0,'fake_tag_list: %s' % str(fake_tag_list))
for fake_tag in fake_tag_list:
if selection_name.find(fake_tag) == 0:
LOG('applyXupdate',0,'selection ignored for delete: %s' % str(selection_name))
to_continue = 1
if not to_continue:
conduit.deleteNode(xml=subnode, object=object)
elif subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'xupdate:update':
conflict_list += conduit.updateNode(xml=subnode, object=object, force=force, **kw) conflict_list += conduit.updateNode(xml=subnode, object=object, force=force, **kw)
elif subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'xupdate:insert-after': elif subnode.nodeName in self.XUPDATE_INSERT:
conflict_list += conduit.addNode(xml=subnode, object=object, force=force, **kw) conflict_list += conduit.addNode(xml=subnode, object=object, force=force, **kw)
return conflict_list return conflict_list
def old_applyXupdate(self, object=None, xupdate=None, conduit=None):
"""
deprecated and should not be used
"""
for subnode in xupdate.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'xupdate:modifications':
for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE:
to_continue = 0
select_list = ()
# First check if we are not a sub-object
for subnode3 in subnode2.attributes:
if subnode3.nodeType == subnode3.ATTRIBUTE_NODE and subnode3.nodeName=='select':
nodeValue = subnode3.nodeValue
if nodeValue.find('/object[1]/object')==0:
to_continue = 1
elif nodeValue.find('/object[1]/workflow_history')==0:
to_continue = 1
elif nodeValue.find('/object[1]/security_info')==0:
to_continue = 1
else:
select_list = subnode3.nodeValue.split('/') # Something like: ('','object[1]','sid[1]')
new_select_list = ()
for select_item in select_list:
new_select_list += (select_item[:select_item.find('[')],)
select_list = new_select_list # Something like : ('','object','sid')
if to_continue:
continue
# Then we have to find the keyword, differents ways are needed
# depending if we are inserting, updating, removing...
keyword = None
data = None
if subnode2.nodeName == 'xupdate:insert-after': # We suppose the tag was empty before
# XXX this supposition could be WRONG
for subnode3 in getElementNodeList(subnode2):
if subnode3.nodeName=='xupdate:element':
for subnode4 in subnode3.attributes:
if subnode4.nodeName=='name':
keyword = subnode4.nodeValue
LOG('ApplyUpdate',0,'i-a, keyword: %s' % keyword)
if keyword=='object': # This is a subobject, we have to stop right now
to_continue = 1
elif keyword.find('element_')==0: # We are on a part of a list
keyword = select_list[len(select_list)-2]
if to_continue:
continue
if len(getElementNodeList(subnode3))==0:
data = str(subnode3.childNodes[0].data) # We assume the child is a text node
else: # We have many elements
data = []
for subnode4 in getElementNodeList(subnode3):
# In this case we should only have one childnode
LOG('ApplyUpdate',0,'subnode4: %s' % str(subnode4))
element_data = subnode4.childNodes[0].data
element_data = element_data[element_data.find('\n')+1:element_data.rfind('\n')]
data += [element_data]
elif subnode2.nodeName == 'xupdate:append':
keyword = select_list[len(select_list)-1]
if len(getElementNodeList(subnode2))==0:
data = subnode2.childNodes[0].data
data = data[data.find('\n')+1:data.rfind('\n')]
else:
data=[]
for subnode3 in getElementNodeList(subnode2):
element_data = subnode3.childNodes[0].data
element_data = element_data[element_data.find('\n')+1:element_data.rfind('\n')]
data += [element_data]
if len(data) == 1: # This is probably because this is not a list but a string XXX may be not good
data = data[0]
LOG('ERP5Conduit.ApplyUpdate',0,'args: %s' % str(args))
if keyword is not None:
if type(keyword) is type(u"a"):
LOG('ERP5Conduit.ApplyUpdate',0,'keyword before encoding: %s' % str(type(keyword)))
keyword = keyword.encode(self.getEncoding())
LOG('ERP5Conduit.ApplyUpdate',0,'keyword after encoding: %s' % str(type(keyword)))
if not(keyword in self.NOT_EDITABLE_PROPERTY):
if type(data) is type([]) or type(data) is type(()):
new_data = []
for item in data:
if type(item) is type(u"a"):
item = item.encode(self.getEncoding())
new_data += [item]
data = new_data
if type(data) is type(u"a"):
data = data.encode(self.getEncoding())
# if we have already this keyword, then we may append to a list
if args.has_key(keyword):
arg_type = type(args[keyword])
if arg_type is type(()) or arg_type is type([]):
if type(data) is not type(()) or type(data) is not type([]):
data = [data]
data = args[keyword] + data
args[keyword] = data
if len(args) > 0:
object.edit(**args)
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