teaching SOAPpy about namespaces... [git-p4: depot-paths = "//depot/": change = 1104]replace/b43bf02ddeddd088c0e6b94974ca1a46562eb3db
| @@ -1,202 +0,0 @@ | |||
| """ | |||
| ################################################################################ | |||
| # Copyright (c) 2003, Pfizer | |||
| # Copyright (c) 2001, Cayce Ullman. | |||
| # Copyright (c) 2001, Brian Matthews. | |||
| # | |||
| # All rights reserved. | |||
| # | |||
| # Redistribution and use in source and binary forms, with or without | |||
| # modification, are permitted provided that the following conditions are met: | |||
| # Redistributions of source code must retain the above copyright notice, this | |||
| # list of conditions and the following disclaimer. | |||
| # | |||
| # Redistributions in binary form must reproduce the above copyright notice, | |||
| # this list of conditions and the following disclaimer in the documentation | |||
| # and/or other materials provided with the distribution. | |||
| # | |||
| # Neither the name of actzero, inc. nor the names of its contributors may | |||
| # be used to endorse or promote products derived from this software without | |||
| # specific prior written permission. | |||
| # | |||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | |||
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
| # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| # | |||
| ################################################################################ | |||
| """ | |||
| ident = '$Id: Config.py,v 1.9 2004/01/31 04:20:05 warnes Exp $' | |||
| from version import __version__ | |||
| import copy, socket | |||
| from types import * | |||
| from NS import NS | |||
| ################################################################################ | |||
| # Configuration class | |||
| ################################################################################ | |||
| class SOAPConfig: | |||
| __readonly = ('SSLserver', 'SSLclient', 'GSIserver', 'GSIclient') | |||
| def __init__(self, config = None, **kw): | |||
| d = self.__dict__ | |||
| if config: | |||
| if not isinstance(config, SOAPConfig): | |||
| raise AttributeError, \ | |||
| "initializer must be SOAPConfig instance" | |||
| s = config.__dict__ | |||
| for k, v in s.items(): | |||
| if k[0] != '_': | |||
| d[k] = v | |||
| else: | |||
| # Setting debug also sets returnFaultInfo, | |||
| # dumpHeadersIn, dumpHeadersOut, dumpSOAPIn, and dumpSOAPOut | |||
| self.debug = 0 | |||
| self.dumpFaultInfo = 1 | |||
| # Setting namespaceStyle sets typesNamespace, typesNamespaceURI, | |||
| # schemaNamespace, and schemaNamespaceURI | |||
| self.namespaceStyle = '1999' | |||
| self.strictNamespaces = 0 | |||
| self.typed = 1 | |||
| self.buildWithNamespacePrefix = 1 | |||
| self.returnAllAttrs = 0 | |||
| # Strict checking of range for floats and doubles | |||
| self.strict_range = 0 | |||
| # Default encoding for dictionary keys | |||
| self.dict_encoding = 'ascii' | |||
| # New argument name handling mechanism. See | |||
| # README.MethodParameterNaming for details | |||
| self.specialArgs = 1 | |||
| # If unwrap_results=1 and there is only element in the struct, | |||
| # SOAPProxy will assume that this element is the result | |||
| # and return it rather than the struct containing it. | |||
| # Otherwise SOAPproxy will return the struct with all the | |||
| # elements as attributes. | |||
| self.unwrap_results = 1 | |||
| # Automatically convert SOAP complex types, and | |||
| # (recursively) public contents into the corresponding | |||
| # python types. (Private subobjects have names that start | |||
| # with '_'.) | |||
| # | |||
| # Conversions: | |||
| # - faultType --> raise python exception | |||
| # - arrayType --> array | |||
| # - compoundType --> dictionary | |||
| # | |||
| self.simplify_objects = 0 | |||
| # Per-class authorization method. If this is set, before | |||
| # calling a any class method, the specified authorization | |||
| # method will be called. If it returns 1, the method call | |||
| # will proceed, otherwise the call will throw with an | |||
| # authorization error. | |||
| self.authMethod = None | |||
| # Globus Support if pyGlobus.io available | |||
| try: | |||
| from pyGlobus import io; | |||
| d['GSIserver'] = 1 | |||
| d['GSIclient'] = 1 | |||
| except: | |||
| d['GSIserver'] = 0 | |||
| d['GSIclient'] = 0 | |||
| # Server SSL support if M2Crypto.SSL available | |||
| try: | |||
| from M2Crypto import SSL | |||
| d['SSLserver'] = 1 | |||
| except: | |||
| d['SSLserver'] = 0 | |||
| # Client SSL support if socket.ssl available | |||
| try: | |||
| from socket import ssl | |||
| d['SSLclient'] = 1 | |||
| except: | |||
| d['SSLclient'] = 0 | |||
| for k, v in kw.items(): | |||
| if k[0] != '_': | |||
| setattr(self, k, v) | |||
| def __setattr__(self, name, value): | |||
| if name in self.__readonly: | |||
| raise AttributeError, "readonly configuration setting" | |||
| d = self.__dict__ | |||
| if name in ('typesNamespace', 'typesNamespaceURI', | |||
| 'schemaNamespace', 'schemaNamespaceURI'): | |||
| if name[-3:] == 'URI': | |||
| base, uri = name[:-3], 1 | |||
| else: | |||
| base, uri = name, 0 | |||
| if type(value) == StringType: | |||
| if NS.NSMAP.has_key(value): | |||
| n = (value, NS.NSMAP[value]) | |||
| elif NS.NSMAP_R.has_key(value): | |||
| n = (NS.NSMAP_R[value], value) | |||
| else: | |||
| raise AttributeError, "unknown namespace" | |||
| elif type(value) in (ListType, TupleType): | |||
| if uri: | |||
| n = (value[1], value[0]) | |||
| else: | |||
| n = (value[0], value[1]) | |||
| else: | |||
| raise AttributeError, "unknown namespace type" | |||
| d[base], d[base + 'URI'] = n | |||
| try: | |||
| d['namespaceStyle'] = \ | |||
| NS.STMAP_R[(d['typesNamespace'], d['schemaNamespace'])] | |||
| except: | |||
| d['namespaceStyle'] = '' | |||
| elif name == 'namespaceStyle': | |||
| value = str(value) | |||
| if not NS.STMAP.has_key(value): | |||
| raise AttributeError, "unknown namespace style" | |||
| d[name] = value | |||
| n = d['typesNamespace'] = NS.STMAP[value][0] | |||
| d['typesNamespaceURI'] = NS.NSMAP[n] | |||
| n = d['schemaNamespace'] = NS.STMAP[value][1] | |||
| d['schemaNamespaceURI'] = NS.NSMAP[n] | |||
| elif name == 'debug': | |||
| d[name] = \ | |||
| d['returnFaultInfo'] = \ | |||
| d['dumpHeadersIn'] = \ | |||
| d['dumpHeadersOut'] = \ | |||
| d['dumpSOAPIn'] = \ | |||
| d['dumpSOAPOut'] = value | |||
| else: | |||
| d[name] = value | |||
| Config = SOAPConfig() | |||
| @@ -1,79 +0,0 @@ | |||
| """ | |||
| ################################################################################ | |||
| # | |||
| # SOAPpy - Cayce Ullman (cayce@actzero.com) | |||
| # Brian Matthews (blm@actzero.com) | |||
| # Gregory Warnes (gregory_r_warnes@groton.pfizer.com) | |||
| # Christopher Blunck (blunck@gst.com) | |||
| # | |||
| ################################################################################ | |||
| # Copyright (c) 2003, Pfizer | |||
| # Copyright (c) 2001, Cayce Ullman. | |||
| # Copyright (c) 2001, Brian Matthews. | |||
| # | |||
| # All rights reserved. | |||
| # | |||
| # Redistribution and use in source and binary forms, with or without | |||
| # modification, are permitted provided that the following conditions are met: | |||
| # Redistributions of source code must retain the above copyright notice, this | |||
| # list of conditions and the following disclaimer. | |||
| # | |||
| # Redistributions in binary form must reproduce the above copyright notice, | |||
| # this list of conditions and the following disclaimer in the documentation | |||
| # and/or other materials provided with the distribution. | |||
| # | |||
| # Neither the name of actzero, inc. nor the names of its contributors may | |||
| # be used to endorse or promote products derived from this software without | |||
| # specific prior written permission. | |||
| # | |||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | |||
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
| # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| # | |||
| ################################################################################ | |||
| """ | |||
| ident = '$Id: Errors.py,v 1.4 2004/01/31 04:20:05 warnes Exp $' | |||
| from version import __version__ | |||
| import exceptions | |||
| ################################################################################ | |||
| # Exceptions | |||
| ################################################################################ | |||
| class Error(exceptions.Exception): | |||
| def __init__(self, msg): | |||
| self.msg = msg | |||
| def __str__(self): | |||
| return "<Error : %s>" % self.msg | |||
| __repr__ = __str__ | |||
| def __call__(self): | |||
| return (msg,) | |||
| class RecursionError(Error): | |||
| pass | |||
| class UnknownTypeError(Error): | |||
| pass | |||
| class HTTPError(Error): | |||
| # indicates an HTTP protocol error | |||
| def __init__(self, code, msg): | |||
| self.code = code | |||
| self.msg = msg | |||
| def __str__(self): | |||
| return "<HTTPError %s %s>" % (self.code, self.msg) | |||
| __repr__ = __str__ | |||
| def __call___(self): | |||
| return (self.code, self.msg, ) | |||
| class UnderflowError(exceptions.ArithmeticError): | |||
| pass | |||
| @@ -1,104 +0,0 @@ | |||
| """ | |||
| ################################################################################ | |||
| # | |||
| # SOAPpy - Cayce Ullman (cayce@actzero.com) | |||
| # Brian Matthews (blm@actzero.com) | |||
| # Gregory Warnes (gregory_r_warnes@groton.pfizer.com) | |||
| # Christopher Blunck (blunck@gst.com) | |||
| # | |||
| ################################################################################ | |||
| # Copyright (c) 2003, Pfizer | |||
| # Copyright (c) 2001, Cayce Ullman. | |||
| # Copyright (c) 2001, Brian Matthews. | |||
| # | |||
| # All rights reserved. | |||
| # | |||
| # Redistribution and use in source and binary forms, with or without | |||
| # modification, are permitted provided that the following conditions are met: | |||
| # Redistributions of source code must retain the above copyright notice, this | |||
| # list of conditions and the following disclaimer. | |||
| # | |||
| # Redistributions in binary form must reproduce the above copyright notice, | |||
| # this list of conditions and the following disclaimer in the documentation | |||
| # and/or other materials provided with the distribution. | |||
| # | |||
| # Neither the name of actzero, inc. nor the names of its contributors may | |||
| # be used to endorse or promote products derived from this software without | |||
| # specific prior written permission. | |||
| # | |||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | |||
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
| # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| # | |||
| ################################################################################ | |||
| """ | |||
| from __future__ import nested_scopes | |||
| ident = '$Id: NS.py,v 1.3 2004/01/31 04:20:05 warnes Exp $' | |||
| from version import __version__ | |||
| ############################################################################## | |||
| # Namespace Class | |||
| ################################################################################ | |||
| def invertDict(dict): | |||
| d = {} | |||
| for k, v in dict.items(): | |||
| d[v] = k | |||
| return d | |||
| class NS: | |||
| XML = "http://www.w3.org/XML/1998/namespace" | |||
| ENV = "http://schemas.xmlsoap.org/soap/envelope/" | |||
| ENC = "http://schemas.xmlsoap.org/soap/encoding/" | |||
| XSD = "http://www.w3.org/1999/XMLSchema" | |||
| XSD2 = "http://www.w3.org/2000/10/XMLSchema" | |||
| XSD3 = "http://www.w3.org/2001/XMLSchema" | |||
| XSD_L = [XSD, XSD2, XSD3] | |||
| EXSD_L= [ENC, XSD, XSD2, XSD3] | |||
| XSI = "http://www.w3.org/1999/XMLSchema-instance" | |||
| XSI2 = "http://www.w3.org/2000/10/XMLSchema-instance" | |||
| XSI3 = "http://www.w3.org/2001/XMLSchema-instance" | |||
| XSI_L = [XSI, XSI2, XSI3] | |||
| URN = "http://soapinterop.org/xsd" | |||
| # For generated messages | |||
| XML_T = "xml" | |||
| ENV_T = "SOAP-ENV" | |||
| ENC_T = "SOAP-ENC" | |||
| XSD_T = "xsd" | |||
| XSD2_T= "xsd2" | |||
| XSD3_T= "xsd3" | |||
| XSI_T = "xsi" | |||
| XSI2_T= "xsi2" | |||
| XSI3_T= "xsi3" | |||
| URN_T = "urn" | |||
| NSMAP = {ENV_T: ENV, ENC_T: ENC, XSD_T: XSD, XSD2_T: XSD2, | |||
| XSD3_T: XSD3, XSI_T: XSI, XSI2_T: XSI2, XSI3_T: XSI3, | |||
| URN_T: URN} | |||
| NSMAP_R = invertDict(NSMAP) | |||
| STMAP = {'1999': (XSD_T, XSI_T), '2000': (XSD2_T, XSI2_T), | |||
| '2001': (XSD3_T, XSI3_T)} | |||
| STMAP_R = invertDict(STMAP) | |||
| def __init__(self): | |||
| raise Error, "Don't instantiate this" | |||
| @@ -1,620 +0,0 @@ | |||
| """ | |||
| ################################################################################ | |||
| # Copyright (c) 2003, Pfizer | |||
| # Copyright (c) 2001, Cayce Ullman. | |||
| # Copyright (c) 2001, Brian Matthews. | |||
| # | |||
| # All rights reserved. | |||
| # | |||
| # Redistribution and use in source and binary forms, with or without | |||
| # modification, are permitted provided that the following conditions are met: | |||
| # Redistributions of source code must retain the above copyright notice, this | |||
| # list of conditions and the following disclaimer. | |||
| # | |||
| # Redistributions in binary form must reproduce the above copyright notice, | |||
| # this list of conditions and the following disclaimer in the documentation | |||
| # and/or other materials provided with the distribution. | |||
| # | |||
| # Neither the name of actzero, inc. nor the names of its contributors may | |||
| # be used to endorse or promote products derived from this software without | |||
| # specific prior written permission. | |||
| # | |||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | |||
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
| # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| # | |||
| ################################################################################ | |||
| """ | |||
| ident = '$Id: SOAPBuilder.py,v 1.19 2004/04/10 04:28:46 irjudson Exp $' | |||
| from version import __version__ | |||
| import cgi | |||
| import copy | |||
| from wstools.XMLname import toXMLname, fromXMLname | |||
| import fpconst | |||
| # SOAPpy modules | |||
| from Config import Config | |||
| from NS import NS | |||
| from Types import * | |||
| # Test whether this Python version has Types.BooleanType | |||
| # If it doesn't have it, then False and True are serialized as integers | |||
| try: | |||
| BooleanType | |||
| pythonHasBooleanType = 1 | |||
| except NameError: | |||
| pythonHasBooleanType = 0 | |||
| ################################################################################ | |||
| # SOAP Builder | |||
| ################################################################################ | |||
| class SOAPBuilder: | |||
| _xml_top = '<?xml version="1.0"?>\n' | |||
| _xml_enc_top = '<?xml version="1.0" encoding="%s"?>\n' | |||
| _env_top = '%(ENV_T)s:Envelope %(ENV_T)s:encodingStyle="%(ENC)s"' % \ | |||
| NS.__dict__ | |||
| _env_bot = '</%(ENV_T)s:Envelope>\n' % NS.__dict__ | |||
| # Namespaces potentially defined in the Envelope tag. | |||
| _env_ns = {NS.ENC: NS.ENC_T, NS.ENV: NS.ENV_T, | |||
| NS.XSD: NS.XSD_T, NS.XSD2: NS.XSD2_T, NS.XSD3: NS.XSD3_T, | |||
| NS.XSI: NS.XSI_T, NS.XSI2: NS.XSI2_T, NS.XSI3: NS.XSI3_T} | |||
| def __init__(self, args = (), kw = {}, method = None, namespace = None, | |||
| header = None, methodattrs = None, envelope = 1, encoding = 'UTF-8', | |||
| use_refs = 0, config = Config, noroot = 0): | |||
| # Test the encoding, raising an exception if it's not known | |||
| if encoding != None: | |||
| ''.encode(encoding) | |||
| self.args = args | |||
| self.kw = kw | |||
| self.envelope = envelope | |||
| self.encoding = encoding | |||
| self.method = method | |||
| self.namespace = namespace | |||
| self.header = header | |||
| self.methodattrs= methodattrs | |||
| self.use_refs = use_refs | |||
| self.config = config | |||
| self.out = [] | |||
| self.tcounter = 0 | |||
| self.ncounter = 1 | |||
| self.icounter = 1 | |||
| self.envns = {} | |||
| self.ids = {} | |||
| self.depth = 0 | |||
| self.multirefs = [] | |||
| self.multis = 0 | |||
| self.body = not isinstance(args, bodyType) | |||
| self.noroot = noroot | |||
| def build(self): | |||
| if Config.debug: print "In build." | |||
| ns_map = {} | |||
| # Cache whether typing is on or not | |||
| typed = self.config.typed | |||
| if self.header: | |||
| # Create a header. | |||
| self.dump(self.header, "Header", typed = typed) | |||
| self.header = None # Wipe it out so no one is using it. | |||
| if self.body: | |||
| # Call genns to record that we've used SOAP-ENV. | |||
| self.depth += 1 | |||
| body_ns = self.genns(ns_map, NS.ENV)[0] | |||
| self.out.append("<%sBody>\n" % body_ns) | |||
| if self.method: | |||
| self.depth += 1 | |||
| a = '' | |||
| if self.methodattrs: | |||
| for (k, v) in self.methodattrs.items(): | |||
| a += ' %s="%s"' % (k, v) | |||
| if self.namespace: # Use the namespace info handed to us | |||
| methodns, n = self.genns(ns_map, self.namespace) | |||
| else: | |||
| methodns, n = '', '' | |||
| self.out.append('<%s%s%s%s%s>\n' % ( | |||
| methodns, self.method, n, a, self.genroot(ns_map))) | |||
| try: | |||
| if type(self.args) != TupleType: | |||
| args = (self.args,) | |||
| else: | |||
| args = self.args | |||
| for i in args: | |||
| self.dump(i, typed = typed, ns_map = ns_map) | |||
| if hasattr(self.config, "argsOrdering") and self.config.argsOrdering.has_key(self.method): | |||
| for k in self.config.argsOrdering.get(self.method): | |||
| self.dump(self.kw.get(k), k, typed = typed, ns_map = ns_map) | |||
| else: | |||
| for (k, v) in self.kw.items(): | |||
| self.dump(v, k, typed = typed, ns_map = ns_map) | |||
| except RecursionError: | |||
| if self.use_refs == 0: | |||
| # restart | |||
| b = SOAPBuilder(args = self.args, kw = self.kw, | |||
| method = self.method, namespace = self.namespace, | |||
| header = self.header, methodattrs = self.methodattrs, | |||
| envelope = self.envelope, encoding = self.encoding, | |||
| use_refs = 1, config = self.config) | |||
| return b.build() | |||
| raise | |||
| if self.method: | |||
| self.out.append("</%s%s>\n" % (methodns, self.method)) | |||
| self.depth -= 1 | |||
| if self.body: | |||
| # dump may add to self.multirefs, but the for loop will keep | |||
| # going until it has used all of self.multirefs, even those | |||
| # entries added while in the loop. | |||
| self.multis = 1 | |||
| for obj, tag in self.multirefs: | |||
| self.dump(obj, tag, typed = typed, ns_map = ns_map) | |||
| self.out.append("</%sBody>\n" % body_ns) | |||
| self.depth -= 1 | |||
| if self.envelope: | |||
| e = map (lambda ns: ' xmlns:%s="%s"' % (ns[1], ns[0]), | |||
| self.envns.items()) | |||
| self.out = ['<', self._env_top] + e + ['>\n'] + \ | |||
| self.out + \ | |||
| [self._env_bot] | |||
| if self.encoding != None: | |||
| self.out.insert(0, self._xml_enc_top % self.encoding) | |||
| return ''.join(self.out).encode(self.encoding) | |||
| self.out.insert(0, self._xml_top) | |||
| return ''.join(self.out) | |||
| def gentag(self): | |||
| if Config.debug: print "In gentag." | |||
| self.tcounter += 1 | |||
| return "v%d" % self.tcounter | |||
| def genns(self, ns_map, nsURI): | |||
| if nsURI == None: | |||
| return ('', '') | |||
| if type(nsURI) == TupleType: # already a tuple | |||
| if len(nsURI) == 2: | |||
| ns, nsURI = nsURI | |||
| else: | |||
| ns, nsURI = None, nsURI[0] | |||
| else: | |||
| ns = None | |||
| if ns_map.has_key(nsURI): | |||
| return (ns_map[nsURI] + ':', '') | |||
| if self._env_ns.has_key(nsURI): | |||
| ns = self.envns[nsURI] = ns_map[nsURI] = self._env_ns[nsURI] | |||
| return (ns + ':', '') | |||
| if not ns: | |||
| ns = "ns%d" % self.ncounter | |||
| self.ncounter += 1 | |||
| ns_map[nsURI] = ns | |||
| if self.config.buildWithNamespacePrefix: | |||
| return (ns + ':', ' xmlns:%s="%s"' % (ns, nsURI)) | |||
| else: | |||
| return ('', ' xmlns="%s"' % (nsURI)) | |||
| def genroot(self, ns_map): | |||
| if self.noroot: | |||
| return '' | |||
| if self.depth != 2: | |||
| return '' | |||
| ns, n = self.genns(ns_map, NS.ENC) | |||
| return ' %sroot="%d"%s' % (ns, not self.multis, n) | |||
| # checkref checks an element to see if it needs to be encoded as a | |||
| # multi-reference element or not. If it returns None, the element has | |||
| # been handled and the caller can continue with subsequent elements. | |||
| # If it returns a string, the string should be included in the opening | |||
| # tag of the marshaled element. | |||
| def checkref(self, obj, tag, ns_map): | |||
| if self.depth < 2: | |||
| return '' | |||
| if not self.ids.has_key(id(obj)): | |||
| n = self.ids[id(obj)] = self.icounter | |||
| self.icounter = n + 1 | |||
| if self.use_refs == 0: | |||
| return '' | |||
| if self.depth == 2: | |||
| return ' id="i%d"' % n | |||
| self.multirefs.append((obj, tag)) | |||
| else: | |||
| if self.use_refs == 0: | |||
| raise RecursionError, "Cannot serialize recursive object" | |||
| n = self.ids[id(obj)] | |||
| if self.multis and self.depth == 2: | |||
| return ' id="i%d"' % n | |||
| self.out.append('<%s href="#i%d"%s/>\n' % | |||
| (tag, n, self.genroot(ns_map))) | |||
| return None | |||
| # dumpers | |||
| def dump(self, obj, tag = None, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump.", "obj=", obj | |||
| ns_map = ns_map.copy() | |||
| self.depth += 1 | |||
| if type(tag) not in (NoneType, StringType, UnicodeType): | |||
| raise KeyError, "tag must be a string or None" | |||
| try: | |||
| meth = getattr(self, "dump_" + type(obj).__name__) | |||
| except AttributeError: | |||
| if type(obj) == LongType: | |||
| obj_type = "integer" | |||
| elif pythonHasBooleanType and type(obj) == BooleanType: | |||
| obj_type = "boolean" | |||
| else: | |||
| obj_type = type(obj).__name__ | |||
| self.out.append(self.dumper(None, obj_type, obj, tag, typed, | |||
| ns_map, self.genroot(ns_map))) | |||
| else: | |||
| meth(obj, tag, typed, ns_map) | |||
| self.depth -= 1 | |||
| # generic dumper | |||
| def dumper(self, nsURI, obj_type, obj, tag, typed = 1, ns_map = {}, | |||
| rootattr = '', id = '', | |||
| xml = '<%(tag)s%(type)s%(id)s%(attrs)s%(root)s>%(data)s</%(tag)s>\n'): | |||
| if Config.debug: print "In dumper." | |||
| if nsURI == None: | |||
| nsURI = self.config.typesNamespaceURI | |||
| tag = tag or self.gentag() | |||
| tag = toXMLname(tag) # convert from SOAP 1.2 XML name encoding | |||
| a = n = t = '' | |||
| if typed and obj_type: | |||
| ns, n = self.genns(ns_map, nsURI) | |||
| ins = self.genns(ns_map, self.config.schemaNamespaceURI)[0] | |||
| t = ' %stype="%s%s"%s' % (ins, ns, obj_type, n) | |||
| try: a = obj._marshalAttrs(ns_map, self) | |||
| except: pass | |||
| try: data = obj._marshalData() | |||
| except: | |||
| if (obj_type != "string"): # strings are already encoded | |||
| data = cgi.escape(str(obj)) | |||
| else: | |||
| data = obj | |||
| return xml % {"tag": tag, "type": t, "data": data, "root": rootattr, | |||
| "id": id, "attrs": a} | |||
| def dump_float(self, obj, tag, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump_float." | |||
| tag = tag or self.gentag() | |||
| tag = toXMLname(tag) # convert from SOAP 1.2 XML name encoding | |||
| if Config.strict_range: | |||
| doubleType(obj) | |||
| if fpconst.isPosInf(obj): | |||
| obj = "INF" | |||
| elif fpconst.isNegInf(obj): | |||
| obj = "-INF" | |||
| elif fpconst.isNaN(obj): | |||
| obj = "NaN" | |||
| else: | |||
| obj = str(obj) | |||
| # Note: python 'float' is actually a SOAP 'double'. | |||
| self.out.append(self.dumper(None, "double", obj, tag, typed, ns_map, | |||
| self.genroot(ns_map))) | |||
| def dump_string(self, obj, tag, typed = 0, ns_map = {}): | |||
| if Config.debug: print "In dump_string." | |||
| tag = tag or self.gentag() | |||
| tag = toXMLname(tag) # convert from SOAP 1.2 XML name encoding | |||
| id = self.checkref(obj, tag, ns_map) | |||
| if id == None: | |||
| return | |||
| try: data = obj._marshalData() | |||
| except: data = obj | |||
| self.out.append(self.dumper(None, "string", cgi.escape(data), tag, | |||
| typed, ns_map, self.genroot(ns_map), id)) | |||
| dump_str = dump_string # For Python 2.2+ | |||
| dump_unicode = dump_string | |||
| def dump_None(self, obj, tag, typed = 0, ns_map = {}): | |||
| if Config.debug: print "In dump_None." | |||
| tag = tag or self.gentag() | |||
| tag = toXMLname(tag) # convert from SOAP 1.2 XML name encoding | |||
| ns = self.genns(ns_map, self.config.schemaNamespaceURI)[0] | |||
| self.out.append('<%s %snull="1"%s/>\n' % | |||
| (tag, ns, self.genroot(ns_map))) | |||
| dump_NoneType = dump_None # For Python 2.2+ | |||
| def dump_list(self, obj, tag, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump_list.", "obj=", obj | |||
| tag = tag or self.gentag() | |||
| tag = toXMLname(tag) # convert from SOAP 1.2 XML name encoding | |||
| if type(obj) == InstanceType: | |||
| data = obj.data | |||
| else: | |||
| data = obj | |||
| id = self.checkref(obj, tag, ns_map) | |||
| if id == None: | |||
| return | |||
| try: | |||
| sample = data[0] | |||
| empty = 0 | |||
| except: | |||
| # preserve type if present | |||
| if getattr(obj,"_typed",None) and getattr(obj,"_type",None): | |||
| if getattr(obj, "_complexType", None): | |||
| sample = typedArrayType(typed=obj._type, | |||
| complexType = obj._complexType) | |||
| sample._typename = obj._type | |||
| obj._ns = NS.URN | |||
| else: | |||
| sample = typedArrayType(typed=obj._type) | |||
| else: | |||
| sample = structType() | |||
| empty = 1 | |||
| # First scan list to see if all are the same type | |||
| same_type = 1 | |||
| if not empty: | |||
| for i in data[1:]: | |||
| if type(sample) != type(i) or \ | |||
| (type(sample) == InstanceType and \ | |||
| sample.__class__ != i.__class__): | |||
| same_type = 0 | |||
| break | |||
| ndecl = '' | |||
| if same_type: | |||
| if (isinstance(sample, structType)) or \ | |||
| type(sample) == DictType or \ | |||
| (isinstance(sample, anyType) and \ | |||
| (getattr(sample, "_complexType", None) and \ | |||
| sample._complexType)): # force to urn struct | |||
| try: | |||
| tns = obj._ns or NS.URN | |||
| except: | |||
| tns = NS.URN | |||
| ns, ndecl = self.genns(ns_map, tns) | |||
| try: | |||
| typename = sample._typename | |||
| except: | |||
| typename = "SOAPStruct" | |||
| t = ns + typename | |||
| elif isinstance(sample, anyType): | |||
| ns = sample._validNamespaceURI(self.config.typesNamespaceURI, | |||
| self.config.strictNamespaces) | |||
| if ns: | |||
| ns, ndecl = self.genns(ns_map, ns) | |||
| t = ns + sample._type | |||
| else: | |||
| t = 'ur-type' | |||
| else: | |||
| typename = type(sample).__name__ | |||
| # For Python 2.2+ | |||
| if type(sample) == StringType: typename = 'string' | |||
| # HACK: python 'float' is actually a SOAP 'double'. | |||
| if typename=="float": typename="double" | |||
| t = self.genns(ns_map, self.config.typesNamespaceURI)[0] + \ | |||
| typename | |||
| else: | |||
| t = self.genns(ns_map, self.config.typesNamespaceURI)[0] + \ | |||
| "ur-type" | |||
| try: a = obj._marshalAttrs(ns_map, self) | |||
| except: a = '' | |||
| ens, edecl = self.genns(ns_map, NS.ENC) | |||
| ins, idecl = self.genns(ns_map, self.config.schemaNamespaceURI) | |||
| self.out.append( | |||
| '<%s %sarrayType="%s[%d]" %stype="%sArray"%s%s%s%s%s%s>\n' % | |||
| (tag, ens, t, len(data), ins, ens, ndecl, edecl, idecl, | |||
| self.genroot(ns_map), id, a)) | |||
| typed = not same_type | |||
| try: elemsname = obj._elemsname | |||
| except: elemsname = "item" | |||
| for i in data: | |||
| self.dump(i, elemsname, typed, ns_map) | |||
| self.out.append('</%s>\n' % tag) | |||
| dump_tuple = dump_list | |||
| def dump_dictionary(self, obj, tag, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump_dictionary." | |||
| tag = tag or self.gentag() | |||
| tag = toXMLname(tag) # convert from SOAP 1.2 XML name encoding | |||
| id = self.checkref(obj, tag, ns_map) | |||
| if id == None: | |||
| return | |||
| try: a = obj._marshalAttrs(ns_map, self) | |||
| except: a = '' | |||
| self.out.append('<%s%s%s%s>\n' % | |||
| (tag, id, a, self.genroot(ns_map))) | |||
| for (k, v) in obj.items(): | |||
| if k[0] != "_": | |||
| self.dump(v, k, 1, ns_map) | |||
| self.out.append('</%s>\n' % tag) | |||
| dump_dict = dump_dictionary # For Python 2.2+ | |||
| def dump_instance(self, obj, tag, typed = 1, ns_map = {}): | |||
| if Config.debug: print "In dump_instance.", "obj=", obj, "tag=", tag | |||
| if not tag: | |||
| # If it has a name use it. | |||
| if isinstance(obj, anyType) and obj._name: | |||
| tag = obj._name | |||
| else: | |||
| tag = self.gentag() | |||
| tag = toXMLname(tag) # convert from SOAP 1.2 XML name encoding | |||
| if isinstance(obj, arrayType): # Array | |||
| self.dump_list(obj, tag, typed, ns_map) | |||
| return | |||
| if isinstance(obj, faultType): # Fault | |||
| cns, cdecl = self.genns(ns_map, NS.ENC) | |||
| vns, vdecl = self.genns(ns_map, NS.ENV) | |||
| self.out.append('''<%sFault %sroot="1"%s%s> | |||
| <faultcode>%s</faultcode> | |||
| <faultstring>%s</faultstring> | |||
| ''' % (vns, cns, vdecl, cdecl, obj.faultcode, obj.faultstring)) | |||
| if hasattr(obj, "detail"): | |||
| self.dump(obj.detail, "detail", typed, ns_map) | |||
| self.out.append("</%sFault>\n" % vns) | |||
| return | |||
| r = self.genroot(ns_map) | |||
| try: a = obj._marshalAttrs(ns_map, self) | |||
| except: a = '' | |||
| if isinstance(obj, voidType): # void | |||
| self.out.append("<%s%s%s></%s>\n" % (tag, a, r, tag)) | |||
| return | |||
| id = self.checkref(obj, tag, ns_map) | |||
| if id == None: | |||
| return | |||
| if isinstance(obj, structType): | |||
| # Check for namespace | |||
| ndecl = '' | |||
| ns = obj._validNamespaceURI(self.config.typesNamespaceURI, | |||
| self.config.strictNamespaces) | |||
| if ns: | |||
| ns, ndecl = self.genns(ns_map, ns) | |||
| tag = ns + tag | |||
| self.out.append("<%s%s%s%s%s>\n" % (tag, ndecl, id, a, r)) | |||
| keylist = obj.__dict__.keys() | |||
| # first write out items with order information | |||
| if hasattr(obj, '_keyord'): | |||
| for i in range(len(obj._keyord)): | |||
| self.dump(obj._aslist(i), obj._keyord[i], 1, ns_map) | |||
| keylist.remove(obj._keyord[i]) | |||
| # now write out the rest | |||
| for k in keylist: | |||
| if (k[0] != "_"): | |||
| self.dump(getattr(obj,k), k, 1, ns_map) | |||
| if isinstance(obj, bodyType): | |||
| self.multis = 1 | |||
| for v, k in self.multirefs: | |||
| self.dump(v, k, typed = typed, ns_map = ns_map) | |||
| self.out.append('</%s>\n' % tag) | |||
| elif isinstance(obj, anyType): | |||
| t = '' | |||
| if typed: | |||
| ns = obj._validNamespaceURI(self.config.typesNamespaceURI, | |||
| self.config.strictNamespaces) | |||
| if ns: | |||
| ons, ondecl = self.genns(ns_map, ns) | |||
| ins, indecl = self.genns(ns_map, | |||
| self.config.schemaNamespaceURI) | |||
| t = ' %stype="%s%s"%s%s' % \ | |||
| (ins, ons, obj._type, ondecl, indecl) | |||
| self.out.append('<%s%s%s%s%s>%s</%s>\n' % | |||
| (tag, t, id, a, r, obj._marshalData(), tag)) | |||
| else: # Some Class | |||
| self.out.append('<%s%s%s>\n' % (tag, id, r)) | |||
| for (k, v) in obj.__dict__.items(): | |||
| if k[0] != "_": | |||
| self.dump(v, k, 1, ns_map) | |||
| self.out.append('</%s>\n' % tag) | |||
| ################################################################################ | |||
| # SOAPBuilder's more public interface | |||
| ################################################################################ | |||
| def buildSOAP(args=(), kw={}, method=None, namespace=None, header=None, | |||
| methodattrs=None,envelope=1,encoding='UTF-8',config=Config,noroot = 0): | |||
| t = SOAPBuilder(args=args,kw=kw, method=method, namespace=namespace, | |||
| header=header, methodattrs=methodattrs,envelope=envelope, | |||
| encoding=encoding, config=config,noroot=noroot) | |||
| return t.build() | |||
| @@ -1,178 +0,0 @@ | |||
| """ | |||
| ################################################################################ | |||
| # Copyright (c) 2003, Pfizer | |||
| # Copyright (c) 2001, Cayce Ullman. | |||
| # Copyright (c) 2001, Brian Matthews. | |||
| # | |||
| # All rights reserved. | |||
| # | |||
| # Redistribution and use in source and binary forms, with or without | |||
| # modification, are permitted provided that the following conditions are met: | |||
| # Redistributions of source code must retain the above copyright notice, this | |||
| # list of conditions and the following disclaimer. | |||
| # | |||
| # Redistributions in binary form must reproduce the above copyright notice, | |||
| # this list of conditions and the following disclaimer in the documentation | |||
| # and/or other materials provided with the distribution. | |||
| # | |||
| # Neither the name of actzero, inc. nor the names of its contributors may | |||
| # be used to endorse or promote products derived from this software without | |||
| # specific prior written permission. | |||
| # | |||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | |||
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
| # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
| # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| # | |||
| ################################################################################ | |||
| """ | |||
| ident = '$Id: Utilities.py,v 1.4 2004/01/31 04:20:06 warnes Exp $' | |||
| from version import __version__ | |||
| import exceptions | |||
| import copy | |||
| import re | |||
| import string | |||
| import sys | |||
| from types import * | |||
| # SOAPpy modules | |||
| from Errors import * | |||
| ################################################################################ | |||
| # Utility infielders | |||
| ################################################################################ | |||
| def collapseWhiteSpace(s): | |||
| return re.sub('\s+', ' ', s).strip() | |||
| def decodeHexString(data): | |||
| conv = { | |||
| '0': 0x0, '1': 0x1, '2': 0x2, '3': 0x3, '4': 0x4, | |||
| '5': 0x5, '6': 0x6, '7': 0x7, '8': 0x8, '9': 0x9, | |||
| 'a': 0xa, 'b': 0xb, 'c': 0xc, 'd': 0xd, 'e': 0xe, | |||
| 'f': 0xf, | |||
| 'A': 0xa, 'B': 0xb, 'C': 0xc, 'D': 0xd, 'E': 0xe, | |||
| 'F': 0xf, | |||
| } | |||
| ws = string.whitespace | |||
| bin = '' | |||
| i = 0 | |||
| while i < len(data): | |||
| if data[i] not in ws: | |||
| break | |||
| i += 1 | |||
| low = 0 | |||
| while i < len(data): | |||
| c = data[i] | |||
| if c in string.whitespace: | |||
| break | |||
| try: | |||
| c = conv[c] | |||
| except KeyError: | |||
| raise ValueError, \ | |||
| "invalid hex string character `%s'" % c | |||
| if low: | |||
| bin += chr(high * 16 + c) | |||
| low = 0 | |||
| else: | |||
| high = c | |||
| low = 1 | |||
| i += 1 | |||
| if low: | |||
| raise ValueError, "invalid hex string length" | |||
| while i < len(data): | |||
| if data[i] not in string.whitespace: | |||
| raise ValueError, \ | |||
| "invalid hex string character `%s'" % c | |||
| i += 1 | |||
| return bin | |||
| def encodeHexString(data): | |||
| h = '' | |||
| for i in data: | |||
| h += "%02X" % ord(i) | |||
| return h | |||
| def leapMonth(year, month): | |||
| return month == 2 and \ | |||
| year % 4 == 0 and \ | |||
| (year % 100 != 0 or year % 400 == 0) | |||
| def cleanDate(d, first = 0): | |||
| ranges = (None, (1, 12), (1, 31), (0, 23), (0, 59), (0, 61)) | |||
| months = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) | |||
| names = ('year', 'month', 'day', 'hours', 'minutes', 'seconds') | |||
| if len(d) != 6: | |||
| raise ValueError, "date must have 6 elements" | |||
| for i in range(first, 6): | |||
| s = d[i] | |||
| if type(s) == FloatType: | |||
| if i < 5: | |||
| try: | |||
| s = int(s) | |||
| except OverflowError: | |||
| if i > 0: | |||
| raise | |||
| s = long(s) | |||
| if s != d[i]: | |||
| raise ValueError, "%s must be integral" % names[i] | |||
| d[i] = s | |||
| elif type(s) == LongType: | |||
| try: s = int(s) | |||
| except: pass | |||
| elif type(s) != IntType: | |||
| raise TypeError, "%s isn't a valid type" % names[i] | |||
| if i == first and s < 0: | |||
| continue | |||
| if ranges[i] != None and \ | |||
| (s < ranges[i][0] or ranges[i][1] < s): | |||
| raise ValueError, "%s out of range" % names[i] | |||
| if first < 6 and d[5] >= 61: | |||
| raise ValueError, "seconds out of range" | |||
| if first < 2: | |||
| leap = first < 1 and leapMonth(d[0], d[1]) | |||
| if d[2] > months[d[1]] + leap: | |||
| raise ValueError, "day out of range" | |||
| def debugHeader(title): | |||
| s = '*** ' + title + ' ' | |||
| print s + ('*' * (72 - len(s))) | |||
| def debugFooter(title): | |||
| print '*' * 72 | |||
| sys.stdout.flush() | |||
| @@ -1,15 +0,0 @@ | |||
| ident = '$Id: __init__.py,v 1.9 2004/01/31 04:20:06 warnes Exp $' | |||
| from version import __version__ | |||
| from Client import * | |||
| from Config import * | |||
| from Errors import * | |||
| from NS import * | |||
| from Parser import * | |||
| from SOAPBuilder import * | |||
| from Server import * | |||
| from Types import * | |||
| from Utilities import * | |||
| import wstools | |||
| import WSDL | |||
| @@ -1,2 +0,0 @@ | |||
| __version__="0.11.6" | |||
| @@ -1,92 +0,0 @@ | |||
| #! /usr/bin/env python | |||
| """Namespace module, so you don't need PyXML | |||
| """ | |||
| try: | |||
| from xml.ns import SOAP, SCHEMA, WSDL, XMLNS, DSIG, ENCRYPTION | |||
| except: | |||
| class SOAP: | |||
| ENV = "http://schemas.xmlsoap.org/soap/envelope/" | |||
| ENC = "http://schemas.xmlsoap.org/soap/encoding/" | |||
| ACTOR_NEXT = "http://schemas.xmlsoap.org/soap/actor/next" | |||
| class SCHEMA: | |||
| XSD1 = "http://www.w3.org/1999/XMLSchema" | |||
| XSD2 = "http://www.w3.org/2000/10/XMLSchema" | |||
| XSD3 = "http://www.w3.org/2001/XMLSchema" | |||
| XSD_LIST = [ XSD1, XSD2, XSD3 ] | |||
| XSI1 = "http://www.w3.org/1999/XMLSchema-instance" | |||
| XSI2 = "http://www.w3.org/2000/10/XMLSchema-instance" | |||
| XSI3 = "http://www.w3.org/2001/XMLSchema-instance" | |||
| XSI_LIST = [ XSI1, XSI2, XSI3 ] | |||
| BASE = XSD3 | |||
| class WSDL: | |||
| BASE = "http://schemas.xmlsoap.org/wsdl/" | |||
| BIND_HTTP = "http://schemas.xmlsoap.org/wsdl/http/" | |||
| BIND_MIME = "http://schemas.xmlsoap.org/wsdl/mime/" | |||
| BIND_SOAP = "http://schemas.xmlsoap.org/wsdl/soap/" | |||
| class XMLNS: | |||
| BASE = "http://www.w3.org/2000/xmlns/" | |||
| XML = "http://www.w3.org/XML/1998/namespace" | |||
| HTML = "http://www.w3.org/TR/REC-html40" | |||
| class DSIG: | |||
| BASE = "http://www.w3.org/2000/09/xmldsig#" | |||
| C14N = "http://www.w3.org/TR/2000/CR-xml-c14n-20010315" | |||
| C14N_COMM = "http://www.w3.org/TR/2000/CR-xml-c14n-20010315#WithComments" | |||
| C14N_EXCL = "http://www.w3.org/2001/10/xml-exc-c14n#" | |||
| DIGEST_MD2 = "http://www.w3.org/2000/09/xmldsig#md2" | |||
| DIGEST_MD5 = "http://www.w3.org/2000/09/xmldsig#md5" | |||
| DIGEST_SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1" | |||
| ENC_BASE64 = "http://www.w3.org/2000/09/xmldsig#base64" | |||
| ENVELOPED = "http://www.w3.org/2000/09/xmldsig#enveloped-signature" | |||
| HMAC_SHA1 = "http://www.w3.org/2000/09/xmldsig#hmac-sha1" | |||
| SIG_DSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#dsa-sha1" | |||
| SIG_RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1" | |||
| XPATH = "http://www.w3.org/TR/1999/REC-xpath-19991116" | |||
| XSLT = "http://www.w3.org/TR/1999/REC-xslt-19991116" | |||
| class ENCRYPTION: | |||
| BASE = "http://www.w3.org/2001/04/xmlenc#" | |||
| BLOCK_3DES = "http://www.w3.org/2001/04/xmlenc#des-cbc" | |||
| BLOCK_AES128 = "http://www.w3.org/2001/04/xmlenc#aes128-cbc" | |||
| BLOCK_AES192 = "http://www.w3.org/2001/04/xmlenc#aes192-cbc" | |||
| BLOCK_AES256 = "http://www.w3.org/2001/04/xmlenc#aes256-cbc" | |||
| DIGEST_RIPEMD160 = "http://www.w3.org/2001/04/xmlenc#ripemd160" | |||
| DIGEST_SHA256 = "http://www.w3.org/2001/04/xmlenc#sha256" | |||
| DIGEST_SHA512 = "http://www.w3.org/2001/04/xmlenc#sha512" | |||
| KA_DH = "http://www.w3.org/2001/04/xmlenc#dh" | |||
| KT_RSA_1_5 = "http://www.w3.org/2001/04/xmlenc#rsa-1_5" | |||
| KT_RSA_OAEP = "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" | |||
| STREAM_ARCFOUR = "http://www.w3.org/2001/04/xmlenc#arcfour" | |||
| WRAP_3DES = "http://www.w3.org/2001/04/xmlenc#kw-3des" | |||
| WRAP_AES128 = "http://www.w3.org/2001/04/xmlenc#kw-aes128" | |||
| WRAP_AES192 = "http://www.w3.org/2001/04/xmlenc#kw-aes192" | |||
| WRAP_AES256 = "http://www.w3.org/2001/04/xmlenc#kw-aes256" | |||
| class WSSE: | |||
| BASE = "http://schemas.xmlsoap.org/ws/2002/04/secext" | |||
| class WSU: | |||
| BASE = "http://schemas.xmlsoap.org/ws/2002/04/utility" | |||
| UTILITY = "http://schemas.xmlsoap.org/ws/2002/07/utility" | |||
| class WSR: | |||
| PROPERTIES = "http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceProperties" | |||
| LIFETIME = "http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceLifetime" | |||
| class WSA: | |||
| ADDRESS = "http://schemas.xmlsoap.org/ws/2003/03/addressing" | |||
| ADDRESS2004 = "http://schemas.xmlsoap.org/ws/2004/03/addressing" | |||
| ANONYMOUS = "%s/role/anonymous" %ADDRESS | |||
| ANONYMOUS2004 = "%s/role/anonymous" %ADDRESS2004 | |||
| FAULT = "http://schemas.xmlsoap.org/ws/2004/03/addressing/fault" | |||
| class WSP: | |||
| POLICY = "http://schemas.xmlsoap.org/ws/2002/12/policy" | |||
| @@ -1,179 +0,0 @@ | |||
| """Based on code from timeout_socket.py, with some tweaks for compatibility. | |||
| These tweaks should really be rolled back into timeout_socket, but it's | |||
| not totally clear who is maintaining it at this point. In the meantime, | |||
| we'll use a different module name for our tweaked version to avoid any | |||
| confusion. | |||
| The original timeout_socket is by: | |||
| Scott Cotton <scott@chronis.pobox.com> | |||
| Lloyd Zusman <ljz@asfast.com> | |||
| Phil Mayes <pmayes@olivebr.com> | |||
| Piers Lauder <piers@cs.su.oz.au> | |||
| Radovan Garabik <garabik@melkor.dnp.fmph.uniba.sk> | |||
| """ | |||
| ident = "$Id: TimeoutSocket.py,v 1.2 2003/05/20 21:10:12 warnes Exp $" | |||
| import string, socket, select, errno | |||
| WSAEINVAL = getattr(errno, 'WSAEINVAL', 10022) | |||
| class TimeoutSocket: | |||
| """A socket imposter that supports timeout limits.""" | |||
| def __init__(self, timeout=20, sock=None): | |||
| self.timeout = float(timeout) | |||
| self.inbuf = '' | |||
| if sock is None: | |||
| sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||
| self.sock = sock | |||
| self.sock.setblocking(0) | |||
| self._rbuf = '' | |||
| self._wbuf = '' | |||
| def __getattr__(self, name): | |||
| # Delegate to real socket attributes. | |||
| return getattr(self.sock, name) | |||
| def connect(self, *addr): | |||
| timeout = self.timeout | |||
| sock = self.sock | |||
| try: | |||
| # Non-blocking mode | |||
| sock.setblocking(0) | |||
| apply(sock.connect, addr) | |||
| sock.setblocking(timeout != 0) | |||
| return 1 | |||
| except socket.error,why: | |||
| if not timeout: | |||
| raise | |||
| sock.setblocking(1) | |||
| if len(why.args) == 1: | |||
| code = 0 | |||
| else: | |||
| code, why = why | |||
| if code not in ( | |||
| errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK | |||
| ): | |||
| raise | |||
| r,w,e = select.select([],[sock],[],timeout) | |||
| if w: | |||
| try: | |||
| apply(sock.connect, addr) | |||
| return 1 | |||
| except socket.error,why: | |||
| if len(why.args) == 1: | |||
| code = 0 | |||
| else: | |||
| code, why = why | |||
| if code in (errno.EISCONN, WSAEINVAL): | |||
| return 1 | |||
| raise | |||
| raise TimeoutError('socket connect() timeout.') | |||
| def send(self, data, flags=0): | |||
| total = len(data) | |||
| next = 0 | |||
| while 1: | |||
| r, w, e = select.select([],[self.sock], [], self.timeout) | |||
| if w: | |||
| buff = data[next:next + 8192] | |||
| sent = self.sock.send(buff, flags) | |||
| next = next + sent | |||
| if next == total: | |||
| return total | |||
| continue | |||
| raise TimeoutError('socket send() timeout.') | |||
| def recv(self, amt, flags=0): | |||
| if select.select([self.sock], [], [], self.timeout)[0]: | |||
| return self.sock.recv(amt, flags) | |||
| raise TimeoutError('socket recv() timeout.') | |||
| buffsize = 4096 | |||
| handles = 1 | |||
| def makefile(self, mode="r", buffsize=-1): | |||
| self.handles = self.handles + 1 | |||
| self.mode = mode | |||
| return self | |||
| def close(self): | |||
| self.handles = self.handles - 1 | |||
| if self.handles == 0 and self.sock.fileno() >= 0: | |||
| self.sock.close() | |||
| def read(self, n=-1): | |||
| if not isinstance(n, type(1)): | |||
| n = -1 | |||
| if n >= 0: | |||
| k = len(self._rbuf) | |||
| if n <= k: | |||
| data = self._rbuf[:n] | |||
| self._rbuf = self._rbuf[n:] | |||
| return data | |||
| n = n - k | |||
| L = [self._rbuf] | |||
| self._rbuf = "" | |||
| while n > 0: | |||
| new = self.recv(max(n, self.buffsize)) | |||
| if not new: break | |||
| k = len(new) | |||
| if k > n: | |||
| L.append(new[:n]) | |||
| self._rbuf = new[n:] | |||
| break | |||
| L.append(new) | |||
| n = n - k | |||
| return "".join(L) | |||
| k = max(4096, self.buffsize) | |||
| L = [self._rbuf] | |||
| self._rbuf = "" | |||
| while 1: | |||
| new = self.recv(k) | |||
| if not new: break | |||
| L.append(new) | |||
| k = min(k*2, 1024**2) | |||
| return "".join(L) | |||
| def readline(self, limit=-1): | |||
| data = "" | |||
| i = self._rbuf.find('\n') | |||
| while i < 0 and not (0 < limit <= len(self._rbuf)): | |||
| new = self.recv(self.buffsize) | |||
| if not new: break | |||
| i = new.find('\n') | |||
| if i >= 0: i = i + len(self._rbuf) | |||
| self._rbuf = self._rbuf + new | |||
| if i < 0: i = len(self._rbuf) | |||
| else: i = i+1 | |||
| if 0 <= limit < len(self._rbuf): i = limit | |||
| data, self._rbuf = self._rbuf[:i], self._rbuf[i:] | |||
| return data | |||
| def readlines(self, sizehint = 0): | |||
| total = 0 | |||
| list = [] | |||
| while 1: | |||
| line = self.readline() | |||
| if not line: break | |||
| list.append(line) | |||
| total += len(line) | |||
| if sizehint and total >= sizehint: | |||
| break | |||
| return list | |||
| def writelines(self, list): | |||
| self.send(''.join(list)) | |||
| def write(self, data): | |||
| self.send(data) | |||
| def flush(self): | |||
| pass | |||
| class TimeoutError(Exception): | |||
| pass | |||
| @@ -1,99 +0,0 @@ | |||
| """ | |||
| A more or less complete user-defined wrapper around tuple objects. | |||
| Adapted version of the standard library's UserList. | |||
| Taken from Stefan Schwarzer's ftputil library, available at | |||
| <http://www.ndh.net/home/sschwarzer/python/python_software.html>, and used under this license: | |||
| Copyright (C) 1999, Stefan Schwarzer | |||
| All rights reserved. | |||
| Redistribution and use in source and binary forms, with or without | |||
| modification, are permitted provided that the following conditions are | |||
| met: | |||
| - Redistributions of source code must retain the above copyright | |||
| notice, this list of conditions and the following disclaimer. | |||
| - Redistributions in binary form must reproduce the above copyright | |||
| notice, this list of conditions and the following disclaimer in the | |||
| documentation and/or other materials provided with the distribution. | |||
| - Neither the name of the above author nor the names of the | |||
| contributors to the software may be used to endorse or promote | |||
| products derived from this software without specific prior written | |||
| permission. | |||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR | |||
| CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| """ | |||
| # $Id: UserTuple.py,v 1.1 2003/07/21 14:18:54 warnes Exp $ | |||
| #XXX tuple instances (in Python 2.2) contain also: | |||
| # __class__, __delattr__, __getattribute__, __hash__, __new__, | |||
| # __reduce__, __setattr__, __str__ | |||
| # What about these? | |||
| class UserTuple: | |||
| def __init__(self, inittuple=None): | |||
| self.data = () | |||
| if inittuple is not None: | |||
| # XXX should this accept an arbitrary sequence? | |||
| if type(inittuple) == type(self.data): | |||
| self.data = inittuple | |||
| elif isinstance(inittuple, UserTuple): | |||
| # this results in | |||
| # self.data is inittuple.data | |||
| # but that's ok for tuples because they are | |||
| # immutable. (Builtin tuples behave the same.) | |||
| self.data = inittuple.data[:] | |||
| else: | |||
| # the same applies here; (t is tuple(t)) == 1 | |||
| self.data = tuple(inittuple) | |||
| def __repr__(self): return repr(self.data) | |||
| def __lt__(self, other): return self.data < self.__cast(other) | |||
| def __le__(self, other): return self.data <= self.__cast(other) | |||
| def __eq__(self, other): return self.data == self.__cast(other) | |||
| def __ne__(self, other): return self.data != self.__cast(other) | |||
| def __gt__(self, other): return self.data > self.__cast(other) | |||
| def __ge__(self, other): return self.data >= self.__cast(other) | |||
| def __cast(self, other): | |||
| if isinstance(other, UserTuple): return other.data | |||
| else: return other | |||
| def __cmp__(self, other): | |||
| return cmp(self.data, self.__cast(other)) | |||
| def __contains__(self, item): return item in self.data | |||
| def __len__(self): return len(self.data) | |||
| def __getitem__(self, i): return self.data[i] | |||
| def __getslice__(self, i, j): | |||
| i = max(i, 0); j = max(j, 0) | |||
| return self.__class__(self.data[i:j]) | |||
| def __add__(self, other): | |||
| if isinstance(other, UserTuple): | |||
| return self.__class__(self.data + other.data) | |||
| elif isinstance(other, type(self.data)): | |||
| return self.__class__(self.data + other) | |||
| else: | |||
| return self.__class__(self.data + tuple(other)) | |||
| # dir( () ) contains no __radd__ (at least in Python 2.2) | |||
| def __mul__(self, n): | |||
| return self.__class__(self.data*n) | |||
| __rmul__ = __mul__ | |||
| @@ -1,839 +0,0 @@ | |||
| # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved. | |||
| # | |||
| # This software is subject to the provisions of the Zope Public License, | |||
| # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. | |||
| # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | |||
| # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
| # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | |||
| # FOR A PARTICULAR PURPOSE. | |||
| ident = "$Id: Utility.py,v 1.15 2004/04/29 01:40:49 boverhof Exp $" | |||
| import types | |||
| import string, httplib, smtplib, urllib, socket, weakref | |||
| import xml.dom.minidom | |||
| from string import join, strip, split | |||
| from UserDict import UserDict | |||
| from StringIO import StringIO | |||
| from TimeoutSocket import TimeoutSocket, TimeoutError | |||
| from urlparse import urlparse | |||
| from httplib import HTTPConnection, HTTPSConnection | |||
| from exceptions import Exception | |||
| try: | |||
| from xml.dom.ext import SplitQName | |||
| except: | |||
| def SplitQName(qname): | |||
| '''SplitQName(qname) -> (string, string) | |||
| Split Qualified Name into a tuple of len 2, consisting | |||
| of the prefix and the local name. | |||
| (prefix, localName) | |||
| Special Cases: | |||
| xmlns -- (localName, 'xmlns') | |||
| None -- (None, localName) | |||
| ''' | |||
| l = qname.split(':') | |||
| if len(l) == 1: | |||
| l.insert(0, None) | |||
| elif len(l) == 2: | |||
| if l[0] == 'xmlns': | |||
| l.reverse() | |||
| else: | |||
| return | |||
| return tuple(l) | |||
| class RecursionError(Exception): | |||
| """Used to indicate a HTTP redirect recursion.""" | |||
| pass | |||
| class HTTPResponse: | |||
| """Captures the information in an HTTP response message.""" | |||
| def __init__(self, response): | |||
| self.status = response.status | |||
| self.reason = response.reason | |||
| self.headers = response.msg | |||
| self.body = response.read() or None | |||
| response.close() | |||
| class TimeoutHTTP(HTTPConnection): | |||
| """A custom http connection object that supports socket timeout.""" | |||
| def __init__(self, host, port=None, timeout=20): | |||
| HTTPConnection.__init__(self, host, port) | |||
| self.timeout = timeout | |||
| def connect(self): | |||
| self.sock = TimeoutSocket(self.timeout) | |||
| self.sock.connect((self.host, self.port)) | |||
| class TimeoutHTTPS(HTTPSConnection): | |||
| """A custom https object that supports socket timeout. Note that this | |||
| is not really complete. The builtin SSL support in the Python socket | |||
| module requires a real socket (type) to be passed in to be hooked to | |||
| SSL. That means our fake socket won't work and our timeout hacks are | |||
| bypassed for send and recv calls. Since our hack _is_ in place at | |||
| connect() time, it should at least provide some timeout protection.""" | |||
| def __init__(self, host, port=None, timeout=20, **kwargs): | |||
| HTTPSConnection.__init__(self, str(host), port, **kwargs) | |||
| self.timeout = timeout | |||
| def connect(self): | |||
| sock = TimeoutSocket(self.timeout) | |||
| sock.connect((self.host, self.port)) | |||
| realsock = getattr(sock.sock, '_sock', sock.sock) | |||
| ssl = socket.ssl(realsock, self.key_file, self.cert_file) | |||
| self.sock = httplib.FakeSocket(sock, ssl) | |||
| def urlopen(url, timeout=20, redirects=None): | |||
| """A minimal urlopen replacement hack that supports timeouts for http. | |||
| Note that this supports GET only.""" | |||
| scheme, host, path, params, query, frag = urlparse(url) | |||
| if not scheme in ('http', 'https'): | |||
| return urllib.urlopen(url) | |||
| if params: path = '%s;%s' % (path, params) | |||
| if query: path = '%s?%s' % (path, query) | |||
| if frag: path = '%s#%s' % (path, frag) | |||
| if scheme == 'https': | |||
| # If ssl is not compiled into Python, you will not get an exception | |||
| # until a conn.endheaders() call. We need to know sooner, so use | |||
| # getattr. | |||
| if hasattr(socket, 'ssl'): | |||
| conn = TimeoutHTTPS(host, None, timeout) | |||
| else: | |||
| import M2Crypto | |||
| ctx = M2Crypto.SSL.Context() | |||
| ctx.set_session_timeout(timeout) | |||
| conn = M2Crypto.httpslib.HTTPSConnection(host, ssl_context=ctx) | |||
| #conn.set_debuglevel(1) | |||
| else: | |||
| conn = TimeoutHTTP(host, None, timeout) | |||
| conn.putrequest('GET', path) | |||
| conn.putheader('Connection', 'close') | |||
| conn.endheaders() | |||
| response = None | |||
| while 1: | |||
| response = conn.getresponse() | |||
| if response.status != 100: | |||
| break | |||
| conn._HTTPConnection__state = httplib._CS_REQ_SENT | |||
| conn._HTTPConnection__response = None | |||
| status = response.status | |||
| # If we get an HTTP redirect, we will follow it automatically. | |||
| if status >= 300 and status < 400: | |||
| location = response.msg.getheader('location') | |||
| if location is not None: | |||
| response.close() | |||
| if redirects is not None and redirects.has_key(location): | |||
| raise RecursionError( | |||
| 'Circular HTTP redirection detected.' | |||
| ) | |||
| if redirects is None: | |||
| redirects = {} | |||
| redirects[location] = 1 | |||
| return urlopen(location, timeout, redirects) | |||
| raise HTTPResponse(response) | |||
| if not (status >= 200 and status < 300): | |||
| raise HTTPResponse(response) | |||
| body = StringIO(response.read()) | |||
| response.close() | |||
| return body | |||
| class DOM: | |||
| """The DOM singleton defines a number of XML related constants and | |||
| provides a number of utility methods for DOM related tasks. It | |||
| also provides some basic abstractions so that the rest of the | |||
| package need not care about actual DOM implementation in use.""" | |||
| # Namespace stuff related to the SOAP specification. | |||
| NS_SOAP_ENV_1_1 = 'http://schemas.xmlsoap.org/soap/envelope/' | |||
| NS_SOAP_ENC_1_1 = 'http://schemas.xmlsoap.org/soap/encoding/' | |||
| NS_SOAP_ENV_1_2 = 'http://www.w3.org/2001/06/soap-envelope' | |||
| NS_SOAP_ENC_1_2 = 'http://www.w3.org/2001/06/soap-encoding' | |||
| NS_SOAP_ENV_ALL = (NS_SOAP_ENV_1_1, NS_SOAP_ENV_1_2) | |||
| NS_SOAP_ENC_ALL = (NS_SOAP_ENC_1_1, NS_SOAP_ENC_1_2) | |||
| NS_SOAP_ENV = NS_SOAP_ENV_1_1 | |||
| NS_SOAP_ENC = NS_SOAP_ENC_1_1 | |||
| _soap_uri_mapping = { | |||
| NS_SOAP_ENV_1_1 : '1.1', | |||
| NS_SOAP_ENV_1_2 : '1.2', | |||
| } | |||
| SOAP_ACTOR_NEXT_1_1 = 'http://schemas.xmlsoap.org/soap/actor/next' | |||
| SOAP_ACTOR_NEXT_1_2 = 'http://www.w3.org/2001/06/soap-envelope/actor/next' | |||
| SOAP_ACTOR_NEXT_ALL = (SOAP_ACTOR_NEXT_1_1, SOAP_ACTOR_NEXT_1_2) | |||
| def SOAPUriToVersion(self, uri): | |||
| """Return the SOAP version related to an envelope uri.""" | |||
| value = self._soap_uri_mapping.get(uri) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported SOAP envelope uri: %s' % uri | |||
| ) | |||
| def GetSOAPEnvUri(self, version): | |||
| """Return the appropriate SOAP envelope uri for a given | |||
| human-friendly SOAP version string (e.g. '1.1').""" | |||
| attrname = 'NS_SOAP_ENV_%s' % join(split(version, '.'), '_') | |||
| value = getattr(self, attrname, None) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported SOAP version: %s' % version | |||
| ) | |||
| def GetSOAPEncUri(self, version): | |||
| """Return the appropriate SOAP encoding uri for a given | |||
| human-friendly SOAP version string (e.g. '1.1').""" | |||
| attrname = 'NS_SOAP_ENC_%s' % join(split(version, '.'), '_') | |||
| value = getattr(self, attrname, None) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported SOAP version: %s' % version | |||
| ) | |||
| def GetSOAPActorNextUri(self, version): | |||
| """Return the right special next-actor uri for a given | |||
| human-friendly SOAP version string (e.g. '1.1').""" | |||
| attrname = 'SOAP_ACTOR_NEXT_%s' % join(split(version, '.'), '_') | |||
| value = getattr(self, attrname, None) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported SOAP version: %s' % version | |||
| ) | |||
| # Namespace stuff related to XML Schema. | |||
| NS_XSD_99 = 'http://www.w3.org/1999/XMLSchema' | |||
| NS_XSI_99 = 'http://www.w3.org/1999/XMLSchema-instance' | |||
| NS_XSD_00 = 'http://www.w3.org/2000/10/XMLSchema' | |||
| NS_XSI_00 = 'http://www.w3.org/2000/10/XMLSchema-instance' | |||
| NS_XSD_01 = 'http://www.w3.org/2001/XMLSchema' | |||
| NS_XSI_01 = 'http://www.w3.org/2001/XMLSchema-instance' | |||
| NS_XSD_ALL = (NS_XSD_99, NS_XSD_00, NS_XSD_01) | |||
| NS_XSI_ALL = (NS_XSI_99, NS_XSI_00, NS_XSI_01) | |||
| NS_XSD = NS_XSD_01 | |||
| NS_XSI = NS_XSI_01 | |||
| _xsd_uri_mapping = { | |||
| NS_XSD_99 : NS_XSI_99, | |||
| NS_XSD_00 : NS_XSI_00, | |||
| NS_XSD_01 : NS_XSI_01, | |||
| } | |||
| for key, value in _xsd_uri_mapping.items(): | |||
| _xsd_uri_mapping[value] = key | |||
| def InstanceUriForSchemaUri(self, uri): | |||
| """Return the appropriate matching XML Schema instance uri for | |||
| the given XML Schema namespace uri.""" | |||
| return self._xsd_uri_mapping.get(uri) | |||
| def SchemaUriForInstanceUri(self, uri): | |||
| """Return the appropriate matching XML Schema namespace uri for | |||
| the given XML Schema instance namespace uri.""" | |||
| return self._xsd_uri_mapping.get(uri) | |||
| # Namespace stuff related to WSDL. | |||
| NS_WSDL_1_1 = 'http://schemas.xmlsoap.org/wsdl/' | |||
| NS_WSDL_ALL = (NS_WSDL_1_1,) | |||
| NS_WSDL = NS_WSDL_1_1 | |||
| NS_SOAP_BINDING_1_1 = 'http://schemas.xmlsoap.org/wsdl/soap/' | |||
| NS_HTTP_BINDING_1_1 = 'http://schemas.xmlsoap.org/wsdl/http/' | |||
| NS_MIME_BINDING_1_1 = 'http://schemas.xmlsoap.org/wsdl/mime/' | |||
| NS_SOAP_BINDING_ALL = (NS_SOAP_BINDING_1_1,) | |||
| NS_HTTP_BINDING_ALL = (NS_HTTP_BINDING_1_1,) | |||
| NS_MIME_BINDING_ALL = (NS_MIME_BINDING_1_1,) | |||
| NS_SOAP_BINDING = NS_SOAP_BINDING_1_1 | |||
| NS_HTTP_BINDING = NS_HTTP_BINDING_1_1 | |||
| NS_MIME_BINDING = NS_MIME_BINDING_1_1 | |||
| NS_SOAP_HTTP_1_1 = 'http://schemas.xmlsoap.org/soap/http' | |||
| NS_SOAP_HTTP_ALL = (NS_SOAP_HTTP_1_1,) | |||
| NS_SOAP_HTTP = NS_SOAP_HTTP_1_1 | |||
| _wsdl_uri_mapping = { | |||
| NS_WSDL_1_1 : '1.1', | |||
| } | |||
| def WSDLUriToVersion(self, uri): | |||
| """Return the WSDL version related to a WSDL namespace uri.""" | |||
| value = self._wsdl_uri_mapping.get(uri) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported SOAP envelope uri: %s' % uri | |||
| ) | |||
| def GetWSDLUri(self, version): | |||
| attr = 'NS_WSDL_%s' % join(split(version, '.'), '_') | |||
| value = getattr(self, attr, None) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported WSDL version: %s' % version | |||
| ) | |||
| def GetWSDLSoapBindingUri(self, version): | |||
| attr = 'NS_SOAP_BINDING_%s' % join(split(version, '.'), '_') | |||
| value = getattr(self, attr, None) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported WSDL version: %s' % version | |||
| ) | |||
| def GetWSDLHttpBindingUri(self, version): | |||
| attr = 'NS_HTTP_BINDING_%s' % join(split(version, '.'), '_') | |||
| value = getattr(self, attr, None) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported WSDL version: %s' % version | |||
| ) | |||
| def GetWSDLMimeBindingUri(self, version): | |||
| attr = 'NS_MIME_BINDING_%s' % join(split(version, '.'), '_') | |||
| value = getattr(self, attr, None) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported WSDL version: %s' % version | |||
| ) | |||
| def GetWSDLHttpTransportUri(self, version): | |||
| attr = 'NS_SOAP_HTTP_%s' % join(split(version, '.'), '_') | |||
| value = getattr(self, attr, None) | |||
| if value is not None: | |||
| return value | |||
| raise ValueError( | |||
| 'Unsupported WSDL version: %s' % version | |||
| ) | |||
| # Other xml namespace constants. | |||
| NS_XMLNS = 'http://www.w3.org/2000/xmlns/' | |||
| def isElement(self, node, name, nsuri=None): | |||
| """Return true if the given node is an element with the given | |||
| name and optional namespace uri.""" | |||
| if node.nodeType != node.ELEMENT_NODE: | |||
| return 0 | |||
| return node.localName == name and \ | |||
| (nsuri is None or self.nsUriMatch(node.namespaceURI, nsuri)) | |||
| def getElement(self, node, name, nsuri=None, default=join): | |||
| """Return the first child of node with a matching name and | |||
| namespace uri, or the default if one is provided.""" | |||
| nsmatch = self.nsUriMatch | |||
| ELEMENT_NODE = node.ELEMENT_NODE | |||
| for child in node.childNodes: | |||
| if child.nodeType == ELEMENT_NODE: | |||
| if ((child.localName == name or name is None) and | |||
| (nsuri is None or nsmatch(child.namespaceURI, nsuri)) | |||
| ): | |||
| return child | |||
| if default is not join: | |||
| return default | |||
| raise KeyError, name | |||
| def getElementById(self, node, id, default=join): | |||
| """Return the first child of node matching an id reference.""" | |||
| attrget = self.getAttr | |||
| ELEMENT_NODE = node.ELEMENT_NODE | |||
| for child in node.childNodes: | |||
| if child.nodeType == ELEMENT_NODE: | |||
| if attrget(child, 'id') == id: | |||
| return child | |||
| if default is not join: | |||
| return default | |||
| raise KeyError, name | |||
| def getMappingById(self, document, depth=None, element=None, | |||
| mapping=None, level=1): | |||
| """Create an id -> element mapping of those elements within a | |||
| document that define an id attribute. The depth of the search | |||
| may be controlled by using the (1-based) depth argument.""" | |||
| if document is not None: | |||
| element = document.documentElement | |||
| mapping = {} | |||
| attr = element._attrs.get('id', None) | |||
| if attr is not None: | |||
| mapping[attr.value] = element | |||
| if depth is None or depth > level: | |||
| level = level + 1 | |||
| ELEMENT_NODE = element.ELEMENT_NODE | |||
| for child in element.childNodes: | |||
| if child.nodeType == ELEMENT_NODE: | |||
| self.getMappingById(None, depth, child, mapping, level) | |||
| return mapping | |||
| def getElements(self, node, name, nsuri=None): | |||
| """Return a sequence of the child elements of the given node that | |||
| match the given name and optional namespace uri.""" | |||
| nsmatch = self.nsUriMatch | |||
| result = [] | |||
| ELEMENT_NODE = node.ELEMENT_NODE | |||
| for child in node.childNodes: | |||
| if child.nodeType == ELEMENT_NODE: | |||
| if ((child.localName == name or name is None) and ( | |||
| (nsuri is None) or nsmatch(child.namespaceURI, nsuri))): | |||
| result.append(child) | |||
| return result | |||
| def hasAttr(self, node, name, nsuri=None): | |||
| """Return true if element has attribute with the given name and | |||
| optional nsuri. If nsuri is not specified, returns true if an | |||
| attribute exists with the given name with any namespace.""" | |||
| if nsuri is None: | |||
| if node.hasAttribute(name): | |||
| return True | |||
| return False | |||
| return node.hasAttributeNS(nsuri, name) | |||
| def getAttr(self, node, name, nsuri=None, default=join): | |||
| """Return the value of the attribute named 'name' with the | |||
| optional nsuri, or the default if one is specified. If | |||
| nsuri is not specified, an attribute that matches the | |||
| given name will be returned regardless of namespace.""" | |||
| if nsuri is None: | |||
| result = node._attrs.get(name, None) | |||
| if result is None: | |||
| for item in node._attrsNS.keys(): | |||
| if item[1] == name: | |||
| result = node._attrsNS[item] | |||
| break | |||
| else: | |||
| result = node._attrsNS.get((nsuri, name), None) | |||
| if result is not None: | |||
| return result.value | |||
| if default is not join: | |||
| return default | |||
| return '' | |||
| def getAttrs(self, node): | |||
| """Return a Collection of all attributes | |||
| """ | |||
| attrs = {} | |||
| for k,v in node._attrs.items(): | |||
| attrs[k] = v.value | |||
| return attrs | |||
| def getElementText(self, node, preserve_ws=None): | |||
| """Return the text value of an xml element node. Leading and trailing | |||
| whitespace is stripped from the value unless the preserve_ws flag | |||
| is passed with a true value.""" | |||
| result = [] | |||
| for child in node.childNodes: | |||
| nodetype = child.nodeType | |||
| if nodetype == child.TEXT_NODE or \ | |||
| nodetype == child.CDATA_SECTION_NODE: | |||
| result.append(child.nodeValue) | |||
| value = join(result, '') | |||
| if preserve_ws is None: | |||
| value = strip(value) | |||
| return value | |||
| def findNamespaceURI(self, prefix, node): | |||
| """Find a namespace uri given a prefix and a context node.""" | |||
| attrkey = (self.NS_XMLNS, prefix) | |||
| DOCUMENT_NODE = node.DOCUMENT_NODE | |||
| ELEMENT_NODE = node.ELEMENT_NODE | |||
| while 1: | |||
| if node.nodeType != ELEMENT_NODE: | |||
| node = node.parentNode | |||
| continue | |||
| result = node._attrsNS.get(attrkey, None) | |||
| if result is not None: | |||
| return result.value | |||
| if hasattr(node, '__imported__'): | |||
| raise DOMException('Value for prefix %s not found.' % prefix) | |||
| node = node.parentNode | |||
| if node.nodeType == DOCUMENT_NODE: | |||
| raise DOMException('Value for prefix %s not found.' % prefix) | |||
| def findDefaultNS(self, node): | |||
| """Return the current default namespace uri for the given node.""" | |||
| attrkey = (self.NS_XMLNS, 'xmlns') | |||
| DOCUMENT_NODE = node.DOCUMENT_NODE | |||
| ELEMENT_NODE = node.ELEMENT_NODE | |||
| while 1: | |||
| if node.nodeType != ELEMENT_NODE: | |||
| node = node.parentNode | |||
| continue | |||
| result = node._attrsNS.get(attrkey, None) | |||
| if result is not None: | |||
| return result.value | |||
| if hasattr(node, '__imported__'): | |||
| raise DOMException('Cannot determine default namespace.') | |||
| node = node.parentNode | |||
| if node.nodeType == DOCUMENT_NODE: | |||
| raise DOMException('Cannot determine default namespace.') | |||
| def findTargetNS(self, node): | |||
| """Return the defined target namespace uri for the given node.""" | |||
| attrget = self.getAttr | |||
| attrkey = (self.NS_XMLNS, 'xmlns') | |||
| DOCUMENT_NODE = node.DOCUMENT_NODE | |||
| ELEMENT_NODE = node.ELEMENT_NODE | |||
| while 1: | |||
| if node.nodeType != ELEMENT_NODE: | |||
| node = node.parentNode | |||
| continue | |||
| result = attrget(node, 'targetNamespace', default=None) | |||
| if result is not None: | |||
| return result | |||
| node = node.parentNode | |||
| if node.nodeType == DOCUMENT_NODE: | |||
| raise DOMException('Cannot determine target namespace.') | |||
| def getTypeRef(self, element): | |||
| """Return (namespaceURI, name) for a type attribue of the given | |||
| element, or None if the element does not have a type attribute.""" | |||
| typeattr = self.getAttr(element, 'type', default=None) | |||
| if typeattr is None: | |||
| return None | |||
| parts = typeattr.split(':', 1) | |||
| if len(parts) == 2: | |||
| nsuri = self.findNamespaceURI(parts[0], element) | |||
| else: | |||
| nsuri = self.findDefaultNS(element) | |||
| return (nsuri, parts[1]) | |||
| def importNode(self, document, node, deep=0): | |||
| """Implements (well enough for our purposes) DOM node import.""" | |||
| nodetype = node.nodeType | |||
| if nodetype in (node.DOCUMENT_NODE, node.DOCUMENT_TYPE_NODE): | |||
| raise DOMException('Illegal node type for importNode') | |||
| if nodetype == node.ENTITY_REFERENCE_NODE: | |||
| deep = 0 | |||
| clone = node.cloneNode(deep) | |||
| self._setOwnerDoc(document, clone) | |||
| clone.__imported__ = 1 | |||
| return clone | |||
| def _setOwnerDoc(self, document, node): | |||
| node.ownerDocument = document | |||
| for child in node.childNodes: | |||
| self._setOwnerDoc(document, child) | |||
| def nsUriMatch(self, value, wanted, strict=0, tt=type(())): | |||
| """Return a true value if two namespace uri values match.""" | |||
| if value == wanted or (type(wanted) is tt) and value in wanted: | |||
| return 1 | |||
| if not strict: | |||
| wanted = type(wanted) is tt and wanted or (wanted,) | |||
| value = value[-1:] != '/' and value or value[:-1] | |||
| for item in wanted: | |||
| if item == value or item[:-1] == value: | |||
| return 1 | |||
| return 0 | |||
| def createDocument(self, nsuri, qname, doctype=None): | |||
| """Create a new writable DOM document object.""" | |||
| impl = xml.dom.minidom.getDOMImplementation() | |||
| return impl.createDocument(nsuri, qname, doctype) | |||
| def loadDocument(self, data): | |||
| """Load an xml file from a file-like object and return a DOM | |||
| document instance.""" | |||
| return xml.dom.minidom.parse(data) | |||
| def loadFromURL(self, url): | |||
| """Load an xml file from a URL and return a DOM document.""" | |||
| file = urlopen(url) | |||
| try: result = self.loadDocument(file) | |||
| finally: file.close() | |||
| return result | |||
| class DOMException(Exception): | |||
| pass | |||
| DOM = DOM() | |||
| class Collection(UserDict): | |||
| """Helper class for maintaining ordered named collections.""" | |||
| default = lambda self,k: k.name | |||
| def __init__(self, parent, key=None): | |||
| UserDict.__init__(self) | |||
| self.parent = weakref.ref(parent) | |||
| self.list = [] | |||
| self._func = key or self.default | |||
| def __getitem__(self, key): | |||
| if type(key) is type(1): | |||
| return self.list[key] | |||
| return self.data[key] | |||
| def __setitem__(self, key, item): | |||
| item.parent = weakref.ref(self) | |||
| self.list.append(item) | |||
| self.data[key] = item | |||
| def keys(self): | |||
| return map(lambda i: self._func(i), self.list) | |||
| def items(self): | |||
| return map(lambda i: (self._func(i), i), self.list) | |||
| def values(self): | |||
| return self.list | |||
| class CollectionNS(UserDict): | |||
| """Helper class for maintaining ordered named collections.""" | |||
| default = lambda self,k: k.name | |||
| def __init__(self, parent, key=None): | |||
| UserDict.__init__(self) | |||
| self.parent = weakref.ref(parent) | |||
| self.targetNamespace = None | |||
| self.list = [] | |||
| self._func = key or self.default | |||
| def __getitem__(self, key): | |||
| self.targetNamespace = self.parent().targetNamespace | |||
| if type(key) is types.IntType: | |||
| return self.list[key] | |||
| elif self.__isSequence(key): | |||
| nsuri,name = key | |||
| return self.data[nsuri][name] | |||
| return self.data[self.parent().targetNamespace][key] | |||
| def __setitem__(self, key, item): | |||
| item.parent = weakref.ref(self) | |||
| self.list.append(item) | |||
| targetNamespace = getattr(item, 'targetNamespace', self.parent().targetNamespace) | |||
| if not self.data.has_key(targetNamespace): | |||
| self.data[targetNamespace] = {} | |||
| self.data[targetNamespace][key] = item | |||
| def __isSequence(self, key): | |||
| return (type(key) in (types.TupleType,types.ListType) and len(key) == 2) | |||
| def keys(self): | |||
| keys = [] | |||
| for tns in self.data.keys(): | |||
| keys.append(map(lambda i: (tns,self._func(i)), self.data[tns].values())) | |||
| return keys | |||
| def items(self): | |||
| return map(lambda i: (self._func(i), i), self.list) | |||
| def values(self): | |||
| return self.list | |||
| # This is a runtime guerilla patch for pulldom (used by minidom) so | |||
| # that xml namespace declaration attributes are not lost in parsing. | |||
| # We need them to do correct QName linking for XML Schema and WSDL. | |||
| # The patch has been submitted to SF for the next Python version. | |||
| from xml.dom.pulldom import PullDOM, START_ELEMENT | |||
| if 1: | |||
| def startPrefixMapping(self, prefix, uri): | |||
| if not hasattr(self, '_xmlns_attrs'): | |||
| self._xmlns_attrs = [] | |||
| self._xmlns_attrs.append((prefix or 'xmlns', uri)) | |||
| self._ns_contexts.append(self._current_context.copy()) | |||
| self._current_context[uri] = prefix or '' | |||
| PullDOM.startPrefixMapping = startPrefixMapping | |||
| def startElementNS(self, name, tagName , attrs): | |||
| # Retrieve xml namespace declaration attributes. | |||
| xmlns_uri = 'http://www.w3.org/2000/xmlns/' | |||
| xmlns_attrs = getattr(self, '_xmlns_attrs', None) | |||
| if xmlns_attrs is not None: | |||
| for aname, value in xmlns_attrs: | |||
| attrs._attrs[(xmlns_uri, aname)] = value | |||
| self._xmlns_attrs = [] | |||
| uri, localname = name | |||
| if uri: | |||
| # When using namespaces, the reader may or may not | |||
| # provide us with the original name. If not, create | |||
| # *a* valid tagName from the current context. | |||
| if tagName is None: | |||
| prefix = self._current_context[uri] | |||
| if prefix: | |||
| tagName = prefix + ":" + localname | |||
| else: | |||
| tagName = localname | |||
| if self.document: | |||
| node = self.document.createElementNS(uri, tagName) | |||
| else: | |||
| node = self.buildDocument(uri, tagName) | |||
| else: | |||
| # When the tagname is not prefixed, it just appears as | |||
| # localname | |||
| if self.document: | |||
| node = self.document.createElement(localname) | |||
| else: | |||
| node = self.buildDocument(None, localname) | |||
| for aname,value in attrs.items(): | |||
| a_uri, a_localname = aname | |||
| if a_uri == xmlns_uri: | |||
| if a_localname == 'xmlns': | |||
| qname = a_localname | |||
| else: | |||
| qname = 'xmlns:' + a_localname | |||
| attr = self.document.createAttributeNS(a_uri, qname) | |||
| node.setAttributeNodeNS(attr) | |||
| elif a_uri: | |||
| prefix = self._current_context[a_uri] | |||
| if prefix: | |||
| qname = prefix + ":" + a_localname | |||
| else: | |||
| qname = a_localname | |||
| attr = self.document.createAttributeNS(a_uri, qname) | |||
| node.setAttributeNodeNS(attr) | |||
| else: | |||
| attr = self.document.createAttribute(a_localname) | |||
| node.setAttributeNode(attr) | |||
| attr.value = value | |||
| self.lastEvent[1] = [(START_ELEMENT, node), None] | |||
| self.lastEvent = self.lastEvent[1] | |||
| self.push(node) | |||
| PullDOM.startElementNS = startElementNS | |||
| # | |||
| # This is a runtime guerilla patch for minidom so | |||
| # that xmlns prefixed attributes dont raise AttributeErrors | |||
| # during cloning. | |||
| # | |||
| # Namespace declarations can appear in any start-tag, must look for xmlns | |||
| # prefixed attribute names during cloning. | |||
| # | |||
| # key (attr.namespaceURI, tag) | |||
| # ('http://www.w3.org/2000/xmlns/', u'xsd') <xml.dom.minidom.Attr instance at 0x82227c4> | |||
| # ('http://www.w3.org/2000/xmlns/', 'xmlns') <xml.dom.minidom.Attr instance at 0x8414b3c> | |||
| # | |||
| # xml.dom.minidom.Attr.nodeName = xmlns:xsd | |||
| # xml.dom.minidom.Attr.value = = http://www.w3.org/2001/XMLSchema | |||
| if 1: | |||
| def _clone_node(node, deep, newOwnerDocument): | |||
| """ | |||
| Clone a node and give it the new owner document. | |||
| Called by Node.cloneNode and Document.importNode | |||
| """ | |||
| if node.ownerDocument.isSameNode(newOwnerDocument): | |||
| operation = xml.dom.UserDataHandler.NODE_CLONED | |||
| else: | |||
| operation = xml.dom.UserDataHandler.NODE_IMPORTED | |||
| if node.nodeType == xml.dom.minidom.Node.ELEMENT_NODE: | |||
| clone = newOwnerDocument.createElementNS(node.namespaceURI, | |||
| node.nodeName) | |||
| for attr in node.attributes.values(): | |||
| clone.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value) | |||
| prefix, tag = xml.dom.minidom._nssplit(attr.nodeName) | |||
| if prefix == 'xmlns': | |||
| a = clone.getAttributeNodeNS(attr.namespaceURI, tag) | |||
| elif prefix: | |||
| a = clone.getAttributeNodeNS(attr.namespaceURI, tag) | |||
| else: | |||
| a = clone.getAttributeNodeNS(attr.namespaceURI, attr.nodeName) | |||
| a.specified = attr.specified | |||
| if deep: | |||
| for child in node.childNodes: | |||
| c = xml.dom.minidom._clone_node(child, deep, newOwnerDocument) | |||
| clone.appendChild(c) | |||
| elif node.nodeType == xml.dom.minidom.Node.DOCUMENT_FRAGMENT_NODE: | |||
| clone = newOwnerDocument.createDocumentFragment() | |||
| if deep: | |||
| for child in node.childNodes: | |||
| c = xml.dom.minidom._clone_node(child, deep, newOwnerDocument) | |||
| clone.appendChild(c) | |||
| elif node.nodeType == xml.dom.minidom.Node.TEXT_NODE: | |||
| clone = newOwnerDocument.createTextNode(node.data) | |||
| elif node.nodeType == xml.dom.minidom.Node.CDATA_SECTION_NODE: | |||
| clone = newOwnerDocument.createCDATASection(node.data) | |||
| elif node.nodeType == xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE: | |||
| clone = newOwnerDocument.createProcessingInstruction(node.target, | |||
| node.data) | |||
| elif node.nodeType == xml.dom.minidom.Node.COMMENT_NODE: | |||
| clone = newOwnerDocument.createComment(node.data) | |||
| elif node.nodeType == xml.dom.minidom.Node.ATTRIBUTE_NODE: | |||
| clone = newOwnerDocument.createAttributeNS(node.namespaceURI, | |||
| node.nodeName) | |||
| clone.specified = True | |||
| clone.value = node.value | |||
| elif node.nodeType == xml.dom.minidom.Node.DOCUMENT_TYPE_NODE: | |||
| assert node.ownerDocument is not newOwnerDocument | |||
| operation = xml.dom.UserDataHandler.NODE_IMPORTED | |||
| clone = newOwnerDocument.implementation.createDocumentType( | |||
| node.name, node.publicId, node.systemId) | |||
| clone.ownerDocument = newOwnerDocument | |||
| if deep: | |||
| clone.entities._seq = [] | |||
| clone.notations._seq = [] | |||
| for n in node.notations._seq: | |||
| notation = xml.dom.minidom.Notation(n.nodeName, n.publicId, n.systemId) | |||
| notation.ownerDocument = newOwnerDocument | |||
| clone.notations._seq.append(notation) | |||
| if hasattr(n, '_call_user_data_handler'): | |||
| n._call_user_data_handler(operation, n, notation) | |||
| for e in node.entities._seq: | |||
| entity = xml.dom.minidom.Entity(e.nodeName, e.publicId, e.systemId, | |||
| e.notationName) | |||
| entity.actualEncoding = e.actualEncoding | |||
| entity.encoding = e.encoding | |||
| entity.version = e.version | |||
| entity.ownerDocument = newOwnerDocument | |||
| clone.entities._seq.append(entity) | |||
| if hasattr(e, '_call_user_data_handler'): | |||
| e._call_user_data_handler(operation, n, entity) | |||
| else: | |||
| # Note the cloning of Document and DocumentType nodes is | |||
| # implemenetation specific. minidom handles those cases | |||
| # directly in the cloneNode() methods. | |||
| raise xml.dom.NotSupportedErr("Cannot clone node %s" % repr(node)) | |||
| # Check for _call_user_data_handler() since this could conceivably | |||
| # used with other DOM implementations (one of the FourThought | |||
| # DOMs, perhaps?). | |||
| if hasattr(node, '_call_user_data_handler'): | |||
| node._call_user_data_handler(operation, node, clone) | |||
| return clone | |||
| xml.dom.minidom._clone_node = _clone_node | |||
| @@ -1,88 +0,0 @@ | |||
| """Translate strings to and from SOAP 1.2 XML name encoding | |||
| Implements rules for mapping application defined name to XML names | |||
| specified by the w3 SOAP working group for SOAP version 1.2 in | |||
| Appendix A of "SOAP Version 1.2 Part 2: Adjuncts", W3C Working Draft | |||
| 17, December 2001, <http://www.w3.org/TR/soap12-part2/#namemap> | |||
| Also see <http://www.w3.org/2000/xp/Group/xmlp-issues>. | |||
| Author: Gregory R. Warnes <gregory_r_warnes@groton.pfizer.com> | |||
| Date:: 2002-04-25 | |||
| Version 0.9.0 | |||
| """ | |||
| ident = "$Id: XMLname.py,v 1.2 2003/05/20 21:10:14 warnes Exp $" | |||
| from re import * | |||
| def _NCNameChar(x): | |||
| return x.isalpha() or x.isdigit() or x=="." or x=='-' or x=="_" | |||
| def _NCNameStartChar(x): | |||
| return x.isalpha() or x=="_" | |||
| def _toUnicodeHex(x): | |||
| hexval = hex(ord(x[0]))[2:] | |||
| hexlen = len(hexval) | |||
| # Make hexval have either 4 or 8 digits by prepending 0's | |||
| if (hexlen==1): hexval = "000" + hexval | |||
| elif (hexlen==2): hexval = "00" + hexval | |||
| elif (hexlen==3): hexval = "0" + hexval | |||
| elif (hexlen==4): hexval = "" + hexval | |||
| elif (hexlen==5): hexval = "000" + hexval | |||
| elif (hexlen==6): hexval = "00" + hexval | |||
| elif (hexlen==7): hexval = "0" + hexval | |||
| elif (hexlen==8): hexval = "" + hexval | |||
| else: raise Exception, "Illegal Value returned from hex(ord(x))" | |||
| return "_x"+ hexval + "_" | |||
| def _fromUnicodeHex(x): | |||
| return eval( r'u"\u'+x[2:-1]+'"' ) | |||
| def toXMLname(string): | |||
| """Convert string to a XML name.""" | |||
| if string.find(':') != -1 : | |||
| (prefix, localname) = string.split(':',1) | |||
| else: | |||
| prefix = None | |||
| localname = string | |||
| T = unicode(localname) | |||
| N = len(localname) | |||
| X = []; | |||
| for i in range(N) : | |||
| if i< N-1 and T[i]==u'_' and T[i+1]==u'x': | |||
| X.append(u'_x005F_') | |||
| elif i==0 and N >= 3 and \ | |||
| ( T[0]==u'x' or T[0]==u'X' ) and \ | |||
| ( T[1]==u'm' or T[1]==u'M' ) and \ | |||
| ( T[2]==u'l' or T[2]==u'L' ): | |||
| X.append(u'_xFFFF_' + T[0]) | |||
| elif (not _NCNameChar(T[i])) or (i==0 and not _NCNameStartChar(T[i])): | |||
| X.append(_toUnicodeHex(T[i])) | |||
| else: | |||
| X.append(T[i]) | |||
| return u''.join(X) | |||
| def fromXMLname(string): | |||
| """Convert XML name to unicode string.""" | |||
| retval = sub(r'_xFFFF_','', string ) | |||
| def fun( matchobj ): | |||
| return _fromUnicodeHex( matchobj.group(0) ) | |||
| retval = sub(r'_x[0-9A-Za-z]+_', fun, retval ) | |||
| return retval | |||
| @@ -1,36 +0,0 @@ | |||
| #! /usr/bin/env python | |||
| """WSDL parsing services package for Web Services for Python.""" | |||
| ident = "$Id: __init__.py,v 1.8 2004/09/09 23:32:09 boverhof Exp $" | |||
| import WSDLTools | |||
| import XMLname | |||
| from logging import getLogger as _getLogger | |||
| import logging.config as _config | |||
| LOGGING = 'logging.txt' | |||
| DEBUG = True | |||
| # | |||
| # If LOGGING configuration file is not found, turn off logging | |||
| # and use _noLogger class because logging module's performance | |||
| # is terrible. | |||
| # | |||
| try: | |||
| _config.fileConfig(LOGGING) | |||
| except: | |||
| DEBUG = False | |||
| class Base: | |||
| def __init__(self, module=__name__): | |||
| self.logger = _noLogger() | |||
| if DEBUG is True: | |||
| self.logger = _getLogger('%s-%s(%x)' %(module, self.__class__, id(self))) | |||
| class _noLogger: | |||
| def __init__(self, *args): pass | |||
| def warning(self, *args): pass | |||
| def debug(self, *args): pass | |||
| def error(self, *args): pass | |||
| @@ -1,5 +0,0 @@ | |||
| #! /usr/bin/env python | |||
| """wstools.WSDLTools.WSDLReader tests directory.""" | |||
| import utils | |||
| @@ -1,20 +0,0 @@ | |||
| ############################################################################ | |||
| # Joshua R. Boverhof, David W. Robertson, LBNL | |||
| # See LBNLCopyright for copyright notice! | |||
| ########################################################################### | |||
| import unittest | |||
| import test_wsdl | |||
| import utils | |||
| def makeTestSuite(): | |||
| suite = unittest.TestSuite() | |||
| suite.addTest(test_wsdl.makeTestSuite("services_by_file")) | |||
| return suite | |||
| def main(): | |||
| loader = utils.MatchTestLoader(True, None, "makeTestSuite") | |||
| unittest.main(defaultTest="makeTestSuite", testLoader=loader) | |||
| if __name__ == "__main__" : main() | |||
| @@ -1,160 +0,0 @@ | |||
| #!/usr/bin/env python | |||
| ############################################################################ | |||
| # Joshua R. Boverhof, David W. Robertson, LBNL | |||
| # See LBNLCopyright for copyright notice! | |||
| ########################################################################### | |||
| import sys, unittest | |||
| import ConfigParser | |||
| from ZSI.wstools.Utility import DOM | |||
| from ZSI.wstools.WSDLTools import WSDLReader | |||
| from ZSI.wstools.TimeoutSocket import TimeoutError | |||
| class WSDLToolsTestCase(unittest.TestCase): | |||
| def __init__(self, methodName='runTest'): | |||
| unittest.TestCase.__init__(self, methodName) | |||
| def setUp(self): | |||
| self.path = nameGenerator.next() | |||
| print self.path | |||
| sys.stdout.flush() | |||
| def __str__(self): | |||
| teststr = unittest.TestCase.__str__(self) | |||
| if hasattr(self, "path"): | |||
| return "%s: %s" % (teststr, self.path ) | |||
| else: | |||
| return "%s" % (teststr) | |||
| def checkWSDLCollection(self, tag_name, component, key='name'): | |||
| if self.wsdl is None: | |||
| return | |||
| definition = self.wsdl.document.documentElement | |||
| version = DOM.WSDLUriToVersion(definition.namespaceURI) | |||
| nspname = DOM.GetWSDLUri(version) | |||
| for node in DOM.getElements(definition, tag_name, nspname): | |||
| name = DOM.getAttr(node, key) | |||
| comp = component[name] | |||
| self.failUnlessEqual(eval('comp.%s' %key), name) | |||
| def checkXSDCollection(self, tag_name, component, node, key='name'): | |||
| for cnode in DOM.getElements(node, tag_name): | |||
| name = DOM.getAttr(cnode, key) | |||
| component[name] | |||
| def test_all(self): | |||
| try: | |||
| if self.path[:7] == 'http://': | |||
| self.wsdl = WSDLReader().loadFromURL(self.path) | |||
| else: | |||
| self.wsdl = WSDLReader().loadFromFile(self.path) | |||
| except TimeoutError: | |||
| print "connection timed out" | |||
| sys.stdout.flush() | |||
| return | |||
| except: | |||
| self.path = self.path + ": load failed, unable to start" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('service', self.wsdl.services) | |||
| except: | |||
| self.path = self.path + ": wsdl.services" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('message', self.wsdl.messages) | |||
| except: | |||
| self.path = self.path + ": wsdl.messages" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('portType', self.wsdl.portTypes) | |||
| except: | |||
| self.path = self.path + ": wsdl.portTypes" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('binding', self.wsdl.bindings) | |||
| except: | |||
| self.path = self.path + ": wsdl.bindings" | |||
| raise | |||
| try: | |||
| self.checkWSDLCollection('import', self.wsdl.imports, key='namespace') | |||
| except: | |||
| self.path = self.path + ": wsdl.imports" | |||
| raise | |||
| try: | |||
| for key in self.wsdl.types.keys(): | |||
| schema = self.wsdl.types[key] | |||
| self.failUnlessEqual(key, schema.getTargetNamespace()) | |||
| definition = self.wsdl.document.documentElement | |||
| version = DOM.WSDLUriToVersion(definition.namespaceURI) | |||
| nspname = DOM.GetWSDLUri(version) | |||
| for node in DOM.getElements(definition, 'types', nspname): | |||
| for snode in DOM.getElements(node, 'schema'): | |||
| tns = DOM.findTargetNS(snode) | |||
| schema = self.wsdl.types[tns] | |||
| self.schemaAttributesDeclarations(schema, snode) | |||
| self.schemaAttributeGroupDeclarations(schema, snode) | |||
| self.schemaElementDeclarations(schema, snode) | |||
| self.schemaTypeDefinitions(schema, snode) | |||
| except: | |||
| self.path = self.path + ": wsdl.types" | |||
| raise | |||
| if self.wsdl.extensions: | |||
| print 'No check for WSDLTools(%s) Extensions:' %(self.wsdl.name) | |||
| for ext in self.wsdl.extensions: print '\t', ext | |||
| def schemaAttributesDeclarations(self, schema, node): | |||
| self.checkXSDCollection('attribute', schema.attr_decl, node) | |||
| def schemaAttributeGroupDeclarations(self, schema, node): | |||
| self.checkXSDCollection('group', schema.attr_groups, node) | |||
| def schemaElementDeclarations(self, schema, node): | |||
| self.checkXSDCollection('element', schema.elements, node) | |||
| def schemaTypeDefinitions(self, schema, node): | |||
| self.checkXSDCollection('complexType', schema.types, node) | |||
| self.checkXSDCollection('simpleType', schema.types, node) | |||
| def setUpOptions(section): | |||
| cp = ConfigParser.ConfigParser() | |||
| cp.read('config.txt') | |||
| if not cp.sections(): | |||
| print 'fatal error: configuration file config.txt not present' | |||
| sys.exit(0) | |||
| if not cp.has_section(section): | |||
| print '%s section not present in configuration file, exiting' % section | |||
| sys.exit(0) | |||
| return cp, len(cp.options(section)) | |||
| def getOption(cp, section): | |||
| for name, value in cp.items(section): | |||
| yield value | |||
| def makeTestSuite(section='services_by_file'): | |||
| global nameGenerator | |||
| cp, numTests = setUpOptions(section) | |||
| nameGenerator = getOption(cp, section) | |||
| suite = unittest.TestSuite() | |||
| for i in range(0, numTests): | |||
| suite.addTest(unittest.makeSuite(WSDLToolsTestCase, 'test_')) | |||
| return suite | |||
| def main(): | |||
| unittest.main(defaultTest="makeTestSuite") | |||
| if __name__ == "__main__" : main() | |||
| @@ -1,37 +0,0 @@ | |||
| #!/usr/bin/env python | |||
| ############################################################################ | |||
| # Joshua R. Boverhof, David W. Robertson, LBNL | |||
| # See LBNLCopyright for copyright notice! | |||
| ########################################################################### | |||
| import unittest, tarfile, os, ConfigParser | |||
| import test_wsdl | |||
| SECTION='files' | |||
| CONFIG_FILE = 'config.txt' | |||
| def extractFiles(section, option): | |||
| config = ConfigParser.ConfigParser() | |||
| config.read(CONFIG_FILE) | |||
| archives = config.get(section, option) | |||
| archives = eval(archives) | |||
| for file in archives: | |||
| tar = tarfile.open(file) | |||
| if not os.access(tar.membernames[0], os.R_OK): | |||
| for i in tar.getnames(): | |||
| tar.extract(i) | |||
| def makeTestSuite(): | |||
| suite = unittest.TestSuite() | |||
| suite.addTest(test_wsdl.makeTestSuite("services_by_file")) | |||
| return suite | |||
| def main(): | |||
| extractFiles(SECTION, 'archives') | |||
| unittest.main(defaultTest="makeTestSuite") | |||
| if __name__ == "__main__" : main() | |||
| @@ -1,20 +0,0 @@ | |||
| #!/usr/bin/env python | |||
| ############################################################################ | |||
| # Joshua R. Boverhof, David W. Robertson, LBNL | |||
| # See LBNLCopyright for copyright notice! | |||
| ########################################################################### | |||
| import unittest | |||
| import test_wsdl | |||
| def makeTestSuite(): | |||
| suite = unittest.TestSuite() | |||
| suite.addTest(test_wsdl.makeTestSuite("services_by_http")) | |||
| return suite | |||
| def main(): | |||
| unittest.main(defaultTest="makeTestSuite") | |||
| if __name__ == "__main__" : main() | |||