# -*- coding: utf-8 -*- ############################################################################## # # Copyright (c) 2007 Nexedi SARL and Contributors. All Rights Reserved. # Fabien Morin <fabien.morin@gmail.com> # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsability of assessing all potential # consequences resulting from its eventual inadequacies and bugs # End users who are looking for a ready-to-use solution with commercial # garantees and support are strongly adviced to contract a Free Software # Service Company # # This program is Free Software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################## from zope.interface import Interface class IConduit(Interface): """ A conduit is a piece of code in charge of - updating an object attributes from an XUpdate XML stream (Conduits are not in charge of creating new objects which are eventually missing in a synchronization process) If an object has be created during a synchronization process, the way to proceed consists in: 1- creating an empty instance of the appropriate class in the appropriate directory 2- updating that empty instance with the conduit The first implementation of ERP5 synchronization will define a default location to create new objects and a default class. This will be defined at the level of the synchronization tool XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx Look carefully when we are adding elements, for example, when we do 'insert-after', with 2 xupdate:element, so adding 2 differents objects, actually it adds only XXXX one XXX object In this case the getSubObjectDepth(), doesn't have too much sence XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX There is also one problem, when we synchronize a conflict, we are not waiting the response of the client, so that we are not sure if it take into account, we may have CONFLICT_NOT_SYNCHRONIZED AND CONFLICT_SYNCHRONIZED XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX """ def constructContent(object, object_id, portal_type): """ This allows to specify how to construct a new content. This is really usefull if you want to write your own Conduit. object: from where new content is created object_id: id of the new object portal_type: portal_type of the new object return newObject, reset_local_roles boolean, reset_workflow boolean """ def addNode(xml=None, object=None, previous_xml=None, object_id=None, sub_object=None, force=0, simulate=0, **kw): """ A node is added xml : the xml wich contains what we want to add object : from where we want to add something previous_xml : the previous xml of the object, if any force : apply updates even if there's a conflict This fucntion returns conflict_list, wich is of the form, [conflict1,conflict2,...] where conclict1 is of the form : [object.getPath(),keyword,local_and_actual_value,subscriber_value] """ def deleteNode(xml=None, object=None, object_id=None, force=None, simulate=0, **kw): """ A node is deleted """ def updateNode(xml=None, object=None, previous_xml=None, force=0, simulate=0, **kw): """ A node is updated with some xupdate - xml : the xml corresponding to the update, it should be xupdate - object : the object on wich we want to apply the xupdate - [previous_xml] : the previous xml of the object, it is mandatory when we have sub objects """ def getGidFromObject(object, configurable_gid_dictionary=None): """ return the Gid composed with the object information - object is the document on which for we are building the gid. It is usefull to interogate properties of this document itself. - configurable_gid_dictionary optional argument which is supposed to be a dictionary with parameters usefull to build the GID. property_list = ordered_list of properties to interrogate prefix = string to add in first place of the outputted string safe = True or False. True means raise an error if interrogated property is empty or doesn't exists. if generated GID is empty an error is allways raised """ def getGidFromXML(xml, namespace, gid_from_xml_list): """ return the Gid composed with xml information """ def applyDiff(original_data, diff): """Patch original data with given diff and return patched data original_data - can be plain/text or text/xml data diff - diff generated with difflib or xupdate """ def generateDiff(old_data, new_data): """return a diff between old_data and new_data respecting mimetype of handled data. text/xml => xupdate plain/text => difflib """