Commit eae6b12d authored by Sebastien Robin's avatar Sebastien Robin

many updates on the conflict management


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@183 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent edd9bf24
...@@ -150,7 +150,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -150,7 +150,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if portal_type == 'Workspace': if portal_type == 'Workspace':
proxy_type = 'folder' proxy_type = 'folder'
proxy = px_tool.createEmptyProxy(proxy_type, proxy = px_tool.createEmptyProxy(proxy_type,
object,portal_type,object_id,docid) object,portal_type,object_id,docid=docid)
proxy.isIndexable = 0 # So it will not be reindexed, this prevent errors proxy.isIndexable = 0 # So it will not be reindexed, this prevent errors
# Calculate rpath # Calculate rpath
utool = getToolByName(object, 'portal_url') utool = getToolByName(object, 'portal_url')
...@@ -184,6 +184,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -184,6 +184,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
conflict_list += self.addNode(xml=sub_xml,object=sub_object, conflict_list += self.addNode(xml=sub_xml,object=sub_object,
previous_xml=sub_previous_xml, force=force) previous_xml=sub_previous_xml, force=force)
elif xml.nodeName == self.history_tag or self.isHistoryAdd(xml)>0: elif xml.nodeName == self.history_tag or self.isHistoryAdd(xml)>0:
#return conflict_list # XXX to be removed soon
# We want to add a workflow action # We want to add a workflow action
wf_tool = getToolByName(object,'portal_workflow') wf_tool = getToolByName(object,'portal_workflow')
wf_id = self.getAttribute(xml,'id') wf_id = self.getAttribute(xml,'id')
...@@ -199,9 +200,11 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -199,9 +200,11 @@ class ERP5Conduit(XMLSyncUtilsMixin):
LOG('addNode, status:',0,status) LOG('addNode, status:',0,status)
wf_tool.setStatusOf(wf_id,object,status) wf_tool.setStatusOf(wf_id,object,status)
elif xml.nodeName in self.local_role_list: elif xml.nodeName in self.local_role_list:
#return conflict_list # XXX to be removed soon
# We want to add a local role # We want to add a local role
#user = self.getParameter(xml,'user') #user = self.getParameter(xml,'user')
roles = self.convertXmlValue(xml.childNodes[0].data,data_type='tokens') roles = self.convertXmlValue(xml.childNodes[0].data,data_type='tokens')
roles = list(roles) # Needed for CPS, or we have a CPS error
user = roles[0] user = roles[0]
roles = roles[1:] roles = roles[1:]
object.manage_setLocalRoles(user,roles) object.manage_setLocalRoles(user,roles)
...@@ -217,6 +220,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -217,6 +220,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
LOG('ERP5Conduit',0,'deleteNode') LOG('ERP5Conduit',0,'deleteNode')
LOG('ERP5Conduit',0,'deleteNode, object.id: %s' % object.getId()) LOG('ERP5Conduit',0,'deleteNode, object.id: %s' % object.getId())
conflict_list = [] conflict_list = []
if xml is not None:
xml = self.convertToXml(xml) xml = self.convertToXml(xml)
if object_id is None: if object_id is None:
LOG('ERP5Conduit',0,'deleteNode, SubObjectDepth: %i' % self.getSubObjectDepth(xml)) LOG('ERP5Conduit',0,'deleteNode, SubObjectDepth: %i' % self.getSubObjectDepth(xml))
...@@ -238,6 +242,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -238,6 +242,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
try: try:
object._delObject(object_id) object._delObject(object_id)
except (AttributeError, KeyError): except (AttributeError, KeyError):
LOG('ERP5Conduit',0,'deleteNode, Unable to delete: %s' % str(object_id))
pass pass
return conflict_list return conflict_list
...@@ -319,10 +324,16 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -319,10 +324,16 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if 1: if 1:
# This is a conflict # This is a conflict
isConflict = 1 isConflict = 1
conflict_list += [Conflict(object_path=object.getPhysicalPath(), string_io = StringIO()
keyword=keyword, PrettyPrint(xml,stream=string_io)
local_value=current_data, conflict = Conflict(object_path=object.getPhysicalPath())
remote_value=data)] conflict.setXupdate(string_io.getvalue())
conflict_list += [conflict]
#conflict_list += [Conflict(object_path=object.getPhysicalPath(),
# keyword=keyword,
# xupdate=string_io)]
#local_value=current_data, # not needed any more
#remote_value=data)] # not needed any more
# We will now apply the argument with the method edit # We will now apply the argument with the method edit
if args != {} and (isConflict==0 or force): if args != {} and (isConflict==0 or force):
LOG('updateNode',0,'object._edit, args: %s' % str(args)) LOG('updateNode',0,'object._edit, args: %s' % str(args))
......
...@@ -41,13 +41,14 @@ class Conflict(SyncCode): ...@@ -41,13 +41,14 @@ class Conflict(SyncCode):
remote_value : the value sent by the remote box remote_value : the value sent by the remote box
""" """
def __init__(self, object_path=None, keyword=None, local_value=None,\ def __init__(self, object_path=None, keyword=None, xupdate=None, local_value=None,\
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.setLocalValue(local_value) self.setLocalValue(local_value)
self.setRemoteValue(remote_value) self.setRemoteValue(remote_value)
self.domain = domain self.domain = domain
self.resetXupdate()
self.domain_id = domain_id self.domain_id = domain_id
def getObjectPath(self): def getObjectPath(self):
...@@ -62,6 +63,37 @@ class Conflict(SyncCode): ...@@ -62,6 +63,37 @@ class Conflict(SyncCode):
""" """
return self.local_value return self.local_value
def getXupdateList(self):
"""
get the xupdate wich gave an error
"""
xupdate_list = []
if len(self.xupdate)>0:
for xupdate in self.xupdate:
xupdate_list+= [xupdate]
return xupdate_list
def resetXupdate(self):
"""
Reset the xupdate list
"""
self.xupdate = PersistentMapping()
def setXupdate(self, xupdate):
"""
set the xupdate
"""
if xupdate == None:
self.resetXupdate()
else:
self.xupdate = self.getXupdateList() + [xupdate]
def setXupdateList(self, xupdate):
"""
set the xupdate
"""
self.xupdate = xupdate
def setLocalValue(self, value): def setLocalValue(self, value):
""" """
get the domain get the domain
...@@ -318,10 +350,24 @@ class Signature(SyncCode): ...@@ -318,10 +350,24 @@ class Signature(SyncCode):
""" """
Return the actual action for a partial synchronization Return the actual action for a partial synchronization
""" """
LOG('setConflictList, list',0,conflict_list)
if conflict_list is None: if conflict_list is None:
self.resetConflictList() self.resetConflictList()
else: else:
self.conflict_list = conflict_list new_conflict_list = []
# If two conflicts are on the same objects, then
# we join them, so we have a conflict with many xupdate
for conflict in conflict_list:
found = None
for n_conflict in new_conflict_list:
if n_conflict.getObjectPath() == conflict.getObjectPath():
found = n_conflict
LOG('setConflictList, found',0,found)
if found == None:
new_conflict_list += [conflict]
else:
n_conflict.setXupdate(conflict.getXupdateList())
self.conflict_list = new_conflict_list
class Subscription(SyncCode): class Subscription(SyncCode):
""" """
......
...@@ -245,7 +245,13 @@ class SynchronizationTool( UniqueObject, SimpleItem, ...@@ -245,7 +245,13 @@ class SynchronizationTool( UniqueObject, SimpleItem,
return_list += [self.list_subscriptions[key]] return_list += [self.list_subscriptions[key]]
return return_list return return_list
def getConflictList(self): def getDomainList(self):
"""
Returns the list of subscriptions and publications
"""
return self.getSubscriptionList() + self.getPublicationList()
def getConflictList(self, path=None):
""" """
Retrieve the list of all conflicts Retrieve the list of all conflicts
Here the list is as follow : Here the list is as follow :
...@@ -256,23 +262,67 @@ class SynchronizationTool( UniqueObject, SimpleItem, ...@@ -256,23 +262,67 @@ class SynchronizationTool( UniqueObject, SimpleItem,
for publication in self.getPublicationList(): for publication in self.getPublicationList():
pub_conflict_list = publication.getConflictList() pub_conflict_list = publication.getConflictList()
for conflict in pub_conflict_list: for conflict in pub_conflict_list:
conflict.setDomain('Publication') #conflict.setDomain('Publication')
conflict.setDomain(publication)
conflict.setDomainId(publication.getId()) conflict.setDomainId(publication.getId())
conflict_list += [conflict] conflict_list += [conflict]
for subscription in self.getSubscriptionList(): for subscription in self.getSubscriptionList():
sub_conflict_list = subscription.getConflictList() sub_conflict_list = subscription.getConflictList()
for conflict in sub_conflict_list: for conflict in sub_conflict_list:
conflict.setDomain('Subscription') #conflict.setDomain('Subscription')
conflict.setDomain(subscription)
conflict.setDomainId(subscription.getId()) conflict.setDomainId(subscription.getId())
conflict_list += [conflict] conflict_list += [conflict]
if path is not None: # Retrieve only conflicts for a given path
new_list = []
for conflict in conflict_list:
if conflict.getObjectPath() == path:
new_list += [conflict]
return new_list
return conflict_list return conflict_list
def getSynchronizationState(self, context): def getSynchronizationState(self, path):
""" """
context -- the context on which we are looking for state context : the context on which we are looking for state
"""
This functions have to retrieve the synchronization state,
it will first look in the conflict list, if nothing is found,
then we have to check on a publication/subscription.
This method returns a mapping between subscription and states
"""
conflict_list = self.getConflictList()
state_list= []
LOG('getSynchronizationState',0,'path: %s' % str(path))
for conflict in conflict_list:
if conflict.getObjectPath() == path:
LOG('getSynchronizationState',0,'found a conflict: %s' % str(conflict))
state_list += [[conflict.getDomain(),self.CONFLICT]]
for domain in self.getDomainList():
destination = domain.getDestinationPath()
LOG('getSynchronizationState',0,'destination: %s' % str(destination))
j_path = '/'.join(path)
LOG('getSynchronizationState',0,'j_path: %s' % str(j_path))
if j_path.find(destination)==0:
o_id = j_path[len(destination)+1:].split('/')[0]
LOG('getSynchronizationState',0,'o_id: %s' % o_id)
subscriber_list = []
if domain.domain_type==self.PUB:
subscriber_list = domain.getSubscriberList()
else:
subscriber_list = [domain]
for subscriber in subscriber_list:
signature = subscriber.getSignature(o_id)
if signature is not None:
state = signature.getStatus()
found = None
# Make sure there is not already a conflict giving the state
for state_item in state_list:
if state_item[0]==subscriber:
found = 1
if found is None:
state_list += [[subscriber,state]]
return state_list
def manageLocalValue(self, domain, domain_id, object_path, RESPONSE=None): def manageLocalValue(self, domain, domain_id, object_path, RESPONSE=None):
""" """
......
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