Commit be3df2e3 authored by Sebastien Robin's avatar Sebastien Robin

added one way synchronization


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@1860 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent ea38db70
......@@ -97,7 +97,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
"""
return the string corresponding to the local encoding
"""
return "iso-8859-1"
#return "iso-8859-1"
return "utf-8"
security.declareProtected(Permissions.ModifyPortalContent, '__init__')
def __init__(self):
......
......@@ -33,6 +33,7 @@ from Products.ERP5Type import Permissions
from Products.ERP5Type.Document.Folder import Folder
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import PropertySheet
from zLOG import LOG
def addSubscriber( self, id, title='', REQUEST=None ):
"""
......@@ -83,6 +84,16 @@ class Subscriber(Subscription):
Send ACK for a group of documents
"""
def getConduit(self):
"""
Return the conduit of the publication
"""
#LOG('Subscriber.getConduit, self.getPhysicalPath()',0,self.getPhysicalPath())
#LOG('Subscriber.getConduit, self.getParent().getPhysicalPath()',0,self.aq_parent.getPhysicalPath())
#LOG('Subscriber.getConduit, self.getParent()',0,self.getParent())
return self.aq_parent.getConduit()
#return self.conduit
def SendDocuments(self):
"""
We send all the updated documents (ie. documents not marked
......@@ -142,7 +153,7 @@ class Publication(Subscription):
constructors = (addPublication,)
# Constructor
def __init__(self, id, title, publication_url, destination_path, query, xml_mapping, gpg_key):
def __init__(self, id, title, publication_url, destination_path, query, xml_mapping, conduit, gpg_key):
"""
constructor
"""
......@@ -156,6 +167,7 @@ class Publication(Subscription):
self.gpg_key = gpg_key
self.setGidGenerator(None)
self.setIdGenerator(None)
self.setConduit(conduit)
Folder.__init__(self, id)
self.title = title
......
......@@ -342,7 +342,10 @@ class Signature(Folder,SyncCode):
"""
set the XML corresponding to the object
"""
return self.xml
xml = getattr(self,'xml',None)
if xml == '':
xml = None
return xml
def setTempXML(self, xml):
"""
......@@ -610,7 +613,7 @@ class Subscription(Folder, SyncCode):
)
# Constructor
def __init__(self, id, title, publication_url, subscription_url, destination_path, query, xml_mapping, gpg_key):
def __init__(self, id, title, publication_url, subscription_url, destination_path, query, xml_mapping, conduit, gpg_key):
"""
We need to create a dictionnary of
signatures of documents which belong to the synchronisation
......@@ -621,7 +624,7 @@ class Subscription(Folder, SyncCode):
self.subscription_url = str(subscription_url)
self.destination_path = str(destination_path)
self.setQuery(query)
self.xml_mapping = xml_mapping
self.setXMLMapping(xml_mapping)
self.anchor = None
self.session_id = 0
#self.signatures = PersistentMapping()
......@@ -631,6 +634,7 @@ class Subscription(Folder, SyncCode):
self.gpg_key = gpg_key
self.setGidGenerator(None)
self.setIdGenerator(None)
self.setConduit(conduit)
Folder.__init__(self, id)
self.title = title
......@@ -675,6 +679,14 @@ class Subscription(Folder, SyncCode):
LOG('Subscription',0,'getSynchronizationType: %s' % code)
return code
def setXMLMapping(self, value):
"""
this the name of the method used in order to get the xml
"""
if value == '':
value = None
self.xml_mapping = value
def checkCorrectRemoteSessionId(self, session_id):
"""
We will see if the last session id was the same
......@@ -726,6 +738,19 @@ class Subscription(Folder, SyncCode):
"""
self.id = id
def setConduit(self, value):
"""
set the Conduit
"""
self.conduit = value
def getConduit(self):
"""
get the Conduit
"""
return getattr(self,'conduit',None)
def getQuery(self):
"""
return the query
......@@ -748,8 +773,8 @@ class Subscription(Folder, SyncCode):
"""
set the query
"""
if query in (None,''):
query = 'objectValues'
if query == '':
query = None
self.query = query
def getPublicationUrl(self):
......@@ -777,11 +802,17 @@ class Subscription(Folder, SyncCode):
xml_mapping = getattr(self,'xml_mapping','asXML')
return xml_mapping
def setXMLMapping(self, xml_mapping):
def getXMLFromObject(self,object):
"""
return the xml mapping
"""
self.xml_mapping = xml_mapping
xml_mapping = self.getXMLMapping()
xml = ''
if xml_mapping is not None:
func = getattr(object,xml_mapping,None)
if func is not None:
xml = func()
return xml
def setGidGenerator(self, method):
"""
......@@ -843,6 +874,15 @@ class Subscription(Folder, SyncCode):
LOG('getObjectFromGid',0,'returning None')
return None
# def setOneWaySyncFromServer(self,value):
# """
# If this option is enabled, then we will not
# send our own modifications
# """
# self.one_way_sync_from_server = value
#
def getObjectList(self):
"""
This returns the list of sub-object corresponding
......@@ -851,6 +891,8 @@ class Subscription(Folder, SyncCode):
destination = self.getDestination()
query = self.getQuery()
query_list = []
if query is None:
return query_list
if type(query) is type('a'):
query_method = getattr(destination,query,None)
if query_method is not None:
......
......@@ -36,6 +36,7 @@ from Globals import InitializeClass, DTMLFile, PersistentMapping, Persistent
from AccessControl import ClassSecurityInfo, getSecurityManager
from Products.CMFCore import CMFCorePermissions
from Products.ERP5SyncML import _dtmldir
from Products.ERP5SyncML import Conduit
from Publication import Publication,Subscriber
from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2
from Subscription import Subscription,Signature
......@@ -158,7 +159,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
security.declareProtected(Permissions.ModifyPortalContent, 'manage_addPublication')
def manage_addPublication(self, title, publication_url, destination_path,
query, xml_mapping, gpg_key, RESPONSE=None):
query, xml_mapping, conduit, gpg_key, RESPONSE=None):
"""
create a new publication
"""
......@@ -168,7 +169,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
folder = self.getObjectContainer()
new_id = self.getPublicationIdFromTitle(title)
pub = Publication(new_id, title, publication_url, destination_path,
query, xml_mapping, gpg_key)
query, xml_mapping, conduit, gpg_key)
folder._setObject( new_id, pub )
#if len(self.list_publications) == 0:
# self.list_publications = PersistentMapping()
......@@ -178,7 +179,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
security.declareProtected(Permissions.ModifyPortalContent, 'manage_addSubscription')
def manage_addSubscription(self, title, publication_url, subscription_url,
destination_path, query, xml_mapping, gpg_key, RESPONSE=None):
destination_path, query, xml_mapping, conduit, gpg_key, RESPONSE=None):
"""
XXX should be renamed as addSubscription
create a new subscription
......@@ -189,7 +190,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
folder = self.getObjectContainer()
new_id = self.getSubscriptionIdFromTitle(title)
sub = Subscription(new_id, title, publication_url, subscription_url,
destination_path, query, xml_mapping, gpg_key)
destination_path, query, xml_mapping, conduit, gpg_key)
folder._setObject( new_id, sub )
#if len(self.list_subscriptions) == 0:
# self.list_subscriptions = PersistentMapping()
......@@ -199,7 +200,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
security.declareProtected(Permissions.ModifyPortalContent, 'manage_editPublication')
def manage_editPublication(self, title, publication_url, destination_path,
query, xml_mapping, gpg_key, RESPONSE=None):
query, xml_mapping, conduit, gpg_key, RESPONSE=None):
"""
modify a publication
"""
......@@ -208,6 +209,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
pub.setPublicationUrl(publication_url)
pub.setDestinationPath(destination_path)
pub.setQuery(query)
pub.setConduit(conduit)
pub.setXMLMapping(xml_mapping)
pub.setGPGKey(gpg_key)
if RESPONSE is not None:
......@@ -215,7 +217,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
security.declareProtected(Permissions.ModifyPortalContent, 'manage_editSubscription')
def manage_editSubscription(self, title, publication_url, subscription_url,
destination_path, query, xml_mapping, gpg_key, RESPONSE=None):
destination_path, query, xml_mapping, conduit, gpg_key, RESPONSE=None):
"""
modify a subscription
"""
......@@ -224,6 +226,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
sub.setPublicationUrl(publication_url)
sub.setDestinationPath(destination_path)
sub.setQuery(query)
sub.setConduit(conduit)
sub.setXMLMapping(xml_mapping)
sub.setGPGKey(gpg_key)
sub.setSubscriptionUrl(subscription_url)
......@@ -370,20 +373,22 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
#conflict.setDomain('Publication')
conflict.setSubscriber(subscriber)
#conflict.setDomainId(subscriber.getId())
conflict_list += [conflict.__of__(self)]
if path is None or conflict.getObjectPath() == path:
conflict_list += [conflict.__of__(subscriber)]
for subscription in self.getSubscriptionList():
sub_conflict_list = subscription.getConflictList()
for conflict in sub_conflict_list:
#conflict.setDomain('Subscription')
conflict.setSubscriber(subscription)
#conflict.setDomainId(subscription.getId())
conflict_list += [conflict.__of__(self)]
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.__of__(self)]
return new_list
if path is None or conflict.getObjectPath() == path:
conflict_list += [conflict.__of__(subscription)]
#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.__of__(self)]
# return new_list
return conflict_list
security.declareProtected(Permissions.AccessContentsInformation,'getDocumentConflictList')
......@@ -530,7 +535,9 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
object_id = docid
if object_id in directory.objectIds():
directory._delObject(object_id)
conduit = ERP5Conduit()
#conduit = ERP5Conduit()
conduit_name = subscriber.getConduit()
conduit = getattr(getattr(Conduit,conduit_name),conduit_name)()
conduit.addNode(xml=publisher_xml,object=directory,object_id=object_id)
subscriber_document = directory._getOb(object_id)
for c in self.getConflictList(conflict.getObjectPath()):
......@@ -565,7 +572,9 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
publisher_xml = self.getXMLObject(object=publisher_object,xml_mapping = subscriber.getXMLMapping())
directory = publisher_object.aq_inner.aq_parent
object_id = self._getCopyId(publisher_object)
conduit = ERP5Conduit()
#conduit = ERP5Conduit()
conduit_name = subscriber.getConduit()
conduit = getattr(getattr(Conduit,conduit_name),conduit_name)()
conduit.addNode(xml=publisher_xml,object=directory,object_id=object_id)
subscriber_document = directory._getOb(object_id)
subscriber_document._conflict_resolution = 1
......@@ -576,7 +585,6 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
conflict.setCopyPath(copy_path)
return copy_path
security.declareProtected(Permissions.AccessContentsInformation, 'getSubscriberDocument')
def getSubscriberDocument(self, conflict):
"""
......@@ -613,7 +621,9 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
# get the signature:
LOG('p_sync.setRemoteObject, subscriber: ',0,subscriber)
signature = subscriber.getSignature(object.getId()) # XXX may be change for rid
conduit = ERP5Conduit()
#conduit = ERP5Conduit()
conduit_name = subscriber.getConduit()
conduit = getattr(getattr(Conduit,conduit_name),conduit_name)()
for xupdate in conflict.getXupdateList():
conduit.updateNode(xml=xupdate,object=object,force=1)
if solve_conflict:
......@@ -632,7 +642,6 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
directory._delObject(copy_id)
signature.setStatus(self.PUB_CONFLICT_MERGE)
security.declareProtected(Permissions.ModifyPortalContent, 'manageLocalValue')
def managePublisherValue(self, subscription_url, property_id, object_path, RESPONSE=None):
"""
......
......@@ -218,6 +218,7 @@ class XMLSyncUtilsMixin(SyncCode):
"""
xml_method = None
xml = ""
if xml_mapping is not None:
if hasattr(object,xml_mapping):
xml_method = getattr(object,xml_mapping)
elif hasattr(object,'manage_FTPget'):
......@@ -601,23 +602,12 @@ class XMLSyncUtilsMixin(SyncCode):
# Here we first check if the object was modified or not by looking at dates
if signature is not None:
signature.checkSynchronizationNeeded(object)
# LOG('getSyncMLData',0,'signature.status: %s' % str(signature.getStatus()))
# LOG('getSyncMLData',0,'signature.action: %s' % str(signature.getAction()))
# last_modification = DateTime(object.ModificationDate())
# LOG('getSyncMLData object.ModificationDate()',0,object.ModificationDate())
# last_synchronization = signature.getLastSynchronizationDate()
# parent = object.aq_parent
# # XXX CPS Specific
# #if parent.id == 'portal_repository':
# if 1:
# if last_synchronization is not None and last_modification is not None:
# if last_synchronization > last_modification:
# LOG('getSyncMLData, no modification on: ',0,object.id)
# signature.setStatus(self.SYNCHRONIZED)
status = self.SENT
more_data=0
# For the case it was never synchronized, we have to send everything
if signature==None or (signature.getXML()==None and signature.getStatus()!=self.PARTIAL) or \
if signature is not None and signature.getXMLMapping()==None:
pass
elif signature==None or (signature.getXML()==None and signature.getStatus()!=self.PARTIAL) or \
self.getAlertCode(remote_xml)==self.SLOW_SYNC:
#LOG('PubSyncModif',0,'Current object.getPath: %s' % object.getPath())
LOG('getSyncMLData',0,'no signature for gid: %s' % object_gid)
......@@ -781,10 +771,10 @@ class XMLSyncUtilsMixin(SyncCode):
LOG('applyActionList',0,'object after add: %s' % repr(object))
if object is not None:
LOG('SyncModif',0,'addNode, found the object')
mapping = getattr(object,domain.getXMLMapping(),None)
xml_object = ''
if mapping is not None:
xml_object = mapping()
#mapping = getattr(object,domain.getXMLMapping(),None)
xml_object = domain.getXMLFromObject(object)
#if mapping is not None:
# xml_object = mapping()
signature.setStatus(self.SYNCHRONIZED)
signature.setId(object.getId())
signature.setXML(xml_object)
......@@ -798,14 +788,14 @@ class XMLSyncUtilsMixin(SyncCode):
signature = subscriber.getSignature(object_gid)
LOG('SyncModif',0,'previous signature: %s' % str(signature))
previous_xml = signature.getXML()
LOG('SyncModif',0,'previous signature: %i' % len(previous_xml))
#LOG('SyncModif',0,'previous signature: %i' % len(previous_xml))
conflict_list += conduit.updateNode(xml=data_subnode, object=object,
previous_xml=signature.getXML(),force=force,
simulate=simulate)
mapping = getattr(object,domain.getXMLMapping(),None)
xml_object = ''
if mapping is not None:
xml_object = mapping()
#mapping = getattr(object,domain.getXMLMapping(),None)
xml_object = domain.getXMLFromObject(object)
#if mapping is not None:
# xml_object = mapping()
signature.setTempXML(xml_object)
if conflict_list != []:
status_code = self.CONFLICT
......@@ -922,7 +912,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
Send the server modification, this happens after the Synchronization
initialization
"""
from Products.ERP5SyncML.Conduit.ERP5Conduit import ERP5Conduit
#from Products.ERP5SyncML.Conduit.ERP5Conduit import ERP5Conduit
from Products.ERP5SyncML import Conduit
has_response = 0 #check if syncmodif replies to this messages
cmd_id = 1 # specifies a SyncML message-unique command identifier
LOG('SyncModif',0,'Starting... domain: %s' % str(domain))
......@@ -968,7 +959,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
remote_xml=remote_xml)
alert_code = self.getAlertCode(remote_xml)
conduit = ERP5Conduit()
#conduit = ERP5Conduit()
conduit_name = subscriber.getConduit()
conduit = getattr(getattr(Conduit,conduit_name),conduit_name)()
LOG('SyncModif, subscriber: ',0,subscriber)
# Then apply the list of actions
(xml_confirmation,has_next_action,cmd_id) = self.applyActionList(cmd_id=cmd_id,
......
......@@ -87,6 +87,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<input type="text" name="xml_mapping" value="<dtml-var getXMLMapping>" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Conduit
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="conduit" value="<dtml-var getConduit>" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
......
......@@ -97,6 +97,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<input type="text" name="xml_mapping" value="<dtml-var getXMLMapping>" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Conduit
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="conduit" value="<dtml-var getConduit>" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
......
......@@ -83,6 +83,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<input type="text" name="xml_mapping" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Conduit
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="conduit" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
......
......@@ -93,6 +93,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<input type="text" name="xml_mapping" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Conduit
</label></div>
</td>
<td align="left" valign="top">
<input type="text" name="conduit" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
......
This diff is collapsed.
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