Commit fb9162fb authored by Sebastien Robin's avatar Sebastien Robin

modified the syncml tool so that it is a folder. Now ERP5Sycml use

folders instead of dictionnaries


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@1003 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent f3a5bd3b
......@@ -29,6 +29,10 @@
from Globals import Persistent, PersistentMapping
from SyncCode import SyncCode
from Subscription import Subscription
from Products.ERP5Type import Permissions
from Products.ERP5Type.Document.Folder import Folder
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import PropertySheet
class Subscriber(Subscription):
......@@ -44,7 +48,7 @@ class Subscriber(Subscription):
next_anchor - it defines the id of the current synchronisation
"""
def __init__(self, subscription_url):
def __init__(self, id, subscription_url):
"""
constructor
"""
......@@ -53,6 +57,7 @@ class Subscriber(Subscription):
self.next_anchor = '00000000T000000Z'
self.session_id = 0
self.signatures = {}
Folder.__init__(self, id)
def ReceiveDocuments(self):
"""
......@@ -75,6 +80,16 @@ class Subscriber(Subscription):
as conflicting)
"""
def addPublication( self, id, title='', REQUEST=None ):
"""
Add a new Category and generate UID by calling the
ZSQLCatalog
"""
o = Publication( id ,'','','','','')
self._setObject( id, o )
if REQUEST is not None:
return self.manage_main(self, REQUEST, update_menu=1)
return o
class Publication(Subscription):
"""
......@@ -93,11 +108,32 @@ class Publication(Subscription):
list_subscribers -- a list of subsbribtions
"""
# Default Values
list_subscribers = PersistentMapping()
meta_type='ERP5 Publication'
portal_type='Publication' # may be useful in the future...
isPortalContent = 1
isRADContent = 1
icon = None
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.SimpleItem )
allowed_types = ( 'Signatures',)
# Declarative security
security = ClassSecurityInfo()
security.declareProtected(Permissions.ManagePortal,
'manage_editProperties',
'manage_changeProperties',
'manage_propertiesForm',
)
# Declarative constructors
constructors = (addPublication,)
# Constructor
def __init__(self, id, publication_url, destination_path, query, xml_mapping, gpg_key):
def __init__(self, id, title, publication_url, destination_path, query, xml_mapping, gpg_key):
"""
constructor
"""
......@@ -106,11 +142,13 @@ class Publication(Subscription):
self.destination_path = destination_path
self.setQuery(query)
self.xml_mapping = xml_mapping
self.list_subscribers = PersistentMapping()
#self.list_subscribers = PersistentMapping()
self.domain_type = self.PUB
self.gpg_key = gpg_key
self.setGidGenerator(None)
self.setIdGenerator(None)
Folder.__init__(self, id)
self.title = title
def getPublicationUrl(self):
"""
......@@ -137,51 +175,43 @@ class Publication(Subscription):
"""
# We have to remove the subscriber if it already exist (there were probably a reset on the client)
self.delSubscriber(subscriber.getSubscriptionUrl())
if len(self.list_subscribers) == 0:
self.list_subscribers = []
self.list_subscribers = self.list_subscribers + [subscriber]
def searchSubscriber(self, subscription_url):
"""
search if subscriber is in the list or not
"""
for f in range(len(self.list_subscribers)):
if self.list_subscribers[f].subscription_url == subscription_url:
return 1
return None
new_id = str(self.generateNewId())
subscriber.id = new_id
#if len(self.list_subscribers) == 0:
# self.list_subscribers = []
#self.list_subscribers = self.list_subscribers + [subscriber]
self._setObject(new_id,subscriber)
def getSubscriber(self, subscription_url):
"""
return the subscriber corresponding the to subscription_url
"""
for f in range(len(self.list_subscribers)):
if self.list_subscribers[f].subscription_url == subscription_url:
return self.list_subscribers[f].__of__(self)
for o in self.objectValues():
if o.getSubscriptionUrl() == subscription_url:
return o
return None
def getSubscriberList(self):
"""
Get the list of subscribers
"""
list_subscribers = []
for f in range(len(self.list_subscribers)):
list_subscribers += [self.list_subscribers[f]]
return list_subscribers
return self.objectValues()
def delSubscriber(self, subscription_url):
"""
Delete a subscriber for this publication
"""
for f in range(len(self.list_subscribers)):
if self.list_subscribers[f].subscription_url == subscription_url:
self.list_subscribers = self.list_subscribers[0:f] + \
self.list_subscribers[f+1:len(self.list_subscribers)]
for o in self.objectValues():
if o.getSubscriptionUrl() == subscription_url:
self._delObject(o.id)
def resetAllSubscribers(self):
"""
Reset all subscribers
"""
self.list_subscribers = PersistentMapping()
for o in self.objectValues():
self._delObject(o.id)
def getConflictList(self):
"""
......
......@@ -138,7 +138,7 @@ class PublicationSynchronization(XMLSyncUtils):
# Get the subscriber or create it if not already in the list
subscriber = self.getPublication(id).getSubscriber(subscription_url)
if subscriber == None:
subscriber = Subscriber(subscription_url)
subscriber = Subscriber(self.generateNewId(),subscription_url)
subscriber.setXMLMapping(publication.getXMLMapping())
self.getPublication(id).addSubscriber(subscriber)
# first synchronization
......@@ -156,8 +156,6 @@ class PublicationSynchronization(XMLSyncUtils):
result = self.PubSyncInit(publication=self.getPublication(id),
xml_client=None, subscriber=subscriber,sync_type=self.TWO_WAY)
has_response = 1 #pubsync always replies to messages
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
elif result is not None:
......
......@@ -29,13 +29,19 @@
from Globals import PersistentMapping
from time import gmtime,strftime # for anchors
from SyncCode import SyncCode
from AccessControl import ClassSecurityInfo
from Products.CMFCore.utils import getToolByName
from Acquisition import Implicit, aq_base
from Products.ERP5Type.Document.Folder import Folder
from Products.ERP5Type.Base import Base
from Products.ERP5Type import Permissions
from Products.ERP5Type import PropertySheet
from zLOG import LOG
import md5
class Conflict(SyncCode, Implicit):
#class Conflict(SyncCode, Implicit):
class Conflict(SyncCode, Base):
"""
object_path : the path of the obect
keyword : an identifier of the conflict
......@@ -206,7 +212,7 @@ class Conflict(SyncCode, Implicit):
"""
return self.keyword
class Signature(SyncCode):
class Signature(SyncCode,Folder):
"""
status -- SENT, CONFLICT...
md5_object -- An MD5 value of a given document
......@@ -233,12 +239,6 @@ class Signature(SyncCode):
self.setSubscriberXupdate(None)
self.setPublisherXupdate(None)
#def __init__(self,object=None, status=None, xml_string=None):
# self.uid = object.uid
# self.id = object.id
# self.status = status
# self.setXML(xml_string)
def setStatus(self, status):
"""
set the Status (see SyncCode for numbers)
......@@ -397,11 +397,9 @@ 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))
if type(xml) is type(u'a'):
xml = xml.encode('utf-8')
self.partial_xml = xml
#LOG('Subscriber.setPartialXML after',0,'partial_xml: %s' % str(self.partial_xml))
def getPartialXML(self):
"""
......@@ -466,7 +464,19 @@ class Signature(SyncCode):
else:
self.resetConflictList()
class Subscription(SyncCode, Implicit):
def addSubscription( self, id, title='', REQUEST=None ):
"""
Add a new Category and generate UID by calling the
ZSQLCatalog
"""
o = Subscription( id ,'','','','','','')
self._setObject( id, o )
if REQUEST is not None:
return self.manage_main(self, REQUEST, update_menu=1)
return o
#class Subscription(SyncCode, Implicit):
class Subscription(SyncCode, Implicit, Folder):
"""
Subscription hold the definition of a master ODB
from/to which a selection of objects will be synchronised
......@@ -502,10 +512,32 @@ class Subscription(SyncCode, Implicit):
"""
signatures = PersistentMapping()
meta_type='ERP5 Subscription'
portal_type='Subscription' # may be useful in the future...
isPortalContent = 1
isRADContent = 1
icon = None
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.SimpleItem )
allowed_types = ( 'Signatures',)
# Declarative constructors
constructors = (addSubscription,)
# Declarative security
security = ClassSecurityInfo()
security.declareProtected(Permissions.ManagePortal,
'manage_editProperties',
'manage_changeProperties',
'manage_propertiesForm',
)
# Constructor
def __init__(self, id, 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, gpg_key):
"""
We need to create a dictionnary of
signatures of documents which belong to the synchronisation
......@@ -519,16 +551,30 @@ class Subscription(SyncCode, Implicit):
self.xml_mapping = xml_mapping
self.anchor = None
self.session_id = 0
self.signatures = PersistentMapping()
#self.signatures = PersistentMapping()
self.last_anchor = '00000000T000000Z'
self.next_anchor = '00000000T000000Z'
self.domain_type = self.SUB
self.gpg_key = gpg_key
self.setGidGenerator(None)
self.setIdGenerator(None)
Folder.__init__(self, id)
self.title = title
#self.signatures = PersitentMapping()
def getTitle(self):
"""
getter for title
"""
return getattr(self,'title',None)
def setTitle(self, value):
"""
setter for title
"""
self.title = value
# Accessors
def getRemoteId(self, id, path=None):
"""
......@@ -544,16 +590,15 @@ class Subscription(SyncCode, Implicit):
# 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()
for o in self.objectValues():
dict_sign[o.getId()] = o.getStatus()
LOG('getSignature',0,'signatures_status: %s' % str(dict_sign))
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
code = self.SLOW_SYNC
if len(self.signatures.keys()) > 0:
if len(self.objectValues()) > 0:
code = self.TWO_WAY
if default is not None:
code = default
LOG('Subscription',0,'getSynchronizationType keys: %s' % str(self.signatures.keys()))
LOG('Subscription',0,'getSynchronizationType: %s' % code)
return code
......@@ -620,6 +665,12 @@ class Subscription(SyncCode, Implicit):
"""
return getattr(self,'gpg_key','')
def setGPGKey(self, value):
"""
setter for the gnupg key name
"""
self.gpg_key = value
def setQuery(self, query):
"""
set the query
......@@ -739,7 +790,7 @@ class Subscription(SyncCode, Implicit):
# query_list = query()
# return query_list
def generateNewId(self, object=None,gid=None):
def generateNewIdWithGenerator(self, object=None,gid=None):
"""
This tries to generate a new Id
"""
......@@ -858,54 +909,50 @@ class Subscription(SyncCode, Implicit):
"""
add a Signature to the subscription
"""
self.signatures[signature.getGid()] = signature
self._setObject( signature.getGid(), signature )
def delSignature(self, gid):
"""
add a Signature to the subscription
"""
del self.signatures[gid]
#del self.signatures[gid]
self._delObject(gid)
def getSignature(self, gid):
"""
add a Signature to the subscription
"""
# This is just a test XXX To be removed
#dict = {}
#for key in self.signatures.keys():
# dict[key]=self.signatures[key].getPartialXML()
#LOG('Subscription',0,'dict: %s' % str(dict))
if self.signatures.has_key(gid):
return self.signatures[gid]
return None
o = None
if gid in self.objectIds():
o = self._getOb(gid)
return o
def getSignatureList(self):
"""
add a Signature to the subscription
"""
signature_list = []
for key in self.signatures.keys():
signature_list += [self.signatures[key]]
return signature_list
return self.objectValues()
def hasSignature(self, gid):
"""
Check if there's a signature with this uid
"""
LOG('Subscription',0,'keys: %s' % str(self.signatures.keys()))
return self.signatures.has_key(gid)
#return self.signatures.has_key(gid)
return gid in self.objectIds()
def resetAllSignatures(self):
"""
Reset all signatures
"""
self.signatures = PersistentMapping()
#self.signatures = PersistentMapping()
for o in self.objectValues():
self._delObject(o.id)
def getGidList(self):
"""
Returns the list of ids from signature
"""
return self.signatures.keys()
return self.objectIds()
def getConflictList(self):
"""
......@@ -920,17 +967,10 @@ class Subscription(SyncCode, Implicit):
"""
Set the status of every object as NOT_SYNCHRONIZED
"""
# 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('startSynchronization',0,'signatures_status: %s' % str(dict_sign))
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
for object_id in self.signatures.keys():
for o in self.objectValues():
# 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,
if not(o.getStatus() in (self.CONFLICT,self.PUB_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)
o.setStatus(self.NOT_SYNCHRONIZED)
o.setPartialXML(None)
o.setTempXML(None)
......@@ -29,13 +29,15 @@ ERP portal_synchronizations tool.
"""
from OFS.SimpleItem import SimpleItem
from OFS.Folder import Folder
from Products.ERP5Type.Document.Folder import Folder
from Products.ERP5Type.Base import Base
from Products.CMFCore.utils import UniqueObject
from Globals import InitializeClass, DTMLFile, PersistentMapping, Persistent
from AccessControl import ClassSecurityInfo, getSecurityManager
from Products.CMFCore import CMFCorePermissions
from Products.ERP5SyncML import _dtmldir
from Publication import Publication,Subscriber
from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2
from Subscription import Subscription,Signature
from xml.dom.ext.reader.Sax2 import FromXmlStream, FromXml
from xml.dom.minidom import parse, parseString
......@@ -59,11 +61,8 @@ from zLOG import LOG
from Conduit.ERP5Conduit import ERP5Conduit
class SynchronizationError( Exception ):
pass
class SynchronizationTool( UniqueObject, SimpleItem,
SubscriptionSynchronization, PublicationSynchronization ):
class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronization,
UniqueObject, Folder, Base):
"""
This tool implements the synchronization algorithm
"""
......@@ -89,9 +88,10 @@ class SynchronizationTool( UniqueObject, SimpleItem,
email = 1
same_export = 1
def __init__( self ):
self.list_publications = PersistentMapping()
self.list_subscriptions = PersistentMapping()
# Multiple inheritance inconsistency caused by Base must be circumvented
def __init__( self, *args, **kwargs ):
Folder.__init__(self, self.id, **kwargs)
#
# ZMI methods
......@@ -109,7 +109,7 @@ class SynchronizationTool( UniqueObject, SimpleItem,
, 'action' : 'manageConflicts'
}
)
+ SimpleItem.manage_options
+ Folder.manage_options
)
security.declareProtected( CMFCorePermissions.ManagePortal
......@@ -156,82 +156,107 @@ class SynchronizationTool( UniqueObject, SimpleItem,
)
security.declareProtected(Permissions.ModifyPortalContent, 'manage_addPublication')
def manage_addPublication(self, id, publication_url, destination_path,
def manage_addPublication(self, title, publication_url, destination_path,
query, xml_mapping, gpg_key, RESPONSE=None):
"""
create a new publication
"""
pub = Publication(id, publication_url, destination_path,
#if not('publications' in self.objectIds()):
# publications = Folder('publications')
# self._setObject(publications.id, publications)
new_id = self.getPublicationIdFromTitle(title)
pub = Publication(new_id, title, publication_url, destination_path,
query, xml_mapping, gpg_key)
if len(self.list_publications) == 0:
self.list_publications = PersistentMapping()
self.list_publications[id] = pub
self._setObject( new_id, pub )
#if len(self.list_publications) == 0:
# self.list_publications = PersistentMapping()
#self.list_publications[id] = pub
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
security.declareProtected(Permissions.ModifyPortalContent, 'manage_addSubscription')
def manage_addSubscription(self, id, publication_url, subscription_url,
def manage_addSubscription(self, title, publication_url, subscription_url,
destination_path, query, xml_mapping, gpg_key, RESPONSE=None):
"""
XXX should be renamed as addSubscription
create a new subscription
"""
sub = Subscription(id, publication_url, subscription_url,
#if not('subscriptions' in self.objectIds()):
# subscriptions = Folder('subscriptions')
# self._setObject(subscriptions.id, subscriptions)
new_id = self.getSubscriptionIdFromTitle(title)
sub = Subscription(new_id, title, publication_url, subscription_url,
destination_path, query, xml_mapping, gpg_key)
if len(self.list_subscriptions) == 0:
self.list_subscriptions = PersistentMapping()
self.list_subscriptions[id] = sub
self._setObject( new_id, sub )
#if len(self.list_subscriptions) == 0:
# self.list_subscriptions = PersistentMapping()
#self.list_subscriptions[id] = sub
if RESPONSE is not None:
RESPONSE.redirect('manageSubscriptions')
security.declareProtected(Permissions.ModifyPortalContent, 'manage_editPublication')
def manage_editPublication(self, id, publication_url, destination_path,
def manage_editPublication(self, title, publication_url, destination_path,
query, xml_mapping, gpg_key, RESPONSE=None):
"""
modify a publication
"""
pub = Publication(id, publication_url, destination_path,
query, xml_mapping, gpg_key)
self.list_publications[id] = pub
id = self.getPublicationIdFromTitle(title)
pub = self._getOb(id)
pub.setTitle(title)
pub.setPublicationUrl(publication_url)
pub.setDestinationPath(destination_path)
pub.setQuery(query)
pub.setXMLMapping(xml_mapping)
pub.setGPGKey(gpg_key)
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
security.declareProtected(Permissions.ModifyPortalContent, 'manage_editSubscription')
def manage_editSubscription(self, id, publication_url, subscription_url,
def manage_editSubscription(self, title, publication_url, subscription_url,
destination_path, query, xml_mapping, gpg_key, RESPONSE=None):
"""
modify a subscription
"""
sub = Subscription(id, publication_url, subscription_url,
destination_path, query, xml_mapping, gpg_key)
self.list_subscriptions[id] = sub
id = self.getSubscriptionIdFromTitle(title)
sub = self._getOb(id)
sub.setTitle(title)
sub.setPublicationUrl(publication_url)
sub.setDestinationPath(destination_path)
sub.setQuery(query)
sub.setXMLMapping(xml_mapping)
sub.setGPGKey(gpg_key)
sub.setSubscriptionUrl(subscription_url)
if RESPONSE is not None:
RESPONSE.redirect('manageSubscriptions')
security.declareProtected(Permissions.ModifyPortalContent, 'manage_deletePublication')
def manage_deletePublication(self, id, RESPONSE=None):
def manage_deletePublication(self, title, RESPONSE=None):
"""
delete a publication
"""
del self.list_publications[id]
id = self.getPublicationIdFromTitle(title)
self._delObject(id)
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
security.declareProtected(Permissions.ModifyPortalContent, 'manage_deleteSubscription')
def manage_deleteSubscription(self, id, RESPONSE=None):
def manage_deleteSubscription(self, title, RESPONSE=None):
"""
delete a subscription
"""
del self.list_subscriptions[id]
id = self.getSubscriptionIdFromTitle(title)
self._delObject(id)
if RESPONSE is not None:
RESPONSE.redirect('manageSubscriptions')
security.declareProtected(Permissions.ModifyPortalContent, 'manage_resetPublication')
def manage_resetPublication(self, id, RESPONSE=None):
def manage_resetPublication(self, title, RESPONSE=None):
"""
reset a publication
"""
self.list_publications[id].resetAllSubscribers()
id = self.getPublicationIdFromTitle(title)
pub = self.getObject(id)
pub.resetAllSubscribers()
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
......@@ -240,8 +265,10 @@ class SynchronizationTool( UniqueObject, SimpleItem,
"""
reset a subscription
"""
self.list_subscriptions[id].resetAllSignatures()
self.list_subscriptions[id].resetAnchors()
id = self.getSubscriptionIdFromTitle(title)
sub = self.getObject(id)
sub.resetAllSignatures()
sub.resetAnchors()
if RESPONSE is not None:
RESPONSE.redirect('manageSubscriptions')
......@@ -250,23 +277,18 @@ class SynchronizationTool( UniqueObject, SimpleItem,
"""
Return a list of publications
"""
return_list = []
if type(self.list_publications) is type([]): # For compatibility with old
# SynchronizationTool, XXX To be removed
self.list_publications = PersistentMapping()
for key in self.list_publications.keys():
LOG('getPublicationList',0,'key: %s, pub:%s' % (key,repr(self.list_publications[key])))
return_list += [self.list_publications[key].__of__(self)]
return return_list
object_list = self.objectValues()
object_list = filter(lambda x: x.id.find('pub')==0,object_list)
return object_list
security.declareProtected(Permissions.AccessContentsInformation,'getPublication')
def getPublication(self, id):
def getPublication(self, title):
"""
Return the publications with this id
"""
#self.list_publications=PersistentMapping()
if self.list_publications.has_key(id):
return self.list_publications[id].__of__(self)
for p in self.getPublicationList():
if p.getTitle() == title:
return p
return None
security.declareProtected(Permissions.AccessContentsInformation,'getSubscriptionList')
......@@ -274,21 +296,17 @@ class SynchronizationTool( UniqueObject, SimpleItem,
"""
Return a list of publications
"""
return_list = []
if type(self.list_subscriptions) is type([]): # For compatibility with old
# SynchronizationTool, XXX To be removed
self.list_subscriptions = PersistentMapping()
for key in self.list_subscriptions.keys():
return_list += [self.list_subscriptions[key].__of__(self)]
return return_list
object_list = self.objectValues()
object_list = filter(lambda x: x.id.find('sub')==0,object_list)
return object_list
def getSubscription(self, id):
def getSubscription(self, title):
"""
Returns the subscription with this id
"""
for subscription in self.getSubscriptionList():
if subscription.getId()==id:
return subscription
for s in self.getSubscriptionList():
if s.getTitle() == title:
return s
return None
......@@ -735,7 +753,7 @@ class SynchronizationTool( UniqueObject, SimpleItem,
if len(message_list) == 0:
for subscription in self.getSubscriptionList():
LOG('sync, subcription:',0,subscription)
self.activate(activity='RAMQueue').SubSync(subscription.getId())
self.activate(activity='RAMQueue').SubSync(subscription.getTitle())
security.declarePublic('readResponse')
def readResponse(self, text=None, sync_id=None, to_url=None, from_url=None):
......@@ -758,11 +776,11 @@ class SynchronizationTool( UniqueObject, SimpleItem,
# to know if we will call a publication or subscription XXX
gpg_key = ''
for publication in self.getPublicationList():
if publication.getId()==sync_id:
if publication.getTitle()==sync_id:
gpg_key = publication.getGPGKey()
if gpg_key == '':
for subscription in self.getSubscriptionList():
if subscription.getId()==sync_id:
if subscription.getTitle()==sync_id:
gpg_key = subscription.getGPGKey()
# decrypt the message if needed
if gpg_key not in (None,''):
......@@ -791,14 +809,14 @@ class SynchronizationTool( UniqueObject, SimpleItem,
if subnode2.nodeName == 'Target':
url = subnode2.childNodes[0].data
for publication in self.getPublicationList():
if publication.getPublicationUrl()==url and publication.getId()==sync_id:
if publication.getPublicationUrl()==url and publication.getTitle()==sync_id:
result = self.PubSync(sync_id,xml)
# Then encrypt the message
xml = result['xml']
xml = self.sendResponse(xml=xml,domain=publication,send=0)
return xml
for subscription in self.getSubscriptionList():
if subscription.getSubscriptionUrl()==url and subscription.getId()==sync_id:
if subscription.getSubscriptionUrl()==url and subscription.getTitle()==sync_id:
result = self.activate(activity='RAMQueue').SubSync(sync_id,xml)
#result = self.SubSync(sync_id,xml)
......@@ -818,4 +836,25 @@ class SynchronizationTool( UniqueObject, SimpleItem,
xml = None
return xml
security.declareProtected(Permissions.ModifyPortalContent, 'getPublicationIdFromTitle')
def getPublicationIdFromTitle(self, title):
"""
simply return an id from a title
"""
return 'pub_' + title
security.declareProtected(Permissions.ModifyPortalContent, 'getPublicationIdFromTitle')
def getSubscriptionIdFromTitle(self, title):
"""
simply return an id from a title
"""
return 'sub_' + title
InitializeClass( SynchronizationTool )
......@@ -43,7 +43,7 @@ except ImportError:
import commands
from zLOG import LOG
class XMLSyncUtilsMixin(SyncCode, ActiveObject):
class XMLSyncUtilsMixin(SyncCode):
def SyncMLHeader(self, session_id, msg_id, target, source):
"""
......@@ -748,7 +748,7 @@ class XMLSyncUtilsMixin(SyncCode, ActiveObject):
if next_action.nodeName == 'Add':
# Then store the xml of this new subobject
if object is None:
object_id = domain.generateNewId(object=destination_path)
object_id = domain.generateNewIdWithGenerator(object=destination_path)
conflict_list += conduit.addNode(xml=data_subnode, object=destination_path,
object_id=object_id)
object = domain.getObjectFromGid(object_gid)
......
......@@ -40,18 +40,30 @@ document_classes = generateInitFiles(this_module, globals())
# Update ERP5 Globals
from Products.ERP5Type.Utils import initializeProduct, updateGlobals
import Interface, PropertySheet, Permissions, Constraint
updateGlobals( this_module, globals(),
property_sheet_module = PropertySheet,
interface_module = Interface,
permissions_module = Permissions,
constraint_module = Constraint)
# Define object classes and tools
import SynchronizationTool
object_classes = ()
object_classes = (Subscription.Subscription, Publication.Publication,)
portal_tools = (SynchronizationTool.SynchronizationTool,)
content_classes = ()
content_constructors = ()
# Finish installation
def initialize( context ):
import Document
initializeProduct(context, this_module, globals(),
document_module = Document,
document_classes = document_classes,
object_classes = object_classes,
portal_tools = portal_tools,
content_constructors = content_constructors,
content_classes = content_classes)
......@@ -40,11 +40,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" value="<dtml-var getId>" size="40"/>
<input type="text" name="title" value="<dtml-var getTitle>" size="40"/>
</td>
</tr>
<tr>
......@@ -107,12 +107,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<form action="manage_resetPublication" method="POST">
<td align="left" valign="top">
<input type="submit" value=" Reset ">
<input type="hidden" name="id" value="<dtml-var getId>" >
<input type="hidden" name="title" value="<dtml-var getTitle>" >
</form>
<form action="manage_deletePublication" method="POST">
<td align="left" valign="top">
<input type="submit" value=" Delete ">
<input type="hidden" name="id" value="<dtml-var getId>" >
<input type="hidden" name="title" value="<dtml-var getTitle>" >
</form>
</td>
</tr>
......
......@@ -40,11 +40,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" value="<dtml-var getId>" size="40"/>
<input type="text" name="title" value="<dtml-var getTitle>" size="40"/>
</td>
</tr>
<tr>
......@@ -117,17 +117,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<form action="SubSync" method="POST">
<td align="left" valign="top">
<input type="submit" value=" Sync ">
<input type="hidden" name="id" value="<dtml-var getId>" >
<input type="hidden" name="title" value="<dtml-var getTitle>" >
</form>
<form action="manage_resetSubscription" method="POST">
<td align="left" valign="top">
<input type="submit" value=" Reset ">
<input type="hidden" name="id" value="<dtml-var getId>" >
<input type="hidden" name="title" value="<dtml-var getTitle>" >
</form>
<form action="manage_deleteSubscription" method="POST">
<td align="left" valign="top">
<input type="submit" value=" Delete ">
<input type="hidden" name="id" value="<dtml-var getId>" >
<input type="hidden" name="title" value="<dtml-var getTitle>" >
</form>
</td>
</tr>
......
......@@ -36,11 +36,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40" />
<input type="text" name="title" size="40" />
</td>
</tr>
<tr>
......
......@@ -36,11 +36,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40" />
<input type="text" name="title" size="40" />
</td>
</tr>
<tr>
......
......@@ -318,10 +318,10 @@ class TestERP5SyncML(ERP5TypeTestCase):
file.write('')
file.close()
nb_message = 1
result = portal_sync.SubSync(subscription.getId())
result = portal_sync.SubSync(subscription.getTitle())
while result['has_response']==1:
portal_sync.PubSync(publication.getId())
result = portal_sync.SubSync(subscription.getId())
portal_sync.PubSync(publication.getTitle())
result = portal_sync.SubSync(subscription.getTitle())
nb_message += 1 + result['has_response']
return nb_message
......@@ -349,16 +349,16 @@ class TestERP5SyncML(ERP5TypeTestCase):
file.write('')
file.close()
nb_message = 1
result = portal_sync.SubSync(subscription.getId())
result = portal_sync.SubSync(subscription.getTitle())
while result['has_response']==1:
# We do thing three times, so that we will test
# if we manage well duplicate messages
portal_sync.PubSync(publication.getId())
portal_sync.PubSync(publication.getId())
portal_sync.PubSync(publication.getId())
result = portal_sync.SubSync(subscription.getId())
result = portal_sync.SubSync(subscription.getId())
result = portal_sync.SubSync(subscription.getId())
portal_sync.PubSync(publication.getTitle())
portal_sync.PubSync(publication.getTitle())
portal_sync.PubSync(publication.getTitle())
result = portal_sync.SubSync(subscription.getTitle())
result = portal_sync.SubSync(subscription.getTitle())
result = portal_sync.SubSync(subscription.getTitle())
nb_message += 1 + result['has_response']
return nb_message
......@@ -372,13 +372,22 @@ class TestERP5SyncML(ERP5TypeTestCase):
self.login()
self.setupPublicationAndSubscription(quiet=1,run=1)
nb_person = self.populatePersonServer(quiet=1,run=1)
portal_sync = self.getSynchronizationTool()
for sub in portal_sync.getSubscriptionList():
self.assertEquals(sub.getSynchronizationType(),SyncCode.SLOW_SYNC)
# Synchronize the first client
nb_message1 = self.synchronize(self.sub_id1)
for sub in portal_sync.getSubscriptionList():
if sub.getTitle() == self.sub_id1:
self.assertEquals(sub.getSynchronizationType(),SyncCode.TWO_WAY)
else:
self.assertEquals(sub.getSynchronizationType(),SyncCode.SLOW_SYNC)
self.failUnless(nb_message1==self.nb_message_first_synchronization)
# Synchronize the second client
nb_message2 = self.synchronize(self.sub_id2)
for sub in portal_sync.getSubscriptionList():
self.assertEquals(sub.getSynchronizationType(),SyncCode.TWO_WAY)
self.failUnless(nb_message2==self.nb_message_first_synchronization)
portal_sync = self.getSynchronizationTool()
subscription1 = portal_sync.getSubscription(self.sub_id1)
subscription2 = portal_sync.getSubscription(self.sub_id2)
self.failUnless(len(subscription1.getObjectList())==nb_person)
......@@ -1153,6 +1162,43 @@ class TestERP5SyncML(ERP5TypeTestCase):
self.failUnless(person1_c.getLastName()==self.last_name1)
SyncCode.MAX_LINES = previous_max_lines
def testGetSynchronizationType(self, quiet=0, run=run_all_test):
# We will try to update some simple data, first
# we change on the server side, the on the client side
if not run: return
if not quiet:
ZopeTestCase._print('\nTest Get Synchronization Type ')
LOG('Testing... ',0,'testGetSynchronizationType')
self.testFirstSynchronization(quiet=1,run=1)
# First we do only modification on server
# Check for each subsription that the synchronization type
# is TWO WAY
portal_sync = self.getSynchronizationTool()
for sub in portal_sync.getSubscriptionList():
self.assertEquals(sub.getSynchronizationType(),SyncCode.TWO_WAY)
person_server = self.getPersonServer()
person1_s = person_server._getOb(self.id1)
kw = {'first_name':self.first_name3,'last_name':self.last_name3}
person1_s.edit(**kw)
self.synchronize(self.sub_id1)
# Then we do only modification on a client
person_client1 = self.getPersonClient1()
person1_c = person_client1._getOb(self.id1)
kw = {'first_name':self.first_name1,'last_name':self.last_name1}
person1_c.edit(**kw)
self.synchronize(self.sub_id1)
for sub in portal_sync.getSubscriptionList():
self.assertEquals(sub.getSynchronizationType(),SyncCode.TWO_WAY)
# Then we do only modification on both the client and the server
# and of course, on the same object
kw = {'first_name':self.first_name3}
person1_s.edit(**kw)
kw = {'description':self.description3}
person1_c.edit(**kw)
self.synchronize(self.sub_id1)
for sub in portal_sync.getSubscriptionList():
self.assertEquals(sub.getSynchronizationType(),SyncCode.TWO_WAY)
# We may add a test in order to check if the slow_sync mode works fine, ie
# if we do have both object on the client and server side, we must make sure
# that the server first sends is own data
......
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