diff --git a/SOAPpy/Config.py b/SOAPpy/Config.py deleted file mode 100644 index 3ec4dfe..0000000 --- a/SOAPpy/Config.py +++ /dev/null @@ -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() diff --git a/SOAPpy/Errors.py b/SOAPpy/Errors.py deleted file mode 100644 index 88e2984..0000000 --- a/SOAPpy/Errors.py +++ /dev/null @@ -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 "" % 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 "" % (self.code, self.msg) - __repr__ = __str__ - def __call___(self): - return (self.code, self.msg, ) - -class UnderflowError(exceptions.ArithmeticError): - pass - diff --git a/SOAPpy/NS.py b/SOAPpy/NS.py deleted file mode 100644 index 658a20e..0000000 --- a/SOAPpy/NS.py +++ /dev/null @@ -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" - - - diff --git a/SOAPpy/Parser.py b/SOAPpy/Parser.py deleted file mode 100644 index aee364d..0000000 --- a/SOAPpy/Parser.py +++ /dev/null @@ -1,1024 +0,0 @@ -# SOAPpy modules -from Config import Config -from Types import * -from NS import NS -from Utilities import * - -import string -import fpconst -import xml.sax -from wstools.XMLname import fromXMLname - -try: from M2Crypto import SSL -except: pass - -ident = '$Id: Parser.py,v 1.14 2004/01/31 04:20:05 warnes Exp $' -from version import __version__ - - -################################################################################ -# SOAP Parser -################################################################################ -class RefHolder: - def __init__(self, name, frame): - self.name = name - self.parent = frame - self.pos = len(frame) - self.subpos = frame.namecounts.get(name, 0) - - def __repr__(self): - return "<%s %s at %d>" % (self.__class__, self.name, id(self)) - - def __str__(self): - return "<%s %s at %d>" % (self.__class__, self.name, id(self)) - -class SOAPParser(xml.sax.handler.ContentHandler): - class Frame: - def __init__(self, name, kind = None, attrs = {}, rules = {}): - self.name = name - self.kind = kind - self.attrs = attrs - self.rules = rules - - self.contents = [] - self.names = [] - self.namecounts = {} - self.subattrs = [] - - def append(self, name, data, attrs): - self.names.append(name) - self.contents.append(data) - self.subattrs.append(attrs) - - if self.namecounts.has_key(name): - self.namecounts[name] += 1 - else: - self.namecounts[name] = 1 - - def _placeItem(self, name, value, pos, subpos = 0, attrs = None): - self.contents[pos] = value - - if attrs: - self.attrs.update(attrs) - - def __len__(self): - return len(self.contents) - - def __repr__(self): - return "<%s %s at %d>" % (self.__class__, self.name, id(self)) - - def __init__(self, rules = None): - xml.sax.handler.ContentHandler.__init__(self) - self.body = None - self.header = None - self.attrs = {} - self._data = None - self._next = "E" # Keeping state for message validity - self._stack = [self.Frame('SOAP')] - - # Make two dictionaries to store the prefix <-> URI mappings, and - # initialize them with the default - self._prem = {NS.XML_T: NS.XML} - self._prem_r = {NS.XML: NS.XML_T} - self._ids = {} - self._refs = {} - self._rules = rules - - def startElementNS(self, name, qname, attrs): - # Workaround two sax bugs - if name[0] == None and name[1][0] == ' ': - name = (None, name[1][1:]) - else: - name = tuple(name) - - # First some checking of the layout of the message - - if self._next == "E": - if name[1] != 'Envelope': - raise Error, "expected `SOAP-ENV:Envelope', gto `%s:%s'" % \ - (self._prem_r[name[0]], name[1]) - if name[0] != NS.ENV: - raise faultType, ("%s:VersionMismatch" % NS.ENV_T, - "Don't understand version `%s' Envelope" % name[0]) - else: - self._next = "HorB" - elif self._next == "HorB": - if name[0] == NS.ENV and name[1] in ("Header", "Body"): - self._next = None - else: - raise Error, \ - "expected `SOAP-ENV:Header' or `SOAP-ENV:Body', " \ - "got `%s'" % self._prem_r[name[0]] + ':' + name[1] - elif self._next == "B": - if name == (NS.ENV, "Body"): - self._next = None - else: - raise Error, "expected `SOAP-ENV:Body', got `%s'" % \ - self._prem_r[name[0]] + ':' + name[1] - elif self._next == "": - raise Error, "expected nothing, got `%s'" % \ - self._prem_r[name[0]] + ':' + name[1] - - if len(self._stack) == 2: - rules = self._rules - else: - try: - rules = self._stack[-1].rules[name[1]] - except: - rules = None - - if type(rules) not in (NoneType, DictType): - kind = rules - else: - kind = attrs.get((NS.ENC, 'arrayType')) - - if kind != None: - del attrs._attrs[(NS.ENC, 'arrayType')] - - i = kind.find(':') - if i >= 0: - kind = (self._prem[kind[:i]], kind[i + 1:]) - else: - kind = None - - self.pushFrame(self.Frame(name[1], kind, attrs._attrs, rules)) - - self._data = [] # Start accumulating - - def pushFrame(self, frame): - self._stack.append(frame) - - def popFrame(self): - return self._stack.pop() - - def endElementNS(self, name, qname): - # Workaround two sax bugs - if name[0] == None and name[1][0] == ' ': - ns, name = None, name[1][1:] - else: - ns, name = tuple(name) - - name = fromXMLname(name) # convert to SOAP 1.2 XML name encoding - - if self._next == "E": - raise Error, "didn't get SOAP-ENV:Envelope" - if self._next in ("HorB", "B"): - raise Error, "didn't get SOAP-ENV:Body" - - cur = self.popFrame() - attrs = cur.attrs - - idval = None - - if attrs.has_key((None, 'id')): - idval = attrs[(None, 'id')] - - if self._ids.has_key(idval): - raise Error, "duplicate id `%s'" % idval - - del attrs[(None, 'id')] - - root = 1 - - if len(self._stack) == 3: - if attrs.has_key((NS.ENC, 'root')): - root = int(attrs[(NS.ENC, 'root')]) - - # Do some preliminary checks. First, if root="0" is present, - # the element must have an id. Next, if root="n" is present, - # n something other than 0 or 1, raise an exception. - - if root == 0: - if idval == None: - raise Error, "non-root element must have an id" - elif root != 1: - raise Error, "SOAP-ENC:root must be `0' or `1'" - - del attrs[(NS.ENC, 'root')] - - while 1: - href = attrs.get((None, 'href')) - if href: - if href[0] != '#': - raise Error, "Non-local hrefs are not yet suppported." - if self._data != None and string.join(self._data, "").strip() != '': - raise Error, "hrefs can't have data" - - href = href[1:] - - if self._ids.has_key(href): - data = self._ids[href] - else: - data = RefHolder(name, self._stack[-1]) - - if self._refs.has_key(href): - self._refs[href].append(data) - else: - self._refs[href] = [data] - - del attrs[(None, 'href')] - - break - - kind = None - - if attrs: - for i in NS.XSI_L: - if attrs.has_key((i, 'type')): - kind = attrs[(i, 'type')] - del attrs[(i, 'type')] - - if kind != None: - i = kind.find(':') - if i >= 0: - kind = (self._prem[kind[:i]], kind[i + 1:]) - else: -# XXX What to do here? (None, kind) is just going to fail in convertType - kind = (None, kind) - - null = 0 - - if attrs: - for i in (NS.XSI, NS.XSI2): - if attrs.has_key((i, 'null')): - null = attrs[(i, 'null')] - del attrs[(i, 'null')] - - if attrs.has_key((NS.XSI3, 'nil')): - null = attrs[(NS.XSI3, 'nil')] - del attrs[(NS.XSI3, 'nil')] - - - ## Check for nil - - # check for nil='true' - if type(null) in (StringType, UnicodeType): - if null.lower() == 'true': - null = 1 - - # check for nil=1, but watch out for string values - try: - null = int(null) - except ValueError, e: - if not e[0].startswith("invalid literal for int()"): - raise e - null = 0 - - if null: - if len(cur) or \ - (self._data != None and string.join(self._data, "").strip() != ''): - raise Error, "nils can't have data" - - data = None - - break - - if len(self._stack) == 2: - if (ns, name) == (NS.ENV, "Header"): - self.header = data = headerType(attrs = attrs) - self._next = "B" - break - elif (ns, name) == (NS.ENV, "Body"): - self.body = data = bodyType(attrs = attrs) - self._next = "" - break - elif len(self._stack) == 3 and self._next == None: - if (ns, name) == (NS.ENV, "Fault"): - data = faultType() - self._next = "" - break - - if cur.rules != None: - rule = cur.rules - - if type(rule) in (StringType, UnicodeType): -# XXX Need a namespace here - rule = (None, rule) - elif type(rule) == ListType: - rule = tuple(rule) - -# XXX What if rule != kind? - if callable(rule): - data = rule(string.join(self._data, "")) - elif type(rule) == DictType: - data = structType(name = (ns, name), attrs = attrs) - else: - data = self.convertType(string.join(self._data, ""), - rule, attrs) - - break - - if (kind == None and cur.kind != None) or \ - (kind == (NS.ENC, 'Array')): - kind = cur.kind - - if kind == None: - kind = 'ur-type[%d]' % len(cur) - else: - kind = kind[1] - - if len(cur.namecounts) == 1: - elemsname = cur.names[0] - else: - elemsname = None - - data = self.startArray((ns, name), kind, attrs, elemsname) - - break - - if len(self._stack) == 3 and kind == None and \ - len(cur) == 0 and \ - (self._data == None or string.join(self._data, "").strip() == ''): - data = structType(name = (ns, name), attrs = attrs) - break - - if len(cur) == 0 and ns != NS.URN: - # Nothing's been added to the current frame so it must be a - # simple type. - - if kind == None: - # If the current item's container is an array, it will - # have a kind. If so, get the bit before the first [, - # which is the type of the array, therefore the type of - # the current item. - - kind = self._stack[-1].kind - - if kind != None: - i = kind[1].find('[') - if i >= 0: - kind = (kind[0], kind[1][:i]) - elif ns != None: - kind = (ns, name) - - if kind != None: - try: - data = self.convertType(string.join(self._data, ""), - kind, attrs) - except UnknownTypeError: - data = None - else: - data = None - - if data == None: - if self._data == None: - data = '' - else: - data = string.join(self._data, "") - - if len(attrs) == 0: - try: data = str(data) - except: pass - - break - - data = structType(name = (ns, name), attrs = attrs) - - break - - if isinstance(data, compoundType): - for i in range(len(cur)): - v = cur.contents[i] - data._addItem(cur.names[i], v, cur.subattrs[i]) - - if isinstance(v, RefHolder): - v.parent = data - - if root: - self._stack[-1].append(name, data, attrs) - - if idval != None: - self._ids[idval] = data - - if self._refs.has_key(idval): - for i in self._refs[idval]: - i.parent._placeItem(i.name, data, i.pos, i.subpos, attrs) - - del self._refs[idval] - - self.attrs[id(data)] = attrs - - if isinstance(data, anyType): - data._setAttrs(attrs) - - self._data = None # Stop accumulating - - def endDocument(self): - if len(self._refs) == 1: - raise Error, \ - "unresolved reference " + self._refs.keys()[0] - elif len(self._refs) > 1: - raise Error, \ - "unresolved references " + ', '.join(self._refs.keys()) - - def startPrefixMapping(self, prefix, uri): - self._prem[prefix] = uri - self._prem_r[uri] = prefix - - def endPrefixMapping(self, prefix): - try: - del self._prem_r[self._prem[prefix]] - del self._prem[prefix] - except: - pass - - def characters(self, c): - if self._data != None: - self._data.append(c) - - arrayre = '^(?:(?P[^:]*):)?' \ - '(?P[^[]+)' \ - '(?:\[(?P,*)\])?' \ - '(?:\[(?P\d+(?:,\d+)*)?\])$' - - def startArray(self, name, kind, attrs, elemsname): - if type(self.arrayre) == StringType: - self.arrayre = re.compile (self.arrayre) - - offset = attrs.get((NS.ENC, "offset")) - - if offset != None: - del attrs[(NS.ENC, "offset")] - - try: - if offset[0] == '[' and offset[-1] == ']': - offset = int(offset[1:-1]) - if offset < 0: - raise Exception - else: - raise Exception - except: - raise AttributeError, "invalid Array offset" - else: - offset = 0 - - try: - m = self.arrayre.search(kind) - - if m == None: - raise Exception - - t = m.group('type') - - if t == 'ur-type': - return arrayType(None, name, attrs, offset, m.group('rank'), - m.group('asize'), elemsname) - elif m.group('ns') != None: - return typedArrayType(None, name, - (self._prem[m.group('ns')], t), attrs, offset, - m.group('rank'), m.group('asize'), elemsname) - else: - return typedArrayType(None, name, (None, t), attrs, offset, - m.group('rank'), m.group('asize'), elemsname) - except: - raise AttributeError, "invalid Array type `%s'" % kind - - # Conversion - - class DATETIMECONSTS: - SIGNre = '(?P-?)' - CENTURYre = '(?P\d{2,})' - YEARre = '(?P\d{2})' - MONTHre = '(?P\d{2})' - DAYre = '(?P\d{2})' - HOURre = '(?P\d{2})' - MINUTEre = '(?P\d{2})' - SECONDre = '(?P\d{2}(?:\.\d*)?)' - TIMEZONEre = '(?PZ)|(?P[-+])(?P\d{2}):' \ - '(?P\d{2})' - BOSre = '^\s*' - EOSre = '\s*$' - - __allres = {'sign': SIGNre, 'century': CENTURYre, 'year': YEARre, - 'month': MONTHre, 'day': DAYre, 'hour': HOURre, - 'minute': MINUTEre, 'second': SECONDre, 'timezone': TIMEZONEre, - 'b': BOSre, 'e': EOSre} - - dateTime = '%(b)s%(sign)s%(century)s%(year)s-%(month)s-%(day)sT' \ - '%(hour)s:%(minute)s:%(second)s(%(timezone)s)?%(e)s' % __allres - timeInstant = dateTime - timePeriod = dateTime - time = '%(b)s%(hour)s:%(minute)s:%(second)s(%(timezone)s)?%(e)s' % \ - __allres - date = '%(b)s%(sign)s%(century)s%(year)s-%(month)s-%(day)s' \ - '(%(timezone)s)?%(e)s' % __allres - century = '%(b)s%(sign)s%(century)s(%(timezone)s)?%(e)s' % __allres - gYearMonth = '%(b)s%(sign)s%(century)s%(year)s-%(month)s' \ - '(%(timezone)s)?%(e)s' % __allres - gYear = '%(b)s%(sign)s%(century)s%(year)s(%(timezone)s)?%(e)s' % \ - __allres - year = gYear - gMonthDay = '%(b)s--%(month)s-%(day)s(%(timezone)s)?%(e)s' % __allres - recurringDate = gMonthDay - gDay = '%(b)s---%(day)s(%(timezone)s)?%(e)s' % __allres - recurringDay = gDay - gMonth = '%(b)s--%(month)s--(%(timezone)s)?%(e)s' % __allres - month = gMonth - - recurringInstant = '%(b)s%(sign)s(%(century)s|-)(%(year)s|-)-' \ - '(%(month)s|-)-(%(day)s|-)T' \ - '(%(hour)s|-):(%(minute)s|-):(%(second)s|-)' \ - '(%(timezone)s)?%(e)s' % __allres - - duration = '%(b)s%(sign)sP' \ - '((?P\d+)Y)?' \ - '((?P\d+)M)?' \ - '((?P\d+)D)?' \ - '((?PT)' \ - '((?P\d+)H)?' \ - '((?P\d+)M)?' \ - '((?P\d*(?:\.\d*)?)S)?)?%(e)s' % \ - __allres - - timeDuration = duration - - # The extra 31 on the front is: - # - so the tuple is 1-based - # - so months[month-1] is December's days if month is 1 - - months = (31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) - - def convertDateTime(self, value, kind): - def getZoneOffset(d): - zoffs = 0 - - try: - if d['zulu'] == None: - zoffs = 60 * int(d['tzhour']) + int(d['tzminute']) - if d['tzsign'] != '-': - zoffs = -zoffs - except TypeError: - pass - - return zoffs - - def applyZoneOffset(months, zoffs, date, minfield, posday = 1): - if zoffs == 0 and (minfield > 4 or 0 <= date[5] < 60): - return date - - if minfield > 5: date[5] = 0 - if minfield > 4: date[4] = 0 - - if date[5] < 0: - date[4] += int(date[5]) / 60 - date[5] %= 60 - - date[4] += zoffs - - if minfield > 3 or 0 <= date[4] < 60: return date - - date[3] += date[4] / 60 - date[4] %= 60 - - if minfield > 2 or 0 <= date[3] < 24: return date - - date[2] += date[3] / 24 - date[3] %= 24 - - if minfield > 1: - if posday and date[2] <= 0: - date[2] += 31 # zoffs is at most 99:59, so the - # day will never be less than -3 - return date - - while 1: - # The date[1] == 3 (instead of == 2) is because we're - # going back a month, so we need to know if the previous - # month is February, so we test if this month is March. - - leap = minfield == 0 and date[1] == 3 and \ - date[0] % 4 == 0 and \ - (date[0] % 100 != 0 or date[0] % 400 == 0) - - if 0 < date[2] <= months[date[1]] + leap: break - - date[2] += months[date[1] - 1] + leap - - date[1] -= 1 - - if date[1] > 0: break - - date[1] = 12 - - if minfield > 0: break - - date[0] -= 1 - - return date - - try: - exp = getattr(self.DATETIMECONSTS, kind) - except AttributeError: - return None - - if type(exp) == StringType: - exp = re.compile(exp) - setattr (self.DATETIMECONSTS, kind, exp) - - m = exp.search(value) - - try: - if m == None: - raise Exception - - d = m.groupdict() - f = ('century', 'year', 'month', 'day', - 'hour', 'minute', 'second') - fn = len(f) # Index of first non-None value - r = [] - - if kind in ('duration', 'timeDuration'): - if d['sep'] != None and d['hour'] == None and \ - d['minute'] == None and d['second'] == None: - raise Exception - - f = f[1:] - - for i in range(len(f)): - s = d[f[i]] - - if s != None: - if f[i] == 'second': - s = float(s) - else: - try: s = int(s) - except ValueError: s = long(s) - - if i < fn: fn = i - - r.append(s) - - if fn > len(r): # Any non-Nones? - raise Exception - - if d['sign'] == '-': - r[fn] = -r[fn] - - return tuple(r) - - if kind == 'recurringInstant': - for i in range(len(f)): - s = d[f[i]] - - if s == None or s == '-': - if i > fn: - raise Exception - s = None - else: - if i < fn: - fn = i - - if f[i] == 'second': - s = float(s) - else: - try: - s = int(s) - except ValueError: - s = long(s) - - r.append(s) - - s = r.pop(0) - - if fn == 0: - r[0] += s * 100 - else: - fn -= 1 - - if fn < len(r) and d['sign'] == '-': - r[fn] = -r[fn] - - cleanDate(r, fn) - - return tuple(applyZoneOffset(self.DATETIMECONSTS.months, - getZoneOffset(d), r, fn, 0)) - - r = [0, 0, 1, 1, 0, 0, 0] - - for i in range(len(f)): - field = f[i] - - s = d.get(field) - - if s != None: - if field == 'second': - s = float(s) - else: - try: - s = int(s) - except ValueError: - s = long(s) - - if i < fn: - fn = i - - r[i] = s - - if fn > len(r): # Any non-Nones? - raise Exception - - s = r.pop(0) - - if fn == 0: - r[0] += s * 100 - else: - fn -= 1 - - if d.get('sign') == '-': - r[fn] = -r[fn] - - cleanDate(r, fn) - - zoffs = getZoneOffset(d) - - if zoffs: - r = applyZoneOffset(self.DATETIMECONSTS.months, zoffs, r, fn) - - if kind == 'century': - return r[0] / 100 - - s = [] - - for i in range(1, len(f)): - if d.has_key(f[i]): - s.append(r[i - 1]) - - if len(s) == 1: - return s[0] - return tuple(s) - except Exception, e: - raise Error, "invalid %s value `%s' - %s" % (kind, value, e) - - intlimits = \ - { - 'nonPositiveInteger': (0, None, 0), - 'non-positive-integer': (0, None, 0), - 'negativeInteger': (0, None, -1), - 'negative-integer': (0, None, -1), - 'long': (1, -9223372036854775808L, - 9223372036854775807L), - 'int': (0, -2147483648L, 2147483647), - 'short': (0, -32768, 32767), - 'byte': (0, -128, 127), - 'nonNegativeInteger': (0, 0, None), - 'non-negative-integer': (0, 0, None), - 'positiveInteger': (0, 1, None), - 'positive-integer': (0, 1, None), - 'unsignedLong': (1, 0, 18446744073709551615L), - 'unsignedInt': (0, 0, 4294967295L), - 'unsignedShort': (0, 0, 65535), - 'unsignedByte': (0, 0, 255), - } - floatlimits = \ - { - 'float': (7.0064923216240861E-46, -3.4028234663852886E+38, - 3.4028234663852886E+38), - 'double': (2.4703282292062327E-324, -1.7976931348623158E+308, - 1.7976931348623157E+308), - } - zerofloatre = '[1-9]' - - - - - - def convertType(self, d, t, attrs, config=Config): - return self.convertToBasicTypes(d, t, attrs, config) - - - def convertToSOAPpyTypes(self, d, t, attrs, config=Config): - pass - - - def convertToBasicTypes(self, d, t, attrs, config=Config): - dnn = d or '' - - if t[0] in NS.EXSD_L: - if t[1] == "integer": - try: - d = int(d) - if len(attrs): - d = long(d) - except: - d = long(d) - return d - if self.intlimits.has_key (t[1]): # integer types - l = self.intlimits[t[1]] - try: d = int(d) - except: d = long(d) - - if l[1] != None and d < l[1]: - raise UnderflowError, "%s too small" % d - if l[2] != None and d > l[2]: - raise OverflowError, "%s too large" % d - - if l[0] or len(attrs): - return long(d) - return d - if t[1] == "string": - if len(attrs): - return unicode(dnn) - try: - return str(dnn) - except: - return dnn - if t[1] == "boolean": - d = d.strip().lower() - if d in ('0', 'false'): - return 0 - if d in ('1', 'true'): - return 1 - raise AttributeError, "invalid boolean value" - if t[1] in ('double','float'): - l = self.floatlimits[t[1]] - s = d.strip().lower() - - d = float(s) - - if config.strict_range: - if d < l[1]: raise UnderflowError - if d > l[2]: raise OverflowError - else: - # some older SOAP impementations (notably SOAP4J, - # Apache SOAP) return "infinity" instead of "INF" - # so check the first 3 characters for a match. - if s == "nan": - return fpconst.NaN - elif s[0:3] in ("inf", "+inf"): - return fpconst.PosInf - elif s[0:3] == "-inf": - return fpconst.NegInf - - if fpconst.isNaN(d): - if s != 'nan': - raise ValueError, "invalid %s: %s" % (t[1], s) - elif fpconst.isNegInf(d): - if s != '-inf': - raise UnderflowError, "%s too small: %s" % (t[1], s) - elif fpconst.isPosInf(d): - if s != 'inf': - raise OverflowError, "%s too large: %s" % (t[1], s) - elif d < 0 and d < l[1]: - raise UnderflowError, "%s too small: %s" % (t[1], s) - elif d > 0 and ( d < l[0] or d > l[2] ): - raise OverflowError, "%s too large: %s" % (t[1], s) - elif d == 0: - if type(self.zerofloatre) == StringType: - self.zerofloatre = re.compile(self.zerofloatre) - - if self.zerofloatre.search(s): - raise UnderflowError, "invalid %s: %s" % (t[1], s) - - return d - if t[1] in ("dateTime", "date", "timeInstant", "time"): - return self.convertDateTime(d, t[1]) - if t[1] == "decimal": - return float(d) - if t[1] in ("language", "QName", "NOTATION", "NMTOKEN", "Name", - "NCName", "ID", "IDREF", "ENTITY"): - return collapseWhiteSpace(d) - if t[1] in ("IDREFS", "ENTITIES", "NMTOKENS"): - d = collapseWhiteSpace(d) - return d.split() - if t[0] in NS.XSD_L: - if t[1] in ("base64", "base64Binary"): - if d: - return base64.decodestring(d) - else: - return '' - if t[1] == "hexBinary": - if d: - return decodeHexString(d) - else: - return - if t[1] == "anyURI": - return urllib.unquote(collapseWhiteSpace(d)) - if t[1] in ("normalizedString", "token"): - return collapseWhiteSpace(d) - if t[0] == NS.ENC: - if t[1] == "base64": - if d: - return base64.decodestring(d) - else: - return '' - if t[0] == NS.XSD: - if t[1] == "binary": - try: - e = attrs[(None, 'encoding')] - - if d: - if e == 'hex': - return decodeHexString(d) - elif e == 'base64': - return base64.decodestring(d) - else: - return '' - except: - pass - - raise Error, "unknown or missing binary encoding" - if t[1] == "uri": - return urllib.unquote(collapseWhiteSpace(d)) - if t[1] == "recurringInstant": - return self.convertDateTime(d, t[1]) - if t[0] in (NS.XSD2, NS.ENC): - if t[1] == "uriReference": - return urllib.unquote(collapseWhiteSpace(d)) - if t[1] == "timePeriod": - return self.convertDateTime(d, t[1]) - if t[1] in ("century", "year"): - return self.convertDateTime(d, t[1]) - if t[0] in (NS.XSD, NS.XSD2, NS.ENC): - if t[1] == "timeDuration": - return self.convertDateTime(d, t[1]) - if t[0] == NS.XSD3: - if t[1] == "anyURI": - return urllib.unquote(collapseWhiteSpace(d)) - if t[1] in ("gYearMonth", "gMonthDay"): - return self.convertDateTime(d, t[1]) - if t[1] == "gYear": - return self.convertDateTime(d, t[1]) - if t[1] == "gMonth": - return self.convertDateTime(d, t[1]) - if t[1] == "gDay": - return self.convertDateTime(d, t[1]) - if t[1] == "duration": - return self.convertDateTime(d, t[1]) - if t[0] in (NS.XSD2, NS.XSD3): - if t[1] == "token": - return collapseWhiteSpace(d) - if t[1] == "recurringDate": - return self.convertDateTime(d, t[1]) - if t[1] == "month": - return self.convertDateTime(d, t[1]) - if t[1] == "recurringDay": - return self.convertDateTime(d, t[1]) - if t[0] == NS.XSD2: - if t[1] == "CDATA": - return collapseWhiteSpace(d) - - raise UnknownTypeError, "unknown type `%s'" % (t[0] + ':' + t[1]) - - -################################################################################ -# call to SOAPParser that keeps all of the info -################################################################################ -def _parseSOAP(xml_str, rules = None): - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO - - parser = xml.sax.make_parser() - t = SOAPParser(rules = rules) - parser.setContentHandler(t) - e = xml.sax.handler.ErrorHandler() - parser.setErrorHandler(e) - - inpsrc = xml.sax.xmlreader.InputSource() - inpsrc.setByteStream(StringIO(xml_str)) - - # turn on namespace mangeling - parser.setFeature(xml.sax.handler.feature_namespaces,1) - - try: - parser.parse(inpsrc) - except xml.sax.SAXParseException, e: - parser._parser = None - raise e - - return t - -################################################################################ -# SOAPParser's more public interface -################################################################################ -def parseSOAP(xml_str, attrs = 0): - t = _parseSOAP(xml_str) - - if attrs: - return t.body, t.attrs - return t.body - - -def parseSOAPRPC(xml_str, header = 0, body = 0, attrs = 0, rules = None): - #config=Config, unwrap_outer=1): - - t = _parseSOAP(xml_str, rules = rules) - p = t.body[0] - - # Empty string, for RPC this translates into a void - if type(p) in (type(''), type(u'')) and p in ('', u''): - name = "Response" - for k in t.body.__dict__.keys(): - if k[0] != "_": - name = k - p = structType(name) - - if header or body or attrs: - ret = (p,) - if header : ret += (t.header,) - if body: ret += (t.body,) - if attrs: ret += (t.attrs,) - return ret - else: - return p diff --git a/SOAPpy/SOAPBuilder.py b/SOAPpy/SOAPBuilder.py deleted file mode 100644 index e375a41..0000000 --- a/SOAPpy/SOAPBuilder.py +++ /dev/null @@ -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 = '\n' - _xml_enc_top = '\n' - _env_top = '%(ENV_T)s:Envelope %(ENV_T)s:encodingStyle="%(ENC)s"' % \ - NS.__dict__ - _env_bot = '\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("\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("\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\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('\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('\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> -%s -%s -''' % (vns, cns, vdecl, cdecl, obj.faultcode, obj.faultstring)) - if hasattr(obj, "detail"): - self.dump(obj.detail, "detail", typed, ns_map) - self.out.append("\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>\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('\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\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('\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() diff --git a/SOAPpy/Types.py b/SOAPpy/Types.py deleted file mode 100644 index b4d9a57..0000000 --- a/SOAPpy/Types.py +++ /dev/null @@ -1,1734 +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: Types.py,v 1.17 2004/09/11 03:03:33 warnes Exp $' -from version import __version__ - -from __future__ import nested_scopes - -import UserList -import base64 -import cgi -import urllib -import copy -import re -import time -from types import * - -# SOAPpy modules -from Errors import * -from NS import NS -from Utilities import encodeHexString, cleanDate -from Config import Config - -############################################################################### -# Utility functions -############################################################################### - -def isPrivate(name): return name[0]=='_' -def isPublic(name): return name[0]!='_' - -############################################################################### -# Types and Wrappers -############################################################################### - -class anyType: - _validURIs = (NS.XSD, NS.XSD2, NS.XSD3, NS.ENC) - - def __init__(self, data = None, name = None, typed = 1, attrs = None): - if self.__class__ == anyType: - raise Error, "anyType can't be instantiated directly" - - if type(name) in (ListType, TupleType): - self._ns, self._name = name - else: - self._ns = self._validURIs[0] - self._name = name - - self._typed = typed - self._attrs = {} - - self._cache = None - self._type = self._typeName() - - self._data = self._checkValueSpace(data) - - if attrs != None: - self._setAttrs(attrs) - - def __str__(self): - if hasattr(self,'_name') and self._name: - return "<%s %s at %d>" % (self.__class__, self._name, id(self)) - return "<%s at %d>" % (self.__class__, id(self)) - - __repr__ = __str__ - - def _checkValueSpace(self, data): - return data - - def _marshalData(self): - return str(self._data) - - def _marshalAttrs(self, ns_map, builder): - a = '' - - for attr, value in self._attrs.items(): - ns, n = builder.genns(ns_map, attr[0]) - a += n + ' %s%s="%s"' % \ - (ns, attr[1], cgi.escape(str(value), 1)) - - return a - - def _fixAttr(self, attr): - if type(attr) in (StringType, UnicodeType): - attr = (None, attr) - elif type(attr) == ListType: - attr = tuple(attr) - elif type(attr) != TupleType: - raise AttributeError, "invalid attribute type" - - if len(attr) != 2: - raise AttributeError, "invalid attribute length" - - if type(attr[0]) not in (NoneType, StringType, UnicodeType): - raise AttributeError, "invalid attribute namespace URI type" - - return attr - - def _getAttr(self, attr): - attr = self._fixAttr(attr) - - try: - return self._attrs[attr] - except: - return None - - def _setAttr(self, attr, value): - attr = self._fixAttr(attr) - - if type(value) is StringType: - value = unicode(value) - - self._attrs[attr] = value - - - def _setAttrs(self, attrs): - if type(attrs) in (ListType, TupleType): - for i in range(0, len(attrs), 2): - self._setAttr(attrs[i], attrs[i + 1]) - - return - - if type(attrs) == DictType: - d = attrs - elif isinstance(attrs, anyType): - d = attrs._attrs - else: - raise AttributeError, "invalid attribute type" - - for attr, value in d.items(): - self._setAttr(attr, value) - - def _setMustUnderstand(self, val): - self._setAttr((NS.ENV, "mustUnderstand"), val) - - def _getMustUnderstand(self): - return self._getAttr((NS.ENV, "mustUnderstand")) - - def _setActor(self, val): - self._setAttr((NS.ENV, "actor"), val) - - def _getActor(self): - return self._getAttr((NS.ENV, "actor")) - - def _typeName(self): - return self.__class__.__name__[:-4] - - def _validNamespaceURI(self, URI, strict): - if not hasattr(self, '_typed') or not self._typed: - return None - if URI in self._validURIs: - return URI - if not strict: - return self._ns - raise AttributeError, \ - "not a valid namespace for type %s" % self._type - -class voidType(anyType): - pass - -class stringType(anyType): - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (StringType, UnicodeType): - raise AttributeError, "invalid %s type:" % self._type - - return data - -class untypedType(stringType): - def __init__(self, data = None, name = None, attrs = None): - stringType.__init__(self, data, name, 0, attrs) - -class IDType(stringType): pass -class NCNameType(stringType): pass -class NameType(stringType): pass -class ENTITYType(stringType): pass -class IDREFType(stringType): pass -class languageType(stringType): pass -class NMTOKENType(stringType): pass -class QNameType(stringType): pass - -class tokenType(anyType): - _validURIs = (NS.XSD2, NS.XSD3) - __invalidre = '[\n\t]|^ | $| ' - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (StringType, UnicodeType): - raise AttributeError, "invalid %s type" % self._type - - if type(self.__invalidre) == StringType: - self.__invalidre = re.compile(self.__invalidre) - - if self.__invalidre.search(data): - raise ValueError, "invalid %s value" % self._type - - return data - -class normalizedStringType(anyType): - _validURIs = (NS.XSD3,) - __invalidre = '[\n\r\t]' - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (StringType, UnicodeType): - raise AttributeError, "invalid %s type" % self._type - - if type(self.__invalidre) == StringType: - self.__invalidre = re.compile(self.__invalidre) - - if self.__invalidre.search(data): - raise ValueError, "invalid %s value" % self._type - - return data - -class CDATAType(normalizedStringType): - _validURIs = (NS.XSD2,) - -class booleanType(anyType): - def __int__(self): - return self._data - - __nonzero__ = __int__ - - def _marshalData(self): - return ['false', 'true'][self._data] - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if data in (0, '0', 'false', ''): - return 0 - if data in (1, '1', 'true'): - return 1 - raise ValueError, "invalid %s value" % self._type - -class decimalType(anyType): - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType, FloatType): - raise Error, "invalid %s value" % self._type - - return data - -class floatType(anyType): - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType, FloatType) or \ - data < -3.4028234663852886E+38 or \ - data > 3.4028234663852886E+38: - raise ValueError, "invalid %s value: %s" % (self._type, repr(data)) - - return data - - def _marshalData(self): - return "%.18g" % self._data # More precision - -class doubleType(anyType): - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType, FloatType) or \ - data < -1.7976931348623158E+308 or \ - data > 1.7976931348623157E+308: - raise ValueError, "invalid %s value: %s" % (self._type, repr(data)) - - return data - - def _marshalData(self): - return "%.18g" % self._data # More precision - -class durationType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - try: - # A tuple or a scalar is OK, but make them into a list - - if type(data) == TupleType: - data = list(data) - elif type(data) != ListType: - data = [data] - - if len(data) > 6: - raise Exception, "too many values" - - # Now check the types of all the components, and find - # the first nonzero element along the way. - - f = -1 - - for i in range(len(data)): - if data[i] == None: - data[i] = 0 - continue - - if type(data[i]) not in \ - (IntType, LongType, FloatType): - raise Exception, "element %d a bad type" % i - - if data[i] and f == -1: - f = i - - # If they're all 0, just use zero seconds. - - if f == -1: - self._cache = 'PT0S' - - return (0,) * 6 - - # Make sure only the last nonzero element has a decimal fraction - # and only the first element is negative. - - d = -1 - - for i in range(f, len(data)): - if data[i]: - if d != -1: - raise Exception, \ - "all except the last nonzero element must be " \ - "integers" - if data[i] < 0 and i > f: - raise Exception, \ - "only the first nonzero element can be negative" - elif data[i] != long(data[i]): - d = i - - # Pad the list on the left if necessary. - - if len(data) < 6: - n = 6 - len(data) - f += n - d += n - data = [0] * n + data - - # Save index of the first nonzero element and the decimal - # element for _marshalData. - - self.__firstnonzero = f - self.__decimal = d - - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return tuple(data) - - def _marshalData(self): - if self._cache == None: - d = self._data - t = 0 - - if d[self.__firstnonzero] < 0: - s = '-P' - else: - s = 'P' - - t = 0 - - for i in range(self.__firstnonzero, len(d)): - if d[i]: - if i > 2 and not t: - s += 'T' - t = 1 - if self.__decimal == i: - s += "%g" % abs(d[i]) - else: - s += "%d" % long(abs(d[i])) - s += ['Y', 'M', 'D', 'H', 'M', 'S'][i] - - self._cache = s - - return self._cache - -class timeDurationType(durationType): - _validURIs = (NS.XSD, NS.XSD2, NS.ENC) - -class dateTimeType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - try: - if data == None: - data = time.time() - - if (type(data) in (IntType, LongType)): - data = list(time.gmtime(data)[:6]) - elif (type(data) == FloatType): - f = data - int(data) - data = list(time.gmtime(int(data))[:6]) - data[5] += f - elif type(data) in (ListType, TupleType): - if len(data) < 6: - raise Exception, "not enough values" - if len(data) > 9: - raise Exception, "too many values" - - data = list(data[:6]) - - cleanDate(data) - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return tuple(data) - - def _marshalData(self): - if self._cache == None: - d = self._data - s = "%04d-%02d-%02dT%02d:%02d:%02d" % ((abs(d[0]),) + d[1:]) - if d[0] < 0: - s = '-' + s - f = d[5] - int(d[5]) - if f != 0: - s += ("%g" % f)[1:] - s += 'Z' - - self._cache = s - - return self._cache - -class recurringInstantType(anyType): - _validURIs = (NS.XSD,) - - def _checkValueSpace(self, data): - try: - if data == None: - data = list(time.gmtime(time.time())[:6]) - if (type(data) in (IntType, LongType)): - data = list(time.gmtime(data)[:6]) - elif (type(data) == FloatType): - f = data - int(data) - data = list(time.gmtime(int(data))[:6]) - data[5] += f - elif type(data) in (ListType, TupleType): - if len(data) < 1: - raise Exception, "not enough values" - if len(data) > 9: - raise Exception, "too many values" - - data = list(data[:6]) - - if len(data) < 6: - data += [0] * (6 - len(data)) - - f = len(data) - - for i in range(f): - if data[i] == None: - if f < i: - raise Exception, \ - "only leftmost elements can be none" - else: - f = i - break - - cleanDate(data, f) - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return tuple(data) - - def _marshalData(self): - if self._cache == None: - d = self._data - e = list(d) - neg = '' - - if not e[0]: - e[0] = '--' - else: - if e[0] < 0: - neg = '-' - e[0] = abs(e[0]) - if e[0] < 100: - e[0] = '-' + "%02d" % e[0] - else: - e[0] = "%04d" % e[0] - - for i in range(1, len(e)): - if e[i] == None or (i < 3 and e[i] == 0): - e[i] = '-' - else: - if e[i] < 0: - neg = '-' - e[i] = abs(e[i]) - - e[i] = "%02d" % e[i] - - if d[5]: - f = abs(d[5] - int(d[5])) - - if f: - e[5] += ("%g" % f)[1:] - - s = "%s%s-%s-%sT%s:%s:%sZ" % ((neg,) + tuple(e)) - - self._cache = s - - return self._cache - -class timeInstantType(dateTimeType): - _validURIs = (NS.XSD, NS.XSD2, NS.ENC) - -class timePeriodType(dateTimeType): - _validURIs = (NS.XSD2, NS.ENC) - -class timeType(anyType): - def _checkValueSpace(self, data): - try: - if data == None: - data = time.gmtime(time.time())[3:6] - elif (type(data) == FloatType): - f = data - int(data) - data = list(time.gmtime(int(data))[3:6]) - data[2] += f - elif type(data) in (IntType, LongType): - data = time.gmtime(data)[3:6] - elif type(data) in (ListType, TupleType): - if len(data) == 9: - data = data[3:6] - elif len(data) > 3: - raise Exception, "too many values" - - data = [None, None, None] + list(data) - - if len(data) < 6: - data += [0] * (6 - len(data)) - - cleanDate(data, 3) - - data = data[3:] - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return tuple(data) - - def _marshalData(self): - if self._cache == None: - d = self._data - s = '' - - s = time.strftime("%H:%M:%S", (0, 0, 0) + d + (0, 0, -1)) - f = d[2] - int(d[2]) - if f != 0: - s += ("%g" % f)[1:] - s += 'Z' - - self._cache = s - - return self._cache - -class dateType(anyType): - def _checkValueSpace(self, data): - try: - if data == None: - data = time.gmtime(time.time())[0:3] - elif type(data) in (IntType, LongType, FloatType): - data = time.gmtime(data)[0:3] - elif type(data) in (ListType, TupleType): - if len(data) == 9: - data = data[0:3] - elif len(data) > 3: - raise Exception, "too many values" - - data = list(data) - - if len(data) < 3: - data += [1, 1, 1][len(data):] - - data += [0, 0, 0] - - cleanDate(data) - - data = data[:3] - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return tuple(data) - - def _marshalData(self): - if self._cache == None: - d = self._data - s = "%04d-%02d-%02dZ" % ((abs(d[0]),) + d[1:]) - if d[0] < 0: - s = '-' + s - - self._cache = s - - return self._cache - -class gYearMonthType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - try: - if data == None: - data = time.gmtime(time.time())[0:2] - elif type(data) in (IntType, LongType, FloatType): - data = time.gmtime(data)[0:2] - elif type(data) in (ListType, TupleType): - if len(data) == 9: - data = data[0:2] - elif len(data) > 2: - raise Exception, "too many values" - - data = list(data) - - if len(data) < 2: - data += [1, 1][len(data):] - - data += [1, 0, 0, 0] - - cleanDate(data) - - data = data[:2] - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return tuple(data) - - def _marshalData(self): - if self._cache == None: - d = self._data - s = "%04d-%02dZ" % ((abs(d[0]),) + d[1:]) - if d[0] < 0: - s = '-' + s - - self._cache = s - - return self._cache - -class gYearType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - try: - if data == None: - data = time.gmtime(time.time())[0:1] - elif type(data) in (IntType, LongType, FloatType): - data = [data] - - if type(data) in (ListType, TupleType): - if len(data) == 9: - data = data[0:1] - elif len(data) < 1: - raise Exception, "too few values" - elif len(data) > 1: - raise Exception, "too many values" - - if type(data[0]) == FloatType: - try: s = int(data[0]) - except: s = long(data[0]) - - if s != data[0]: - raise Exception, "not integral" - - data = [s] - elif type(data[0]) not in (IntType, LongType): - raise Exception, "bad type" - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return data[0] - - def _marshalData(self): - if self._cache == None: - d = self._data - s = "%04dZ" % abs(d) - if d < 0: - s = '-' + s - - self._cache = s - - return self._cache - -class centuryType(anyType): - _validURIs = (NS.XSD2, NS.ENC) - - def _checkValueSpace(self, data): - try: - if data == None: - data = time.gmtime(time.time())[0:1] / 100 - elif type(data) in (IntType, LongType, FloatType): - data = [data] - - if type(data) in (ListType, TupleType): - if len(data) == 9: - data = data[0:1] / 100 - elif len(data) < 1: - raise Exception, "too few values" - elif len(data) > 1: - raise Exception, "too many values" - - if type(data[0]) == FloatType: - try: s = int(data[0]) - except: s = long(data[0]) - - if s != data[0]: - raise Exception, "not integral" - - data = [s] - elif type(data[0]) not in (IntType, LongType): - raise Exception, "bad type" - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return data[0] - - def _marshalData(self): - if self._cache == None: - d = self._data - s = "%02dZ" % abs(d) - if d < 0: - s = '-' + s - - self._cache = s - - return self._cache - -class yearType(gYearType): - _validURIs = (NS.XSD2, NS.ENC) - -class gMonthDayType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - try: - if data == None: - data = time.gmtime(time.time())[1:3] - elif type(data) in (IntType, LongType, FloatType): - data = time.gmtime(data)[1:3] - elif type(data) in (ListType, TupleType): - if len(data) == 9: - data = data[0:2] - elif len(data) > 2: - raise Exception, "too many values" - - data = list(data) - - if len(data) < 2: - data += [1, 1][len(data):] - - data = [0] + data + [0, 0, 0] - - cleanDate(data, 1) - - data = data[1:3] - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return tuple(data) - - def _marshalData(self): - if self._cache == None: - self._cache = "--%02d-%02dZ" % self._data - - return self._cache - -class recurringDateType(gMonthDayType): - _validURIs = (NS.XSD2, NS.ENC) - -class gMonthType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - try: - if data == None: - data = time.gmtime(time.time())[1:2] - elif type(data) in (IntType, LongType, FloatType): - data = [data] - - if type(data) in (ListType, TupleType): - if len(data) == 9: - data = data[1:2] - elif len(data) < 1: - raise Exception, "too few values" - elif len(data) > 1: - raise Exception, "too many values" - - if type(data[0]) == FloatType: - try: s = int(data[0]) - except: s = long(data[0]) - - if s != data[0]: - raise Exception, "not integral" - - data = [s] - elif type(data[0]) not in (IntType, LongType): - raise Exception, "bad type" - - if data[0] < 1 or data[0] > 12: - raise Exception, "bad value" - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return data[0] - - def _marshalData(self): - if self._cache == None: - self._cache = "--%02d--Z" % self._data - - return self._cache - -class monthType(gMonthType): - _validURIs = (NS.XSD2, NS.ENC) - -class gDayType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - try: - if data == None: - data = time.gmtime(time.time())[2:3] - elif type(data) in (IntType, LongType, FloatType): - data = [data] - - if type(data) in (ListType, TupleType): - if len(data) == 9: - data = data[2:3] - elif len(data) < 1: - raise Exception, "too few values" - elif len(data) > 1: - raise Exception, "too many values" - - if type(data[0]) == FloatType: - try: s = int(data[0]) - except: s = long(data[0]) - - if s != data[0]: - raise Exception, "not integral" - - data = [s] - elif type(data[0]) not in (IntType, LongType): - raise Exception, "bad type" - - if data[0] < 1 or data[0] > 31: - raise Exception, "bad value" - else: - raise Exception, "invalid type" - except Exception, e: - raise ValueError, "invalid %s value - %s" % (self._type, e) - - return data[0] - - def _marshalData(self): - if self._cache == None: - self._cache = "---%02dZ" % self._data - - return self._cache - -class recurringDayType(gDayType): - _validURIs = (NS.XSD2, NS.ENC) - -class hexBinaryType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (StringType, UnicodeType): - raise AttributeError, "invalid %s type" % self._type - - return data - - def _marshalData(self): - if self._cache == None: - self._cache = encodeHexString(self._data) - - return self._cache - -class base64BinaryType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (StringType, UnicodeType): - raise AttributeError, "invalid %s type" % self._type - - return data - - def _marshalData(self): - if self._cache == None: - self._cache = base64.encodestring(self._data) - - return self._cache - -class base64Type(base64BinaryType): - _validURIs = (NS.ENC,) - -class binaryType(anyType): - _validURIs = (NS.XSD, NS.ENC) - - def __init__(self, data, name = None, typed = 1, encoding = 'base64', - attrs = None): - - anyType.__init__(self, data, name, typed, attrs) - - self._setAttr('encoding', encoding) - - def _marshalData(self): - if self._cache == None: - if self._getAttr((None, 'encoding')) == 'base64': - self._cache = base64.encodestring(self._data) - else: - self._cache = encodeHexString(self._data) - - return self._cache - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (StringType, UnicodeType): - raise AttributeError, "invalid %s type" % self._type - - return data - - def _setAttr(self, attr, value): - attr = self._fixAttr(attr) - - if attr[1] == 'encoding': - if attr[0] != None or value not in ('base64', 'hex'): - raise AttributeError, "invalid encoding" - - self._cache = None - - anyType._setAttr(self, attr, value) - - -class anyURIType(anyType): - _validURIs = (NS.XSD3,) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (StringType, UnicodeType): - raise AttributeError, "invalid %s type" % self._type - - return data - - def _marshalData(self): - if self._cache == None: - self._cache = urllib.quote(self._data) - - return self._cache - -class uriType(anyURIType): - _validURIs = (NS.XSD,) - -class uriReferenceType(anyURIType): - _validURIs = (NS.XSD2,) - -class NOTATIONType(anyType): - def __init__(self, data, name = None, typed = 1, attrs = None): - - if self.__class__ == NOTATIONType: - raise Error, "a NOTATION can't be instantiated directly" - - anyType.__init__(self, data, name, typed, attrs) - -class ENTITIESType(anyType): - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) in (StringType, UnicodeType): - return (data,) - - if type(data) not in (ListType, TupleType) or \ - filter (lambda x: type(x) not in (StringType, UnicodeType), data): - raise AttributeError, "invalid %s type" % self._type - - return data - - def _marshalData(self): - return ' '.join(self._data) - -class IDREFSType(ENTITIESType): pass -class NMTOKENSType(ENTITIESType): pass - -class integerType(anyType): - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType): - raise ValueError, "invalid %s value" % self._type - - return data - -class nonPositiveIntegerType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or data > 0: - raise ValueError, "invalid %s value" % self._type - - return data - -class non_Positive_IntegerType(nonPositiveIntegerType): - _validURIs = (NS.XSD,) - - def _typeName(self): - return 'non-positive-integer' - -class negativeIntegerType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or data >= 0: - raise ValueError, "invalid %s value" % self._type - - return data - -class negative_IntegerType(negativeIntegerType): - _validURIs = (NS.XSD,) - - def _typeName(self): - return 'negative-integer' - -class longType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or \ - data < -9223372036854775808L or \ - data > 9223372036854775807L: - raise ValueError, "invalid %s value" % self._type - - return data - -class intType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or \ - data < -2147483648L or \ - data > 2147483647: - raise ValueError, "invalid %s value" % self._type - - return data - -class shortType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or \ - data < -32768 or \ - data > 32767: - raise ValueError, "invalid %s value" % self._type - - return data - -class byteType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or \ - data < -128 or \ - data > 127: - raise ValueError, "invalid %s value" % self._type - - return data - -class nonNegativeIntegerType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or data < 0: - raise ValueError, "invalid %s value" % self._type - - return data - -class non_Negative_IntegerType(nonNegativeIntegerType): - _validURIs = (NS.XSD,) - - def _typeName(self): - return 'non-negative-integer' - -class unsignedLongType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or \ - data < 0 or \ - data > 18446744073709551615L: - raise ValueError, "invalid %s value" % self._type - - return data - -class unsignedIntType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or \ - data < 0 or \ - data > 4294967295L: - raise ValueError, "invalid %s value" % self._type - - return data - -class unsignedShortType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or \ - data < 0 or \ - data > 65535: - raise ValueError, "invalid %s value" % self._type - - return data - -class unsignedByteType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or \ - data < 0 or \ - data > 255: - raise ValueError, "invalid %s value" % self._type - - return data - -class positiveIntegerType(anyType): - _validURIs = (NS.XSD2, NS.XSD3, NS.ENC) - - def _checkValueSpace(self, data): - if data == None: - raise ValueError, "must supply initial %s value" % self._type - - if type(data) not in (IntType, LongType) or data <= 0: - raise ValueError, "invalid %s value" % self._type - - return data - -class positive_IntegerType(positiveIntegerType): - _validURIs = (NS.XSD,) - - def _typeName(self): - return 'positive-integer' - -# Now compound types - -class compoundType(anyType): - def __init__(self, data = None, name = None, typed = 1, attrs = None): - if self.__class__ == compoundType: - raise Error, "a compound can't be instantiated directly" - - anyType.__init__(self, data, name, typed, attrs) - self._keyord = [] - - if type(data) == DictType: - self.__dict__.update(data) - - def _aslist(self, item=None): - if item: - return self.__dict__[self._keyord[item]] - else: - return map( lambda x: self.__dict__[x], self._keyord) - - def _asdict(self, item=None, encoding=Config.dict_encoding): - if item: - if type(item) in (UnicodeType,StringType): - item = item.encode(encoding) - return self.__dict__[item] - else: - retval = {} - def fun(x): retval[x.encode(encoding)] = self.__dict__[x] - - if hasattr(self, '_keyord'): - map( fun, self._keyord) - else: - for name in dir(self): - if isPublic(name): - retval[name] = getattr(self,name) - return retval - - - def __getitem__(self, item): - if type(item) == IntType: - return self.__dict__[self._keyord[item]] - else: - return getattr(self, item) - - def __len__(self): - return len(self._keyord) - - def __nonzero__(self): - return 1 - - def _keys(self): - return filter(lambda x: x[0] != '_', self.__dict__.keys()) - - def _addItem(self, name, value, attrs = None): - - if name in self._keyord: - if type(self.__dict__[name]) != ListType: - self.__dict__[name] = [self.__dict__[name]] - self.__dict__[name].append(value) - else: - self.__dict__[name] = value - self._keyord.append(name) - - def _placeItem(self, name, value, pos, subpos = 0, attrs = None): - - if subpos == 0 and type(self.__dict__[name]) != ListType: - self.__dict__[name] = value - else: - self.__dict__[name][subpos] = value - - self._keyord[pos] = name - - - def _getItemAsList(self, name, default = []): - try: - d = self.__dict__[name] - except: - return default - - if type(d) == ListType: - return d - return [d] - - def __str__(self): - return anyType.__str__(self) + ": " + str(self._asdict()) - - def __repr__(self): - return self.__str__() - -class structType(compoundType): - pass - -class headerType(structType): - _validURIs = (NS.ENV,) - - def __init__(self, data = None, typed = 1, attrs = None): - structType.__init__(self, data, "Header", typed, attrs) - -class bodyType(structType): - _validURIs = (NS.ENV,) - - def __init__(self, data = None, typed = 1, attrs = None): - structType.__init__(self, data, "Body", typed, attrs) - -class arrayType(UserList.UserList, compoundType): - def __init__(self, data = None, name = None, attrs = None, - offset = 0, rank = None, asize = 0, elemsname = None): - - if data: - if type(data) not in (ListType, TupleType): - raise Error, "Data must be a sequence" - - UserList.UserList.__init__(self, data) - compoundType.__init__(self, data, name, 0, attrs) - - self._elemsname = elemsname or "item" - - if data == None: - self._rank = rank - - # According to 5.4.2.2 in the SOAP spec, each element in a - # sparse array must have a position. _posstate keeps track of - # whether we've seen a position or not. It's possible values - # are: - # -1 No elements have been added, so the state is indeterminate - # 0 An element without a position has been added, so no - # elements can have positions - # 1 An element with a position has been added, so all elements - # must have positions - - self._posstate = -1 - - self._full = 0 - - if asize in ('', None): - asize = '0' - - self._dims = map (lambda x: int(x), str(asize).split(',')) - self._dims.reverse() # It's easier to work with this way - self._poss = [0] * len(self._dims) # This will end up - # reversed too - - for i in range(len(self._dims)): - if self._dims[i] < 0 or \ - self._dims[i] == 0 and len(self._dims) > 1: - raise TypeError, "invalid Array dimensions" - - if offset > 0: - self._poss[i] = offset % self._dims[i] - offset = int(offset / self._dims[i]) - - # Don't break out of the loop if offset is 0 so we test all the - # dimensions for > 0. - if offset: - raise AttributeError, "invalid Array offset" - - a = [None] * self._dims[0] - - for i in range(1, len(self._dims)): - b = [] - - for j in range(self._dims[i]): - b.append(copy.deepcopy(a)) - - a = b - - self.data = a - - - def _aslist(self, item=None): - if item: - return self.data[int(item)] - else: - return self.data - - def _asdict(self, item=None, encoding=Config.dict_encoding): - if item: - if type(item) in (UnicodeType,StringType): - item = item.encode(encoding) - return self.data[int(item)] - else: - retval = {} - def fun(x): retval[str(x).encode(encoding)] = self.data[x] - - map( fun, range(len(self.data)) ) - return retval - - def __getitem__(self, item): - try: - return self.data[int(item)] - except ValueError: - return getattr(self, item) - - def __len__(self): - return len(self.data) - - def __nonzero__(self): - return 1 - - def __str__(self): - return anyType.__str__(self) + ": " + str(self._aslist()) - - def _keys(self): - return filter(lambda x: x[0] != '_', self.__dict__.keys()) - - def _addItem(self, name, value, attrs): - if self._full: - raise ValueError, "Array is full" - - pos = attrs.get((NS.ENC, 'position')) - - if pos != None: - if self._posstate == 0: - raise AttributeError, \ - "all elements in a sparse Array must have a " \ - "position attribute" - - self._posstate = 1 - - try: - if pos[0] == '[' and pos[-1] == ']': - pos = map (lambda x: int(x), pos[1:-1].split(',')) - pos.reverse() - - if len(pos) == 1: - pos = pos[0] - - curpos = [0] * len(self._dims) - - for i in range(len(self._dims)): - curpos[i] = pos % self._dims[i] - pos = int(pos / self._dims[i]) - - if pos == 0: - break - - if pos: - raise Exception - elif len(pos) != len(self._dims): - raise Exception - else: - for i in range(len(self._dims)): - if pos[i] >= self._dims[i]: - raise Exception - - curpos = pos - else: - raise Exception - except: - raise AttributeError, \ - "invalid Array element position %s" % str(pos) - else: - if self._posstate == 1: - raise AttributeError, \ - "only elements in a sparse Array may have a " \ - "position attribute" - - self._posstate = 0 - - curpos = self._poss - - a = self.data - - for i in range(len(self._dims) - 1, 0, -1): - a = a[curpos[i]] - - if curpos[0] >= len(a): - a += [None] * (len(a) - curpos[0] + 1) - - a[curpos[0]] = value - - if pos == None: - self._poss[0] += 1 - - for i in range(len(self._dims) - 1): - if self._poss[i] < self._dims[i]: - break - - self._poss[i] = 0 - self._poss[i + 1] += 1 - - if self._dims[-1] and self._poss[-1] >= self._dims[-1]: - self._full = 1 - - def _placeItem(self, name, value, pos, subpos, attrs = None): - curpos = [0] * len(self._dims) - - for i in range(len(self._dims)): - if self._dims[i] == 0: - curpos[0] = pos - break - - curpos[i] = pos % self._dims[i] - pos = int(pos / self._dims[i]) - - if pos == 0: - break - - if self._dims[i] != 0 and pos: - raise Error, "array index out of range" - - a = self.data - - for i in range(len(self._dims) - 1, 0, -1): - a = a[curpos[i]] - - if curpos[0] >= len(a): - a += [None] * (len(a) - curpos[0] + 1) - - a[curpos[0]] = value - -class typedArrayType(arrayType): - def __init__(self, data = None, name = None, typed = None, attrs = None, - offset = 0, rank = None, asize = 0, elemsname = None, complexType = 0): - - arrayType.__init__(self, data, name, attrs, offset, rank, asize, - elemsname) - - self._typed = 1 - self._type = typed - self._complexType = complexType - -class faultType(structType, Error): - def __init__(self, faultcode = "", faultstring = "", detail = None): - self.faultcode = faultcode - self.faultstring = faultstring - if detail != None: - self.detail = detail - - structType.__init__(self, None, 0) - - def _setDetail(self, detail = None): - if detail != None: - self.detail = detail - else: - try: del self.detail - except AttributeError: pass - - def __repr__(self): - if getattr(self, 'detail', None) != None: - return "" % (self.faultcode, - self.faultstring, - self.detail) - else: - return "" % (self.faultcode, self.faultstring) - - __str__ = __repr__ - - def __call__(self): - return (self.faultcode, self.faultstring, self.detail) - -class SOAPException(Exception): - def __init__(self, code="", string="", detail=None): - self.value = ("SOAPpy SOAP Exception", code, string, detail) - self.code = code - self.string = string - self.detail = detail - - def __str__(self): - return repr(self.value) - -class RequiredHeaderMismatch(Exception): - def __init__(self, value): - self.value = value - - def __str__(self): - return repr(self.value) - -class MethodNotFound(Exception): - def __init__(self, value): - (val, detail) = value.split(":") - self.value = val - self.detail = detail - - def __str__(self): - return repr(self.value, self.detail) - -class AuthorizationFailed(Exception): - def __init__(self, value): - self.value = value - - def __str__(self): - return repr(self.value) - -class MethodFailed(Exception): - def __init__(self, value): - self.value = value - - def __str__(self): - return repr(self.value) - -####### -# Convert complex SOAPpy objects to native python equivalents -####### - -def simplify(object, level=0): - """ - Convert the SOAPpy objects and thier contents to simple python types. - - This function recursively converts the passed 'container' object, - and all public subobjects. (Private subobjects have names that - start with '_'.) - - Conversions: - - faultType --> raise python exception - - arrayType --> array - - compoundType --> dictionary - """ - - if level > 10: - return object - - if isinstance( object, faultType ): - if object.faultstring == "Required Header Misunderstood": - raise RequiredHeaderMismatch(object.detail) - elif object.faultstring == "Method Not Found": - raise MethodNotFound(object.detail) - elif object.faultstring == "Authorization Failed": - raise AuthorizationFailed(object.detail) - elif object.faultstring == "Method Failed": - raise MethodFailed(object.detail) - else: - se = SOAPException(object.faultcode, object.faultstring, - object.detail) - raise se - elif isinstance( object, arrayType ): - data = object._aslist() - for k in range(len(data)): - data[k] = simplify(data[k], level=level+1) - return data - elif isinstance( object, compoundType ) or isinstance(object, structType): - data = object._asdict() - for k in data.keys(): - if isPublic(k): - data[k] = simplify(data[k], level=level+1) - return data - elif type(object)==DictType: - for k in object.keys(): - if isPublic(k): - object[k] = simplify(object[k]) - return object - elif type(object)==list: - for k in range(len(object)): - object[k] = simplify(object[k]) - return object - else: - return object - - -def simplify_contents(object, level=0): - """ - Convert the contents of SOAPpy objects to simple python types. - - This function recursively converts the sub-objects contained in a - 'container' object to simple python types. - - Conversions: - - faultType --> raise python exception - - arrayType --> array - - compoundType --> dictionary - """ - - if level>10: return object - - if isinstance( object, faultType ): - for k in object._keys(): - if isPublic(k): - setattr(object, k, simplify(object[k], level=level+1)) - raise object - elif isinstance( object, arrayType ): - data = object._aslist() - for k in range(len(data)): - object[k] = simplify(data[k], level=level+1) - elif isinstance(object, structType): - data = object._asdict() - for k in data.keys(): - if isPublic(k): - setattr(object, k, simplify(data[k], level=level+1)) - elif isinstance( object, compoundType ) : - data = object._asdict() - for k in data.keys(): - if isPublic(k): - object[k] = simplify(data[k], level=level+1) - elif type(object)==DictType: - for k in object.keys(): - if isPublic(k): - object[k] = simplify(object[k]) - elif type(object)==list: - for k in range(len(object)): - object[k] = simplify(object[k]) - - return object - - diff --git a/SOAPpy/Utilities.py b/SOAPpy/Utilities.py deleted file mode 100644 index 03d3433..0000000 --- a/SOAPpy/Utilities.py +++ /dev/null @@ -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() diff --git a/SOAPpy/__init__.py b/SOAPpy/__init__.py deleted file mode 100644 index 0e039f8..0000000 --- a/SOAPpy/__init__.py +++ /dev/null @@ -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 diff --git a/SOAPpy/version.py b/SOAPpy/version.py deleted file mode 100644 index eda6139..0000000 --- a/SOAPpy/version.py +++ /dev/null @@ -1,2 +0,0 @@ -__version__="0.11.6" - diff --git a/SOAPpy/wstools/Namespaces.py b/SOAPpy/wstools/Namespaces.py deleted file mode 100755 index 60eaa0f..0000000 --- a/SOAPpy/wstools/Namespaces.py +++ /dev/null @@ -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" - - - diff --git a/SOAPpy/wstools/TimeoutSocket.py b/SOAPpy/wstools/TimeoutSocket.py deleted file mode 100755 index 2d804dd..0000000 --- a/SOAPpy/wstools/TimeoutSocket.py +++ /dev/null @@ -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 - Lloyd Zusman - Phil Mayes - Piers Lauder - Radovan Garabik -""" - -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 diff --git a/SOAPpy/wstools/UserTuple.py b/SOAPpy/wstools/UserTuple.py deleted file mode 100755 index 5b193e7..0000000 --- a/SOAPpy/wstools/UserTuple.py +++ /dev/null @@ -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 -, 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__ - diff --git a/SOAPpy/wstools/Utility.py b/SOAPpy/wstools/Utility.py deleted file mode 100755 index b2bfb3c..0000000 --- a/SOAPpy/wstools/Utility.py +++ /dev/null @@ -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') -# ('http://www.w3.org/2000/xmlns/', 'xmlns') -# -# 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 diff --git a/SOAPpy/wstools/WSDLTools.py b/SOAPpy/wstools/WSDLTools.py deleted file mode 100755 index ad4e58e..0000000 --- a/SOAPpy/wstools/WSDLTools.py +++ /dev/null @@ -1,1336 +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: WSDLTools.py,v 1.23 2004/09/09 04:37:55 boverhof Exp $" - -from Utility import DOM, Collection, CollectionNS -from XMLSchema import XMLSchema, SchemaReader, WSDLToolsAdapter -from Namespaces import WSR, WSA -from StringIO import StringIO -import urllib - - -class WSDLReader: - """A WSDLReader creates WSDL instances from urls and xml data.""" - - # Custom subclasses of WSDLReader may wish to implement a caching - # strategy or other optimizations. Because application needs vary - # so widely, we don't try to provide any caching by default. - - def loadFromStream(self, stream, name=None): - """Return a WSDL instance loaded from a stream object.""" - document = DOM.loadDocument(stream) - wsdl = WSDL() - if name: - wsdl.location = name - elif hasattr(stream, 'name'): - wsdl.location = stream.name - wsdl.load(document) - return wsdl - - def loadFromURL(self, url): - """Return a WSDL instance loaded from the given url.""" - document = DOM.loadFromURL(url) - wsdl = WSDL() - wsdl.location = url - wsdl.load(document) - return wsdl - - def loadFromString(self, data): - """Return a WSDL instance loaded from an xml string.""" - return self.loadFromStream(StringIO(data)) - - def loadFromFile(self, filename): - """Return a WSDL instance loaded from the given file.""" - file = open(filename, 'rb') - try: - wsdl = self.loadFromStream(file) - finally: - file.close() - return wsdl - -class WSDL: - """A WSDL object models a WSDL service description. WSDL objects - may be created manually or loaded from an xml representation - using a WSDLReader instance.""" - - def __init__(self, targetNamespace=None, strict=1): - self.targetNamespace = targetNamespace or 'urn:this-document.wsdl' - self.documentation = '' - self.location = None - self.document = None - self.name = None - self.services = CollectionNS(self) - self.messages = CollectionNS(self) - self.portTypes = CollectionNS(self) - self.bindings = CollectionNS(self) - #self.imports = Collection(self) - self.types = Types(self) - self.extensions = [] - self.strict = strict - - def __del__(self): - if self.document is not None: - self.document.unlink() - - version = '1.1' - - def addService(self, name, documentation='', targetNamespace=None): - if self.services.has_key(name): - raise WSDLError( - 'Duplicate service element: %s' % name - ) - item = Service(name, documentation) - if targetNamespace: - item.targetNamespace = targetNamespace - self.services[name] = item - return item - - def addMessage(self, name, documentation='', targetNamespace=None): - if self.messages.has_key(name): - raise WSDLError( - 'Duplicate message element: %s.' % name - ) - item = Message(name, documentation) - if targetNamespace: - item.targetNamespace = targetNamespace - self.messages[name] = item - return item - - def addPortType(self, name, documentation='', targetNamespace=None): - if self.portTypes.has_key(name): - raise WSDLError( - 'Duplicate portType element: name' - ) - item = PortType(name, documentation) - if targetNamespace: - item.targetNamespace = targetNamespace - self.portTypes[name] = item - return item - - def addBinding(self, name, type, documentation='', targetNamespace=None): - if self.bindings.has_key(name): - raise WSDLError( - 'Duplicate binding element: %s' % name - ) - item = Binding(name, type, documentation) - if targetNamespace: - item.targetNamespace = targetNamespace - self.bindings[name] = item - return item - - #def addImport(self, namespace, location): - # item = ImportElement(namespace, location) - # self.imports[namespace] = item - # return item - - def load(self, document): - # We save a reference to the DOM document to ensure that elements - # saved as "extensions" will continue to have a meaningful context - # for things like namespace references. The lifetime of the DOM - # document is bound to the lifetime of the WSDL instance. - self.document = document - - definitions = DOM.getElement(document, 'definitions', None, None) - if definitions is None: - raise WSDLError( - 'Missing element.' - ) - self.version = DOM.WSDLUriToVersion(definitions.namespaceURI) - NS_WSDL = DOM.GetWSDLUri(self.version) - - self.targetNamespace = DOM.getAttr(definitions, 'targetNamespace', - None, None) - self.name = DOM.getAttr(definitions, 'name', None, None) - self.documentation = GetDocumentation(definitions) - - # Resolve (recursively) any import elements in the document. - imported = {} - base_location = self.location - while 1: - #XXX - imports = [] - for element in DOM.getElements(definitions, 'import', NS_WSDL): - location = DOM.getAttr(element, 'location') - # Resolve relative location, and save - location = urllib.basejoin(base_location, location) - - if not imported.has_key(location): - imports.append(element) - - if not imports: - break - for element in imports: - location = DOM.getAttr(element, 'location') - self._import(document, element, base_location) - location = urllib.basejoin(base_location, location) - imported[location] = 1 - base_location = '' - - #reader = SchemaReader(base_url=self.location) - for element in DOM.getElements(definitions, None, None): - targetNamespace = DOM.getAttr(element, 'targetNamespace') - localName = element.localName - - if not DOM.nsUriMatch(element.namespaceURI, NS_WSDL): - if localName == 'schema': - reader = SchemaReader(base_url=self.location) - schema = reader.loadFromNode(WSDLToolsAdapter(self), element) - schema.setBaseUrl(self.location) - self.types.addSchema(schema) - else: - self.extensions.append(element) - continue - - elif localName == 'message': - name = DOM.getAttr(element, 'name') - docs = GetDocumentation(element) - message = self.addMessage(name, docs, targetNamespace) - parts = DOM.getElements(element, 'part', NS_WSDL) - message.load(parts) - continue - - elif localName == 'portType': - name = DOM.getAttr(element, 'name') - docs = GetDocumentation(element) - ptype = self.addPortType(name, docs, targetNamespace) - #operations = DOM.getElements(element, 'operation', NS_WSDL) - #ptype.load(operations) - ptype.load(element) - continue - - elif localName == 'binding': - name = DOM.getAttr(element, 'name') - type = DOM.getAttr(element, 'type', default=None) - if type is None: - raise WSDLError( - 'Missing type attribute for binding %s.' % name - ) - type = ParseQName(type, element) - docs = GetDocumentation(element) - binding = self.addBinding(name, type, docs, targetNamespace) - operations = DOM.getElements(element, 'operation', NS_WSDL) - binding.load(operations) - binding.load_ex(GetExtensions(element)) - continue - - elif localName == 'service': - name = DOM.getAttr(element, 'name') - docs = GetDocumentation(element) - service = self.addService(name, docs, targetNamespace) - ports = DOM.getElements(element, 'port', NS_WSDL) - service.load(ports) - service.load_ex(GetExtensions(element)) - continue - - elif localName == 'types': - self.types.documentation = GetDocumentation(element) - base_location = DOM.getAttr(element, 'base-location') - if base_location: - element.removeAttribute('base-location') - base_location = base_location or self.location - reader = SchemaReader(base_url=base_location) - for item in DOM.getElements(element, None, None): - if item.localName == 'schema': - schema = reader.loadFromNode(WSDLToolsAdapter(self), item) - # XXX could have been imported - #schema.setBaseUrl(self.location) - schema.setBaseUrl(base_location) - self.types.addSchema(schema) - else: - self.types.addExtension(item) - # XXX remove the attribute - # element.removeAttribute('base-location') - continue - - def _import(self, document, element, base_location=None): - '''Algo take element's children, clone them, - and add them to the main document. Support for relative - locations is a bit complicated. The orig document context - is lost, so we need to store base location in DOM elements - representing , by creating a special temporary - "base-location" attribute, and , by resolving - the relative "location" and storing it as "location". - - document -- document we are loading - element -- DOM Element representing - base_location -- location of document from which this - was gleaned. - ''' - namespace = DOM.getAttr(element, 'namespace', default=None) - location = DOM.getAttr(element, 'location', default=None) - if namespace is None or location is None: - raise WSDLError( - 'Invalid import element (missing namespace or location).' - ) - if base_location: - location = urllib.basejoin(base_location, location) - element.setAttributeNS(None, 'location', location) - - #location = urllib.basejoin(self.location, location) - #obimport = self.addImport(namespace, location) - #obimport._loaded = 1 - - importdoc = DOM.loadFromURL(location) - try: - if location.find('#') > -1: - idref = location.split('#')[-1] - imported = DOM.getElementById(importdoc, idref) - else: - imported = importdoc.documentElement - if imported is None: - raise WSDLError( - 'Import target element not found for: %s' % location - ) - - imported_tns = DOM.findTargetNS(imported) - if imported_tns != namespace: - return - - if imported.localName == 'definitions': - imported_nodes = imported.childNodes - else: - imported_nodes = [imported] - parent = element.parentNode - for node in imported_nodes: - if node.nodeType != node.ELEMENT_NODE: - continue - child = DOM.importNode(document, node, 1) - parent.appendChild(child) - child.setAttribute('targetNamespace', namespace) - attrsNS = imported._attrsNS - for attrkey in attrsNS.keys(): - if attrkey[0] == DOM.NS_XMLNS: - attr = attrsNS[attrkey].cloneNode(1) - child.setAttributeNode(attr) - - #XXX Quick Hack, should be in WSDL Namespace. - if child.localName == 'import': - rlocation = child.getAttributeNS(None, 'location') - alocation = urllib.basejoin(location, rlocation) - child.setAttribute('location', alocation) - elif child.localName == 'types': - child.setAttribute('base-location', location) - - finally: - importdoc.unlink() - return location - -class Element: - """A class that provides common functions for WSDL element classes.""" - def __init__(self, name=None, documentation=''): - self.name = name - self.documentation = documentation - self.extensions = [] - - def addExtension(self, item): - self.extensions.append(item) - - -class ImportElement(Element): - def __init__(self, namespace, location): - self.namespace = namespace - self.location = location - - _loaded = None - - -class Types(Collection): - default = lambda self,k: k.targetNamespace - def __init__(self, parent): - Collection.__init__(self, parent) - self.documentation = '' - self.extensions = [] - - def addSchema(self, schema): - name = schema.targetNamespace - self[name] = schema - return schema - - def addExtension(self, item): - self.extensions.append(item) - - -class Message(Element): - def __init__(self, name, documentation=''): - Element.__init__(self, name, documentation) - self.parts = Collection(self) - - def addPart(self, name, type=None, element=None): - if self.parts.has_key(name): - raise WSDLError( - 'Duplicate message part element: %s' % name - ) - if type is None and element is None: - raise WSDLError( - 'Missing type or element attribute for part: %s' % name - ) - item = MessagePart(name) - item.element = element - item.type = type - self.parts[name] = item - return item - - def load(self, elements): - for element in elements: - name = DOM.getAttr(element, 'name') - part = MessagePart(name) - self.parts[name] = part - elemref = DOM.getAttr(element, 'element', default=None) - typeref = DOM.getAttr(element, 'type', default=None) - if typeref is None and elemref is None: - raise WSDLError( - 'No type or element attribute for part: %s' % name - ) - if typeref is not None: - part.type = ParseTypeRef(typeref, element) - if elemref is not None: - part.element = ParseTypeRef(elemref, element) - - -class MessagePart(Element): - def __init__(self, name): - Element.__init__(self, name, '') - self.element = None - self.type = None - - def getWSDL(self): - """Return the WSDL object that contains this Message Part.""" - return self.parent().parent().parent().parent() - - def getTypeDefinition(self): - wsdl = self.getWSDL() - nsuri,name = self.type - schema = wsdl.types.get(nsuri, {}) - return schema.get(name) - - def getElementDeclaration(self): - wsdl = self.getWSDL() - nsuri,name = self.element - schema = wsdl.types.get(nsuri, {}) - return schema.get(name) - - -class PortType(Element): - '''PortType has a anyAttribute, thus must provide for an extensible - mechanism for supporting such attributes. ResourceProperties is - specified in WS-ResourceProperties. wsa:Action is specified in - WS-Address. - - Instance Data: - name -- name attribute - resourceProperties -- optional. wsr:ResourceProperties attribute, - value is a QName this is Parsed into a (namespaceURI, name) - that represents a Global Element Declaration. - operations - ''' - - def __init__(self, name, documentation=''): - Element.__init__(self, name, documentation) - self.operations = Collection(self) - self.resourceProperties = None - - def getWSDL(self): - return self.parent().parent() - - def getResourceProperties(self): - return self.resourceProperties - - def addOperation(self, name, documentation='', parameterOrder=None): - item = Operation(name, documentation, parameterOrder) - self.operations[name] = item - return item - - def load(self, element): - self.name = DOM.getAttr(element, 'name') - self.documentation = GetDocumentation(element) - - if DOM.hasAttr(element, 'ResourceProperties', WSR.PROPERTIES): - rpref = DOM.getAttr(element, 'ResourceProperties', WSR.PROPERTIES) - self.resourceProperties = ParseQName(rpref, element) - - NS_WSDL = DOM.GetWSDLUri(self.getWSDL().version) - elements = DOM.getElements(element, 'operation', NS_WSDL) - for element in elements: - name = DOM.getAttr(element, 'name') - docs = GetDocumentation(element) - param_order = DOM.getAttr(element, 'parameterOrder', default=None) - if param_order is not None: - param_order = param_order.split(' ') - operation = self.addOperation(name, docs, param_order) - - item = DOM.getElement(element, 'input', None, None) - if item is not None: - name = DOM.getAttr(item, 'name') - docs = GetDocumentation(item) - msgref = DOM.getAttr(item, 'message') - message = ParseQName(msgref, item) - action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None) - operation.setInput(message, name, docs, action) - - item = DOM.getElement(element, 'output', None, None) - if item is not None: - name = DOM.getAttr(item, 'name') - docs = GetDocumentation(item) - msgref = DOM.getAttr(item, 'message') - message = ParseQName(msgref, item) - action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None) - operation.setOutput(message, name, docs, action) - - for item in DOM.getElements(element, 'fault', None): - name = DOM.getAttr(item, 'name') - docs = GetDocumentation(item) - msgref = DOM.getAttr(item, 'message') - message = ParseQName(msgref, item) - action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None) - operation.addFault(message, name, docs, action) - - - -class Operation(Element): - def __init__(self, name, documentation='', parameterOrder=None): - Element.__init__(self, name, documentation) - self.parameterOrder = parameterOrder - self.faults = Collection(self) - self.input = None - self.output = None - - def getPortType(self): - return self.parent().parent() - - def getInputAction(self): - """wsa:Action attribute""" - return GetWSAActionInput(self) - - def getInputMessage(self): - if self.input is None: - return None - wsdl = self.getPortType().getWSDL() - return wsdl.messages[self.input.message] - - def getOutputAction(self): - """wsa:Action attribute""" - return GetWSAActionOutput(self) - - def getOutputMessage(self): - if self.output is None: - return None - wsdl = self.getPortType().getWSDL() - return wsdl.messages[self.output.message] - - def getFaultAction(self, name): - """wsa:Action attribute""" - return GetWSAActionFault(self, name) - - def getFaultMessage(self, name): - wsdl = self.getPortType().getWSDL() - return wsdl.messages[self.faults[name].message] - - def addFault(self, message, name, documentation='', action=None): - if self.faults.has_key(name): - raise WSDLError( - 'Duplicate fault element: %s' % name - ) - item = MessageRole('fault', message, name, documentation, action) - self.faults[name] = item - return item - - def setInput(self, message, name='', documentation='', action=None): - self.input = MessageRole('input', message, name, documentation, action) - return self.input - - def setOutput(self, message, name='', documentation='', action=None): - self.output = MessageRole('output', message, name, documentation, action) - return self.output - - -class MessageRole(Element): - def __init__(self, type, message, name='', documentation='', action=None): - Element.__init__(self, name, documentation) - self.message = message - self.type = type - self.action = action - - -class Binding(Element): - def __init__(self, name, type, documentation=''): - Element.__init__(self, name, documentation) - self.operations = Collection(self) - self.type = type - - def getWSDL(self): - """Return the WSDL object that contains this binding.""" - return self.parent().parent() - - def getPortType(self): - """Return the PortType object associated with this binding.""" - return self.getWSDL().portTypes[self.type] - - def findBinding(self, kind): - for item in self.extensions: - if isinstance(item, kind): - return item - return None - - def findBindings(self, kind): - return [ item for item in self.extensions if isinstance(item, kind) ] - - def addOperationBinding(self, name, documentation=''): - item = OperationBinding(name, documentation) - self.operations[name] = item - return item - - def load(self, elements): - for element in elements: - name = DOM.getAttr(element, 'name') - docs = GetDocumentation(element) - opbinding = self.addOperationBinding(name, docs) - opbinding.load_ex(GetExtensions(element)) - - item = DOM.getElement(element, 'input', None, None) - if item is not None: - mbinding = MessageRoleBinding('input') - mbinding.documentation = GetDocumentation(item) - opbinding.input = mbinding - mbinding.load_ex(GetExtensions(item)) - - item = DOM.getElement(element, 'output', None, None) - if item is not None: - mbinding = MessageRoleBinding('output') - mbinding.documentation = GetDocumentation(item) - opbinding.output = mbinding - mbinding.load_ex(GetExtensions(item)) - - for item in DOM.getElements(element, 'fault', None): - name = DOM.getAttr(item, 'name') - mbinding = MessageRoleBinding('fault', name) - mbinding.documentation = GetDocumentation(item) - opbinding.faults[name] = mbinding - mbinding.load_ex(GetExtensions(item)) - - def load_ex(self, elements): - for e in elements: - ns, name = e.namespaceURI, e.localName - if ns in DOM.NS_SOAP_BINDING_ALL and name == 'binding': - transport = DOM.getAttr(e, 'transport', default=None) - style = DOM.getAttr(e, 'style', default='document') - ob = SoapBinding(transport, style) - self.addExtension(ob) - continue - elif ns in DOM.NS_HTTP_BINDING_ALL and name == 'binding': - verb = DOM.getAttr(e, 'verb') - ob = HttpBinding(verb) - self.addExtension(ob) - continue - else: - self.addExtension(e) - - -class OperationBinding(Element): - def __init__(self, name, documentation=''): - Element.__init__(self, name, documentation) - self.input = None - self.output = None - self.faults = Collection(self) - - def getBinding(self): - """Return the parent Binding object of the operation binding.""" - return self.parent().parent() - - def getOperation(self): - """Return the abstract Operation associated with this binding.""" - return self.getBinding().getPortType().operations[self.name] - - def findBinding(self, kind): - for item in self.extensions: - if isinstance(item, kind): - return item - return None - - def findBindings(self, kind): - return [ item for item in self.extensions if isinstance(item, kind) ] - - def addInputBinding(self, binding): - if self.input is None: - self.input = MessageRoleBinding('input') - self.input.addExtension(binding) - return binding - - def addOutputBinding(self, binding): - if self.output is None: - self.output = MessageRoleBinding('output') - self.output.addExtension(binding) - return binding - - def addFaultBinding(self, name, binding): - fault = self.get(name, None) - if fault is None: - fault = MessageRoleBinding('fault', name) - fault.addExtension(binding) - return binding - - def load_ex(self, elements): - for e in elements: - ns, name = e.namespaceURI, e.localName - if ns in DOM.NS_SOAP_BINDING_ALL and name == 'operation': - soapaction = DOM.getAttr(e, 'soapAction', default=None) - style = DOM.getAttr(e, 'style', default=None) - ob = SoapOperationBinding(soapaction, style) - self.addExtension(ob) - continue - elif ns in DOM.NS_HTTP_BINDING_ALL and name == 'operation': - location = DOM.getAttr(e, 'location') - ob = HttpOperationBinding(location) - self.addExtension(ob) - continue - else: - self.addExtension(e) - - -class MessageRoleBinding(Element): - def __init__(self, type, name='', documentation=''): - Element.__init__(self, name, documentation) - self.type = type - - def findBinding(self, kind): - for item in self.extensions: - if isinstance(item, kind): - return item - return None - - def findBindings(self, kind): - return [ item for item in self.extensions if isinstance(item, kind) ] - - def load_ex(self, elements): - for e in elements: - ns, name = e.namespaceURI, e.localName - if ns in DOM.NS_SOAP_BINDING_ALL and name == 'body': - encstyle = DOM.getAttr(e, 'encodingStyle', default=None) - namespace = DOM.getAttr(e, 'namespace', default=None) - parts = DOM.getAttr(e, 'parts', default=None) - use = DOM.getAttr(e, 'use', default=None) - if use is None: - raise WSDLError( - 'Invalid soap:body binding element.' - ) - ob = SoapBodyBinding(use, namespace, encstyle, parts) - self.addExtension(ob) - continue - - elif ns in DOM.NS_SOAP_BINDING_ALL and name == 'fault': - encstyle = DOM.getAttr(e, 'encodingStyle', default=None) - namespace = DOM.getAttr(e, 'namespace', default=None) - name = DOM.getAttr(e, 'name', default=None) - use = DOM.getAttr(e, 'use', default=None) - if use is None or name is None: - raise WSDLError( - 'Invalid soap:fault binding element.' - ) - ob = SoapFaultBinding(name, use, namespace, encstyle) - self.addExtension(ob) - continue - - elif ns in DOM.NS_SOAP_BINDING_ALL and name in ( - 'header', 'headerfault' - ): - encstyle = DOM.getAttr(e, 'encodingStyle', default=None) - namespace = DOM.getAttr(e, 'namespace', default=None) - message = DOM.getAttr(e, 'message') - part = DOM.getAttr(e, 'part') - use = DOM.getAttr(e, 'use') - if name == 'header': - _class = SoapHeaderBinding - else: - _class = SoapHeaderFaultBinding - message = ParseQName(message, e) - ob = _class(message, part, use, namespace, encstyle) - self.addExtension(ob) - continue - - elif ns in DOM.NS_HTTP_BINDING_ALL and name == 'urlReplacement': - ob = HttpUrlReplacementBinding() - self.addExtension(ob) - continue - - elif ns in DOM.NS_HTTP_BINDING_ALL and name == 'urlEncoded': - ob = HttpUrlEncodedBinding() - self.addExtension(ob) - continue - - elif ns in DOM.NS_MIME_BINDING_ALL and name == 'multipartRelated': - ob = MimeMultipartRelatedBinding() - self.addExtension(ob) - ob.load_ex(GetExtensions(e)) - continue - - elif ns in DOM.NS_MIME_BINDING_ALL and name == 'content': - part = DOM.getAttr(e, 'part', default=None) - type = DOM.getAttr(e, 'type', default=None) - ob = MimeContentBinding(part, type) - self.addExtension(ob) - continue - - elif ns in DOM.NS_MIME_BINDING_ALL and name == 'mimeXml': - part = DOM.getAttr(e, 'part', default=None) - ob = MimeXmlBinding(part) - self.addExtension(ob) - continue - - else: - self.addExtension(e) - - -class Service(Element): - def __init__(self, name, documentation=''): - Element.__init__(self, name, documentation) - self.ports = Collection(self) - - def getWSDL(self): - return self.parent().parent() - - def addPort(self, name, binding, documentation=''): - item = Port(name, binding, documentation) - self.ports[name] = item - return item - - def load(self, elements): - for element in elements: - name = DOM.getAttr(element, 'name', default=None) - docs = GetDocumentation(element) - binding = DOM.getAttr(element, 'binding', default=None) - if name is None or binding is None: - raise WSDLError( - 'Invalid port element.' - ) - binding = ParseQName(binding, element) - port = self.addPort(name, binding, docs) - port.load_ex(GetExtensions(element)) - - def load_ex(self, elements): - for e in elements: - self.addExtension(e) - - -class Port(Element): - def __init__(self, name, binding, documentation=''): - Element.__init__(self, name, documentation) - self.binding = binding - - def getService(self): - """Return the Service object associated with this port.""" - return self.parent().parent() - - def getBinding(self): - """Return the Binding object that is referenced by this port.""" - wsdl = self.getService().getWSDL() - return wsdl.bindings[self.binding] - - def getPortType(self): - """Return the PortType object that is referenced by this port.""" - wsdl = self.getService().getWSDL() - binding = wsdl.bindings[self.binding] - return wsdl.portTypes[binding.type] - - def getAddressBinding(self): - """A convenience method to obtain the extension element used - as the address binding for the port, or None if undefined.""" - for item in self.extensions: - if isinstance(item, SoapAddressBinding) or \ - isinstance(item, HttpAddressBinding): - return item - raise WSDLError( - 'No address binding found in port.' - ) - - def load_ex(self, elements): - for e in elements: - ns, name = e.namespaceURI, e.localName - if ns in DOM.NS_SOAP_BINDING_ALL and name == 'address': - location = DOM.getAttr(e, 'location', default=None) - ob = SoapAddressBinding(location) - self.addExtension(ob) - continue - elif ns in DOM.NS_HTTP_BINDING_ALL and name == 'address': - location = DOM.getAttr(e, 'location', default=None) - ob = HttpAddressBinding(location) - self.addExtension(ob) - continue - else: - self.addExtension(e) - - -class SoapBinding: - def __init__(self, transport, style='rpc'): - self.transport = transport - self.style = style - - -class SoapAddressBinding: - def __init__(self, location): - self.location = location - - -class SoapOperationBinding: - def __init__(self, soapAction=None, style=None): - self.soapAction = soapAction - self.style = style - - -class SoapBodyBinding: - def __init__(self, use, namespace=None, encodingStyle=None, parts=None): - if not use in ('literal', 'encoded'): - raise WSDLError( - 'Invalid use attribute value: %s' % use - ) - self.encodingStyle = encodingStyle - self.namespace = namespace - if type(parts) in (type(''), type(u'')): - parts = parts.split() - self.parts = parts - self.use = use - -class SoapFaultBinding: - def __init__(self, name, use, namespace=None, encodingStyle=None): - if not use in ('literal', 'encoded'): - raise WSDLError( - 'Invalid use attribute value: %s' % use - ) - self.encodingStyle = encodingStyle - self.namespace = namespace - self.name = name - self.use = use - - -class SoapHeaderBinding: - def __init__(self, message, part, use, namespace=None, encodingStyle=None): - if not use in ('literal', 'encoded'): - raise WSDLError( - 'Invalid use attribute value: %s' % use - ) - self.encodingStyle = encodingStyle - self.namespace = namespace - self.message = message - self.part = part - self.use = use - - tagname = 'header' - -class SoapHeaderFaultBinding(SoapHeaderBinding): - tagname = 'headerfault' - - -class HttpBinding: - def __init__(self, verb): - self.verb = verb - -class HttpAddressBinding: - def __init__(self, location): - self.location = location - - -class HttpOperationBinding: - def __init__(self, location): - self.location = location - -class HttpUrlReplacementBinding: - pass - - -class HttpUrlEncodedBinding: - pass - - -class MimeContentBinding: - def __init__(self, part=None, type=None): - self.part = part - self.type = type - - -class MimeXmlBinding: - def __init__(self, part=None): - self.part = part - - -class MimeMultipartRelatedBinding: - def __init__(self): - self.parts = [] - - def load_ex(self, elements): - for e in elements: - ns, name = e.namespaceURI, e.localName - if ns in DOM.NS_MIME_BINDING_ALL and name == 'part': - self.parts.append(MimePartBinding()) - continue - - -class MimePartBinding: - def __init__(self): - self.items = [] - - def load_ex(self, elements): - for e in elements: - ns, name = e.namespaceURI, e.localName - if ns in DOM.NS_MIME_BINDING_ALL and name == 'content': - part = DOM.getAttr(e, 'part', default=None) - type = DOM.getAttr(e, 'type', default=None) - ob = MimeContentBinding(part, type) - self.items.append(ob) - continue - - elif ns in DOM.NS_MIME_BINDING_ALL and name == 'mimeXml': - part = DOM.getAttr(e, 'part', default=None) - ob = MimeXmlBinding(part) - self.items.append(ob) - continue - - elif ns in DOM.NS_SOAP_BINDING_ALL and name == 'body': - encstyle = DOM.getAttr(e, 'encodingStyle', default=None) - namespace = DOM.getAttr(e, 'namespace', default=None) - parts = DOM.getAttr(e, 'parts', default=None) - use = DOM.getAttr(e, 'use', default=None) - if use is None: - raise WSDLError( - 'Invalid soap:body binding element.' - ) - ob = SoapBodyBinding(use, namespace, encstyle, parts) - self.items.append(ob) - continue - - -class WSDLError(Exception): - pass - - - -def DeclareNSPrefix(writer, prefix, nsuri): - if writer.hasNSPrefix(nsuri): - return - writer.declareNSPrefix(prefix, nsuri) - -def ParseTypeRef(value, element): - parts = value.split(':', 1) - if len(parts) == 1: - return (DOM.findTargetNS(element), value) - nsuri = DOM.findNamespaceURI(parts[0], element) - return (nsuri, parts[1]) - -def ParseQName(value, element): - nameref = value.split(':', 1) - if len(nameref) == 2: - nsuri = DOM.findNamespaceURI(nameref[0], element) - name = nameref[-1] - else: - nsuri = DOM.findTargetNS(element) - name = nameref[-1] - return nsuri, name - -def GetDocumentation(element): - docnode = DOM.getElement(element, 'documentation', None, None) - if docnode is not None: - return DOM.getElementText(docnode) - return '' - -def GetExtensions(element): - return [ item for item in DOM.getElements(element, None, None) - if item.namespaceURI != DOM.NS_WSDL ] - -def GetWSAActionFault(operation, name): - """Find wsa:Action attribute, and return value or WSA.FAULT - for the default. - """ - attr = operation.faults[name].action - if attr is not None: - return attr - return WSA.FAULT - -def GetWSAActionInput(operation): - """Find wsa:Action attribute, and return value or the default.""" - attr = operation.input.action - if attr is not None: - return attr - portType = operation.getPortType() - targetNamespace = portType.getWSDL().targetNamespace - ptName = portType.name - msgName = operation.input.name - if not msgName: - msgName = operation.name + 'Request' - if targetNamespace.endswith('/'): - return '%s%s/%s' %(targetNamespace, ptName, msgName) - return '%s/%s/%s' %(targetNamespace, ptName, msgName) - -def GetWSAActionOutput(operation): - """Find wsa:Action attribute, and return value or the default.""" - attr = operation.output.action - if attr is not None: - return attr - targetNamespace = operation.getPortType().getWSDL().targetNamespace - ptName = operation.getPortType().name - msgName = operation.output.name - if not msgName: - msgName = operation.name + 'Response' - if targetNamespace.endswith('/'): - return '%s%s/%s' %(targetNamespace, ptName, msgName) - return '%s/%s/%s' %(targetNamespace, ptName, msgName) - -def FindExtensions(object, kind, t_type=type(())): - if isinstance(kind, t_type): - result = [] - namespaceURI, name = kind - return [ item for item in object.extensions - if hasattr(item, 'nodeType') \ - and DOM.nsUriMatch(namespaceURI, item.namespaceURI) \ - and item.name == name ] - return [ item for item in object.extensions if isinstance(item, kind) ] - -def FindExtension(object, kind, t_type=type(())): - if isinstance(kind, t_type): - namespaceURI, name = kind - for item in object.extensions: - if hasattr(item, 'nodeType') \ - and DOM.nsUriMatch(namespaceURI, item.namespaceURI) \ - and item.name == name: - return item - else: - for item in object.extensions: - if isinstance(item, kind): - return item - return None - - -class SOAPCallInfo: - """SOAPCallInfo captures the important binding information about a - SOAP operation, in a structure that is easier to work with than - raw WSDL structures.""" - - def __init__(self, methodName): - self.methodName = methodName - self.inheaders = [] - self.outheaders = [] - self.inparams = [] - self.outparams = [] - self.retval = None - - encodingStyle = DOM.NS_SOAP_ENC - documentation = '' - soapAction = None - transport = None - namespace = None - location = None - use = 'encoded' - style = 'rpc' - - def addInParameter(self, name, type, namespace=None, element_type=0): - """Add an input parameter description to the call info.""" - parameter = ParameterInfo(name, type, namespace, element_type) - self.inparams.append(parameter) - return parameter - - def addOutParameter(self, name, type, namespace=None, element_type=0): - """Add an output parameter description to the call info.""" - parameter = ParameterInfo(name, type, namespace, element_type) - self.outparams.append(parameter) - return parameter - - def setReturnParameter(self, name, type, namespace=None, element_type=0): - """Set the return parameter description for the call info.""" - parameter = ParameterInfo(name, type, namespace, element_type) - self.retval = parameter - return parameter - - def addInHeaderInfo(self, name, type, namespace, element_type=0, - mustUnderstand=0): - """Add an input SOAP header description to the call info.""" - headerinfo = HeaderInfo(name, type, namespace, element_type) - if mustUnderstand: - headerinfo.mustUnderstand = 1 - self.inheaders.append(headerinfo) - return headerinfo - - def addOutHeaderInfo(self, name, type, namespace, element_type=0, - mustUnderstand=0): - """Add an output SOAP header description to the call info.""" - headerinfo = HeaderInfo(name, type, namespace, element_type) - if mustUnderstand: - headerinfo.mustUnderstand = 1 - self.outheaders.append(headerinfo) - return headerinfo - - def getInParameters(self): - """Return a sequence of the in parameters of the method.""" - return self.inparams - - def getOutParameters(self): - """Return a sequence of the out parameters of the method.""" - return self.outparams - - def getReturnParameter(self): - """Return param info about the return value of the method.""" - return self.retval - - def getInHeaders(self): - """Return a sequence of the in headers of the method.""" - return self.inheaders - - def getOutHeaders(self): - """Return a sequence of the out headers of the method.""" - return self.outheaders - - -class ParameterInfo: - """A ParameterInfo object captures parameter binding information.""" - def __init__(self, name, type, namespace=None, element_type=0): - if element_type: - self.element_type = 1 - if namespace is not None: - self.namespace = namespace - self.name = name - self.type = type - - element_type = 0 - namespace = None - default = None - - -class HeaderInfo(ParameterInfo): - """A HeaderInfo object captures SOAP header binding information.""" - def __init__(self, name, type, namespace, element_type=None): - ParameterInfo.__init__(self, name, type, namespace, element_type) - - mustUnderstand = 0 - actor = None - - -def callInfoFromWSDL(port, name): - """Return a SOAPCallInfo given a WSDL port and operation name.""" - wsdl = port.getService().getWSDL() - binding = port.getBinding() - portType = binding.getPortType() - operation = portType.operations[name] - opbinding = binding.operations[name] - messages = wsdl.messages - callinfo = SOAPCallInfo(name) - - addrbinding = port.getAddressBinding() - if not isinstance(addrbinding, SoapAddressBinding): - raise ValueError, 'Unsupported binding type.' - callinfo.location = addrbinding.location - - soapbinding = binding.findBinding(SoapBinding) - if soapbinding is None: - raise ValueError, 'Missing soap:binding element.' - callinfo.transport = soapbinding.transport - callinfo.style = soapbinding.style or 'document' - - soap_op_binding = opbinding.findBinding(SoapOperationBinding) - if soap_op_binding is not None: - callinfo.soapAction = soap_op_binding.soapAction - callinfo.style = soap_op_binding.style or callinfo.style - - parameterOrder = operation.parameterOrder - - if operation.input is not None: - message = messages[operation.input.message] - msgrole = opbinding.input - - mime = msgrole.findBinding(MimeMultipartRelatedBinding) - if mime is not None: - raise ValueError, 'Mime bindings are not supported.' - else: - for item in msgrole.findBindings(SoapHeaderBinding): - part = messages[item.message].parts[item.part] - header = callinfo.addInHeaderInfo( - part.name, - part.element or part.type, - item.namespace, - element_type = part.element and 1 or 0 - ) - header.encodingStyle = item.encodingStyle - - body = msgrole.findBinding(SoapBodyBinding) - if body is None: - raise ValueError, 'Missing soap:body binding.' - callinfo.encodingStyle = body.encodingStyle - callinfo.namespace = body.namespace - callinfo.use = body.use - - if body.parts is not None: - parts = [] - for name in body.parts: - parts.append(message.parts[name]) - else: - parts = message.parts.values() - - for part in parts: - callinfo.addInParameter( - part.name, - part.element or part.type, - element_type = part.element and 1 or 0 - ) - - if operation.output is not None: - try: - message = messages[operation.output.message] - except KeyError: - if self.strict: - raise RuntimeError( - "Recieved message not defined in the WSDL schema: %s" % - operation.output.message) - else: - message = wsdl.addMessage(operation.output.message) - print "Warning:", \ - "Recieved message not defined in the WSDL schema.", \ - "Adding it." - print "Message:", operation.output.message - - msgrole = opbinding.output - - mime = msgrole.findBinding(MimeMultipartRelatedBinding) - if mime is not None: - raise ValueError, 'Mime bindings are not supported.' - else: - for item in msgrole.findBindings(SoapHeaderBinding): - part = messages[item.message].parts[item.part] - header = callinfo.addOutHeaderInfo( - part.name, - part.element or part.type, - item.namespace, - element_type = part.element and 1 or 0 - ) - header.encodingStyle = item.encodingStyle - - body = msgrole.findBinding(SoapBodyBinding) - if body is None: - raise ValueError, 'Missing soap:body binding.' - callinfo.encodingStyle = body.encodingStyle - callinfo.namespace = body.namespace - callinfo.use = body.use - - if body.parts is not None: - parts = [] - for name in body.parts: - parts.append(message.parts[name]) - else: - parts = message.parts.values() - - if parts: - # XXX no idea what this is for, but it breaks everything. jrb - #callinfo.setReturnParameter( - # parts[0].name, - # parts[0].element or parts[0].type, - # element_type = parts[0].element and 1 or 0 - # ) - #for part in parts[1:]: - for part in parts: - callinfo.addOutParameter( - part.name, - part.element or part.type, - element_type = part.element and 1 or 0 - ) - - return callinfo diff --git a/SOAPpy/wstools/XMLSchema.py b/SOAPpy/wstools/XMLSchema.py deleted file mode 100755 index aaaaffc..0000000 --- a/SOAPpy/wstools/XMLSchema.py +++ /dev/null @@ -1,2976 +0,0 @@ -# Copyright (c) 2003, The Regents of the University of California, -# through Lawrence Berkeley National Laboratory (subject to receipt of -# any required approvals from the U.S. Dept. of Energy). All rights -# reserved. -# -# 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: XMLSchema.py,v 1.38 2004/06/23 20:10:26 boverhof Exp $" - -import types, weakref, urllib, sys -from threading import RLock -from Namespaces import XMLNS -from Utility import DOM, DOMException, Collection, SplitQName -from StringIO import StringIO - -def GetSchema(component): - """convience function for finding the parent XMLSchema instance. - """ - parent = component - while not isinstance(parent, XMLSchema): - parent = parent._parent() - return parent - -class SchemaReader: - """A SchemaReader creates XMLSchema objects from urls and xml data. - """ - def __init__(self, domReader=None, base_url=None): - """domReader -- class must implement DOMAdapterInterface - base_url -- base url string - """ - self.__base_url = base_url - self.__readerClass = domReader - if not self.__readerClass: - self.__readerClass = DOMAdapter - self._includes = {} - self._imports = {} - - def __setImports(self, schema): - """Add dictionary of imports to schema instance. - schema -- XMLSchema instance - """ - for ns,val in schema.imports.items(): - if self._imports.has_key(ns): - schema.addImportSchema(self._imports[ns]) - - def __setIncludes(self, schema): - """Add dictionary of includes to schema instance. - schema -- XMLSchema instance - """ - for schemaLocation, val in schema.includes.items(): - if self._includes.has_key(schemaLocation): - schema.addIncludeSchema(self._imports[schemaLocation]) - - def addSchemaByLocation(self, location, schema): - """provide reader with schema document for a location. - """ - self._includes[location] = schema - - def addSchemaByNamespace(self, schema): - """provide reader with schema document for a targetNamespace. - """ - self._imports[schema.targetNamespace] = schema - - def loadFromNode(self, parent, element): - """element -- DOM node or document - parent -- WSDLAdapter instance - """ - reader = self.__readerClass(element) - schema = XMLSchema(parent) - #HACK to keep a reference - schema.wsdl = parent - schema.setBaseUrl(self.__base_url) - schema.load(reader) - return schema - - def loadFromStream(self, file): - """Return an XMLSchema instance loaded from a file object. - file -- file object - """ - reader = self.__readerClass() - reader.loadDocument(file) - schema = XMLSchema() - schema.setBaseUrl(self.__base_url) - schema.load(reader) - self.__setIncludes(schema) - self.__setImports(schema) - return schema - - def loadFromString(self, data): - """Return an XMLSchema instance loaded from an XML string. - data -- XML string - """ - return self.loadFromStream(StringIO(data)) - - def loadFromURL(self, url): - """Return an XMLSchema instance loaded from the given url. - url -- URL to dereference - """ - if not url.endswith('xsd'): - raise SchemaError, 'unknown file type %s' %url - reader = self.__readerClass() - if self.__base_url: - url = urllib.basejoin(self.__base_url,url) - reader.loadFromURL(url) - schema = XMLSchema() - schema.setBaseUrl(self.__base_url) - schema.load(reader) - self.__setIncludes(schema) - self.__setImports(schema) - return schema - - def loadFromFile(self, filename): - """Return an XMLSchema instance loaded from the given file. - filename -- name of file to open - """ - file = open(filename, 'rb') - try: schema = self.loadFromStream(file) - finally: file.close() - return schema - - -class SchemaError(Exception): - pass - -########################### -# DOM Utility Adapters -########################## -class DOMAdapterInterface: - def hasattr(self, attr, ns=None): - """return true if node has attribute - attr -- attribute to check for - ns -- namespace of attribute, by default None - """ - raise NotImplementedError, 'adapter method not implemented' - - def getContentList(self, *contents): - """returns an ordered list of child nodes - *contents -- list of node names to return - """ - raise NotImplementedError, 'adapter method not implemented' - - def setAttributeDictionary(self, attributes): - """set attribute dictionary - """ - raise NotImplementedError, 'adapter method not implemented' - - def getAttributeDictionary(self): - """returns a dict of node's attributes - """ - raise NotImplementedError, 'adapter method not implemented' - - def getNamespace(self, prefix): - """returns namespace referenced by prefix. - """ - raise NotImplementedError, 'adapter method not implemented' - - def getTagName(self): - """returns tagName of node - """ - raise NotImplementedError, 'adapter method not implemented' - - - def getParentNode(self): - """returns parent element in DOMAdapter or None - """ - raise NotImplementedError, 'adapter method not implemented' - - def loadDocument(self, file): - """load a Document from a file object - file -- - """ - raise NotImplementedError, 'adapter method not implemented' - - def loadFromURL(self, url): - """load a Document from an url - url -- URL to dereference - """ - raise NotImplementedError, 'adapter method not implemented' - - -class DOMAdapter(DOMAdapterInterface): - """Adapter for ZSI.Utility.DOM - """ - def __init__(self, node=None): - """Reset all instance variables. - element -- DOM document, node, or None - """ - if hasattr(node, 'documentElement'): - self.__node = node.documentElement - else: - self.__node = node - self.__attributes = None - - def hasattr(self, attr, ns=None): - """attr -- attribute - ns -- optional namespace, None means unprefixed attribute. - """ - if not self.__attributes: - self.setAttributeDictionary() - if ns: - return self.__attributes.get(ns,{}).has_key(attr) - return self.__attributes.has_key(attr) - - def getContentList(self, *contents): - nodes = [] - ELEMENT_NODE = self.__node.ELEMENT_NODE - for child in DOM.getElements(self.__node, None): - if child.nodeType == ELEMENT_NODE and\ - SplitQName(child.tagName)[1] in contents: - nodes.append(child) - return map(self.__class__, nodes) - - def setAttributeDictionary(self): - self.__attributes = {} - for v in self.__node._attrs.values(): - self.__attributes[v.nodeName] = v.nodeValue - - def getAttributeDictionary(self): - if not self.__attributes: - self.setAttributeDictionary() - return self.__attributes - - def getTagName(self): - return self.__node.tagName - - def getParentNode(self): - if self.__node.parentNode.nodeType == self.__node.ELEMENT_NODE: - return DOMAdapter(self.__node.parentNode) - return None - - def getNamespace(self, prefix): - """prefix -- deference namespace prefix in node's context. - Ascends parent nodes until found. - """ - namespace = None - if prefix == 'xmlns': - namespace = DOM.findDefaultNS(prefix, self.__node) - else: - try: - namespace = DOM.findNamespaceURI(prefix, self.__node) - except DOMException, ex: - if prefix != 'xml': - raise SchemaError, '%s namespace not declared for %s'\ - %(prefix, self.__node._get_tagName()) - namespace = XMLNS.XML - return namespace - - def loadDocument(self, file): - self.__node = DOM.loadDocument(file) - if hasattr(self.__node, 'documentElement'): - self.__node = self.__node.documentElement - - def loadFromURL(self, url): - self.__node = DOM.loadFromURL(url) - if hasattr(self.__node, 'documentElement'): - self.__node = self.__node.documentElement - - -class XMLBase: - """ These class variables are for string indentation. - """ - __indent = 0 - __rlock = RLock() - - def __str__(self): - XMLBase.__rlock.acquire() - XMLBase.__indent += 1 - tmp = "<" + str(self.__class__) + '>\n' - for k,v in self.__dict__.items(): - tmp += "%s* %s = %s\n" %(XMLBase.__indent*' ', k, v) - XMLBase.__indent -= 1 - XMLBase.__rlock.release() - return tmp - - -"""Marker Interface: can determine something about an instances properties by using - the provided convenience functions. - -""" -class DefinitionMarker: - """marker for definitions - """ - pass - -class DeclarationMarker: - """marker for declarations - """ - pass - -class AttributeMarker: - """marker for attributes - """ - pass - -class AttributeGroupMarker: - """marker for attribute groups - """ - pass - -class WildCardMarker: - """marker for wildcards - """ - pass - -class ElementMarker: - """marker for wildcards - """ - pass - -class ReferenceMarker: - """marker for references - """ - pass - -class ModelGroupMarker: - """marker for model groups - """ - pass - -class ExtensionMarker: - """marker for extensions - """ - pass - -class RestrictionMarker: - """marker for restrictions - """ - facets = ['enumeration', 'length', 'maxExclusive', 'maxInclusive',\ - 'maxLength', 'minExclusive', 'minInclusive', 'minLength',\ - 'pattern', 'fractionDigits', 'totalDigits', 'whiteSpace'] - -class SimpleMarker: - """marker for simple type information - """ - pass - -class ComplexMarker: - """marker for complex type information - """ - pass - -class LocalMarker: - """marker for complex type information - """ - pass - - -class MarkerInterface: - def isDefinition(self): - return isinstance(self, DefinitionMarker) - - def isDeclaration(self): - return isinstance(self, DeclarationMarker) - - def isAttribute(self): - return isinstance(self, AttributeMarker) - - def isAttributeGroup(self): - return isinstance(self, AttributeGroupMarker) - - def isElement(self): - return isinstance(self, ElementMarker) - - def isReference(self): - return isinstance(self, ReferenceMarker) - - def isWildCard(self): - return isinstance(self, WildCardMarker) - - def isModelGroup(self): - return isinstance(self, ModelGroupMarker) - - def isExtension(self): - return isinstance(self, ExtensionMarker) - - def isRestriction(self): - return isinstance(self, RestrictionMarker) - - def isSimple(self): - return isinstance(self, SimpleMarker) - - def isComplex(self): - return isinstance(self, ComplexMarker) - - def isLocal(self): - return isinstance(self, LocalMarker) - - -########################################################## -# Schema Components -######################################################### -class XMLSchemaComponent(XMLBase, MarkerInterface): - """ - class variables: - required -- list of required attributes - attributes -- dict of default attribute values, including None. - Value can be a function for runtime dependencies. - contents -- dict of namespace keyed content lists. - 'xsd' content of xsd namespace. - xmlns_key -- key for declared xmlns namespace. - xmlns -- xmlns is special prefix for namespace dictionary - xml -- special xml prefix for xml namespace. - """ - required = [] - attributes = {} - contents = {} - xmlns_key = '' - xmlns = 'xmlns' - xml = 'xml' - - def __init__(self, parent=None): - """parent -- parent instance - instance variables: - attributes -- dictionary of node's attributes - """ - self.attributes = None - self._parent = parent - if self._parent: - self._parent = weakref.ref(parent) - - if not self.__class__ == XMLSchemaComponent\ - and not (type(self.__class__.required) == type(XMLSchemaComponent.required)\ - and type(self.__class__.attributes) == type(XMLSchemaComponent.attributes)\ - and type(self.__class__.contents) == type(XMLSchemaComponent.contents)): - raise RuntimeError, 'Bad type for a class variable in %s' %self.__class__ - - def getTargetNamespace(self): - """return targetNamespace - """ - parent = self - targetNamespace = 'targetNamespace' - tns = self.attributes.get(targetNamespace) - while not tns: - parent = parent._parent() - tns = parent.attributes.get(targetNamespace) - return tns - - def getTypeDefinition(self, attribute): - """attribute -- attribute with a QName value (eg. type). - collection -- check types collection in parent Schema instance - """ - return self.getQNameAttribute('types', attribute) - - def getElementDeclaration(self, attribute): - """attribute -- attribute with a QName value (eg. element). - collection -- check elements collection in parent Schema instance. - """ - return self.getQNameAttribute('elements', attribute) - - def getQNameAttribute(self, collection, attribute): - """returns object instance representing QName --> (namespace,name), - or if does not exist return None. - attribute -- an information item attribute, with a QName value. - collection -- collection in parent Schema instance to search. - """ - obj = None - tdc = self.attributes.get(attribute) - if tdc: - parent = GetSchema(self) - targetNamespace = tdc.getTargetNamespace() - if parent.targetNamespace == targetNamespace: - item = tdc.getName() - try: - obj = getattr(parent, collection)[item] - except KeyError, ex: - raise KeyError, "targetNamespace(%s) collection(%s) has no item(%s)"\ - %(targetNamespace, collection, item) - elif parent.imports.has_key(targetNamespace): - schema = parent.imports[targetNamespace].getSchema() - item = tdc.getName() - try: - obj = getattr(schema, collection)[item] - except KeyError, ex: - raise KeyError, "targetNamespace(%s) collection(%s) has no item(%s)"\ - %(targetNamespace, collection, item) - return obj - - def getXMLNS(self, prefix=None): - """deference prefix or by default xmlns, returns namespace. - """ - if prefix == XMLSchemaComponent.xml: - return XMLNS.XML - parent = self - ns = self.attributes[XMLSchemaComponent.xmlns].get(prefix or\ - XMLSchemaComponent.xmlns_key) - while not ns: - parent = parent._parent() - ns = parent.attributes[XMLSchemaComponent.xmlns].get(prefix or\ - XMLSchemaComponent.xmlns_key) - if not ns and isinstance(parent, WSDLToolsAdapter): - raise SchemaError, 'unknown prefix %s' %prefix - return ns - - def getAttribute(self, attribute): - """return requested attribute or None - """ - return self.attributes.get(attribute) - - def setAttributes(self, node): - """Sets up attribute dictionary, checks for required attributes and - sets default attribute values. attr is for default attribute values - determined at runtime. - - structure of attributes dictionary - ['xmlns'][xmlns_key] -- xmlns namespace - ['xmlns'][prefix] -- declared namespace prefix - [namespace][prefix] -- attributes declared in a namespace - [attribute] -- attributes w/o prefix, default namespaces do - not directly apply to attributes, ie Name can't collide - with QName. - """ - self.attributes = {XMLSchemaComponent.xmlns:{}} - for k,v in node.getAttributeDictionary().items(): - prefix,value = SplitQName(k) - if value == XMLSchemaComponent.xmlns: - self.attributes[value][prefix or XMLSchemaComponent.xmlns_key] = v - elif prefix: - ns = node.getNamespace(prefix) - if not ns: - raise SchemaError, 'no namespace for attribute prefix %s'\ - %prefix - if not self.attributes.has_key(ns): - self.attributes[ns] = {} - elif self.attributes[ns].has_key(value): - raise SchemaError, 'attribute %s declared multiple times in %s'\ - %(value, ns) - self.attributes[ns][value] = v - elif not self.attributes.has_key(value): - self.attributes[value] = v - else: - raise SchemaError, 'attribute %s declared multiple times' %value - - self.__checkAttributes() - self.__setAttributeDefaults() - - #set QNames - for k in ['type', 'element', 'base', 'ref', 'substitutionGroup', 'itemType']: - if self.attributes.has_key(k): - prefix, value = SplitQName(self.attributes.get(k)) - self.attributes[k] = \ - TypeDescriptionComponent((self.getXMLNS(prefix), value)) - - #Union, memberTypes is a whitespace separated list of QNames - for k in ['memberTypes']: - if self.attributes.has_key(k): - qnames = self.attributes[k] - self.attributes[k] = [] - for qname in qnames.split(): - prefix, value = SplitQName(qname) - self.attributes['memberTypes'].append(\ - TypeDescriptionComponent(\ - (self.getXMLNS(prefix), value))) - - def getContents(self, node): - """retrieve xsd contents - """ - return node.getContentList(*self.__class__.contents['xsd']) - - def __setAttributeDefaults(self): - """Looks for default values for unset attributes. If - class variable representing attribute is None, then - it must be defined as an instance variable. - """ - for k,v in self.__class__.attributes.items(): - if v and not self.attributes.has_key(k): - if isinstance(v, types.FunctionType): - self.attributes[k] = v(self) - else: - self.attributes[k] = v - - def __checkAttributes(self): - """Checks that required attributes have been defined, - attributes w/default cannot be required. Checks - all defined attributes are legal, attribute - references are not subject to this test. - """ - for a in self.__class__.required: - if not self.attributes.has_key(a): - raise SchemaError,\ - 'class instance %s, missing required attribute %s'\ - %(self.__class__, a) - for a in self.attributes.keys(): - if (a not in (XMLSchemaComponent.xmlns, XMLNS.XML)) and\ - (a not in self.__class__.attributes.keys()) and not\ - (self.isAttribute() and self.isReference()): - raise SchemaError, '%s, unknown attribute' %a - - -class WSDLToolsAdapter(XMLSchemaComponent): - """WSDL Adapter to grab the attributes from the wsdl document node. - """ - attributes = {'name':None, 'targetNamespace':None} - - def __init__(self, wsdl): - #XMLSchemaComponent.__init__(self, None) - XMLSchemaComponent.__init__(self, parent=wsdl) - self.setAttributes(DOMAdapter(wsdl.document)) - - def getImportSchemas(self): - """returns WSDLTools.WSDL types Collection - """ - return self._parent().types - - -class Notation(XMLSchemaComponent): - """ - parent: - schema - attributes: - id -- ID - name -- NCName, Required - public -- token, Required - system -- anyURI - contents: - annotation? - """ - required = ['name', 'public'] - attributes = {'id':None, 'name':None, 'public':None, 'system':None} - contents = {'xsd':('annotation')} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -class Annotation(XMLSchemaComponent): - """ - parent: - all,any,anyAttribute,attribute,attributeGroup,choice,complexContent, - complexType,element,extension,field,group,import,include,key,keyref, - list,notation,redefine,restriction,schema,selector,simpleContent, - simpleType,union,unique - attributes: - id -- ID - contents: - (documentation | appinfo)* - """ - attributes = {'id':None} - contents = {'xsd':('documentation', 'appinfo')} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'documentation': - #print_debug('class %s, documentation skipped' %self.__class__, 5) - continue - elif component == 'appinfo': - #print_debug('class %s, appinfo skipped' %self.__class__, 5) - continue - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content = tuple(content) - - - class Documentation(XMLSchemaComponent): - """ - parent: - annotation - attributes: - source, anyURI - xml:lang, language - contents: - mixed, any - """ - attributes = {'source':None, 'xml:lang':None} - contents = {'xsd':('mixed', 'any')} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'mixed': - #print_debug('class %s, mixed skipped' %self.__class__, 5) - continue - elif component == 'any': - #print_debug('class %s, any skipped' %self.__class__, 5) - continue - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content = tuple(content) - - - class Appinfo(XMLSchemaComponent): - """ - parent: - annotation - attributes: - source, anyURI - contents: - mixed, any - """ - attributes = {'source':None, 'anyURI':None} - contents = {'xsd':('mixed', 'any')} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'mixed': - #print_debug('class %s, mixed skipped' %self.__class__, 5) - continue - elif component == 'any': - #print_debug('class %s, any skipped' %self.__class__, 5) - continue - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content = tuple(content) - - -class XMLSchemaFake: - # This is temporary, for the benefit of WSDL until the real thing works. - def __init__(self, element): - self.targetNamespace = DOM.getAttr(element, 'targetNamespace') - self.element = element - -class XMLSchema(XMLSchemaComponent): - """A schema is a collection of schema components derived from one - or more schema documents, that is, one or more element - information items. It represents the abstract notion of a schema - rather than a single schema document (or other representation). - - - parent: - ROOT - attributes: - id -- ID - version -- token - xml:lang -- language - targetNamespace -- anyURI - attributeFormDefault -- 'qualified' | 'unqualified', 'unqualified' - elementFormDefault -- 'qualified' | 'unqualified', 'unqualified' - blockDefault -- '#all' | list of - ('substitution | 'extension' | 'restriction') - finalDefault -- '#all' | list of - ('extension' | 'restriction' | 'list' | 'union') - - contents: - ((include | import | redefine | annotation)*, - (attribute, attributeGroup, complexType, element, group, - notation, simpleType)*, annotation*)* - - - attributes -- schema attributes - imports -- import statements - includes -- include statements - redefines -- - types -- global simpleType, complexType definitions - elements -- global element declarations - attr_decl -- global attribute declarations - attr_groups -- attribute Groups - model_groups -- model Groups - notations -- global notations - """ - attributes = {'id':None, - 'version':None, - 'xml:lang':None, - 'targetNamespace':None, - 'attributeFormDefault':'unqualified', - 'elementFormDefault':'unqualified', - 'blockDefault':None, - 'finalDefault':None} - contents = {'xsd':('include', 'import', 'redefine', 'annotation', 'attribute',\ - 'attributeGroup', 'complexType', 'element', 'group',\ - 'notation', 'simpleType', 'annotation')} - empty_namespace = '' - - def __init__(self, parent=None): - """parent -- - instance variables: - targetNamespace -- schema's declared targetNamespace, or empty string. - _imported_schemas -- namespace keyed dict of schema dependencies, if - a schema is provided instance will not resolve import statement. - _included_schemas -- schemaLocation keyed dict of component schemas, - if schema is provided instance will not resolve include statement. - _base_url -- needed for relative URLs support, only works with URLs - relative to initial document. - includes -- collection of include statements - imports -- collection of import statements - elements -- collection of global element declarations - types -- collection of global type definitions - attr_decl -- collection of global attribute declarations - attr_groups -- collection of global attribute group definitions - model_groups -- collection of model group definitions - notations -- collection of notations - - """ - self.targetNamespace = None - XMLSchemaComponent.__init__(self, parent) - f = lambda k: k.attributes['name'] - ns = lambda k: k.attributes['namespace'] - sl = lambda k: k.attributes['schemaLocation'] - self.includes = Collection(self, key=sl) - self.imports = Collection(self, key=ns) - self.elements = Collection(self, key=f) - self.types = Collection(self, key=f) - self.attr_decl = Collection(self, key=f) - self.attr_groups = Collection(self, key=f) - self.model_groups = Collection(self, key=f) - self.notations = Collection(self, key=f) - - self._imported_schemas = {} - self._included_schemas = {} - self._base_url = None - - def addImportSchema(self, schema): - """for resolving import statements in Schema instance - schema -- schema instance - _imported_schemas - """ - if not isinstance(schema, XMLSchema): - raise TypeError, 'expecting a Schema instance' - if schema.targetNamespace != self.targetNamespace: - self._imported_schemas[schema.targetNamespace] = schema - else: - raise SchemaError, 'import schema bad targetNamespace' - - def addIncludeSchema(self, schemaLocation, schema): - """for resolving include statements in Schema instance - schemaLocation -- schema location - schema -- schema instance - _included_schemas - """ - if not isinstance(schema, XMLSchema): - raise TypeError, 'expecting a Schema instance' - if not schema.targetNamespace or\ - schema.targetNamespace == self.targetNamespace: - self._included_schemas[schemaLocation] = schema - else: - raise SchemaError, 'include schema bad targetNamespace' - - def setImportSchemas(self, schema_dict): - """set the import schema dictionary, which is used to - reference depedent schemas. - """ - self._imported_schemas = schema_dict - - def getImportSchemas(self): - """get the import schema dictionary, which is used to - reference depedent schemas. - """ - return self._imported_schemas - - def getSchemaNamespacesToImport(self): - """returns tuple of namespaces the schema instance has declared - itself to be depedent upon. - """ - return tuple(self.includes.keys()) - - def setIncludeSchemas(self, schema_dict): - """set the include schema dictionary, which is keyed with - schemaLocation (uri). - This is a means of providing - schemas to the current schema for content inclusion. - """ - self._included_schemas = schema_dict - - def getIncludeSchemas(self): - """get the include schema dictionary, which is keyed with - schemaLocation (uri). - """ - return self._included_schemas - - def getBaseUrl(self): - """get base url, used for normalizing all relative uri's - """ - return self._base_url - - def setBaseUrl(self, url): - """set base url, used for normalizing all relative uri's - """ - self._base_url = url - - def getElementFormDefault(self): - """return elementFormDefault attribute - """ - return self.attributes.get('elementFormDefault') - - def getAttributeFormDefault(self): - """return attributeFormDefault attribute - """ - return self.attributes.get('attributeFormDefault') - - def getBlockDefault(self): - """return blockDefault attribute - """ - return self.attributes.get('blockDefault') - - def getFinalDefault(self): - """return finalDefault attribute - """ - return self.attributes.get('finalDefault') - - def load(self, node): - pnode = node.getParentNode() - if pnode: - pname = SplitQName(pnode.getTagName())[1] - if pname == 'types': - attributes = {} - self.setAttributes(pnode) - attributes.update(self.attributes) - self.setAttributes(node) - for k,v in attributes['xmlns'].items(): - if not self.attributes['xmlns'].has_key(k): - self.attributes['xmlns'][k] = v - else: - self.setAttributes(node) - else: - self.setAttributes(node) - - self.targetNamespace = self.getTargetNamespace() - contents = self.getContents(node) - - indx = 0 - num = len(contents) - while indx < num: - while indx < num: - node = contents[indx] - component = SplitQName(node.getTagName())[1] - - if component == 'include': - tp = self.__class__.Include(self) - tp.fromDom(node) - self.includes[tp.attributes['schemaLocation']] = tp - - schema = tp.getSchema() - if schema.targetNamespace and \ - schema.targetNamespace != self.targetNamespace: - raise SchemaError, 'included schema bad targetNamespace' - - for collection in ['imports','elements','types',\ - 'attr_decl','attr_groups','model_groups','notations']: - for k,v in getattr(schema,collection).items(): - if not getattr(self,collection).has_key(k): - v._parent = weakref.ref(self) - getattr(self,collection)[k] = v - - elif component == 'import': - tp = self.__class__.Import(self) - tp.fromDom(node) - import_ns = tp.getAttribute('namespace') - if import_ns: - if import_ns == self.targetNamespace: - raise SchemaError,\ - 'import and schema have same targetNamespace' - self.imports[import_ns] = tp - else: - self.imports[self.__class__.empty_namespace] = tp - - if not self.getImportSchemas().has_key(import_ns) and\ - tp.getAttribute('schemaLocation'): - self.addImportSchema(tp.getSchema()) - - elif component == 'redefine': - #print_debug('class %s, redefine skipped' %self.__class__, 5) - pass - elif component == 'annotation': - #print_debug('class %s, annotation skipped' %self.__class__, 5) - pass - else: - break - indx += 1 - - # (attribute, attributeGroup, complexType, element, group, - # notation, simpleType)*, annotation*)* - while indx < num: - node = contents[indx] - component = SplitQName(node.getTagName())[1] - - if component == 'attribute': - tp = AttributeDeclaration(self) - tp.fromDom(node) - self.attr_decl[tp.getAttribute('name')] = tp - elif component == 'attributeGroup': - tp = AttributeGroupDefinition(self) - tp.fromDom(node) - self.attr_groups[tp.getAttribute('name')] = tp - elif component == 'complexType': - tp = ComplexType(self) - tp.fromDom(node) - self.types[tp.getAttribute('name')] = tp - elif component == 'element': - tp = ElementDeclaration(self) - tp.fromDom(node) - self.elements[tp.getAttribute('name')] = tp - elif component == 'group': - tp = ModelGroupDefinition(self) - tp.fromDom(node) - self.model_groups[tp.getAttribute('name')] = tp - elif component == 'notation': - tp = Notation(self) - tp.fromDom(node) - self.notations[tp.getAttribute('name')] = tp - elif component == 'simpleType': - tp = SimpleType(self) - tp.fromDom(node) - self.types[tp.getAttribute('name')] = tp - else: - break - indx += 1 - - while indx < num: - node = contents[indx] - component = SplitQName(node.getTagName())[1] - - if component == 'annotation': - #print_debug('class %s, annotation 2 skipped' %self.__class__, 5) - pass - else: - break - indx += 1 - - - class Import(XMLSchemaComponent): - """ - parent: - schema - attributes: - id -- ID - namespace -- anyURI - schemaLocation -- anyURI - contents: - annotation? - """ - attributes = {'id':None, - 'namespace':None, - 'schemaLocation':None} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self._schema = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - if self.attributes['namespace'] == self._parent().attributes['targetNamespace']: - raise SchemaError, 'namespace of schema and import match' - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - def getSchema(self): - """if schema is not defined, first look for a Schema class instance - in parent Schema. Else if not defined resolve schemaLocation - and create a new Schema class instance, and keep a hard reference. - """ - if not self._schema: - ns = self.attributes['namespace'] - schema = self._parent().getImportSchemas().get(ns) - if not schema and self._parent()._parent: - schema = self._parent()._parent().getImportSchemas().get(ns) - if not schema: - url = self.attributes.get('schemaLocation') - if not url: - raise SchemaError, 'namespace(%s) is unknown' %ns - base_url = self._parent().getBaseUrl() - reader = SchemaReader(base_url=base_url) - reader._imports = self._parent().getImportSchemas() - reader._includes = self._parent().getIncludeSchemas() - self._schema = reader.loadFromURL(url) - return self._schema or schema - - - class Include(XMLSchemaComponent): - """ - parent: - schema - attributes: - id -- ID - schemaLocation -- anyURI, required - contents: - annotation? - """ - required = ['schemaLocation'] - attributes = {'id':None, - 'schemaLocation':None} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self._schema = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - def getSchema(self): - """if schema is not defined, first look for a Schema class instance - in parent Schema. Else if not defined resolve schemaLocation - and create a new Schema class instance. - """ - if not self._schema: - #schema = self._parent()._parent() - schema = self._parent() - #self._schema = schema.getIncludeSchemas(\ - # self.attributes['schemaLocation']) - self._schema = schema.getIncludeSchemas().get(\ - self.attributes['schemaLocation'] - ) - if not self._schema: - url = self.attributes['schemaLocation'] - reader = SchemaReader(base_url=schema.getBaseUrl()) - reader._imports = schema.getImportSchemas() - reader._includes = schema.getIncludeSchemas() - self._schema = reader.loadFromURL(url) - return self._schema - - -class AttributeDeclaration(XMLSchemaComponent,\ - AttributeMarker,\ - DeclarationMarker): - """ - parent: - schema - attributes: - id -- ID - name -- NCName, required - type -- QName - default -- string - fixed -- string - contents: - annotation?, simpleType? - """ - required = ['name'] - attributes = {'id':None, - 'name':None, - 'type':None, - 'default':None, - 'fixed':None} - contents = {'xsd':['annotation','simpleType']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - """ No list or union support - """ - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - elif component == 'simpleType': - self.content = AnonymousSimpleType(self) - self.content.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -class LocalAttributeDeclaration(AttributeDeclaration,\ - AttributeMarker,\ - LocalMarker,\ - DeclarationMarker): - """ - parent: - complexType, restriction, extension, attributeGroup - attributes: - id -- ID - name -- NCName, required - type -- QName - form -- ('qualified' | 'unqualified'), schema.attributeFormDefault - use -- ('optional' | 'prohibited' | 'required'), optional - default -- string - fixed -- string - contents: - annotation?, simpleType? - """ - required = ['name'] - attributes = {'id':None, - 'name':None, - 'type':None, - 'form':lambda self: GetSchema(self).getAttributeFormDefault(), - 'use':'optional', - 'default':None, - 'fixed':None} - contents = {'xsd':['annotation','simpleType']} - - def __init__(self, parent): - AttributeDeclaration.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - elif component == 'simpleType': - self.content = AnonymousSimpleType(self) - self.content.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -class AttributeWildCard(XMLSchemaComponent,\ - AttributeMarker,\ - DeclarationMarker,\ - WildCardMarker): - """ - parents: - complexType, restriction, extension, attributeGroup - attributes: - id -- ID - namespace -- '##any' | '##other' | - (anyURI* | '##targetNamespace' | '##local'), ##any - processContents -- 'lax' | 'skip' | 'strict', strict - contents: - annotation? - """ - attributes = {'id':None, - 'namespace':'##any', - 'processContents':'strict'} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -class AttributeReference(XMLSchemaComponent,\ - AttributeMarker,\ - ReferenceMarker): - """ - parents: - complexType, restriction, extension, attributeGroup - attributes: - id -- ID - ref -- QName, required - use -- ('optional' | 'prohibited' | 'required'), optional - default -- string - fixed -- string - contents: - annotation? - """ - required = ['ref'] - attributes = {'id':None, - 'ref':None, - 'use':'optional', - 'default':None, - 'fixed':None} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -class AttributeGroupDefinition(XMLSchemaComponent,\ - AttributeGroupMarker,\ - DefinitionMarker): - """ - parents: - schema, redefine - attributes: - id -- ID - name -- NCName, required - contents: - annotation?, (attribute | attributeGroup)*, anyAttribute? - """ - required = ['name'] - attributes = {'id':None, - 'name':None} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.attr_content = None - - def getAttributeContent(self): - return self.attr_content - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for indx in range(len(contents)): - component = SplitQName(contents[indx].getTagName())[1] - if (component == 'annotation') and (not indx): - self.annotation = Annotation(self) - self.annotation.fromDom(contents[indx]) - elif (component == 'attribute'): - if contents[indx].hasattr('name'): - content.append(AttributeDeclaration()) - elif contents[indx].hasattr('ref'): - content.append(AttributeReference()) - else: - raise SchemaError, 'Unknown attribute type' - content[-1].fromDom(contents[indx]) - elif (component == 'attributeGroup'): - content.append(AttributeGroupReference()) - content[-1].fromDom(contents[indx]) - elif (component == 'anyAttribute') and (len(contents) == x+1): - content.append(AttributeWildCard()) - content[-1].fromDom(contents[indx]) - else: - raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName()) - - self.attr_content = tuple(content) - -class AttributeGroupReference(XMLSchemaComponent,\ - AttributeGroupMarker,\ - ReferenceMarker): - """ - parents: - complexType, restriction, extension, attributeGroup - attributes: - id -- ID - ref -- QName, required - contents: - annotation? - """ - required = ['ref'] - attributes = {'id':None, - 'ref':None} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - - -###################################################### -# Elements -##################################################### -class IdentityConstrants(XMLSchemaComponent): - """Allow one to uniquely identify nodes in a document and ensure the - integrity of references between them. - - attributes -- dictionary of attributes - selector -- XPath to selected nodes - fields -- list of XPath to key field - """ - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.selector = None - self.fields = None - self.annotation = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - fields = [] - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - elif component == 'selector': - self.selector = self.Selector(self) - self.selector.fromDom(i) - continue - elif component == 'field': - fields.append(self.Field(self)) - fields[-1].fromDom(i) - continue - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.fields = tuple(fields) - - - class Constraint(XMLSchemaComponent): - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - class Selector(Constraint): - """ - parent: - unique, key, keyref - attributes: - id -- ID - xpath -- XPath subset, required - contents: - annotation? - """ - required = ['xpath'] - attributes = {'id':None, - 'xpath':None} - contents = {'xsd':['annotation']} - - class Field(Constraint): - """ - parent: - unique, key, keyref - attributes: - id -- ID - xpath -- XPath subset, required - contents: - annotation? - """ - required = ['xpath'] - attributes = {'id':None, - 'xpath':None} - contents = {'xsd':['annotation']} - - -class Unique(IdentityConstrants): - """ Enforce fields are unique w/i a specified scope. - - parent: - element - attributes: - id -- ID - name -- NCName, required - contents: - annotation?, selector, field+ - """ - required = ['name'] - attributes = {'id':None, - 'name':None} - contents = {'xsd':['annotation', 'selector', 'field']} - - -class Key(IdentityConstrants): - """ Enforce fields are unique w/i a specified scope, and all - field values are present w/i document. Fields cannot - be nillable. - - parent: - element - attributes: - id -- ID - name -- NCName, required - contents: - annotation?, selector, field+ - """ - required = ['name'] - attributes = {'id':None, - 'name':None} - contents = {'xsd':['annotation', 'selector', 'field']} - - -class KeyRef(IdentityConstrants): - """ Ensure a match between two sets of values in an - instance. - parent: - element - attributes: - id -- ID - name -- NCName, required - refer -- QName, required - contents: - annotation?, selector, field+ - """ - required = ['name', 'refer'] - attributes = {'id':None, - 'name':None, - 'refer':None} - contents = {'xsd':['annotation', 'selector', 'field']} - - -class ElementDeclaration(XMLSchemaComponent,\ - ElementMarker,\ - DeclarationMarker): - """ - parents: - schema - attributes: - id -- ID - name -- NCName, required - type -- QName - default -- string - fixed -- string - nillable -- boolean, false - abstract -- boolean, false - substitutionGroup -- QName - block -- ('#all' | ('substition' | 'extension' | 'restriction')*), - schema.blockDefault - final -- ('#all' | ('extension' | 'restriction')*), - schema.finalDefault - contents: - annotation?, (simpleType,complexType)?, (key | keyref | unique)* - - """ - required = ['name'] - attributes = {'id':None, - 'name':None, - 'type':None, - 'default':None, - 'fixed':None, - 'nillable':0, - 'abstract':0, - 'substitutionGroup':None, - 'block':lambda self: self._parent().getBlockDefault(), - 'final':lambda self: self._parent().getFinalDefault()} - contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\ - 'keyref', 'unique']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - self.constraints = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - constraints = [] - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - elif component == 'simpleType' and not self.content: - self.content = AnonymousSimpleType(self) - self.content.fromDom(i) - elif component == 'complexType' and not self.content: - self.content = LocalComplexType(self) - self.content.fromDom(i) - elif component == 'key': - constraints.append(Key(self)) - constraints[-1].fromDom(i) - elif component == 'keyref': - constraints.append(KeyRef(self)) - constraints[-1].fromDom(i) - elif component == 'unique': - constraints.append(Unique(self)) - constraints[-1].fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.constraints = tuple(constraints) - - -class LocalElementDeclaration(ElementDeclaration,\ - LocalMarker): - """ - parents: - all, choice, sequence - attributes: - id -- ID - name -- NCName, required - form -- ('qualified' | 'unqualified'), schema.elementFormDefault - type -- QName - minOccurs -- Whole Number, 1 - maxOccurs -- (Whole Number | 'unbounded'), 1 - default -- string - fixed -- string - nillable -- boolean, false - block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault - contents: - annotation?, (simpleType,complexType)?, (key | keyref | unique)* - """ - required = ['name'] - attributes = {'id':None, - 'name':None, - 'form':lambda self: GetSchema(self).getElementFormDefault(), - 'type':None, - 'minOccurs':'1', - 'maxOccurs':'1', - 'default':None, - 'fixed':None, - 'nillable':0, - 'abstract':0, - 'block':lambda self: GetSchema(self).getBlockDefault()} - contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\ - 'keyref', 'unique']} - - -class ElementReference(XMLSchemaComponent,\ - ElementMarker,\ - ReferenceMarker): - """ - parents: - all, choice, sequence - attributes: - id -- ID - ref -- QName, required - minOccurs -- Whole Number, 1 - maxOccurs -- (Whole Number | 'unbounded'), 1 - contents: - annotation? - """ - required = ['ref'] - attributes = {'id':None, - 'ref':None, - 'minOccurs':'1', - 'maxOccurs':'1'} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - - def fromDom(self, node): - self.annotation = None - self.setAttributes(node) - for i in self.getContents(node): - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -class ElementWildCard(LocalElementDeclaration,\ - WildCardMarker): - """ - parents: - choice, sequence - attributes: - id -- ID - minOccurs -- Whole Number, 1 - maxOccurs -- (Whole Number | 'unbounded'), 1 - namespace -- '##any' | '##other' | - (anyURI* | '##targetNamespace' | '##local'), ##any - processContents -- 'lax' | 'skip' | 'strict', strict - contents: - annotation? - """ - required = [] - attributes = {'id':None, - 'minOccurs':'1', - 'maxOccurs':'1', - 'namespace':'##any', - 'processContents':'strict'} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - - def fromDom(self, node): - self.annotation = None - self.setAttributes(node) - for i in self.getContents(node): - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -###################################################### -# Model Groups -##################################################### -class Sequence(XMLSchemaComponent,\ - ModelGroupMarker): - """ - parents: - complexType, extension, restriction, group, choice, sequence - attributes: - id -- ID - minOccurs -- Whole Number, 1 - maxOccurs -- (Whole Number | 'unbounded'), 1 - - contents: - annotation?, (element | group | choice | sequence | any)* - """ - attributes = {'id':None, - 'minOccurs':'1', - 'maxOccurs':'1'} - contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\ - 'any']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - continue - elif component == 'element': - if i.hasattr('ref'): - content.append(ElementReference(self)) - else: - content.append(LocalElementDeclaration(self)) - elif component == 'group': - content.append(ModelGroupReference(self)) - elif component == 'choice': - content.append(Choice(self)) - elif component == 'sequence': - content.append(Sequence(self)) - elif component == 'any': - content.append(ElementWildCard(self)) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - content[-1].fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content = tuple(content) - - -class All(XMLSchemaComponent,\ - ModelGroupMarker): - """ - parents: - complexType, extension, restriction, group - attributes: - id -- ID - minOccurs -- '0' | '1', 1 - maxOccurs -- '1', 1 - - contents: - annotation?, element* - """ - attributes = {'id':None, - 'minOccurs':'1', - 'maxOccurs':'1'} - contents = {'xsd':['annotation', 'element']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - continue - elif component == 'element': - if i.hasattr('ref'): - content.append(ElementReference(self)) - else: - content.append(LocalElementDeclaration(self)) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - content[-1].fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content = tuple(content) - - -class Choice(XMLSchemaComponent,\ - ModelGroupMarker): - """ - parents: - complexType, extension, restriction, group, choice, sequence - attributes: - id -- ID - minOccurs -- Whole Number, 1 - maxOccurs -- (Whole Number | 'unbounded'), 1 - - contents: - annotation?, (element | group | choice | sequence | any)* - """ - attributes = {'id':None, - 'minOccurs':'1', - 'maxOccurs':'1'} - contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\ - 'any']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - continue - elif component == 'element': - if i.hasattr('ref'): - content.append(ElementReference(self)) - else: - content.append(LocalElementDeclaration(self)) - elif component == 'group': - content.append(ModelGroupReference(self)) - elif component == 'choice': - content.append(Choice(self)) - elif component == 'sequence': - content.append(Sequence(self)) - elif component == 'any': - content.append(ElementWildCard(self)) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - content[-1].fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content = tuple(content) - - -class ModelGroupDefinition(XMLSchemaComponent,\ - ModelGroupMarker,\ - DefinitionMarker): - """ - parents: - redefine, schema - attributes: - id -- ID - name -- NCName, required - - contents: - annotation?, (all | choice | sequence)? - """ - required = ['name'] - attributes = {'id':None, - 'name':None} - contents = {'xsd':['annotation', 'all', 'choice', 'sequence']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - continue - elif component == 'all' and not self.content: - self.content = All(self) - elif component == 'choice' and not self.content: - self.content = Choice(self) - elif component == 'sequence' and not self.content: - self.content = Sequence(self) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -class ModelGroupReference(XMLSchemaComponent,\ - ModelGroupMarker,\ - ReferenceMarker): - """ - parents: - choice, complexType, extension, restriction, sequence - attributes: - id -- ID - ref -- NCName, required - minOccurs -- Whole Number, 1 - maxOccurs -- (Whole Number | 'unbounded'), 1 - - contents: - annotation? - """ - required = ['ref'] - attributes = {'id':None, - 'ref':None, - 'minOccurs':'1', - 'maxOccurs':'1'} - contents = {'xsd':['annotation']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - - -class ComplexType(XMLSchemaComponent,\ - DefinitionMarker,\ - ComplexMarker): - """ - parents: - redefine, schema - attributes: - id -- ID - name -- NCName, required - mixed -- boolean, false - abstract -- boolean, false - block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault - final -- ('#all' | ('extension' | 'restriction')*), schema.finalDefault - - contents: - annotation?, (simpleContent | complexContent | - ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?)) - """ - required = ['name'] - attributes = {'id':None, - 'name':None, - 'mixed':0, - 'abstract':0, - 'block':lambda self: self._parent().getBlockDefault(), - 'final':lambda self: self._parent().getFinalDefault()} - contents = {'xsd':['annotation', 'simpleContent', 'complexContent',\ - 'group', 'all', 'choice', 'sequence', 'attribute', 'attributeGroup',\ - 'anyAttribute', 'any']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - self.attr_content = None - - def getAttributeContent(self): - return self.attr_content - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - indx = 0 - num = len(contents) - #XXX ugly - if not num: - return - component = SplitQName(contents[indx].getTagName())[1] - if component == 'annotation': - self.annotation = Annotation(self) - self.annotation.fromDom(contents[indx]) - indx += 1 - component = SplitQName(contents[indx].getTagName())[1] - - self.content = None - if component == 'simpleContent': - self.content = self.__class__.SimpleContent(self) - self.content.fromDom(contents[indx]) - elif component == 'complexContent': - self.content = self.__class__.ComplexContent(self) - self.content.fromDom(contents[indx]) - else: - if component == 'all': - self.content = All(self) - elif component == 'choice': - self.content = Choice(self) - elif component == 'sequence': - self.content = Sequence(self) - elif component == 'group': - self.content = ModelGroupReference(self) - - if self.content: - self.content.fromDom(contents[indx]) - indx += 1 - - self.attr_content = [] - while indx < num: - component = SplitQName(contents[indx].getTagName())[1] - if component == 'attribute': - if contents[indx].hasattr('ref'): - self.attr_content.append(AttributeReference(self)) - else: - self.attr_content.append(LocalAttributeDeclaration(self)) - elif component == 'attributeGroup': - self.attr_content.append(AttributeGroupReference(self)) - elif component == 'anyAttribute': - self.attr_content.append(AttributeWildCard(self)) - else: - raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName()) - self.attr_content[-1].fromDom(contents[indx]) - indx += 1 - - class _DerivedType(XMLSchemaComponent): - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.derivation = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - for i in contents: - component = SplitQName(i.getTagName())[1] - if component in self.__class__.contents['xsd']: - if component == 'annotation' and not self.annotation: - self.annotation = Annotation(self) - self.annotation.fromDom(i) - continue - elif component == 'restriction' and not self.derivation: - self.derivation = self.__class__.Restriction(self) - elif component == 'extension' and not self.derivation: - self.derivation = self.__class__.Extension(self) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.derivation.fromDom(i) - - class ComplexContent(_DerivedType,\ - ComplexMarker): - """ - parents: - complexType - attributes: - id -- ID - mixed -- boolean, false - - contents: - annotation?, (restriction | extension) - """ - attributes = {'id':None, - 'mixed':0 } - contents = {'xsd':['annotation', 'restriction', 'extension']} - - class _DerivationBase(XMLSchemaComponent): - """, - parents: - complexContent - attributes: - id -- ID - base -- QName, required - - contents: - annotation?, (group | all | choice | sequence)?, - (attribute | attributeGroup)*, anyAttribute? - """ - required = ['base'] - attributes = {'id':None, - 'base':None } - contents = {'xsd':['annotation', 'group', 'all', 'choice',\ - 'sequence', 'attribute', 'attributeGroup', 'anyAttribute']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - self.attr_content = None - - def getAttributeContent(self): - return self.attr_content - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - indx = 0 - num = len(contents) - #XXX ugly - if not num: - return - component = SplitQName(contents[indx].getTagName())[1] - if component == 'annotation': - self.annotation = Annotation(self) - self.annotation.fromDom(contents[indx]) - indx += 1 - component = SplitQName(contents[indx].getTagName())[1] - - if component == 'all': - self.content = All(self) - self.content.fromDom(contents[indx]) - indx += 1 - elif component == 'choice': - self.content = Choice(self) - self.content.fromDom(contents[indx]) - indx += 1 - elif component == 'sequence': - self.content = Sequence(self) - self.content.fromDom(contents[indx]) - indx += 1 - elif component == 'group': - self.content = ModelGroupReference(self) - self.content.fromDom(contents[indx]) - indx += 1 - else: - self.content = None - - self.attr_content = [] - while indx < num: - component = SplitQName(contents[indx].getTagName())[1] - if component == 'attribute': - if contents[indx].hasattr('ref'): - self.attr_content.append(AttributeReference(self)) - else: - self.attr_content.append(LocalAttributeDeclaration(self)) - elif component == 'attributeGroup': - if contents[indx].hasattr('ref'): - self.attr_content.append(AttributeGroupReference(self)) - else: - self.attr_content.append(AttributeGroupDefinition(self)) - elif component == 'anyAttribute': - self.attr_content.append(AttributeWildCard(self)) - else: - raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName()) - self.attr_content[-1].fromDom(contents[indx]) - indx += 1 - - class Extension(_DerivationBase, - ExtensionMarker): - """ - parents: - complexContent - attributes: - id -- ID - base -- QName, required - - contents: - annotation?, (group | all | choice | sequence)?, - (attribute | attributeGroup)*, anyAttribute? - """ - pass - - class Restriction(_DerivationBase,\ - RestrictionMarker): - """ - parents: - complexContent - attributes: - id -- ID - base -- QName, required - - contents: - annotation?, (group | all | choice | sequence)?, - (attribute | attributeGroup)*, anyAttribute? - """ - pass - - - class SimpleContent(_DerivedType,\ - SimpleMarker): - """ - parents: - complexType - attributes: - id -- ID - - contents: - annotation?, (restriction | extension) - """ - attributes = {'id':None} - contents = {'xsd':['annotation', 'restriction', 'extension']} - - class Extension(XMLSchemaComponent,\ - ExtensionMarker): - """ - parents: - simpleContent - attributes: - id -- ID - base -- QName, required - - contents: - annotation?, (attribute | attributeGroup)*, anyAttribute? - """ - required = ['base'] - attributes = {'id':None, - 'base':None } - contents = {'xsd':['annotation', 'attribute', 'attributeGroup', - 'anyAttribute']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.attr_content = None - - def getAttributeContent(self): - return self.attr_content - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - - indx = 0 - num = len(contents) - component = SplitQName(contents[indx].getTagName())[1] - if component == 'annotation': - self.annotation = Annotation(self) - self.annotation.fromDom(contents[indx]) - indx += 1 - component = SplitQName(contents[indx].getTagName())[1] - - content = [] - while indx < num: - component = SplitQName(contents[indx].getTagName())[1] - if component == 'attribute': - if contents[indx].hasattr('ref'): - content.append(AttributeReference(self)) - else: - content.append(LocalAttributeDeclaration(self)) - elif component == 'attributeGroup': - content.append(AttributeGroupReference(self)) - elif component == 'anyAttribute': - content.append(AttributeWildCard(self)) - else: - raise SchemaError, 'Unknown component (%s)'\ - %(contents[indx].getTagName()) - content[-1].fromDom(contents[indx]) - indx += 1 - self.attr_content = tuple(content) - - - class Restriction(XMLSchemaComponent,\ - RestrictionMarker): - """ - parents: - simpleContent - attributes: - id -- ID - base -- QName, required - - contents: - annotation?, simpleType?, (enumeration | length | - maxExclusive | maxInclusive | maxLength | minExclusive | - minInclusive | minLength | pattern | fractionDigits | - totalDigits | whiteSpace)*, (attribute | attributeGroup)*, - anyAttribute? - """ - required = ['base'] - attributes = {'id':None, - 'base':None } - contents = {'xsd':['annotation', 'simpleType', 'attribute',\ - 'attributeGroup', 'anyAttribute'] + RestrictionMarker.facets} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - self.attr_content = None - - def getAttributeContent(self): - return self.attr_content - - def fromDom(self, node): - self.content = [] - self.setAttributes(node) - contents = self.getContents(node) - - indx = 0 - num = len(contents) - component = SplitQName(contents[indx].getTagName())[1] - if component == 'annotation': - self.annotation = Annotation(self) - self.annotation.fromDom(contents[indx]) - indx += 1 - component = SplitQName(contents[indx].getTagName())[1] - - content = [] - while indx < num: - component = SplitQName(contents[indx].getTagName())[1] - if component == 'attribute': - if contents[indx].hasattr('ref'): - content.append(AttributeReference(self)) - else: - content.append(LocalAttributeDeclaration(self)) - elif component == 'attributeGroup': - content.append(AttributeGroupReference(self)) - elif component == 'anyAttribute': - content.append(AttributeWildCard(self)) - elif component == 'simpleType': - self.content.append(LocalSimpleType(self)) - self.content[-1].fromDom(contents[indx]) - else: - raise SchemaError, 'Unknown component (%s)'\ - %(contents[indx].getTagName()) - content[-1].fromDom(contents[indx]) - indx += 1 - self.attr_content = tuple(content) - - -class LocalComplexType(ComplexType,\ - LocalMarker): - """ - parents: - element - attributes: - id -- ID - mixed -- boolean, false - - contents: - annotation?, (simpleContent | complexContent | - ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?)) - """ - required = [] - attributes = {'id':None, - 'mixed':0} - - -class SimpleType(XMLSchemaComponent,\ - DefinitionMarker,\ - SimpleMarker): - """ - parents: - redefine, schema - attributes: - id -- ID - name -- NCName, required - final -- ('#all' | ('extension' | 'restriction' | 'list' | 'union')*), - schema.finalDefault - - contents: - annotation?, (restriction | list | union) - """ - required = ['name'] - attributes = {'id':None, - 'name':None, - 'final':lambda self: self._parent().getFinalDefault()} - contents = {'xsd':['annotation', 'restriction', 'list', 'union']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - for child in contents: - component = SplitQName(child.getTagName())[1] - if component == 'annotation': - self.annotation = Annotation(self) - self.annotation.fromDom(child) - continue - break - else: - return - if component == 'restriction': - self.content = self.__class__.Restriction(self) - elif component == 'list': - self.content = self.__class__.List(self) - elif component == 'union': - self.content = self.__class__.Union(self) - else: - raise SchemaError, 'Unknown component (%s)' %(component) - self.content.fromDom(child) - - class Restriction(XMLSchemaComponent,\ - RestrictionMarker): - """ - parents: - simpleType - attributes: - id -- ID - base -- QName, required or simpleType child - - contents: - annotation?, simpleType?, (enumeration | length | - maxExclusive | maxInclusive | maxLength | minExclusive | - minInclusive | minLength | pattern | fractionDigits | - totalDigits | whiteSpace)* - """ - attributes = {'id':None, - 'base':None } - contents = {'xsd':['annotation', 'simpleType']+RestrictionMarker.facets} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for indx in range(len(contents)): - component = SplitQName(contents[indx].getTagName())[1] - if (component == 'annotation') and (not indx): - self.annotation = Annotation(self) - self.annotation.fromDom(contents[indx]) - continue - elif (component == 'simpleType') and (not indx or indx == 1): - content.append(AnonymousSimpleType(self)) - content[-1].fromDom(contents[indx]) - elif component in RestrictionMarker.facets: - #print_debug('%s class instance, skipping %s' %(self.__class__, component)) - pass - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content = tuple(content) - - - class Union(XMLSchemaComponent): - """ - parents: - simpleType - attributes: - id -- ID - memberTypes -- list of QNames, required or simpleType child. - - contents: - annotation?, simpleType* - """ - attributes = {'id':None, - 'memberTypes':None } - contents = {'xsd':['annotation', 'simpleType']} - - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - content = [] - - for indx in range(len(contents)): - component = SplitQName(contents[indx].getTagName())[1] - if (component == 'annotation') and (not indx): - self.annotation = Annotation(self) - self.annotation.fromDom(contents[indx]) - elif (component == 'simpleType'): - content.append(AnonymousSimpleType(self)) - content[-1].fromDom(contents[indx]) - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - self.content = tuple(content) - - class List(XMLSchemaComponent): - """ - parents: - simpleType - attributes: - id -- ID - itemType -- QName, required or simpleType child. - - contents: - annotation?, simpleType? - """ - attributes = {'id':None, - 'itemType':None } - contents = {'xsd':['annotation', 'simpleType']} - def __init__(self, parent): - XMLSchemaComponent.__init__(self, parent) - self.annotation = None - self.content = None - - def fromDom(self, node): - self.setAttributes(node) - contents = self.getContents(node) - self.content = [] - - for indx in range(len(contents)): - component = SplitQName(contents[indx].getTagName())[1] - if (component == 'annotation') and (not indx): - self.annotation = Annotation(self) - self.annotation.fromDom(contents[indx]) - elif (component == 'simpleType'): - self.content = AnonymousSimpleType(self) - self.content.fromDom(contents[indx]) - break - else: - raise SchemaError, 'Unknown component (%s)' %(i.getTagName()) - - -class AnonymousSimpleType(SimpleType,\ - SimpleMarker): - """ - parents: - attribute, element, list, restriction, union - attributes: - id -- ID - - contents: - annotation?, (restriction | list | union) - """ - required = [] - attributes = {'id':None} - - -class Redefine: - """ - parents: - attributes: - - contents: - """ - pass - -########################### -########################### - - -if sys.version_info[:2] >= (2, 2): - tupleClass = tuple -else: - import UserTuple - tupleClass = UserTuple.UserTuple - -class TypeDescriptionComponent(tupleClass): - """Tuple of length 2, consisting of - a namespace and unprefixed name. - """ - def __init__(self, args): - """args -- (namespace, name) - Remove the name's prefix, irrelevant. - """ - if len(args) != 2: - raise TypeError, 'expecting tuple (namespace, name), got %s' %args - elif args[1].find(':') >= 0: - args = (args[0], SplitQName(args[1])[1]) - tuple.__init__(self, args) - return - - def getTargetNamespace(self): - return self[0] - - def getName(self): - return self[1] - - -''' -import string, types, base64, re -from Utility import DOM, Collection -from StringIO import StringIO - - -class SchemaReader: - """A SchemaReader creates XMLSchema objects from urls and xml data.""" - - def loadFromStream(self, file): - """Return an XMLSchema instance loaded from a file object.""" - document = DOM.loadDocument(file) - schema = XMLSchema() - schema.load(document) - return schema - - def loadFromString(self, data): - """Return an XMLSchema instance loaded from an xml string.""" - return self.loadFromStream(StringIO(data)) - - def loadFromURL(self, url): - """Return an XMLSchema instance loaded from the given url.""" - document = DOM.loadFromURL(url) - schema = XMLSchema() - schema.location = url - schema.load(document) - return schema - - def loadFromFile(self, filename): - """Return an XMLSchema instance loaded from the given file.""" - file = open(filename, 'rb') - try: schema = self.loadFromStream(file) - finally: file.close() - return schema - -class SchemaError(Exception): - pass - -class XMLSchema: - # This is temporary, for the benefit of WSDL until the real thing works. - def __init__(self, element): - self.targetNamespace = DOM.getAttr(element, 'targetNamespace') - self.element = element - -class realXMLSchema: - """A schema is a collection of schema components derived from one - or more schema documents, that is, one or more element - information items. It represents the abstract notion of a schema - rather than a single schema document (or other representation).""" - def __init__(self): - self.simpleTypes = Collection(self) - self.complexTypes = Collection(self) - self.attributes = Collection(self) - self.elements = Collection(self) - self.attrGroups = Collection(self) - self.idConstraints=None - self.modelGroups = None - self.notations = None - self.extensions = [] - - targetNamespace = None - attributeFormDefault = 'unqualified' - elementFormDefault = 'unqualified' - blockDefault = None - finalDefault = None - location = None - version = None - id = None - - def load(self, document): - if document.nodeType == document.DOCUMENT_NODE: - schema = DOM.getElement(document, 'schema', None, None) - else: - schema = document - if schema is None: - raise SchemaError('Missing element.') - - self.namespace = namespace = schema.namespaceURI - if not namespace in DOM.NS_XSD_ALL: - raise SchemaError( - 'Unknown XML schema namespace: %s.' % self.namespace - ) - - for attrname in ( - 'targetNamespace', 'attributeFormDefault', 'elementFormDefault', - 'blockDefault', 'finalDefault', 'version', 'id' - ): - value = DOM.getAttr(schema, attrname, None, None) - if value is not None: - setattr(self, attrname, value) - - - # Resolve imports and includes here? -## imported = {} -## while 1: -## imports = [] -## for element in DOM.getElements(definitions, 'import', NS_WSDL): -## location = DOM.getAttr(element, 'location') -## if not imported.has_key(location): -## imports.append(element) -## if not imports: -## break -## for element in imports: -## self._import(document, element) -## imported[location] = 1 - - for element in DOM.getElements(schema, None, None): - localName = element.localName - - if not DOM.nsUriMatch(element.namespaceURI, namespace): - self.extensions.append(element) - continue - - elif localName == 'message': - name = DOM.getAttr(element, 'name') - docs = GetDocumentation(element) - message = self.addMessage(name, docs) - parts = DOM.getElements(element, 'part', NS_WSDL) - message.load(parts) - continue - - def _import(self, document, element): - namespace = DOM.getAttr(element, 'namespace', default=None) - location = DOM.getAttr(element, 'location', default=None) - if namespace is None or location is None: - raise WSDLError( - 'Invalid import element (missing namespace or location).' - ) - - # Sort-of support relative locations to simplify unit testing. The - # WSDL specification actually doesn't allow relative URLs, so its - # ok that this only works with urls relative to the initial document. - location = urllib.basejoin(self.location, location) - - obimport = self.addImport(namespace, location) - obimport._loaded = 1 - - importdoc = DOM.loadFromURL(location) - try: - if location.find('#') > -1: - idref = location.split('#')[-1] - imported = DOM.getElementById(importdoc, idref) - else: - imported = importdoc.documentElement - if imported is None: - raise WSDLError( - 'Import target element not found for: %s' % location - ) - - imported_tns = DOM.getAttr(imported, 'targetNamespace') - importer_tns = namespace - - if imported_tns != importer_tns: - return - - if imported.localName == 'definitions': - imported_nodes = imported.childNodes - else: - imported_nodes = [imported] - parent = element.parentNode - for node in imported_nodes: - if node.nodeType != node.ELEMENT_NODE: - continue - child = DOM.importNode(document, node, 1) - parent.appendChild(child) - child.setAttribute('targetNamespace', importer_tns) - attrsNS = imported._attrsNS - for attrkey in attrsNS.keys(): - if attrkey[0] == DOM.NS_XMLNS: - attr = attrsNS[attrkey].cloneNode(1) - child.setAttributeNode(attr) - finally: - importdoc.unlink() - - -class Element: - """Common base class for element representation classes.""" - def __init__(self, name=None, documentation=''): - self.name = name - self.documentation = documentation - self.extensions = [] - - def addExtension(self, item): - self.extensions.append(item) - - -class SimpleTypeDefinition: - """Represents an xml schema simple type definition.""" - -class ComplexTypeDefinition: - """Represents an xml schema complex type definition.""" - -class AttributeDeclaration: - """Represents an xml schema attribute declaration.""" - -class ElementDeclaration: - """Represents an xml schema element declaration.""" - def __init__(self, name, type=None, targetNamespace=None): - self.name = name - - targetNamespace = None - annotation = None - nillable = 0 - abstract = 0 - default = None - fixed = None - scope = 'global' - type = None - form = 0 - # Things we will not worry about for now. - id_constraint_defs = None - sub_group_exclude = None - sub_group_affils = None - disallowed_subs = None - - - - - - - - - - -class AttributeGroupDefinition: - """Represents an xml schema attribute group definition.""" - -class IdentityConstraintDefinition: - """Represents an xml schema identity constraint definition.""" - -class ModelGroupDefinition: - """Represents an xml schema model group definition.""" - -class NotationDeclaration: - """Represents an xml schema notation declaration.""" - -class Annotation: - """Represents an xml schema annotation.""" - -class ModelGroup: - """Represents an xml schema model group.""" - -class Particle: - """Represents an xml schema particle.""" - -class WildCard: - """Represents an xml schema wildcard.""" - -class AttributeUse: - """Represents an xml schema attribute use.""" - - -class ElementComponent: - namespace = '' - name = '' - type = None - form = 'qualified | unqualified' - scope = 'global or complex def' - constraint = ('value', 'default | fixed') - nillable = 0 - id_constraint_defs = None - sub_group_affil = None - sub_group_exclusions = None - disallowed_subs = 'substitution, extension, restriction' - abstract = 0 - minOccurs = 1 - maxOccurs = 1 - ref = '' - -class AttributeThing: - name = '' - namespace = '' - typeName = '' - typeUri = '' - scope = 'global | local to complex def' - constraint = ('value:default', 'value:fixed') - use = 'optional | prohibited | required' - -class ElementDataType: - namespace = '' - name = '' - element_form = 'qualified | unqualified' - attr_form = None - type_name = '' - type_uri = '' - def __init__(self, name, namespace, type_name, type_uri): - self.namespace = namespace - self.name = name - # type may be anonymous... - self.type_name = type_name - self.type_uri = type_uri - - def checkValue(self, value, context): - # Delegate value checking to the type of the element. - typeref = (self.type_uri, self.type_name) - handler = context.serializer.getType(typeref) - return handler.checkValue(value, context) - - def serialize(self, name, namespace, value, context, **kwargs): - if context.check_values: - self.checkValue(value, context) - # Delegate serialization to the type of the element. - typeref = (self.type_uri, self.type_name) - handler = context.serializer.getType(typeref) - return handler.serialize(self.name, self.namespace, value, context) - - def deserialize(self, element, context): - if element_is_null(element, context): - return None - # Delegate deserialization to the type of the element. - typeref = (self.type_uri, self.type_name) - handler = context.serializer.getType(typeref) - return handler.deserialize(element, context) - - - -def parse_schema(data): - targetNS = '' - attributeFormDefault = 0 - elementFormDefault = 0 - blockDefault = '' - finalDefault = '' - language = None - version = None - id = '' -''' diff --git a/SOAPpy/wstools/XMLname.py b/SOAPpy/wstools/XMLname.py deleted file mode 100755 index 532f02b..0000000 --- a/SOAPpy/wstools/XMLname.py +++ /dev/null @@ -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, - -Also see . - -Author: Gregory R. Warnes -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 diff --git a/SOAPpy/wstools/__init__.py b/SOAPpy/wstools/__init__.py deleted file mode 100644 index 12a584f..0000000 --- a/SOAPpy/wstools/__init__.py +++ /dev/null @@ -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 diff --git a/SOAPpy/wstools/test/__init__.py b/SOAPpy/wstools/test/__init__.py deleted file mode 100644 index d5a5350..0000000 --- a/SOAPpy/wstools/test/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -#! /usr/bin/env python -"""wstools.WSDLTools.WSDLReader tests directory.""" - -import utils - diff --git a/SOAPpy/wstools/test/test_t1.py b/SOAPpy/wstools/test/test_t1.py deleted file mode 100644 index 5c33899..0000000 --- a/SOAPpy/wstools/test/test_t1.py +++ /dev/null @@ -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() - - diff --git a/SOAPpy/wstools/test/test_wsdl.py b/SOAPpy/wstools/test/test_wsdl.py deleted file mode 100644 index 90b0c4d..0000000 --- a/SOAPpy/wstools/test/test_wsdl.py +++ /dev/null @@ -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() diff --git a/SOAPpy/wstools/test/test_wstools.py b/SOAPpy/wstools/test/test_wstools.py deleted file mode 100644 index 0e0f958..0000000 --- a/SOAPpy/wstools/test/test_wstools.py +++ /dev/null @@ -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() - - diff --git a/SOAPpy/wstools/test/test_wstools_net.py b/SOAPpy/wstools/test/test_wstools_net.py deleted file mode 100644 index 880cff3..0000000 --- a/SOAPpy/wstools/test/test_wstools_net.py +++ /dev/null @@ -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() - -