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):
if portal_type == 'Workspace':
proxy_type = 'folder'
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
# Calculate rpath
utool = getToolByName(object, 'portal_url')
......@@ -184,6 +184,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
conflict_list += self.addNode(xml=sub_xml,object=sub_object,
previous_xml=sub_previous_xml, force=force)
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
wf_tool = getToolByName(object,'portal_workflow')
wf_id = self.getAttribute(xml,'id')
......@@ -199,9 +200,11 @@ class ERP5Conduit(XMLSyncUtilsMixin):
LOG('addNode, status:',0,status)
wf_tool.setStatusOf(wf_id,object,status)
elif xml.nodeName in self.local_role_list:
#return conflict_list # XXX to be removed soon
# We want to add a local role
#user = self.getParameter(xml,'user')
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]
roles = roles[1:]
object.manage_setLocalRoles(user,roles)
......@@ -217,7 +220,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
LOG('ERP5Conduit',0,'deleteNode')
LOG('ERP5Conduit',0,'deleteNode, object.id: %s' % object.getId())
conflict_list = []
xml = self.convertToXml(xml)
if xml is not None:
xml = self.convertToXml(xml)
if object_id is None:
LOG('ERP5Conduit',0,'deleteNode, SubObjectDepth: %i' % self.getSubObjectDepth(xml))
if xml.nodeName == self.xml_object_tag:
......@@ -238,6 +242,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
try:
object._delObject(object_id)
except (AttributeError, KeyError):
LOG('ERP5Conduit',0,'deleteNode, Unable to delete: %s' % str(object_id))
pass
return conflict_list
......@@ -319,10 +324,16 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if 1:
# This is a conflict
isConflict = 1
conflict_list += [Conflict(object_path=object.getPhysicalPath(),
keyword=keyword,
local_value=current_data,
remote_value=data)]
string_io = StringIO()
PrettyPrint(xml,stream=string_io)
conflict = Conflict(object_path=object.getPhysicalPath())
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
if args != {} and (isConflict==0 or force):
LOG('updateNode',0,'object._edit, args: %s' % str(args))
......
......@@ -41,13 +41,14 @@ class Conflict(SyncCode):
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):
self.object_path=object_path
self.keyword = keyword
self.setLocalValue(local_value)
self.setRemoteValue(remote_value)
self.domain = domain
self.resetXupdate()
self.domain_id = domain_id
def getObjectPath(self):
......@@ -62,6 +63,37 @@ class Conflict(SyncCode):
"""
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):
"""
get the domain
......@@ -318,10 +350,24 @@ class Signature(SyncCode):
"""
Return the actual action for a partial synchronization
"""
LOG('setConflictList, list',0,conflict_list)
if conflict_list is None:
self.resetConflictList()
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):
"""
......
......@@ -245,7 +245,13 @@ class SynchronizationTool( UniqueObject, SimpleItem,
return_list += [self.list_subscriptions[key]]
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
Here the list is as follow :
......@@ -256,23 +262,67 @@ class SynchronizationTool( UniqueObject, SimpleItem,
for publication in self.getPublicationList():
pub_conflict_list = publication.getConflictList()
for conflict in pub_conflict_list:
conflict.setDomain('Publication')
#conflict.setDomain('Publication')
conflict.setDomain(publication)
conflict.setDomainId(publication.getId())
conflict_list += [conflict]
for subscription in self.getSubscriptionList():
sub_conflict_list = subscription.getConflictList()
for conflict in sub_conflict_list:
conflict.setDomain('Subscription')
#conflict.setDomain('Subscription')
conflict.setDomain(subscription)
conflict.setDomainId(subscription.getId())
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
def getSynchronizationState(self, context):
"""
context -- the context on which we are looking for state
def getSynchronizationState(self, path):
"""
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):
"""
......
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