1 """SOAP client package - XML representation using ElementTree
2
3 NERC DataGrid Project
4 """
5 __author__ = "P J Kershaw"
6 __date__ = "27/07/09"
7 __copyright__ = "(C) 2010 Science and Technology Facilities Council"
8 __license__ = "http://www.apache.org/licenses/LICENSE-2.0"
9 __contact__ = "Philip.Kershaw@stfc.ac.uk"
10 __revision__ = '$Id: etree.py 7131 2010-06-30 13:37:48Z pjkersha $'
11 import logging
12 log = logging.getLogger(__name__)
13
14 from ndg.saml import Config, importElementTreeAndCElementTree
15 (ElementTree, cElementTree) = importElementTreeAndCElementTree()
16
17
18 import ndg.soap.utils.etree as etree
19 from ndg.soap.utils.etree import QName
20
21 from ndg.soap import (SOAPObject, SOAPEnvelopeBase, SOAPHeaderBase,
22 SOAPBodyBase, SOAPFaultBase)
23 from ndg.soap import SOAPFaultException as SOAPFaultExceptionBase
27 """Utility to enable addition of core ElementTree specific attributes and
28 methods for ElementTree SOAP implementation
29 """
31 self.__qname = None
32 self.__elem = None
33
36
42
45
51
52 qname = property(_getQname, _setQname, None, "Qualified name object")
53 elem = property(_getElem, _setElem, None, "Root element")
54
55 @staticmethod
62
63 @classmethod
65 """Basic pretty printing separating each element on to a new line"""
66 xml = cls._serialize(elem)
67 xml = ">\n".join(xml.split(">"))
68 xml = "\n<".join(xml.split("<"))
69 xml = '\n'.join(xml.split('\n\n'))
70 return xml
71
72 @staticmethod
74 """Read in the XML from source
75 @type source: basestring/file
76 @param source: file path to XML file or file object
77 """
78 tree = ElementTree.parse(source)
79 elem = tree.getroot()
80
81 return elem
82
113
114
115 -class SOAPBody(SOAPBodyBase, ETreeSOAPExtensions):
116 """ElementTree based implementation for SOAP Body object"""
117
118 DEFAULT_ELEMENT_NAME = QName(SOAPBodyBase.DEFAULT_ELEMENT_NS,
119 tag=SOAPBodyBase.DEFAULT_ELEMENT_LOCAL_NAME,
120 prefix=SOAPBodyBase.DEFAULT_ELEMENT_NS_PREFIX)
121
122 - def __init__(self):
130
131
132 @property
133 - def hasSOAPFault(self):
134 """Boolean True if this SOAP BOdy contains a SOAPFault instance"""
135 return self.fault is not None
136
137 - def _getFault(self):
139
140 - def _setFault(self, value):
141 if not isinstance(value, SOAPFault):
142 raise TypeError('Expecting %r type for "fault" attribute; got %r' %
143 (SOAPFault, type(value)))
144 self.__fault = value
145
146 fault = property(_getFault, _setFault, doc="SOAP Fault")
147
156
157 - def serialize(self):
158 """Serialise element tree into string"""
159 return ETreeSOAPExtensions._serialize(self.elem)
160
161 - def parse(self, source):
162 """This method ONLY parses a SOAPFault IF one is found"""
163 if ElementTree.iselement(source):
164 self.elem = source
165 else:
166 self.elem = self._parse(source)
167
168 for elem in self.elem:
169 localName = QName.getLocalPart(elem.tag)
170 if localName == SOAPFault.DEFAULT_ELEMENT_LOCAL_NAME:
171 if self.fault is None:
172 self.fault = SOAPFault()
173
174 self.fault.parse(elem)
175
176
177 break
178
179 - def prettyPrint(self):
180 """Basic pretty printing separating each element on to a new line"""
181 return ETreeSOAPExtensions._prettyPrint(self.elem)
182
183
184 -class SOAPFault(SOAPFaultBase, ETreeSOAPExtensions):
185 """Extend SOAP Fault for ElementTree parsing and serialisation"""
186
187 DEFAULT_ELEMENT_NAME = QName(SOAPFaultBase.DEFAULT_ELEMENT_NS,
188 tag=SOAPFaultBase.DEFAULT_ELEMENT_LOCAL_NAME,
189 prefix=SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX)
190
191 FAULT_CODE_ELEMENT_NAME = QName(SOAPFaultBase.DEFAULT_ELEMENT_NS,
192 tag=SOAPFaultBase.FAULT_CODE_ELEMENT_LOCAL_NAME,
193 prefix=SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX)
194
195 FAULT_STRING_ELEMENT_NAME = QName(SOAPFaultBase.DEFAULT_ELEMENT_NS,
196 tag=SOAPFaultBase.FAULT_STRING_ELEMENT_LOCAL_NAME,
197 prefix=SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX)
198
199 FAULT_ACTOR_ELEMENT_NAME = QName(SOAPFaultBase.DEFAULT_ELEMENT_NS,
200 tag=SOAPFaultBase.FAULT_ACTOR_ELEMENT_LOCAL_NAME,
201 prefix=SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX)
202
203 DETAIL_ELEMENT_NAME = QName(SOAPFaultBase.DEFAULT_ELEMENT_NS,
204 tag=SOAPFaultBase.DETAIL_ELEMENT_LOCAL_NAME,
205 prefix=SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX)
206
214
224
225 faultCode = property(SOAPFaultBase._getFaultCode, _setFaultCode,
226 doc="Fault code")
227
229 """Create Fault ElementTree element"""
230 self.elem = etree.makeEtreeElement(str(self.qname),
231 SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX,
232 SOAPFaultBase.DEFAULT_ELEMENT_NS)
233
234 faultStringElem = etree.makeEtreeElement(
235 str(self.__class__.FAULT_STRING_ELEMENT_NAME),
236 SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX,
237 SOAPFaultBase.DEFAULT_ELEMENT_NS)
238 faultStringElem.text = self.faultString
239 self.elem.append(faultStringElem)
240
241 faultCodeElem = etree.makeEtreeElement(
242 str(self.__class__.FAULT_CODE_ELEMENT_NAME),
243 SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX,
244 SOAPFaultBase.DEFAULT_ELEMENT_NS)
245 faultCodeElem.text = self.faultCode
246 self.elem.append(faultCodeElem)
247
248 if self.faultActor is not None:
249 faultActorElem = etree.makeEtreeElement(
250 str(self.__class__.FAULT_ACTOR_ELEMENT_NAME),
251 SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX,
252 SOAPFaultBase.DEFAULT_ELEMENT_NS)
253 faultActorElem.text = self.faultActor
254 self.elem.append(faultActorElem)
255
256 if self.detail is not None:
257 detailElem = etree.makeEtreeElement(
258 str(self.__class__.DETAIL_ELEMENT_NAME),
259 SOAPFaultBase.DEFAULT_ELEMENT_NS_PREFIX,
260 SOAPFaultBase.DEFAULT_ELEMENT_NS)
261
262 if ElementTree.iselement(self.detail):
263 detailElem.append(self.detail)
264
265 elif isinstance(self.detail, basestring):
266 detailElem.text = self.detail
267 else:
268 raise TypeError('Expecting ElementTree.Element or string '
269 'type for SOAPFault detail; got %r' %
270 type(self.detail))
271
272 self.elem.append(detailElem)
273
274 - def parse(self, source):
306
310
314
317 """Extend SOAP Fault Exception base class to use ElementTree based
318 SOAP Fault implementation for parsing and serialisation"""
319 SOAP_FAULT_CLASS = SOAPFault
320
321
322 -class SOAPEnvelope(SOAPEnvelopeBase, ETreeSOAPExtensions):
323 """ElementTree based SOAP implementation"""
324 DEFAULT_ELEMENT_NAME = QName(SOAPEnvelopeBase.DEFAULT_ELEMENT_NS,
325 tag=SOAPEnvelopeBase.DEFAULT_ELEMENT_LOCAL_NAME,
326 prefix=SOAPEnvelopeBase.DEFAULT_ELEMENT_NS_PREFIX)
327
337
340
346
347 - def _getBody(self):
349
350 - def _setBody(self, value):
351 if not isinstance(value, SOAPBody):
352 raise TypeError('Expecting %r for "header" attribute; got %r' %
353 (SOAPBody, type(value)))
354 self.__body = value
355
356 header = property(_getHeader, _setHeader, None, "SOAP header object")
357 body = property(_getBody, _setBody, None, "SOAP body object")
358
371
375
379
380 - def parse(self, source):
400