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):
# FIXME: Why can't we use the method addSubscriber ??
self.list_publications[id].addSubscriber(subscriber)
# 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):
self.PubSyncInit(publication=self.list_publications[id],
......
......@@ -45,8 +45,8 @@ class Conflict(SyncCode):
remote_value=None, domain=None, domain_id=None):
self.object_path=object_path
self.keyword = keyword
self.local_value=local_value
self.remote_value=remote_value
self.setLocalValue(local_value)
self.setRemoteValue(remote_value)
self.domain = domain
self.domain_id = domain_id
......@@ -56,6 +56,36 @@ class Conflict(SyncCode):
"""
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):
"""
set the domain
......@@ -68,6 +98,12 @@ class Conflict(SyncCode):
"""
return self.domain
def getKeyword(self):
"""
get the domain
"""
return self.keyword
def getDomainId(self):
"""
get the domain id
......@@ -80,6 +116,17 @@ class Conflict(SyncCode):
"""
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):
"""
......@@ -102,6 +149,7 @@ class Signature(SyncCode):
self.setTempXML(None)
self.setTempXML(None)
self.resetConflictList()
self.md5_string = None
self.force = 0
#def __init__(self,object=None, status=None, xml_string=None):
......@@ -125,6 +173,9 @@ class Signature(SyncCode):
self.setTempXML(None)
if len(self.getConflictList())>0:
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):
"""
......@@ -151,7 +202,7 @@ class Signature(SyncCode):
self.xml = xml
if self.xml != None:
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):
"""
......@@ -183,7 +234,7 @@ class Signature(SyncCode):
"""
get the MD5 object of this signature
"""
return self.md5_object
return self.md5_string
def checkMD5(self, xml_string):
"""
......@@ -192,7 +243,7 @@ class Signature(SyncCode):
if we want to know if an objects has changed or not
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):
"""
......@@ -223,14 +274,16 @@ class Signature(SyncCode):
Set the partial string we will have to
deliver in the future
"""
#LOG('Subscriber.setPartialXML before',0,'partial_xml: %s' % str(self.partial_xml))
self.partial_xml = xml
#LOG('Subscriber.setPartialXML after',0,'partial_xml: %s' % str(self.partial_xml))
def getPartialXML(self):
"""
Set the partial string we will have to
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
def getAction(self):
......@@ -339,6 +392,13 @@ class Subscription(SyncCode):
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
if len(self.signatures.keys()) > 0:
code = self.TWO_WAY
......@@ -562,7 +622,7 @@ class Subscription(SyncCode):
for object_id in self.signatures.keys():
# 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,
self.SUB_CONFLICT_MERGE)):
self.PUB_CONFLICT_CLIENT_WIN)):
self.signatures[object_id].setStatus(self.NOT_SYNCHRONIZED)
self.signatures[object_id].setPartialXML(None)
self.signatures[object_id].setTempXML(None)
......@@ -26,6 +26,7 @@
#
##############################################################################
from Products.ERP5Type.Accessor.TypeDefinition import list_types
from Globals import Persistent
class SyncCode(Persistent):
......@@ -60,10 +61,28 @@ class SyncCode(Persistent):
PARTIAL = 4
NOT_SYNCHRONIZED = 5
PUB_CONFLICT_MERGE = 6
SUB_CONFLICT_MERGE = 7
#SUB_CONFLICT_MERGE = 7
PUB_CONFLICT_CLIENT_WIN = 8
SUB_CONFLICT_CLIENT_WIN = 9
#SUB_CONFLICT_CLIENT_WIN = 9
MAX_LINES = 1000
#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 @@
#
##############################################################################
from Products.ERP5SyncML.XMLSyncUtils import *
from Products.ERP5SyncML.XMLSyncUtils import XMLSyncUtilsMixin
from xml.dom.ext.reader.Sax2 import FromXml
from Products.ERP5SyncML.SyncCode import SyncCode
from zLOG import LOG
class XupdateUtils:
class XupdateUtils(XMLSyncUtilsMixin):
"""
This class contains method specific to xupdate xml,
this is the place where we should parse xupdate data.
......@@ -41,155 +42,25 @@ class XupdateUtils:
Parse the xupdate and then it will call the conduit
"""
conflict_list = []
if type(xupdate) is type('a'):
if type(xupdate) in (type('a'),type(u'a')):
xupdate = FromXml(xupdate)
# This is a list of selection with a fake tag
fake_tag_list = ()
for subnode in xupdate.childNodes:
to_continue = 0
for subnode in self.getElementNodeList(xupdate):
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
for subnode1 in subnode.attributes:
if subnode1.nodeType == subnode1.ATTRIBUTE_NODE and subnode1.nodeName=='select':
selection_name = subnode1.nodeValue
LOG('applyXupdate',0,'selection_name: %s' % str(selection_name))
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)
#if to_continue:
# continue
elif subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'xupdate:remove':
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':
for subnode1 in self.getElementNodeList(subnode):
if subnode1.nodeName == 'xupdate:element':
conflict_list += conduit.addNode(xml=subnode, object=object, force=force, **kw)
elif subnode1.nodeName == 'xupdate:text':
conflict_list += conduit.addNode(xml=subnode,object=object, force=force, **kw)
elif subnode.nodeName in self.XUPDATE_DEL:
conflict_list += conduit.deleteNode(xml=subnode, object=object, force=force, **kw)
elif subnode.nodeName in self.XUPDATE_UPDATE:
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)
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