Commit ab293d32 authored by Nicolas Delaby's avatar Nicolas Delaby

Remove default namespace of syncml streams and declare a specific prefix.

This avoid conflict between SyncML Stream and carried Data in xml w/o prefix.
Carried data must never belong to SyncML namespace even for NonQualified XML.
before:
<SyncML xmlns="SYNCML:SYNCML1.2">
...<object portal_type="Person" id="1">
  ...
   </object>
</SyncML>
after:
<syncml:SyncML xmlns:syncml="SYNCML:SYNCML1.2">
...<object portal_type="Person" id="1">
  ...
   </object>
</syncml:SyncML>
 


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@29478 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 822cab72
...@@ -641,7 +641,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -641,7 +641,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if subnode.xpath('local-name()') == property: if subnode.xpath('local-name()') == property:
return self.convertXmlValue(subnode) return self.convertXmlValue(subnode)
return None return None
def replaceIdFromXML(self, xml, new_id): def replaceIdFromXML(self, xml, new_id):
""" """
return a xml with id replace by a new id return a xml with id replace by a new id
...@@ -652,16 +652,12 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -652,16 +652,12 @@ class ERP5Conduit(XMLSyncUtilsMixin):
#copy of xml object for modification #copy of xml object for modification
from copy import deepcopy from copy import deepcopy
xml_copy = deepcopy(xml) xml_copy = deepcopy(xml)
if xml.nsmap is None or xml.nsmap == {}: if xml_copy.tag == self.xml_object_tag:
object_element = xml_copy.find(self.xml_object_tag) object_element = xml_copy
if object_element is None and xml_copy.tag == self.xml_object_tag:
object_element = xml_copy
id_element = object_element.find('id')
else: else:
object_element = xml_copy.xpath('//syncml:object', object_element = xml_copy.xpath('//object')[0]
namespaces={'syncml':xml_copy.nsmap[xml_copy.prefix]})[0] #XXXElement id will be removed from asXML
id_element = object_element.xpath('//syncml:id', id_element = object_element.xpath('./id')[0]
namespaces={'syncml':xml_copy.nsmap[xml_copy.prefix]})[0]
object_element.attrib['id'] = new_id object_element.attrib['id'] = new_id
id_element.text = new_id id_element.text = new_id
return etree.tostring(xml_copy) return etree.tostring(xml_copy)
......
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# Copyright (c) 2003 Nexedi SARL and Contributors. All Rights Reserved. # Copyright (c) 2003 Nexedi SARL and Contributors. All Rights Reserved.
...@@ -39,8 +40,11 @@ from AccessControl.SecurityManagement import newSecurityManager ...@@ -39,8 +40,11 @@ from AccessControl.SecurityManagement import newSecurityManager
import commands import commands
from DateTime import DateTime from DateTime import DateTime
from zLOG import LOG, DEBUG, INFO, WARNING from zLOG import LOG, DEBUG, INFO, WARNING
from lxml.etree import Element, SubElement
from lxml import etree from lxml import etree
from lxml.builder import ElementMaker
from SyncCode import SYNCML_NAMESPACE
nsmap = {'syncml' : SYNCML_NAMESPACE}
E = ElementMaker(namespace=SYNCML_NAMESPACE, nsmap=nsmap)
class PublicationSynchronization(XMLSyncUtils): class PublicationSynchronization(XMLSyncUtils):
""" """
...@@ -78,18 +82,17 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -78,18 +82,17 @@ class PublicationSynchronization(XMLSyncUtils):
subscriber.setSourceURI(self.getTargetURI(xml_client)) subscriber.setSourceURI(self.getTargetURI(xml_client))
subscriber.setTargetURI(self.getSourceURI(xml_client)) subscriber.setTargetURI(self.getSourceURI(xml_client))
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
#create element 'SyncML' with a default namespace #create element 'SyncML' with a default namespace
nsmap = {None : self.XHTML_NAMESPACE} xml = E.SyncML()
xml = Element('SyncML',nsmap=nsmap)
# syncml header # syncml header
xml.append(self.SyncMLHeader(subscriber.getSessionId(), xml.append(self.SyncMLHeader(subscriber.getSessionId(),
subscriber.getMessageId(), subscriber.getMessageId(),
subscriber.getSubscriptionUrl(), subscriber.getSubscriptionUrl(),
publication.getPublicationUrl())) publication.getPublicationUrl()))
# syncml body # syncml body
sync_body = SubElement(xml, 'SyncBody') sync_body = E.SyncBody()
xml.append(sync_body)
#at the begining, the code is initialised at UNAUTHORIZED #at the begining, the code is initialised at UNAUTHORIZED
auth_code = self.UNAUTHORIZED auth_code = self.UNAUTHORIZED
...@@ -197,7 +200,7 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -197,7 +200,7 @@ class PublicationSynchronization(XMLSyncUtils):
has been started from the server (forbiden)" has been started from the server (forbiden)"
# a synchronisation is always starded from a client and can't be from # a synchronisation is always starded from a client and can't be from
# a server ! # a server !
sync_body.append(Element('Final')) sync_body.append(E.Final())
xml_string = etree.tostring(xml, encoding='utf-8', pretty_print=True) xml_string = etree.tostring(xml, encoding='utf-8', pretty_print=True)
if publication.getSyncContentType() == self.CONTENT_TYPE['SYNCML_WBXML']: if publication.getSyncContentType() == self.CONTENT_TYPE['SYNCML_WBXML']:
xml_string = self.xml2wbxml(xml_string) xml_string = self.xml2wbxml(xml_string)
......
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# Copyright (c) 2003 Nexedi SARL and Contributors. All Rights Reserved. # Copyright (c) 2003 Nexedi SARL and Contributors. All Rights Reserved.
...@@ -35,8 +36,11 @@ from Conduit.ERP5Conduit import ERP5Conduit ...@@ -35,8 +36,11 @@ from Conduit.ERP5Conduit import ERP5Conduit
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from DateTime import DateTime from DateTime import DateTime
from zLOG import LOG, DEBUG, INFO from zLOG import LOG, DEBUG, INFO
from lxml.etree import Element, SubElement
from lxml import etree from lxml import etree
from lxml.builder import ElementMaker
from SyncCode import SYNCML_NAMESPACE
nsmap = {'syncml' : SYNCML_NAMESPACE}
E = ElementMaker(namespace=SYNCML_NAMESPACE, nsmap=nsmap)
class SubscriptionSynchronization(XMLSyncUtils): class SubscriptionSynchronization(XMLSyncUtils):
...@@ -54,17 +58,16 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -54,17 +58,16 @@ class SubscriptionSynchronization(XMLSyncUtils):
subscription.setZopeUser(user) subscription.setZopeUser(user)
subscription.setAuthenticated(True) subscription.setAuthenticated(True)
#create element 'SyncML' with a default namespace #create element 'SyncML'
nsmap = {None : self.XHTML_NAMESPACE} xml = E.SyncML()
xml = Element('SyncML',nsmap=nsmap)
# syncml header # syncml header
xml.append(self.SyncMLHeader(subscription.incrementSessionId(), xml.append(self.SyncMLHeader(subscription.incrementSessionId(),
subscription.incrementMessageId(), subscription.getPublicationUrl(), subscription.incrementMessageId(), subscription.getPublicationUrl(),
subscription.getSubscriptionUrl(), source_name=subscription.getLogin())) subscription.getSubscriptionUrl(), source_name=subscription.getLogin()))
# syncml body # syncml body
sync_body = SubElement(xml, 'SyncBody') sync_body = E.SyncBody()
xml.append(sync_body)
# We have to set every object as NOT_SYNCHRONIZED # We have to set every object as NOT_SYNCHRONIZED
subscription.startSynchronization() subscription.startSynchronization()
...@@ -96,8 +99,7 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -96,8 +99,7 @@ class SubscriptionSynchronization(XMLSyncUtils):
""" """
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
#create element 'SyncML' with a default namespace #create element 'SyncML' with a default namespace
nsmap = {None : self.XHTML_NAMESPACE} xml = E.SyncML()
xml = Element('SyncML',nsmap=nsmap)
# syncml header # syncml header
data = "%s:%s" % (subscription.getLogin(), subscription.getPassword()) data = "%s:%s" % (subscription.getLogin(), subscription.getPassword())
data = subscription.encode(subscription.getAuthenticationFormat(), data) data = subscription.encode(subscription.getAuthenticationFormat(), data)
...@@ -112,7 +114,8 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -112,7 +114,8 @@ class SubscriptionSynchronization(XMLSyncUtils):
authentication_type=subscription.getAuthenticationType())) authentication_type=subscription.getAuthenticationType()))
# syncml body # syncml body
sync_body = SubElement(xml, 'SyncBody') sync_body = E.SyncBody()
xml.append(sync_body)
# We have to set every object as NOT_SYNCHRONIZED # We have to set every object as NOT_SYNCHRONIZED
subscription.startSynchronization() subscription.startSynchronization()
...@@ -128,7 +131,7 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -128,7 +131,7 @@ class SubscriptionSynchronization(XMLSyncUtils):
if syncml_put is not None: if syncml_put is not None:
sync_body.append(syncml_put) sync_body.append(syncml_put)
cmd_id += 1 cmd_id += 1
sync_body.append(Element('Final')) sync_body.append(E.Final())
xml_string = etree.tostring(xml, encoding='utf-8', xml_declaration=True, xml_string = etree.tostring(xml, encoding='utf-8', xml_declaration=True,
pretty_print=True) pretty_print=True)
self.sendResponse(from_url=subscription.subscription_url, self.sendResponse(from_url=subscription.subscription_url,
......
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved. # Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
...@@ -30,6 +31,8 @@ from Products.ERP5Type.Accessor.TypeDefinition import list_types ...@@ -30,6 +31,8 @@ from Products.ERP5Type.Accessor.TypeDefinition import list_types
from Globals import Persistent from Globals import Persistent
import re import re
SYNCML_NAMESPACE = 'SYNCML:SYNCML1.2'
class SyncCode(Persistent): class SyncCode(Persistent):
""" """
Class giving the Synchronization's Constants Class giving the Synchronization's Constants
...@@ -133,7 +136,6 @@ class SyncCode(Persistent): ...@@ -133,7 +136,6 @@ class SyncCode(Persistent):
#Namespace #Namespace
#In SyncML Representation Protocol OMA #In SyncML Representation Protocol OMA
#we use URN as format of namespace #we use URN as format of namespace
XHTML_NAMESPACE = 'SYNCML:SYNCML1.2'
# List namespaces supported # List namespaces supported
URN_LIST = ('SYNCML:SYNCML1.1', 'SYNCML:SYNCML1.2') URN_LIST = ('SYNCML:SYNCML1.1', 'SYNCML:SYNCML1.2')
# -*- coding: utf-8 -*-
## Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved. ## Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
# Sebastien Robin <seb@nexedi.com> # Sebastien Robin <seb@nexedi.com>
# #
...@@ -35,8 +36,6 @@ from Products.CMFCore.utils import UniqueObject ...@@ -35,8 +36,6 @@ from Products.CMFCore.utils import UniqueObject
from Globals import InitializeClass, DTMLFile, PersistentMapping, Persistent from Globals import InitializeClass, DTMLFile, PersistentMapping, Persistent
from AccessControl import ClassSecurityInfo, getSecurityManager from AccessControl import ClassSecurityInfo, getSecurityManager
from Products.CMFCore import CMFCorePermissions from Products.CMFCore import CMFCorePermissions
from Products.ERP5SyncML import _dtmldir
from Products.ERP5SyncML import Conduit
from Publication import Publication, Subscriber from Publication import Publication, Subscriber
from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2 from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2
from Subscription import Subscription from Subscription import Subscription
......
...@@ -35,8 +35,10 @@ from ERP5Diff import ERP5Diff ...@@ -35,8 +35,10 @@ from ERP5Diff import ERP5Diff
from zLOG import LOG, INFO from zLOG import LOG, INFO
from lxml import etree from lxml import etree
from lxml.etree import Element, SubElement from lxml.builder import ElementMaker
from lxml.builder import E from SyncCode import SYNCML_NAMESPACE
nsmap = {'syncml' : SYNCML_NAMESPACE}
E = ElementMaker(namespace=SYNCML_NAMESPACE, nsmap=nsmap)
parser = etree.XMLParser(remove_blank_text=True) parser = etree.XMLParser(remove_blank_text=True)
from xml.dom import minidom from xml.dom import minidom
...@@ -187,7 +189,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -187,7 +189,7 @@ class XMLSyncUtilsMixin(SyncCode):
cmd_ref = '%s' % remote_xml.xpath("string(.//syncml:CmdID)") cmd_ref = '%s' % remote_xml.xpath("string(.//syncml:CmdID)")
target_ref = '%s' % remote_xml.xpath("string(.//syncml:Target/syncml:LocURI)") target_ref = '%s' % remote_xml.xpath("string(.//syncml:Target/syncml:LocURI)")
source_ref = '%s' % remote_xml.xpath("string(.//syncml:Source/syncml:LocURI)") source_ref = '%s' % remote_xml.xpath("string(.//syncml:Source/syncml:LocURI)")
xml = Element('Status') xml = E.Status()
if cmd_id: if cmd_id:
xml.append(E.CmdID('%s' % cmd_id)) xml.append(E.CmdID('%s' % cmd_id))
if msg_ref: if msg_ref:
...@@ -240,7 +242,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -240,7 +242,7 @@ class XMLSyncUtilsMixin(SyncCode):
if getattr(conduit, 'getCapabilitiesCTTypeList', None) is not None and \ if getattr(conduit, 'getCapabilitiesCTTypeList', None) is not None and \
getattr(conduit, 'getCapabilitiesVerCTList', None) is not None and \ getattr(conduit, 'getCapabilitiesVerCTList', None) is not None and \
getattr(conduit, 'getPreferedCapabilitieVerCT', None) is not None: getattr(conduit, 'getPreferedCapabilitieVerCT', None) is not None:
xml = Element(markup) xml = Element('{%s}%s' % (SYNCML_NAMESPACE, markup))
xml.append(E.CmdID('%s' % cmd_id)) xml.append(E.CmdID('%s' % cmd_id))
if message_id: if message_id:
xml.append(E.MsgRef('%s' % message_id)) xml.append(E.MsgRef('%s' % message_id))
...@@ -269,12 +271,12 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -269,12 +271,12 @@ class XMLSyncUtilsMixin(SyncCode):
for x_version in conduit.getCapabilitiesVerCTList(type): for x_version in conduit.getCapabilitiesVerCTList(type):
rx_element_list.append(E.Rx(E.CTType(type), E.VerCT(x_version))) rx_element_list.append(E.Rx(E.CTType(type), E.VerCT(x_version)))
tx_element_list.append(E.Tx(E.CTType(type), E.VerCT(x_version))) tx_element_list.append(E.Tx(E.CTType(type), E.VerCT(x_version)))
rx_pref = Element('Rx-Pref') rx_pref = Element('{%s}Rx-Pref' % SYNCML_NAMESPACE)
rx_pref.extend((E.CTType(conduit.getPreferedCapabilitieCTType()), rx_pref.extend((E.CTType(conduit.getPreferedCapabilitieCTType()),
E.VerCT(conduit.getPreferedCapabilitieVerCT()))) E.VerCT(conduit.getPreferedCapabilitieVerCT())))
data_store.append(rx_pref) data_store.append(rx_pref)
data_store.extend(rx_element_list) data_store.extend(rx_element_list)
tx_pref = Element('Tx-Pref') tx_pref = Element('{%s}Tx-Pref' % SYNCML_NAMESPACE)
tx_pref.extend((E.CTType(conduit.getPreferedCapabilitieCTType()), tx_pref.extend((E.CTType(conduit.getPreferedCapabilitieCTType()),
E.VerCT(conduit.getPreferedCapabilitieVerCT()))) E.VerCT(conduit.getPreferedCapabilitieVerCT())))
data_store.append(tx_pref) data_store.append(tx_pref)
...@@ -323,7 +325,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -323,7 +325,7 @@ class XMLSyncUtilsMixin(SyncCode):
""" """
Add an object with the SyncML protocol Add an object with the SyncML protocol
""" """
data_node = Element('Data') data_node = E.Data()
if media_type == self.MEDIA_TYPE['TEXT_XML'] and isinstance(xml_string, str): if media_type == self.MEDIA_TYPE['TEXT_XML'] and isinstance(xml_string, str):
data_node.append(etree.XML(xml_string, parser=parser)) data_node.append(etree.XML(xml_string, parser=parser))
elif media_type == self.MEDIA_TYPE['TEXT_XML'] and \ elif media_type == self.MEDIA_TYPE['TEXT_XML'] and \
...@@ -346,8 +348,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -346,8 +348,8 @@ class XMLSyncUtilsMixin(SyncCode):
) )
)) ))
if more_data: if more_data:
item_node = xml.find('Item') item_node = xml.find('{%s}Item' % SYNCML_NAMESPACE)
item_node.append(Element('MoreData')) item_node.append(E.MoreData())
return etree.tostring(xml, encoding='utf-8', pretty_print=True) return etree.tostring(xml, encoding='utf-8', pretty_print=True)
def deleteXMLObject(self, cmd_id=0, object_gid=None, rid=None): def deleteXMLObject(self, cmd_id=0, object_gid=None, rid=None):
...@@ -375,7 +377,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -375,7 +377,7 @@ class XMLSyncUtilsMixin(SyncCode):
elem_to_append = E.Target(E.LocURI('%s' % rid)) elem_to_append = E.Target(E.LocURI('%s' % rid))
else: else:
elem_to_append = E.Source(E.LocURI('%s' % gid)) elem_to_append = E.Source(E.LocURI('%s' % gid))
data_node = Element('Data') data_node = E.Data()
if not isinstance(xml_string, (str, unicode)): if not isinstance(xml_string, (str, unicode)):
data_node.append(xml_string) data_node.append(xml_string)
else: else:
...@@ -391,8 +393,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -391,8 +393,8 @@ class XMLSyncUtilsMixin(SyncCode):
) )
)) ))
if more_data: if more_data:
item_node = xml.find('Item') item_node = xml.find('{%s}Item' % SYNCML_NAMESPACE)
item_node.append(Element('MoreData')) item_node.append(E.MoreData())
return etree.tostring(xml, encoding='utf-8', pretty_print=True) return etree.tostring(xml, encoding='utf-8', pretty_print=True)
def getXupdateObject(self, object_xml=None, old_xml=None): def getXupdateObject(self, object_xml=None, old_xml=None):
...@@ -422,76 +424,76 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -422,76 +424,76 @@ class XMLSyncUtilsMixin(SyncCode):
""" """
We will retrieve the session id of the message We will retrieve the session id of the message
""" """
namespace = self.getNamespace(xml.nsmap) return int(xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:SessionID)',
return int(xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:SessionID)')) namespaces=xml.nsmap))
def getMessageIdFromXml(self, xml): def getMessageIdFromXml(self, xml):
""" """
We will retrieve the message id of the message We will retrieve the message id of the message
""" """
namespace = self.getNamespace(xml.nsmap) return int(xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:MsgID)',
return int(xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:MsgID)')) namespaces=xml.nsmap))
def getTarget(self, xml): def getTarget(self, xml):
""" """
return the target in the SyncHdr section return the target in the SyncHdr section
""" """
namespace = self.getNamespace(xml.nsmap) return '%s' %\
return '%s' % xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:Target/syncml:LocURI)') xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:Target/syncml:LocURI)',
namespaces=xml.nsmap)
def getAlertLastAnchor(self, xml_stream): def getAlertLastAnchor(self, xml):
""" """
Return the value of the last anchor, in the Return the value of the last anchor, in the
alert section of the xml_stream alert section of the xml_stream
""" """
namespace = self.getNamespace(xml_stream.nsmap) return '%s' %\
return '%s' % xml_stream.xpath('string(.//syncml:Alert/syncml:Item/syncml:Meta/syncml:Anchor/syncml:Last)') xml.xpath('string(.//syncml:Alert/syncml:Item/syncml:Meta/syncml:Anchor/syncml:Last)',
namespaces=xml.nsmap)
def getAlertNextAnchor(self, xml_stream): def getAlertNextAnchor(self, xml):
""" """
Return the value of the next anchor, in the Return the value of the next anchor, in the
alert section of the xml_stream alert section of the xml_stream
""" """
namespace = self.getNamespace(xml_stream.nsmap)
return '%s' %\ return '%s' %\
xml_stream.xpath('string(.//syncml:Alert/syncml:Item/syncml:Meta/syncml:Anchor/syncml:Next)') xml.xpath('string(.//syncml:Alert/syncml:Item/syncml:Meta/syncml:Anchor/syncml:Next)',
namespaces=xml.nsmap)
def getSourceURI(self, xml): def getSourceURI(self, xml):
""" """
return the source uri of the data base return the source uri of the data base
""" """
namespace = self.getNamespace(xml.nsmap)
return '%s' %\ return '%s' %\
xml.xpath('string(//syncml:SyncBody/syncml:Alert/syncml:Item/syncml:Source/syncml:LocURI)') xml.xpath('string(//syncml:SyncBody/syncml:Alert/syncml:Item/syncml:Source/syncml:LocURI)',
namespaces=xml.nsmap)
def getTargetURI(self, xml): def getTargetURI(self, xml):
""" """
return the target uri of the data base return the target uri of the data base
""" """
namespace = self.getNamespace(xml.nsmap)
return '%s' %\ return '%s' %\
xml.xpath('string(//syncml:SyncBody/syncml:Alert/syncml:Item/syncml:Target/syncml:LocURI)') xml.xpath('string(//syncml:SyncBody/syncml:Alert/syncml:Item/syncml:Target/syncml:LocURI)',
namespaces=xml.nsmap)
def getSubscriptionUrlFromXML(self, xml): def getSubscriptionUrlFromXML(self, xml):
""" """
return the source URI of the syncml header return the source URI of the syncml header
""" """
namespace = self.getNamespace(xml.nsmap) return '%s' % xml.xpath('string(//syncml:SyncHdr/syncml:Source/syncml:LocURI)',
return '%s' % xml.xpath('string(//syncml:SyncHdr/syncml:Source/syncml:LocURI)') namespaces=xml.nsmap)
def getStatusTarget(self, xml): def getStatusTarget(self, xml):
""" """
Return the value of the alert code inside the xml_stream Return the value of the alert code inside the xml_stream
""" """
namespace = self.getNamespace(xml.nsmap) return '%s' % xml.xpath('string(syncml:TargetRef)', namespaces=xml.nsmap)
return '%s' % xml.xpath('string(syncml:TargetRef)')
def getStatusCode(self, xml): def getStatusCode(self, xml):
""" """
Return the value of the alert code inside the xml_stream Return the value of the alert code inside the xml_stream
""" """
namespace = self.getNamespace(xml.nsmap) status_code = '%s' % xml.xpath('string(syncml:Data)', namespaces=xml.nsmap)
status_code = '%s' % xml.xpath('string(syncml:Data)')
if status_code: if status_code:
return int(status_code) return int(status_code)
return None return None
...@@ -500,173 +502,175 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -500,173 +502,175 @@ class XMLSyncUtilsMixin(SyncCode):
""" """
Return the value of the command inside the xml_stream Return the value of the command inside the xml_stream
""" """
namespace = self.getNamespace(xml.nsmap)
cmd = None cmd = None
if xml.xpath('local-name()') == 'Status': if xml.xpath('local-name()') == 'Status':
cmd = '%s' % xml.xpath('string(syncml:Cmd)') cmd = '%s' % xml.xpath('string(syncml:Cmd)', namespaces=xml.nsmap)
return cmd return cmd
def getCred(self, xml): def getCred(self, xml):
""" """
return the credential information : type, format and data return the credential information : type, format and data
""" """
namespace = self.getNamespace(xml.nsmap)
format = '%s' %\ format = '%s' %\
xml.xpath("string(/syncml:SyncML/syncml:SyncHdr/syncml:Cred/syncml:Meta/*[local-name() = 'Format'])") xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:Cred/syncml:Meta/*[local-name() = "Format"])',
namespaces=xml.nsmap)
type = '%s' %\ type = '%s' %\
xml.xpath("string(/syncml:SyncML/syncml:SyncHdr/syncml:Cred/syncml:Meta/*[local-name() = 'Type'])") xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:Cred/syncml:Meta/*[local-name() = "Type"])',
data = '%s' % xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:Cred/syncml:Data)') namespaces=xml.nsmap)
data = '%s' % xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:Cred/syncml:Data)',
namespaces=xml.nsmap)
return (format, type, data) return (format, type, data)
def checkCred(self, xml_stream): def checkCred(self, xml):
""" """
Check if there's a Cred section in the xml_stream Check if there's a Cred section in the xml_stream
""" """
namespace = self.getNamespace(xml_stream.nsmap) return bool(xml.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:Cred)', namespaces=xml.nsmap))
return bool(xml_stream.xpath('string(/syncml:SyncML/syncml:SyncHdr/syncml:Cred)'))
def getChal(self, xml): def getChal(self, xml):
""" """
return the chalenge information : format and type return the chalenge information : format and type
""" """
format = '%s' % xml.xpath("string(//*[local-name() = 'Format'])") format = '%s' % xml.xpath('string(//*[local-name() = "Format"])', namespaces=xml.nsmap)
type = '%s' % xml.xpath("string(//*[local-name() = 'Type'])") type = '%s' % xml.xpath('string(//*[local-name() = "Type"])', namespaces=xml.nsmap)
return (format, type) return (format, type)
def checkChal(self, xml_stream): def checkChal(self, xml):
""" """
Check if there's a Chal section in the xml_stream Check if there's a Chal section in the xml_stream
""" """
namespace = self.getNamespace(xml_stream.nsmap) return bool(xml.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Status/syncml:Chal)',
return\ namespaces=xml.nsmap))
bool(xml_stream.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Status/syncml:Chal)'))
def checkMap(self, xml_stream): def checkMap(self, xml):
""" """
Check if there's a Map section in the xml_stream Check if there's a Map section in the xml_stream
""" """
namespace = self.getNamespace(xml_stream.nsmap) return bool(xml.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Map)', namespaces=xml.nsmap))
return bool(xml_stream.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Map)'))
def setRidWithMap(self, xml_stream, subscriber): def setRidWithMap(self, xml, subscriber):
""" """
get all the local objects of the given target id and set them the rid with get all the local objects of the given target id and set them the rid with
the given source id (in the Map section) the given source id (in the Map section)
""" """
namespace = self.getNamespace(xml_stream.nsmap) item_list = xml.xpath('/syncml:SyncML/syncml:SyncBody/syncml:Map/syncml:MapItem',
item_list = xml_stream.xpath('/syncml:SyncML/syncml:SyncBody/syncml:Map/syncml:MapItem') namespaces=xml.nsmap)
for map_item in item_list: for map_item in item_list:
gid = '%s' % map_item.xpath('string(.//syncml:Target/syncml:LocURI)') gid = '%s' % map_item.xpath('string(.//syncml:Target/syncml:LocURI)', namespaces=xml.nsmap)
signature = subscriber.getSignatureFromGid(gid) signature = subscriber.getSignatureFromGid(gid)
rid = '%s' % map_item.xpath('string(.//syncml:Source/syncml:LocURI)') rid = '%s' % map_item.xpath('string(.//syncml:Source/syncml:LocURI)', namespaces=xml.nsmap)
signature.setRid(rid) signature.setRid(rid)
def getAlertCodeFromXML(self, xml_stream): def getAlertCodeFromXML(self, xml):
""" """
Return the value of the alert code inside the full syncml message Return the value of the alert code inside the full syncml message
""" """
namespace = self.getNamespace(xml_stream.nsmap)
alert_code = '%s' %\ alert_code = '%s' %\
xml_stream.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Alert/syncml:Data)') xml.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Alert/syncml:Data)',
namespaces=xml.nsmap)
if alert_code: if alert_code:
return int(alert_code) return int(alert_code)
else: else:
return None return None
def checkAlert(self, xml_stream): def checkAlert(self, xml):
""" """
Check if there's an Alert section in the xml_stream Check if there's an Alert section in the xml_stream
""" """
namespace = self.getNamespace(xml_stream.nsmap) return bool(xml.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Alert)',
return bool(xml_stream.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Alert)')) namespaces=xml.nsmap))
def checkSync(self, xml_stream): def checkSync(self, xml):
""" """
Check if there's an Sync section in the xml_stream Check if there's an Sync section in the xml_stream
""" """
namespace = self.getNamespace(xml_stream.nsmap) return bool(xml.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Sync)',
return bool(xml_stream.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Sync)')) namespaces=xml.nsmap))
def checkFinal(self, xml_stream): def checkFinal(self, xml):
""" """
Check if there's an Final section in the xml_stream Check if there's an Final section in the xml_stream
The end sections (inizialisation, modification) have this tag The end sections (inizialisation, modification) have this tag
""" """
namespace = self.getNamespace(xml_stream.nsmap) return bool(xml.xpath('/syncml:SyncML/syncml:SyncBody/syncml:Final',
return bool(xml_stream.xpath('/syncml:SyncML/syncml:SyncBody/syncml:Final')) namespaces=xml.nsmap))
def checkStatus(self, xml_stream): def checkStatus(self, xml):
""" """
Check if there's a Status section in the xml_stream Check if there's a Status section in the xml_stream
""" """
namespace = self.getNamespace(xml_stream.nsmap) return bool(xml.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Status)',
return bool(xml_stream.xpath('string(/syncml:SyncML/syncml:SyncBody/syncml:Status)')) namespaces=xml.nsmap))
def getSyncActionList(self, xml_stream): def getSyncActionList(self, xml):
""" """
return the list of the action (could be "add", "replace", "delete"). return the list of the action (could be "add", "replace", "delete").
""" """
namespace = self.getNamespace(xml_stream.nsmap) return xml.xpath('//syncml:Add|//syncml:Delete|//syncml:Replace',
return xml_stream.xpath('//syncml:Add|//syncml:Delete|//syncml:Replace') namespaces=xml.nsmap)
def getSyncBodyStatusList(self, xml_stream): def getSyncBodyStatusList(self, xml):
""" """
return the list of dictionary corredponding to the data of each status bloc return the list of dictionary corredponding to the data of each status bloc
the data are : cmd, code and source the data are : cmd, code and source
""" """
namespace = self.getNamespace(xml_stream.nsmap)
status_list = [] status_list = []
status_node_list = xml_stream.xpath('//syncml:Status') status_node_list = xml.xpath('//syncml:Status')
for status in status_node_list: for status in status_node_list:
tmp_dict = {} tmp_dict = {}
tmp_dict['cmd'] = '%s' % status.xpath('string(./syncml:Cmd)') tmp_dict['cmd'] = '%s' % status.xpath('string(./syncml:Cmd)',
tmp_dict['code'] = '%s' % status.xpath('string(./syncml:Data)') namespaces=xml.nsmap)
tmp_dict['source'] = '%s' % status.xpath('string(./syncml:SourceRef)') tmp_dict['code'] = '%s' % status.xpath('string(./syncml:Data)',
tmp_dict['target'] = '%s' % status.xpath('string(./syncml:TargetRef)') namespaces=xml.nsmap)
tmp_dict['source'] = '%s' % status.xpath('string(./syncml:SourceRef)',
namespaces=xml.nsmap)
tmp_dict['target'] = '%s' % status.xpath('string(./syncml:TargetRef)',
namespaces=xml.nsmap)
status_list.append(tmp_dict) status_list.append(tmp_dict)
return status_list return status_list
def getDataText(self, action): def getDataText(self, xml):
""" """
return the section data in text form, it's usefull for the VCardConduit return the section data in text form, it's usefull for the VCardConduit
""" """
namespace = self.getNamespace(action.nsmap) return '%s' % xml.xpath('string(.//syncml:Item/syncml:Data)',
return '%s' % action.xpath('string(.//syncml:Item/syncml:Data)') namespaces=xml.nsmap)
def getDataSubNode(self, action): def getDataSubNode(self, xml):
""" """
Return the node starting with <object....> of the action Return the node starting with <object....> of the action
""" """
namespace = self.getNamespace(action.nsmap) object_node_list = xml.xpath('.//syncml:Item/syncml:Data/*[1]',
object_node_list = action.xpath('.//syncml:Item/syncml:Data/*[1]') namespaces=xml.nsmap)
if object_node_list: if object_node_list:
return object_node_list[0] return object_node_list[0]
return None return None
def getActionId(self, action): def getActionId(self, xml):
""" """
Return the rid of the object described by the action Return the rid of the object described by the action
""" """
namespace = self.getNamespace(action.nsmap) id = '%s' % xml.xpath('string(.//syncml:Item/syncml:Source/syncml:LocURI)',
id = '%s' % action.xpath('string(.//syncml:Item/syncml:Source/syncml:LocURI)') namespaces=xml.nsmap)
if not id: if not id:
id = '%s' % action.xpath('string(.//syncml:Item/syncml:Target/syncml:LocURI)') id = '%s' % xml.xpath('string(.//syncml:Item/syncml:Target/syncml:LocURI)',
namespaces=xml.nsmap)
return id return id
def checkActionMoreData(self, action): def checkActionMoreData(self, xml):
""" """
Return the rid of the object described by the action Return the rid of the object described by the action
""" """
namespace = self.getNamespace(action.nsmap) return bool(xml.xpath('.//syncml:Item/syncml:MoreData',
return bool(action.xpath('.//syncml:Item/syncml:MoreData')) namespaces=xml.nsmap))
def getActionType(self, action): def getActionType(self, xml):
""" """
Return the type of the object described by the action Return the type of the object described by the action
""" """
namespace = self.getNamespace(action.nsmap) return '%s' % xml.xpath('string(.//syncml:Meta/syncml:Type)',
return '%s' % action.xpath('string(.//syncml:Meta/syncml:Type)') namespaces=xml.nsmap)
def cutXML(self, xml_string): def cutXML(self, xml_string):
""" """
...@@ -675,9 +679,9 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -675,9 +679,9 @@ class XMLSyncUtilsMixin(SyncCode):
line_list = xml_string.split('\n') line_list = xml_string.split('\n')
short_string = '\n'.join(line_list[:self.MAX_LINES]) short_string = '\n'.join(line_list[:self.MAX_LINES])
rest_string = '\n'.join(line_list[self.MAX_LINES:]) rest_string = '\n'.join(line_list[self.MAX_LINES:])
xml_string = etree.Element('Partial') xml_tree = E.Partial()
xml_string.text = etree.CDATA(short_string.decode('utf-8')) xml_tree.text = etree.CDATA(short_string.decode('utf-8'))
return xml_string, rest_string return xml_tree, rest_string
def getSyncMLData(self, domain=None, remote_xml=None, cmd_id=0, def getSyncMLData(self, domain=None, remote_xml=None, cmd_id=0,
subscriber=None, xml_confirmation_list=None, conduit=None, subscriber=None, xml_confirmation_list=None, conduit=None,
...@@ -884,11 +888,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -884,11 +888,11 @@ class XMLSyncUtilsMixin(SyncCode):
more_data = 1 more_data = 1
# Receive the chunk of partial xml # Receive the chunk of partial xml
short_string = signature.getFirstChunkPdata(self.MAX_LINES) short_string = signature.getFirstChunkPdata(self.MAX_LINES)
xml_to_send = etree.Element('Partial') xml_to_send = E.Partial()
xml_to_send.text = etree.CDATA(short_string.decode('utf-8')) xml_to_send.text = etree.CDATA(short_string.decode('utf-8'))
status = self.PARTIAL status = self.PARTIAL
else: else:
xml_to_send = Element('Partial') xml_to_send = E.Partial()
xml_to_send.text = etree.CDATA(xml_string.decode('utf-8')) xml_to_send.text = etree.CDATA(xml_string.decode('utf-8'))
signature.setStatus(status) signature.setStatus(status)
if signature.getAction() == 'Replace': if signature.getAction() == 'Replace':
...@@ -1275,8 +1279,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1275,8 +1279,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
remote_xml=remote_xml, remote_xml=remote_xml,
conduit=conduit, simulate=simulate) conduit=conduit, simulate=simulate)
nsmap = {None : self.XHTML_NAMESPACE} xml = E.SyncML()
xml = Element('SyncML', nsmap=nsmap)
# syncml header # syncml header
if domain.domain_type == self.PUB: if domain.domain_type == self.PUB:
...@@ -1292,7 +1295,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1292,7 +1295,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
domain.getSubscriptionUrl())) domain.getSubscriptionUrl()))
# syncml body # syncml body
sync_body = SubElement(xml, 'SyncBody') sync_body = E.SyncBody()
xml.append(sync_body)
xml_status, cmd_id = self.SyncMLStatus( xml_status, cmd_id = self.SyncMLStatus(
remote_xml, remote_xml,
...@@ -1430,9 +1434,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1430,9 +1434,8 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
if sync_body is None: if sync_body is None:
sync_body = xml_tree.xpath('syncml:SyncBody')[0] sync_body = xml_tree.xpath('syncml:SyncBody')[0]
if syncml_data_list: if syncml_data_list:
sync_node = SubElement(sync_body, 'Sync') sync_node = E.Sync(E.CmdID('%s' % cmd_id_before_getsyncmldata))
cmd_id_node = SubElement(sync_node, 'CmdID') sync_body.append(sync_node)
cmd_id_node.text = '%s' % cmd_id_before_getsyncmldata
target_uri = subscriber.getTargetURI() target_uri = subscriber.getTargetURI()
if target_uri: if target_uri:
sync_node.append(E.Target(E.LocURI(target_uri))) sync_node.append(E.Target(E.LocURI(target_uri)))
...@@ -1445,14 +1448,14 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1445,14 +1448,14 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
if isinstance(xml_confirmation, str): if isinstance(xml_confirmation, str):
xml_confirmation = etree.XML(xml_confirmation, parser=parser) xml_confirmation = etree.XML(xml_confirmation, parser=parser)
sync_body.append(xml_confirmation) sync_body.append(xml_confirmation)
self.sync_finished = 0 self.sync_finished = 0
if domain.domain_type == self.PUB: # We always reply if domain.domain_type == self.PUB: # We always reply
# When the publication recieved the response Final and the modification # When the publication recieved the response Final and the modification
# data is finished so the publication send the tag "Final" # data is finished so the publication send the tag "Final"
if not self.checkSync(remote_xml) and not xml_confirmation_list\ if not self.checkSync(remote_xml) and not xml_confirmation_list\
and not syncml_data_list and self.checkFinal(remote_xml): and not syncml_data_list and self.checkFinal(remote_xml):
sync_body.append(Element('Final')) sync_body.append(E.Final())
self.sync_finished = 1 self.sync_finished = 1
xml_string = etree.tostring(xml_tree, encoding='utf-8', pretty_print=True) xml_string = etree.tostring(xml_tree, encoding='utf-8', pretty_print=True)
subscriber.setLastSentMessage(xml_string) subscriber.setLastSentMessage(xml_string)
...@@ -1473,7 +1476,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1473,7 +1476,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
# "Final" sent to the publication # "Final" sent to the publication
if not self.checkAlert(remote_xml) and not xml_confirmation_list\ if not self.checkAlert(remote_xml) and not xml_confirmation_list\
and not syncml_data_list: and not syncml_data_list:
sync_body.append(Element('Final')) sync_body.append(E.Final())
self.sync_finished = 1 self.sync_finished = 1
xml_string = etree.tostring(xml_tree, encoding='utf-8', pretty_print=True) xml_string = etree.tostring(xml_tree, encoding='utf-8', pretty_print=True)
if not self.sync_finished or not self.checkFinal(remote_xml): if not self.sync_finished or not self.checkFinal(remote_xml):
...@@ -1539,10 +1542,6 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1539,10 +1542,6 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
if xml_client is not None: if xml_client is not None:
if isinstance(xml_client, (str, unicode)): if isinstance(xml_client, (str, unicode)):
xml_client = etree.XML(xml_client, parser=parser) xml_client = etree.XML(xml_client, parser=parser)
if len(xml_client.nsmap) ==1:
namespace = xml_client.nsmap[None]
else :
namespace = xml_client.nsmap['syncml']
#FIXME to apply a DTD or schema #FIXME to apply a DTD or schema
if xml_client.xpath('local-name()') != "SyncML": if xml_client.xpath('local-name()') != "SyncML":
LOG('PubSync', INFO, 'This is not a SyncML Message') LOG('PubSync', INFO, 'This is not a SyncML Message')
......
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