4.1 --- a/libxml2dom/xmlrpc.py Sun Sep 07 18:46:50 2008 +0200
4.2 +++ b/libxml2dom/xmlrpc.py Wed Sep 10 00:35:11 2008 +0200
4.3 @@ -5,7 +5,7 @@
4.4
4.5 See: http://www.xmlrpc.com/spec
4.6
4.7 -Copyright (C) 2007 Paul Boddie <paul@boddie.org.uk>
4.8 +Copyright (C) 2007, 2008 Paul Boddie <paul@boddie.org.uk>
4.9
4.10 This program is free software; you can redistribute it and/or modify it under
4.11 the terms of the GNU Lesser General Public License as published by the Free
4.12 @@ -34,87 +34,18 @@
4.13 createDocument as Node_createDocument
4.14 import datetime
4.15
4.16 -class XMLRPCImplementation(libxml2dom.Implementation):
4.17 -
4.18 - "Contains an XML-RPC-specific implementation."
4.19 -
4.20 - # Wrapping of documents.
4.21 -
4.22 - def adoptDocument(self, node):
4.23 - return XMLRPCDocument(node, self)
4.24 -
4.25 - # Factory functions.
4.26 -
4.27 - def get_node(self, _node, context_node):
4.28 -
4.29 - """
4.30 - Get a libxml2dom node for the given low-level '_node' and libxml2dom
4.31 - 'context_node'.
4.32 - """
4.33 -
4.34 - if Node_nodeType(_node) == context_node.ELEMENT_NODE:
4.35 -
4.36 - # Make special elements.
4.37 -
4.38 - if Node_localName(_node) in ("methodCall", "methodResponse"):
4.39 - return XMLRPCMethodElement(_node, self, context_node.ownerDocument)
4.40 - elif Node_localName(_node) == "methodName":
4.41 - return XMLRPCMethodNameElement(_node, self, context_node.ownerDocument)
4.42 - elif Node_localName(_node) == "fault":
4.43 - return XMLRPCFaultElement(_node, self, context_node.ownerDocument)
4.44 - elif Node_localName(_node) == "string":
4.45 - return XMLRPCStringElement(_node, self, context_node.ownerDocument)
4.46 - elif Node_localName(_node) in ("int", "i4"):
4.47 - return XMLRPCIntegerElement(_node, self, context_node.ownerDocument)
4.48 - elif Node_localName(_node) == "boolean":
4.49 - return XMLRPCBooleanElement(_node, self, context_node.ownerDocument)
4.50 - elif Node_localName(_node) == "double":
4.51 - return XMLRPCDoubleElement(_node, self, context_node.ownerDocument)
4.52 - elif Node_localName(_node) == "dateTime.iso8601":
4.53 - return XMLRPCDateTimeElement(_node, self, context_node.ownerDocument)
4.54 - elif Node_localName(_node) == "base64":
4.55 - return XMLRPCBase64Element(_node, self, context_node.ownerDocument)
4.56 - elif Node_localName(_node) == "struct":
4.57 - return XMLRPCStructElement(_node, self, context_node.ownerDocument)
4.58 - elif Node_localName(_node) == "member":
4.59 - return XMLRPCMemberElement(_node, self, context_node.ownerDocument)
4.60 - elif Node_localName(_node) == "value":
4.61 - return XMLRPCValueElement(_node, self, context_node.ownerDocument)
4.62 - elif Node_localName(_node) == "name":
4.63 - return XMLRPCNameElement(_node, self, context_node.ownerDocument)
4.64 - elif Node_localName(_node) == "array":
4.65 - return XMLRPCArrayElement(_node, self, context_node.ownerDocument)
4.66 - elif Node_localName(_node) == "data":
4.67 - return XMLRPCDataElement(_node, self, context_node.ownerDocument)
4.68 -
4.69 - # Otherwise, make generic XML-RPC elements.
4.70 -
4.71 - return XMLRPCElement(_node, self, context_node.ownerDocument)
4.72 -
4.73 - else:
4.74 - return libxml2dom.Implementation.get_node(self, _node, context_node)
4.75 -
4.76 - # Convenience functions.
4.77 -
4.78 - def createXMLRPCMessage(self, namespaceURI, localName):
4.79 -
4.80 - "Create a new XML-RPC message document (fragment)."
4.81 -
4.82 - return XMLRPCDocument(Node_createDocument(namespaceURI, localName, None), self).documentElement
4.83 -
4.84 - def createMethodCall(self):
4.85 - return self.createXMLRPCMessage(None, "methodCall")
4.86 -
4.87 - def createMethodResponse(self):
4.88 - return self.createXMLRPCMessage(None, "methodResponse")
4.89 -
4.90 # Node classes.
4.91
4.92 class XMLRPCNode(libxml2dom.Node):
4.93
4.94 "Convenience modifications to nodes specific to libxml2dom.xmlrpc."
4.95
4.96 - pass
4.97 + def add_or_replace_element(self, new_element):
4.98 + elements = self.xpath("*")
4.99 + if elements:
4.100 + self.replaceChild(new_element, elements[0])
4.101 + else:
4.102 + self.appendChild(new_element)
4.103
4.104 class XMLRPCElement(XMLRPCNode):
4.105
4.106 @@ -140,11 +71,17 @@
4.107
4.108 # Node construction methods.
4.109
4.110 - def createMethodCall(self):
4.111 - return self.ownerDocument.createElement("methodCall")
4.112 + def createMethodCall(self, insert=0):
4.113 + e = self.ownerDocument.createElement("methodCall")
4.114 + if insert:
4.115 + self.add_or_replace_element(e)
4.116 + return e
4.117
4.118 - def createMethodResponse(self):
4.119 - return self.ownerDocument.createElement("methodResponse")
4.120 + def createMethodResponse(self, insert=0):
4.121 + e = self.ownerDocument.createElement("methodResponse")
4.122 + if insert:
4.123 + self.add_or_replace_element(e)
4.124 + return e
4.125
4.126 class XMLRPCMethodElement(XMLRPCNode):
4.127
4.128 @@ -174,20 +111,56 @@
4.129
4.130 # Node construction methods.
4.131
4.132 - def createMethodName(self):
4.133 - return self.ownerDocument.createElement("methodName")
4.134 + def createMethodName(self, insert=0):
4.135 + e = self.ownerDocument.createElement("methodName")
4.136 + if insert:
4.137 + self.add_or_replace_element(e)
4.138 + return e
4.139
4.140 - def createParameters(self):
4.141 - return self.ownerDocument.createElement("params")
4.142 + def createParameters(self, insert=0):
4.143 + e = self.ownerDocument.createElement("params")
4.144 + if insert:
4.145 + self.add_or_replace_element(e)
4.146 + return e
4.147
4.148 - def createFault(self):
4.149 - return self.ownerDocument.createElement("fault")
4.150 + def createFault(self, insert=0):
4.151 + e = self.ownerDocument.createElement("fault")
4.152 + if insert:
4.153 + self.add_or_replace_element(e)
4.154 + return e
4.155
4.156 fault = property(_fault)
4.157 methodNameElement = property(_methodNameElement)
4.158 methodName = property(_methodName, _setMethodName)
4.159 parameterValues = property(_parameterValues)
4.160
4.161 +class XMLRPCParametersElement(XMLRPCNode):
4.162 +
4.163 + "An XML-RPC parameters/params element."
4.164 +
4.165 + # Node construction methods.
4.166 +
4.167 + def createParameter(self, insert=0):
4.168 + e = self.ownerDocument.createElement("param")
4.169 + if insert:
4.170 + self.appendChild(e)
4.171 + return e
4.172 +
4.173 +class XMLRPCParameterElement(XMLRPCNode):
4.174 +
4.175 + "An XML-RPC parameter/param element."
4.176 +
4.177 + # Node construction methods.
4.178 +
4.179 + def createValue(self, typename=None, insert=0):
4.180 + value = self.ownerDocument.createElement("value")
4.181 + if typename is not None:
4.182 + contents = self.ownerDocument.createElement(typename)
4.183 + value.appendChild(contents)
4.184 + if insert:
4.185 + self.add_or_replace_element(value)
4.186 + return value
4.187 +
4.188 class XMLRPCArrayElement(XMLRPCNode):
4.189
4.190 "An XML-RPC array element."
4.191 @@ -220,8 +193,11 @@
4.192
4.193 # Node construction methods.
4.194
4.195 - def createData(self):
4.196 - return self.ownerDocument.createElement("data")
4.197 + def createData(self, insert=0):
4.198 + e = self.ownerDocument.createElement("data")
4.199 + if insert:
4.200 + self.add_or_replace_element(e)
4.201 + return e
4.202
4.203 data = property(_data)
4.204 contents = property(_contents)
4.205 @@ -252,8 +228,11 @@
4.206
4.207 # Node construction methods.
4.208
4.209 - def createMember(self):
4.210 - return self.ownerDocument.createElement("member")
4.211 + def createMember(self, insert=0):
4.212 + e = self.ownerDocument.createElement("member")
4.213 + if insert:
4.214 + self.add_or_replace_element(e)
4.215 + return e
4.216
4.217 members = property(_members)
4.218 contents = property(_contents)
4.219 @@ -275,8 +254,11 @@
4.220
4.221 # Node construction methods.
4.222
4.223 - def createValue(self):
4.224 - return self.ownerDocument.createElement("value")
4.225 + def createValue(self, insert=0):
4.226 + e = self.ownerDocument.createElement("value")
4.227 + if insert:
4.228 + self.add_or_replace_element(e)
4.229 + return e
4.230
4.231 values = property(_values)
4.232
4.233 @@ -318,11 +300,17 @@
4.234
4.235 # Node construction methods.
4.236
4.237 - def createName(self):
4.238 - return self.ownerDocument.createElement("name")
4.239 + def createName(self, insert=0):
4.240 + e = self.ownerDocument.createElement("name")
4.241 + if insert:
4.242 + self.add_or_replace_element(e)
4.243 + return e
4.244
4.245 - def createValue(self):
4.246 - return self.ownerDocument.createElement("value")
4.247 + def createValue(self, insert=0):
4.248 + e = self.ownerDocument.createElement("value")
4.249 + if insert:
4.250 + self.add_or_replace_element(e)
4.251 + return e
4.252
4.253 value = property(_value)
4.254 nameElement = property(_nameElement)
4.255 @@ -373,10 +361,14 @@
4.256 else:
4.257 return "string"
4.258
4.259 + def _setType(self, typename):
4.260 + new_contents = self.ownerDocument.createElement(typename)
4.261 + self.add_or_replace_element(new_contents)
4.262 +
4.263 def _container(self):
4.264 return (self.xpath("*") or [self])[0]
4.265
4.266 - type = property(_type)
4.267 + type = property(_type, _setType)
4.268 container = property(_container)
4.269
4.270 class XMLRPCMethodNameElement(XMLRPCStringElement):
4.271 @@ -463,6 +455,87 @@
4.272 "base64" : str
4.273 }
4.274
4.275 +# Implementation-related functionality.
4.276 +
4.277 +class XMLRPCImplementation(libxml2dom.Implementation):
4.278 +
4.279 + "Contains an XML-RPC-specific implementation."
4.280 +
4.281 + # Mapping of element names to wrappers.
4.282 +
4.283 + _class_for_name = {
4.284 + "methodCall" : XMLRPCMethodElement,
4.285 + "methodResponse" : XMLRPCMethodElement,
4.286 + "methodName" : XMLRPCMethodNameElement,
4.287 + "params" : XMLRPCParametersElement,
4.288 + "param" : XMLRPCParameterElement,
4.289 + "fault" : XMLRPCFaultElement,
4.290 + "string" : XMLRPCStringElement,
4.291 + "int" : XMLRPCIntegerElement,
4.292 + "i4" : XMLRPCIntegerElement,
4.293 + "boolean" : XMLRPCBooleanElement,
4.294 + "double" : XMLRPCDoubleElement,
4.295 + "dateTime.iso8601" : XMLRPCDateTimeElement,
4.296 + "base64" : XMLRPCBase64Element,
4.297 + "struct" : XMLRPCStructElement,
4.298 + "member" : XMLRPCMemberElement,
4.299 + "value" : XMLRPCValueElement,
4.300 + "name" : XMLRPCNameElement,
4.301 + "array" : XMLRPCArrayElement,
4.302 + "data" : XMLRPCDataElement
4.303 + }
4.304 +
4.305 + # Wrapping of documents.
4.306 +
4.307 + def adoptDocument(self, node):
4.308 + return XMLRPCDocument(node, self)
4.309 +
4.310 + # Factory functions.
4.311 +
4.312 + def get_node(self, _node, context_node):
4.313 +
4.314 + """
4.315 + Get a libxml2dom node for the given low-level '_node' and libxml2dom
4.316 + 'context_node'.
4.317 + """
4.318 +
4.319 + if Node_nodeType(_node) == context_node.ELEMENT_NODE:
4.320 +
4.321 + # Make special objects for certain elements.
4.322 + # Otherwise, make generic XML-RPC elements.
4.323 +
4.324 + cls = self._class_for_name.get(Node_localName(_node)) or XMLRPCElement
4.325 + return cls(_node, self, context_node.ownerDocument)
4.326 +
4.327 + else:
4.328 + return libxml2dom.Implementation.get_node(self, _node, context_node)
4.329 +
4.330 + # Convenience functions.
4.331 +
4.332 + def createXMLRPCMessage(self, namespaceURI, localName):
4.333 +
4.334 + "Create a new XML-RPC message document (fragment)."
4.335 +
4.336 + return XMLRPCDocument(Node_createDocument(namespaceURI, localName, None), self).documentElement
4.337 +
4.338 + def createMethodCall(self, name=None):
4.339 +
4.340 + """
4.341 + Create and return a message fragment for a method call having the given
4.342 + 'name'.
4.343 + """
4.344 +
4.345 + message = self.createXMLRPCMessage(None, "methodCall")
4.346 + if name is not None:
4.347 + message.methodName = name
4.348 + return message
4.349 +
4.350 + def createMethodResponse(self):
4.351 +
4.352 + "Create and return a message fragment for a method response."
4.353 +
4.354 + return self.createXMLRPCMessage(None, "methodResponse")
4.355 +
4.356 # Utility functions.
4.357
4.358 createDocument = libxml2dom.createDocument
4.359 @@ -471,8 +544,8 @@
4.360 def createXMLRPCMessage(namespaceURI, localName):
4.361 return default_impl.createXMLRPCMessage(None, localName)
4.362
4.363 -def createMethodCall():
4.364 - return default_impl.createMethodCall()
4.365 +def createMethodCall(name=None):
4.366 + return default_impl.createMethodCall(name)
4.367
4.368 def createMethodResponse():
4.369 return default_impl.createMethodResponse()