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