Commit 1ef01e23 authored by Sebastien Robin's avatar Sebastien Robin

many updates


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@227 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 3484454e
This diff is collapsed.
...@@ -29,11 +29,13 @@ ...@@ -29,11 +29,13 @@
from Globals import PersistentMapping from Globals import PersistentMapping
from time import gmtime,strftime # for anchors from time import gmtime,strftime # for anchors
from SyncCode import SyncCode from SyncCode import SyncCode
from Products.CMFCore.utils import getToolByName
from Acquisition import Implicit, aq_base
from zLOG import LOG from zLOG import LOG
import md5 import md5
class Conflict(SyncCode): class Conflict(SyncCode, Implicit):
""" """
object_path : the path of the obect object_path : the path of the obect
keyword : an identifier of the conflict keyword : an identifier of the conflict
...@@ -118,6 +120,21 @@ class Conflict(SyncCode): ...@@ -118,6 +120,21 @@ class Conflict(SyncCode):
except TypeError: # It happens when we try to store StringIO except TypeError: # It happens when we try to store StringIO
self.remote_value = None self.remote_value = None
def applyLocalValue(self):
"""
after a conflict resolution, we have decided
to keep the local version of this object
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync.applyLocalValue(self)
def applyRemoteValue(self):
"""
get the domain
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync.applyRemoteValue(self)
def setDomain(self, domain): def setDomain(self, domain):
""" """
set the domain set the domain
...@@ -148,18 +165,6 @@ class Conflict(SyncCode): ...@@ -148,18 +165,6 @@ 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):
""" """
status -- SENT, CONFLICT... status -- SENT, CONFLICT...
...@@ -179,7 +184,6 @@ class Signature(SyncCode): ...@@ -179,7 +184,6 @@ class Signature(SyncCode):
self.partial_xml = None self.partial_xml = None
self.action = None self.action = None
self.setTempXML(None) self.setTempXML(None)
self.setTempXML(None)
self.resetConflictList() self.resetConflictList()
self.md5_string = None self.md5_string = None
self.force = 0 self.force = 0
...@@ -351,23 +355,39 @@ class Signature(SyncCode): ...@@ -351,23 +355,39 @@ 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) LOG('setConflictList, list',0,conflict_list)
if conflict_list is None: if conflict_list is None or conflict_list==[]:
self.resetConflictList() self.resetConflictList()
else: else:
new_conflict_list = [] #new_conflict_list = []
# If two conflicts are on the same objects, then # If two conflicts are on the same objects, then
# we join them, so we have a conflict with many xupdate # we join them, so we have a conflict with many xupdate
for conflict in conflict_list: # for conflict in conflict_list:
found = None # found = None
for n_conflict in new_conflict_list: # for n_conflict in new_conflict_list:
if n_conflict.getObjectPath() == conflict.getObjectPath(): # if n_conflict.getObjectPath() == conflict.getObjectPath():
found = n_conflict # found = n_conflict
LOG('setConflictList, found',0,found) # LOG('setConflictList, found',0,found)
if found == None: # if found == None:
new_conflict_list += [conflict] # new_conflict_list += [conflict]
else: # else:
n_conflict.setXupdate(conflict.getXupdateList()) # n_conflict.setXupdate(conflict.getXupdateList())
self.conflict_list = new_conflict_list #self.conflict_list = new_conflict_list
self.conflict_list = conflict_list
def delConflict(self, conflict):
"""
Return the actual action for a partial synchronization
"""
LOG('delConflict, conflict',0,conflict)
conflict_list = []
for c in self.getConflictList():
LOG('delConflict, c==conflict',0,c==aq_base(conflict))
if c != aq_base(conflict):
conflict_list += [c]
if conflict_list != []:
self.setConflictList(conflict_list)
else:
self.resetConflictList()
class Subscription(SyncCode): class Subscription(SyncCode):
""" """
......
...@@ -70,7 +70,8 @@ class SyncCode(Persistent): ...@@ -70,7 +70,8 @@ class SyncCode(Persistent):
#ENCODING='iso-8859-1' #ENCODING='iso-8859-1'
NOT_EDITABLE_PROPERTY = ('id','object','uid','xupdate:element','workflow_history', action_tag = 'workflow_action'
NOT_EDITABLE_PROPERTY = ('id','object','uid','xupdate:element',action_tag,
'xupdate:attribute','local_role') 'xupdate:attribute','local_role')
XUPDATE_INSERT = ('xupdate:insert-after','xupdate:insert-before') XUPDATE_INSERT = ('xupdate:insert-after','xupdate:insert-before')
XUPDATE_ADD = ('xupdate:append',) XUPDATE_ADD = ('xupdate:append',)
...@@ -87,12 +88,13 @@ class SyncCode(Persistent): ...@@ -87,12 +88,13 @@ class SyncCode(Persistent):
dict_type_list = ('dict',) dict_type_list = ('dict',)
pickle_type_list = ('pickle',) pickle_type_list = ('pickle',)
xml_object_tag = 'object' xml_object_tag = 'object'
history_tag = 'workflow_history' #history_tag = 'workflow_history'
history_tag = 'workflow_action'
local_role_tag = 'local_role' local_role_tag = 'local_role'
local_role_list = (local_role_tag,'/'+local_role_tag) local_role_list = (local_role_tag,'/'+local_role_tag)
action_tag = 'workflow_action'
ADDABLE_PROPERTY = (local_role_tag,history_tag) ADDABLE_PROPERTY = (local_role_tag,history_tag)
sub_object_exp = "/object\[@id='.*'\]/object\[@id='.*'\]" sub_object_exp = "/object\[@id='.*'\]/object\[@id='.*'\]"
object_exp = "/object\[@id='.*'\]" object_exp = "/object\[@id='.*'\]"
sub_sub_object_exp = "/object\[@id='.*'\]/object\[@id='.*'\]/object\[@id='.*'\]" sub_sub_object_exp = "/object\[@id='.*'\]/object\[@id='.*'\]/object\[@id='.*'\]"
history_exp = "/object\[@id='.*'\]/%s\[@id='.*'\]" % history_tag history_exp = "/%s\[@id='.*'\]" % history_tag
bad_history_exp = "/%s\[@id='.*'\]/" % history_tag
...@@ -101,7 +101,7 @@ Details ...@@ -101,7 +101,7 @@ Details
and the realm of attributes we synchronise (ie. the mapping) and the realm of attributes we synchronise (ie. the mapping)
2 The slave sends the "initialisation package" (SyncML specification), in this package, 2 The slave sends the "initialisation package" (SyncML specification), in this package,
appears several elements : appears several elements :
- the SynchHdr element with several informations about the protocol used. We will - the SynchHdr element with several informations about the protocol used. We will
...@@ -128,7 +128,7 @@ Details ...@@ -128,7 +128,7 @@ Details
4 The master sends the "Initialisation package" to the client with : 4 The master sends the "Initialisation package" to the client with :
- the SynchHdr element with several informations about the protocol used, - the SynchHdr element with several informations about the protocol used,
and also authentification informations. and also authentification informations.
- the Status element, in order to respond to the alert command sent by the client. - the Status element, in order to respond to the alert command sent by the client.
...@@ -141,12 +141,8 @@ Details ...@@ -141,12 +141,8 @@ Details
for us it will be 201 wich specifies a client-initiated, two-way slow-synchronisation. for us it will be 201 wich specifies a client-initiated, two-way slow-synchronisation.
This just means that both the server and the client sends all their data. Each This just means that both the server and the client sends all their data. Each
data must specify the DTD used. data must specify the DTD used.
//4 The master updates is database with the objects from the client. Then
//the master generate an xml file of differences between the two databases (tricky if
//at the beginning the client don't have any data), differences only all objects
//corresponding to the query.
At this step, we may eventually record the subscriber in the publication At this step, we may eventually record the subscriber in the publication
of the master database for... (OPTION). This is like of the master database for... (OPTION). This is like
the subscribtion is becoming member of mail list to be informed of the subscribtion is becoming member of mail list to be informed of
...@@ -190,7 +186,7 @@ Details ...@@ -190,7 +186,7 @@ Details
1 update the slave S(tn) <- S(tn) + DM(tn) + C(tn) 1 update the slave S(tn) <- S(tn) + DM(tn) + C(tn)
Detail implementation Detail implementation
blabla blabla
...@@ -199,5 +195,5 @@ References ...@@ -199,5 +195,5 @@ References
XMLDiff - http://www.garshol.priv.no/download/xmltools/prod/xmldiff.html XMLDiff - http://www.garshol.priv.no/download/xmltools/prod/xmldiff.html
SyncML - http://www.syncml.org SyncML - http://www.syncml.org
ZSyncer - http://www.zope.org/Members/andym/ZSyncer ZSyncer - http://www.zope.org/Members/andym/ZSyncer
This diff is collapsed.
...@@ -73,23 +73,27 @@ Conflict management with n clients, n >= 2 ...@@ -73,23 +73,27 @@ Conflict management with n clients, n >= 2
I guess the best way is to just solve conflict one by one, then we are still I guess the best way is to just solve conflict one by one, then we are still
free to make another method wich solve for all versions by the same time. free to make another method wich solve for all versions by the same time.
- So we have to do : - So we have to do :
Conflict2.manageRemoteObject() Conflict2.setRemoteObject()
Conflict1.manageLocalObject() # wich is the version of D because of the previous call Conflict1.setLocalObject() # wich is the version of D because of the previous call
Conflict3.manageLocalObject() Conflict3.setLocalObject()
Conflict4.manageLocalObject() Conflict4.setLocalObject()
- May be we can do a global method, like : - May be we can do a global method, like :
Conflict2.manageGlobalRemoteObject() wich implicitly call Conflict2.setGlobalRemoteObject() wich implicitly call
Conflict1.manageLocalObject() Conflict1.setLocalObject()
and Conflict3.manageGlobalLocalObject() wich implicitly call and Conflict3.setGlobalLocalObject() wich implicitly call
Conflict4.manageLocalObject() Conflict4.setLocalObject()
- Conflict2.manageRemoteObject() have to apply all xupdate strings stored - Conflict2.setRemoteObject() have to apply all xupdate strings stored
in Conflict2 in Conflict2. Then it have to set the status as CONFLICT_CLIENT_WIN.
- Conflict3.manageLocalObject() have to set the status as SYNCHRONIZED and then - Conflict3.setLocalObject() have to set the status as CONFLICT_MERGE. How ??
it has to delete itself (Conflict3) -> How ?? - Probably the best way is to call the synchronizationTool wich know everything
Probably the best way is to call the synchronizationTool wich know everything
about subscription and subscriber. about subscription and subscriber.
- synchronizationtool.setLocalObject should have as parameter: the conflict (wich
store the subscriber), that's all
- then we can look at the signature of the object, delete the corresponding
Conflict, and if there is no conflict left, then we can set the signature
as CONFLICT_MERGE
- At this state, we do have the /w/x/truc of D, and the /w/x/machin of B, and - At this state, we do have the /w/x/truc of D, and the /w/x/machin of B, and
there is no conflict left, at least on the server side. there is no conflict left, at least on the server side.
- at the time of the next synchronization, the server should send is new version #- at the time of the next synchronization, the server should send is new version
of /w/x/truc and /w/x/machin to B, C and D, so that everyone is synchronized of /w/x/truc and /w/x/machin to B, C and D, so that everyone is synchronized
without conflict. without conflict.
\ No newline at end of file
...@@ -40,11 +40,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -40,11 +40,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<th align="left" valign="top">Local Value</th> <th align="left" valign="top">Local Value</th>
<th align="left" valign="top">Remote Value</th> <th align="left" valign="top">Remote Value</th>
</tr> </tr>
<dtml-in getConflictList> <dtml-in prefix="loop" expr="getConflictList()">
<tr> <tr>
<td align="left" valign="top"><a href="manageLocalValue?domain=<dtml-var domain>&domain_id=<dtml-var domain_id>&object_path=<dtml-var "'/'.join(object_path)">">Local</a> <a href="manageRemoteValue?domain=<dtml-var domain>&domain_id=<dtml-var domain_id>&object_path=<dtml-var "'/'.join(object_path)">">Remote</a></td> <td align="left" valign="top"><a href="manageLocalValue?subscription_url=<dtml-var expr="loop_item.getDomain().getSubscriptionUrl()">&keyword=<dtml-var keyword>&object_path=<dtml-var "'/'.join(object_path)">">Local</a> <a href="manageRemoteValue?subscription_url=<dtml-var expr="loop_item.getDomain().getSubscriptionUrl()">&keyword=<dtml-var keyword>&object_path=<dtml-var "'/'.join(object_path)">">Remote</a></td>
<td align="left" valign="top"><dtml-var expr="loop_item.getDomain().getSubscriptionUrl()"></td>
<td align="left" valign="top"><dtml-var domain></td> <td align="left" valign="top"><dtml-var domain></td>
<td align="left" valign="top"><dtml-var domain_id></td>
<td align="left" valign="top"><dtml-var "'/'.join(object_path)"></td> <td align="left" valign="top"><dtml-var "'/'.join(object_path)"></td>
<td align="left" valign="top"><dtml-var keyword></td> <td align="left" valign="top"><dtml-var keyword></td>
<td align="left" valign="top"><dtml-var local_value></td> <td align="left" valign="top"><dtml-var local_value></td>
......
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