@@ -1,2 +1,3 @@ | |||
dist | |||
*.egg-info | |||
*.pyc |
@@ -1,12 +1,11 @@ | |||
CHANGELOG | |||
=========== | |||
0.4 (unreleased) | |||
0.4 (2012-06-26) | |||
---------------- | |||
- Nothing changed yet. | |||
- Replaced print() with logging.debug() or warn() in order to allow users to change verbosity. | |||
- Added release.sh script which runs tests, pep8 and allow you to release only when these are passing. | |||
0.3 (2011-02-21) | |||
---------------- | |||
@@ -1,5 +1,5 @@ | |||
include README.txt | |||
include CHANGES.txt | |||
include README | |||
recursive-include src *.txt *.py *.tar.gz | |||
recursive-include docs *.* | |||
recursive-include src *.txt *.py *.tar.gz README | |||
@@ -2,21 +2,22 @@ | |||
# | |||
# $Id: setup.py,v 1.11 2005/02/15 16:32:22 warnes Exp $ | |||
import os,re | |||
import os | |||
import re | |||
from setuptools import setup, find_packages | |||
__version__ = '0.3' | |||
__version__ = '0.4' | |||
url="https://github.com/kiorky/wstools.git" | |||
url = "https://github.com/pycontribs/wstools.git" | |||
def read(*rnames): | |||
return "\n"+ open( | |||
return "\n" + open( | |||
os.path.join('.', *rnames) | |||
).read() | |||
long_description="""WSDL parsing services package for Web Services for Python. see """ + url \ | |||
long_description = """WSDL parsing services package for Web Services for Python. see """ + url \ | |||
+ read('README.txt')\ | |||
+ read('CHANGES.txt')\ | |||
@@ -25,13 +26,12 @@ setup( | |||
name="wstools", | |||
version=__version__, | |||
description="wstools", | |||
maintainer="Gregory Warnes, kiorky", | |||
maintainer_email="Gregory.R.Warnes@Pfizer.com, kiorky@cryptelium.net", | |||
url = url, | |||
maintainer="Gregory Warnes, kiorky, sorin", | |||
maintainer_email="Gregory.R.Warnes@Pfizer.com, kiorky@cryptelium.net, sorin.sbarnea@gmail.com", | |||
url=url, | |||
long_description=long_description, | |||
packages=find_packages('src'), | |||
package_dir = {'': 'src'}, | |||
include_package_data=True, | |||
package_dir={'': 'src'}, | |||
include_package_data=True, | |||
install_requires=[] | |||
) | |||
@@ -12,11 +12,12 @@ import sys | |||
#new line | |||
NL='\r\n' | |||
NL = '\r\n' | |||
_width = len(repr(sys.maxint-1)) | |||
_width = len(repr(sys.maxint - 1)) | |||
_fmt = '%%0%dd' % _width | |||
class MIMEMessage: | |||
def __init__(self): | |||
@@ -26,19 +27,18 @@ class MIMEMessage: | |||
self._boundary = "" | |||
def makeBoundary(self): | |||
#create the boundary | |||
#create the boundary | |||
msgparts = [] | |||
msgparts.append(self._xmlMessage) | |||
for i in self._files: | |||
msgparts.append(i.read()) | |||
#this sucks, all in memory | |||
alltext = NL.join(msgparts) | |||
self._boundary = _make_boundary(alltext) | |||
self._boundary = _make_boundary(alltext) | |||
#maybe I can save some memory | |||
del alltext | |||
del msgparts | |||
self._startCID = "<" + (_fmt % random.randrange(sys.maxint)) + (_fmt % random.randrange(sys.maxint)) + ">" | |||
self._startCID = "<" + (_fmt % random.randrange(sys.maxint)) + (_fmt % random.randrange(sys.maxint)) + ">" | |||
def toString(self): | |||
'''it return a string with the MIME message''' | |||
@@ -61,7 +61,7 @@ class MIMEMessage: | |||
file.seek(0) | |||
returnstr += file.read() + NL | |||
#closing boundary | |||
returnstr += "--" + self._boundary + "--" + NL | |||
returnstr += "--" + self._boundary + "--" + NL | |||
return returnstr | |||
def attachFile(self, file): | |||
@@ -78,7 +78,7 @@ class MIMEMessage: | |||
def getBoundary(self): | |||
''' | |||
this function returns the string used in the mime message as a | |||
this function returns the string used in the mime message as a | |||
boundary. First the write method as to be called | |||
''' | |||
return self._boundary | |||
@@ -107,4 +107,3 @@ def _make_boundary(text=None): | |||
b = boundary + '.' + str(counter) | |||
counter += 1 | |||
return b | |||
@@ -6,76 +6,76 @@ | |||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | |||
# FOR A PARTICULAR PURPOSE. | |||
"""Namespace module, so you don't need PyXML | |||
"""Namespace module, so you don't need PyXML | |||
""" | |||
ident = "$Id$" | |||
try: | |||
from xml.ns import SOAP, SCHEMA, WSDL, XMLNS, DSIG, ENCRYPTION | |||
DSIG.C14N = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" | |||
DSIG.C14N = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" | |||
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" | |||
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 | |||
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/" | |||
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/" | |||
BIND_SOAP12 = "http://schemas.xmlsoap.org/wsdl/soap12/" | |||
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" | |||
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/2001/REC-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" | |||
BASE = "http://www.w3.org/2000/09/xmldsig#" | |||
C14N = "http://www.w3.org/TR/2001/REC-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" | |||
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" | |||
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 WSRF_V1_2: | |||
@@ -123,9 +123,9 @@ WSRFLIST = (WSRF_V1_2,) | |||
class OASIS: | |||
'''URLs for Oasis specifications | |||
''' | |||
WSSE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" | |||
WSSE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" | |||
UTILITY = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" | |||
class X509TOKEN: | |||
Base64Binary = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" | |||
STRTransform = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0" | |||
@@ -133,7 +133,7 @@ class OASIS: | |||
X509 = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509" | |||
X509PKIPathv1 = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" | |||
X509v3SubjectKeyIdentifier = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3SubjectKeyIdentifier" | |||
LIFETIME = WSRF_V1_2.LIFETIME.XSD_DRAFT1 | |||
PROPERTIES = WSRF_V1_2.PROPERTIES.XSD_DRAFT1 | |||
BASENOTIFICATION = WSRF_V1_2.BASENOTIFICATION.XSD_DRAFT1 | |||
@@ -151,45 +151,50 @@ class WSTRUST: | |||
BASE = "http://schemas.xmlsoap.org/ws/2004/04/trust" | |||
ISSUE = "http://schemas.xmlsoap.org/ws/2004/04/trust/Issue" | |||
class WSSE: | |||
BASE = "http://schemas.xmlsoap.org/ws/2002/04/secext" | |||
TRUST = WSTRUST.BASE | |||
BASE = "http://schemas.xmlsoap.org/ws/2002/04/secext" | |||
TRUST = WSTRUST.BASE | |||
class WSU: | |||
BASE = "http://schemas.xmlsoap.org/ws/2002/04/utility" | |||
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" | |||
LIFETIME = "http://www.ibm.com/xmlns/stdwip/web-services/WS-ResourceLifetime" | |||
class WSA200508: | |||
ADDRESS = "http://www.w3.org/2005/08/addressing" | |||
ANONYMOUS = "%s/anonymous" %ADDRESS | |||
FAULT = "%s/fault" %ADDRESS | |||
ADDRESS = "http://www.w3.org/2005/08/addressing" | |||
ANONYMOUS = "%s/anonymous" % ADDRESS | |||
FAULT = "%s/fault" % ADDRESS | |||
class WSA200408: | |||
ADDRESS = "http://schemas.xmlsoap.org/ws/2004/08/addressing" | |||
ANONYMOUS = "%s/role/anonymous" %ADDRESS | |||
FAULT = "%s/fault" %ADDRESS | |||
ADDRESS = "http://schemas.xmlsoap.org/ws/2004/08/addressing" | |||
ANONYMOUS = "%s/role/anonymous" % ADDRESS | |||
FAULT = "%s/fault" % ADDRESS | |||
class WSA200403: | |||
ADDRESS = "http://schemas.xmlsoap.org/ws/2004/03/addressing" | |||
ANONYMOUS = "%s/role/anonymous" %ADDRESS | |||
FAULT = "%s/fault" %ADDRESS | |||
ADDRESS = "http://schemas.xmlsoap.org/ws/2004/03/addressing" | |||
ANONYMOUS = "%s/role/anonymous" % ADDRESS | |||
FAULT = "%s/fault" % ADDRESS | |||
class WSA200303: | |||
ADDRESS = "http://schemas.xmlsoap.org/ws/2003/03/addressing" | |||
ANONYMOUS = "%s/role/anonymous" %ADDRESS | |||
FAULT = None | |||
ADDRESS = "http://schemas.xmlsoap.org/ws/2003/03/addressing" | |||
ANONYMOUS = "%s/role/anonymous" % ADDRESS | |||
FAULT = None | |||
WSA = WSA200408 | |||
WSA_LIST = (WSA200508, WSA200408, WSA200403, WSA200303) | |||
class _WSAW(str): | |||
""" Define ADDRESS attribute to be compatible with WSA* layout """ | |||
ADDRESS = property(lambda s: s) | |||
@@ -197,18 +202,21 @@ class _WSAW(str): | |||
WSAW200605 = _WSAW("http://www.w3.org/2006/05/addressing/wsdl") | |||
WSAW_LIST = (WSAW200605,) | |||
class WSP: | |||
POLICY = "http://schemas.xmlsoap.org/ws/2002/12/policy" | |||
class BEA: | |||
SECCONV = "http://schemas.xmlsoap.org/ws/2004/04/sc" | |||
SCTOKEN = "http://schemas.xmlsoap.org/ws/2004/04/security/sc/sct" | |||
class GLOBUS: | |||
SECCONV = "http://wsrf.globus.org/core/2004/07/security/secconv" | |||
CORE = "http://www.globus.org/namespaces/2004/06/core" | |||
SIG = "http://www.globus.org/2002/04/xmlenc#gssapi-sign" | |||
TOKEN = "http://www.globus.org/ws/2004/09/security/sc#GSSAPI_GSI_TOKEN" | |||
CORE = "http://www.globus.org/namespaces/2004/06/core" | |||
SIG = "http://www.globus.org/2002/04/xmlenc#gssapi-sign" | |||
TOKEN = "http://www.globus.org/ws/2004/09/security/sc#GSSAPI_GSI_TOKEN" | |||
ZSI_SCHEMA_URI = 'http://www.zolera.com/schemas/ZSI/' |
@@ -6,16 +6,19 @@ | |||
The original timeout_socket is by: | |||
Scott Cotton <scott@chronis.pobox.com> | |||
Lloyd Zusman <ljz@asfast.com> | |||
Phil Mayes <pmayes@olivebr.com> | |||
Piers Lauder <piers@cs.su.oz.au> | |||
Radovan Garabik <garabik@melkor.dnp.fmph.uniba.sk> | |||
Scott Cotton <scott@chronis.pobox.com> | |||
Lloyd Zusman <ljz@asfast.com> | |||
Phil Mayes <pmayes@olivebr.com> | |||
Piers Lauder <piers@cs.su.oz.au> | |||
Radovan Garabik <garabik@melkor.dnp.fmph.uniba.sk> | |||
""" | |||
ident = "$Id$" | |||
import string, socket, select, errno | |||
import string | |||
import socket | |||
import select | |||
import errno | |||
WSAEINVAL = getattr(errno, 'WSAEINVAL', 10022) | |||
@@ -46,7 +49,7 @@ class TimeoutSocket: | |||
apply(sock.connect, addr) | |||
sock.setblocking(timeout != 0) | |||
return 1 | |||
except socket.error,why: | |||
except socket.error, why: | |||
if not timeout: | |||
raise | |||
sock.setblocking(1) | |||
@@ -58,12 +61,12 @@ class TimeoutSocket: | |||
errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK | |||
): | |||
raise | |||
r,w,e = select.select([],[sock],[],timeout) | |||
r, w, e = select.select([], [sock], [], timeout) | |||
if w: | |||
try: | |||
apply(sock.connect, addr) | |||
return 1 | |||
except socket.error,why: | |||
except socket.error, why: | |||
if len(why.args) == 1: | |||
code = 0 | |||
else: | |||
@@ -77,7 +80,7 @@ class TimeoutSocket: | |||
total = len(data) | |||
next = 0 | |||
while 1: | |||
r, w, e = select.select([],[self.sock], [], self.timeout) | |||
r, w, e = select.select([], [self.sock], [], self.timeout) | |||
if w: | |||
buff = data[next:next + 8192] | |||
sent = self.sock.send(buff, flags) | |||
@@ -119,7 +122,8 @@ class TimeoutSocket: | |||
self._rbuf = "" | |||
while n > 0: | |||
new = self.recv(max(n, self.buffsize)) | |||
if not new: break | |||
if not new: | |||
break | |||
k = len(new) | |||
if k > n: | |||
L.append(new[:n]) | |||
@@ -133,9 +137,10 @@ class TimeoutSocket: | |||
self._rbuf = "" | |||
while 1: | |||
new = self.recv(k) | |||
if not new: break | |||
if not new: | |||
break | |||
L.append(new) | |||
k = min(k*2, 1024**2) | |||
k = min(k * 2, 1024 ** 2) | |||
return "".join(L) | |||
def readline(self, limit=-1): | |||
@@ -143,22 +148,28 @@ class TimeoutSocket: | |||
i = self._rbuf.find('\n') | |||
while i < 0 and not (0 < limit <= len(self._rbuf)): | |||
new = self.recv(self.buffsize) | |||
if not new: break | |||
if not new: | |||
break | |||
i = new.find('\n') | |||
if i >= 0: i = i + len(self._rbuf) | |||
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 | |||
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): | |||
def readlines(self, sizehint=0): | |||
total = 0 | |||
list = [] | |||
while 1: | |||
line = self.readline() | |||
if not line: break | |||
if not line: | |||
break | |||
list.append(line) | |||
total += len(line) | |||
if sizehint and total >= sizehint: | |||
@@ -8,7 +8,7 @@ Taken from Stefan Schwarzer's ftputil library, available at | |||
Copyright (C) 1999, Stefan Schwarzer | |||
Copyright (C) 1999, Stefan Schwarzer | |||
All rights reserved. | |||
Redistribution and use in source and binary forms, with or without | |||
@@ -42,15 +42,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
""" | |||
# $Id$ | |||
#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 = () | |||
@@ -67,24 +63,51 @@ class UserTuple: | |||
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 __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 | |||
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 __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) | |||
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) | |||
@@ -93,7 +116,7 @@ class UserTuple: | |||
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) | |||
return self.__class__(self.data * n) | |||
__rmul__ = __mul__ | |||
@@ -1,7 +1,8 @@ | |||
#!/usr/bin/env python | |||
# 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. | |||
# reserved. | |||
# | |||
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved. | |||
# | |||
@@ -14,7 +15,12 @@ | |||
ident = "$Id$" | |||
import sys, types, httplib, urllib, socket, weakref | |||
import sys | |||
import types | |||
import httplib | |||
import urllib | |||
import socket | |||
import weakref | |||
from os.path import isfile | |||
from string import join, strip, split | |||
from UserDict import UserDict | |||
@@ -48,17 +54,17 @@ try: | |||
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. | |||
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) | |||
@@ -77,10 +83,12 @@ basejoin = urllib.basejoin | |||
if sys.version_info[0:2] < (2, 4, 0, 'final', 0)[0:2]: | |||
#basejoin = lambda base,url: urllib.basejoin(base,url.lstrip('./')) | |||
token = './' | |||
def basejoin(base, url): | |||
def basejoin(base, url): | |||
if url.startswith(token) is True: | |||
return urllib.basejoin(base,url[2:]) | |||
return urllib.basejoin(base,url) | |||
return urllib.basejoin(base, url[2:]) | |||
return urllib.basejoin(base, url) | |||
class NamespaceError(Exception): | |||
"""Used to indicate a Namespace Error.""" | |||
@@ -101,7 +109,7 @@ class DOMException(Exception): | |||
class Base: | |||
"""Base class for instance level Logging""" | |||
def __init__(self, module=__name__): | |||
self.logger = logging.getLogger('%s-%s(%s)' %(module, self.__class__, _get_idstr(self))) | |||
self.logger = logging.getLogger('%s-%s(%s)' % (module, self.__class__, _get_idstr(self))) | |||
class HTTPResponse: | |||
@@ -114,6 +122,7 @@ class HTTPResponse: | |||
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): | |||
@@ -151,9 +160,12 @@ def urlopen(url, timeout=20, redirects=None): | |||
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 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 | |||
@@ -163,7 +175,7 @@ def urlopen(url, timeout=20, redirects=None): | |||
import M2Crypto | |||
except ImportError: | |||
if not hasattr(socket, 'ssl'): | |||
raise RuntimeError, 'no built-in SSL Support' | |||
raise RuntimeError('no built-in SSL Support') | |||
conn = TimeoutHTTPS(host, None, timeout) | |||
else: | |||
@@ -193,7 +205,7 @@ def urlopen(url, timeout=20, redirects=None): | |||
location = response.msg.getheader('location') | |||
if location is not None: | |||
response.close() | |||
if redirects is not None and redirects.has_key(location): | |||
if redirects is not None and location in redirects: | |||
raise RecursionError( | |||
'Circular HTTP redirection detected.' | |||
) | |||
@@ -210,14 +222,15 @@ def urlopen(url, timeout=20, redirects=None): | |||
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.""" | |||
looseNamespaces = False # if can't find a referenced namespace, try the default one | |||
looseNamespaces = False # if can't find a referenced namespace, try the default one | |||
# Namespace stuff related to the SOAP specification. | |||
NS_SOAP_ENV_1_1 = 'http://schemas.xmlsoap.org/soap/envelope/' | |||
@@ -233,14 +246,14 @@ class DOM: | |||
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', | |||
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) | |||
@@ -283,14 +296,12 @@ class DOM: | |||
'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_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_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' | |||
@@ -302,15 +313,14 @@ class DOM: | |||
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, | |||
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.""" | |||
@@ -321,9 +331,7 @@ class DOM: | |||
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 | |||
@@ -343,12 +351,11 @@ class DOM: | |||
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', | |||
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) | |||
@@ -403,11 +410,8 @@ class DOM: | |||
'Unsupported WSDL version: %s' % version | |||
) | |||
# Other xml namespace constants. | |||
NS_XMLNS = 'http://www.w3.org/2000/xmlns/' | |||
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 | |||
@@ -430,7 +434,7 @@ class DOM: | |||
return child | |||
if default is not join: | |||
return default | |||
raise KeyError, name | |||
raise KeyError(name) | |||
def getElementById(self, node, id, default=join): | |||
"""Return the first child of node matching an id reference.""" | |||
@@ -442,7 +446,7 @@ class DOM: | |||
return child | |||
if default is not join: | |||
return default | |||
raise KeyError, name | |||
raise KeyError(name) | |||
def getMappingById(self, document, depth=None, element=None, | |||
mapping=None, level=1): | |||
@@ -461,7 +465,7 @@ class DOM: | |||
for child in element.childNodes: | |||
if child.nodeType == ELEMENT_NODE: | |||
self.getMappingById(None, depth, child, mapping, level) | |||
return mapping | |||
return mapping | |||
def getElements(self, node, name, nsuri=None): | |||
"""Return a sequence of the child elements of the given node that | |||
@@ -507,10 +511,10 @@ class DOM: | |||
return '' | |||
def getAttrs(self, node): | |||
"""Return a Collection of all attributes | |||
"""Return a Collection of all attributes | |||
""" | |||
attrs = {} | |||
for k,v in node._attrs.items(): | |||
for k, v in node._attrs.items(): | |||
attrs[k] = v.value | |||
return attrs | |||
@@ -647,11 +651,11 @@ class DOM: | |||
else: | |||
file = urlopen(url) | |||
try: | |||
try: | |||
result = self.loadDocument(file) | |||
except Exception, ex: | |||
file.close() | |||
raise ParseError(('Failed to load document %s' %url,) + ex.args) | |||
raise ParseError(('Failed to load document %s' % url,) + ex.args) | |||
else: | |||
file.close() | |||
return result | |||
@@ -660,7 +664,7 @@ DOM = DOM() | |||
class MessageInterface: | |||
'''Higher Level Interface, delegates to DOM singleton, must | |||
'''Higher Level Interface, delegates to DOM singleton, must | |||
be subclassed and implement all methods that throw NotImplementedError. | |||
''' | |||
def __init__(self, sw): | |||
@@ -685,39 +689,39 @@ class MessageInterface: | |||
def canonicalize(self): | |||
'''canonicalize the underlying DOM, and return as string. | |||
''' | |||
raise NotImplementedError, '' | |||
raise NotImplementedError('') | |||
def createDocument(self, namespaceURI=SOAP.ENV, localName='Envelope'): | |||
'''create Document | |||
''' | |||
raise NotImplementedError, '' | |||
raise NotImplementedError('') | |||
def createAppendElement(self, namespaceURI, localName): | |||
'''create and append element(namespaceURI,localName), and return | |||
the node. | |||
''' | |||
raise NotImplementedError, '' | |||
raise NotImplementedError('') | |||
def findNamespaceURI(self, qualifiedName): | |||
raise NotImplementedError, '' | |||
raise NotImplementedError('') | |||
def resolvePrefix(self, prefix): | |||
raise NotImplementedError, '' | |||
raise NotImplementedError('') | |||
def setAttributeNS(self, namespaceURI, localName, value): | |||
'''set attribute (namespaceURI, localName)=value | |||
''' | |||
raise NotImplementedError, '' | |||
raise NotImplementedError('') | |||
def setAttributeType(self, namespaceURI, localName): | |||
'''set attribute xsi:type=(namespaceURI, localName) | |||
''' | |||
raise NotImplementedError, '' | |||
raise NotImplementedError('') | |||
def setNamespaceAttribute(self, namespaceURI, prefix): | |||
'''set namespace attribute xmlns:prefix=namespaceURI | |||
'''set namespace attribute xmlns:prefix=namespaceURI | |||
''' | |||
raise NotImplementedError, '' | |||
raise NotImplementedError('') | |||
class ElementProxy(Base, MessageInterface): | |||
@@ -734,27 +738,27 @@ class ElementProxy(Base, MessageInterface): | |||
_soap_env_nsuri = SOAP.ENV | |||
_soap_enc_nsuri = SOAP.ENC | |||
_zsi_nsuri = ZSI_SCHEMA_URI | |||
_xsd_nsuri = SCHEMA.XSD3 | |||
_xsd_nsuri = SCHEMA.XSD3 | |||
_xsi_nsuri = SCHEMA.XSI3 | |||
_xml_nsuri = XMLNS.XML | |||
_xmlns_nsuri = XMLNS.BASE | |||
standard_ns = {\ | |||
_xml_prefix:_xml_nsuri, | |||
_xmlns_prefix:_xmlns_nsuri | |||
_xml_prefix: _xml_nsuri, | |||
_xmlns_prefix: _xmlns_nsuri | |||
} | |||
reserved_ns = {\ | |||
_soap_env_prefix:_soap_env_nsuri, | |||
_soap_enc_prefix:_soap_enc_nsuri, | |||
_zsi_prefix:_zsi_nsuri, | |||
_xsd_prefix:_xsd_nsuri, | |||
_xsi_prefix:_xsi_nsuri, | |||
_soap_env_prefix: _soap_env_nsuri, | |||
_soap_enc_prefix: _soap_enc_nsuri, | |||
_zsi_prefix: _zsi_nsuri, | |||
_xsd_prefix: _xsd_nsuri, | |||
_xsi_prefix: _xsi_nsuri, | |||
} | |||
name = None | |||
namespaceURI = None | |||
def __init__(self, sw, message=None): | |||
'''Initialize. | |||
'''Initialize. | |||
sw -- SoapWriter | |||
''' | |||
self._indx = 0 | |||
@@ -762,7 +766,7 @@ class ElementProxy(Base, MessageInterface): | |||
Base.__init__(self) | |||
self._dom = DOM | |||
self.node = None | |||
if type(message) in (types.StringType,types.UnicodeType): | |||
if type(message) in (types.StringType, types.UnicodeType): | |||
self.loadFromString(message) | |||
elif isinstance(message, ElementProxy): | |||
self.node = message._getNode() | |||
@@ -783,11 +787,11 @@ class ElementProxy(Base, MessageInterface): | |||
else: | |||
context = XPath.Context.Context(self.node, processorNss=processorNss) | |||
nodes = expression.evaluate(context) | |||
return map(lambda node: ElementProxy(self.sw,node), nodes) | |||
return map(lambda node: ElementProxy(self.sw, node), nodes) | |||
############################################# | |||
# Methods for checking/setting the | |||
# classes (namespaceURI,name) node. | |||
# classes (namespaceURI,name) node. | |||
############################################# | |||
def checkNode(self, namespaceURI=None, localName=None): | |||
''' | |||
@@ -800,7 +804,7 @@ class ElementProxy(Base, MessageInterface): | |||
if localName and self.node: | |||
check = self._dom.isElement(self.node, localName, namespaceURI) | |||
if not check: | |||
raise NamespaceError, 'unexpected node type %s, expecting %s' %(self.node, localName) | |||
raise NamespaceError('unexpected node type %s, expecting %s' % (self.node, localName)) | |||
def setNode(self, node=None): | |||
if node: | |||
@@ -811,12 +815,12 @@ class ElementProxy(Base, MessageInterface): | |||
elif self.node: | |||
node = self._dom.getElement(self.node, self.name, self.namespaceURI, default=None) | |||
if not node: | |||
raise NamespaceError, 'cant find element (%s,%s)' %(self.namespaceURI,self.name) | |||
raise NamespaceError('cant find element (%s, %s)' % (self.namespaceURI, self.name)) | |||
self.node = node | |||
else: | |||
#self.node = self._dom.create(self.node, self.name, self.namespaceURI, default=None) | |||
self.createDocument(self.namespaceURI, localName=self.name, doctype=None) | |||
self.checkNode() | |||
############################################# | |||
@@ -833,12 +837,12 @@ class ElementProxy(Base, MessageInterface): | |||
def _getUniquePrefix(self): | |||
'''I guess we need to resolve all potential prefixes | |||
because when the current node is attached it copies the | |||
because when the current node is attached it copies the | |||
namespaces into the parent node. | |||
''' | |||
while 1: | |||
self._indx += 1 | |||
prefix = 'ns%d' %self._indx | |||
prefix = 'ns%d' % self._indx | |||
try: | |||
self._dom.findNamespaceURI(prefix, self._getNode()) | |||
except DOMException, ex: | |||
@@ -867,7 +871,7 @@ class ElementProxy(Base, MessageInterface): | |||
else: | |||
if node.parentNode: | |||
return self._getPrefix(node.parentNode, nsuri) | |||
raise NamespaceError, 'namespaceURI "%s" is not defined' %nsuri | |||
raise NamespaceError('namespaceURI "%s" is not defined' % nsuri) | |||
def _appendChild(self, node): | |||
''' | |||
@@ -875,14 +879,14 @@ class ElementProxy(Base, MessageInterface): | |||
node -- DOM Element Node | |||
''' | |||
if node is None: | |||
raise TypeError, 'node is None' | |||
raise TypeError('node is None') | |||
self.node.appendChild(node) | |||
def _insertBefore(self, newChild, refChild): | |||
''' | |||
Keyword arguments: | |||
child -- DOM Element Node to insert | |||
refChild -- DOM Element Node | |||
refChild -- DOM Element Node | |||
''' | |||
self.node.insertBefore(newChild, refChild) | |||
@@ -907,7 +911,7 @@ class ElementProxy(Base, MessageInterface): | |||
try: | |||
prefix = self._getPrefix(node=self.node, nsuri=namespaceURI) | |||
except NamespaceError, ex: | |||
prefix = self._getUniquePrefix() | |||
prefix = self._getUniquePrefix() | |||
self.setNamespaceAttribute(prefix, namespaceURI) | |||
return prefix | |||
@@ -943,20 +947,20 @@ class ElementProxy(Base, MessageInterface): | |||
prefix = self._soap_env_prefix | |||
if namespaceURI == self.reserved_ns[prefix]: | |||
qualifiedName = '%s:%s' %(prefix,localName) | |||
qualifiedName = '%s:%s' % (prefix, localName) | |||
elif namespaceURI is localName is None: | |||
self.node = self._dom.createDocument(None,None,None) | |||
self.node = self._dom.createDocument(None, None, None) | |||
return | |||
else: | |||
raise KeyError, 'only support creation of document in %s' %self.reserved_ns[prefix] | |||
raise KeyError('only support creation of document in %s' % self.reserved_ns[prefix]) | |||
document = self._dom.createDocument(nsuri=namespaceURI, qname=qualifiedName, doctype=doctype) | |||
self.node = document.childNodes[0] | |||
#set up reserved namespace attributes | |||
for prefix,nsuri in self.reserved_ns.items(): | |||
self._setAttributeNS(namespaceURI=self._xmlns_nsuri, | |||
qualifiedName='%s:%s' %(self._xmlns_prefix,prefix), | |||
for prefix, nsuri in self.reserved_ns.items(): | |||
self._setAttributeNS(namespaceURI=self._xmlns_nsuri, | |||
qualifiedName='%s:%s' % (self._xmlns_prefix, prefix), | |||
value=nsuri) | |||
############################################# | |||
@@ -975,10 +979,10 @@ class ElementProxy(Base, MessageInterface): | |||
self.logger.debug('setAttributeType: (%s,%s)', namespaceURI, localName) | |||
value = localName | |||
if namespaceURI: | |||
value = '%s:%s' %(self.getPrefix(namespaceURI),localName) | |||
value = '%s:%s' % (self.getPrefix(namespaceURI), localName) | |||
xsi_prefix = self.getPrefix(self._xsi_nsuri) | |||
self._setAttributeNS(self._xsi_nsuri, '%s:type' %xsi_prefix, value) | |||
self._setAttributeNS(self._xsi_nsuri, '%s:type' % xsi_prefix, value) | |||
def createAttributeNS(self, namespace, name, value): | |||
document = self._getOwnerDocument() | |||
@@ -992,7 +996,7 @@ class ElementProxy(Base, MessageInterface): | |||
attributes in no namespace. | |||
localName -- local name of new attribute | |||
value -- value of new attribute | |||
''' | |||
''' | |||
prefix = None | |||
if namespaceURI: | |||
try: | |||
@@ -1002,7 +1006,7 @@ class ElementProxy(Base, MessageInterface): | |||
self.setNamespaceAttribute(prefix, namespaceURI) | |||
qualifiedName = localName | |||
if prefix: | |||
qualifiedName = '%s:%s' %(prefix, localName) | |||
qualifiedName = '%s:%s' % (prefix, localName) | |||
self._setAttributeNS(namespaceURI, qualifiedName, value) | |||
def setNamespaceAttribute(self, prefix, namespaceURI): | |||
@@ -1011,7 +1015,7 @@ class ElementProxy(Base, MessageInterface): | |||
prefix -- xmlns prefix | |||
namespaceURI -- value of prefix | |||
''' | |||
self._setAttributeNS(XMLNS.BASE, 'xmlns:%s' %prefix, namespaceURI) | |||
self._setAttributeNS(XMLNS.BASE, 'xmlns:%s' % prefix, namespaceURI) | |||
############################################# | |||
#Methods for elements | |||
@@ -1036,7 +1040,7 @@ class ElementProxy(Base, MessageInterface): | |||
to 'ns1' if left unspecified. | |||
''' | |||
node = self.createAppendElement(namespaceURI, localName, prefix=None) | |||
node=node._getNode() | |||
node = node._getNode() | |||
self._setNode(node._getNode()) | |||
def createAppendElement(self, namespaceURI, localName, prefix=None): | |||
@@ -1056,19 +1060,19 @@ class ElementProxy(Base, MessageInterface): | |||
except: | |||
declare = True | |||
prefix = prefix or self._getUniquePrefix() | |||
if prefix: | |||
qualifiedName = '%s:%s' %(prefix, localName) | |||
if prefix: | |||
qualifiedName = '%s:%s' % (prefix, localName) | |||
node = self.createElementNS(namespaceURI, qualifiedName) | |||
if declare: | |||
node._setAttributeNS(XMLNS.BASE, 'xmlns:%s' %prefix, namespaceURI) | |||
node._setAttributeNS(XMLNS.BASE, 'xmlns:%s' % prefix, namespaceURI) | |||
self._appendChild(node=node._getNode()) | |||
return node | |||
def createInsertBefore(self, namespaceURI, localName, refChild): | |||
qualifiedName = localName | |||
prefix = self.getPrefix(namespaceURI) | |||
if prefix: | |||
qualifiedName = '%s:%s' %(prefix, localName) | |||
if prefix: | |||
qualifiedName = '%s:%s' % (prefix, localName) | |||
node = self.createElementNS(namespaceURI, qualifiedName) | |||
self._insertBefore(newChild=node._getNode(), refChild=refChild._getNode()) | |||
return node | |||
@@ -1091,12 +1095,12 @@ class ElementProxy(Base, MessageInterface): | |||
localName -- local name of attribute | |||
''' | |||
if self.hasAttribute(namespaceURI, localName): | |||
attr = self.node.getAttributeNodeNS(namespaceURI,localName) | |||
attr = self.node.getAttributeNodeNS(namespaceURI, localName) | |||
return attr.value | |||
return None | |||
def getValue(self): | |||
return self._dom.getElementText(self.node, preserve_ws=True) | |||
return self._dom.getElementText(self.node, preserve_ws=True) | |||
############################################# | |||
#Methods for text nodes | |||
@@ -1132,10 +1136,10 @@ class ElementProxy(Base, MessageInterface): | |||
return not self.node | |||
class Collection(UserDict): | |||
"""Helper class for maintaining ordered named collections.""" | |||
default = lambda self,k: k.name | |||
default = lambda self, k: k.name | |||
def __init__(self, parent, key=None): | |||
UserDict.__init__(self) | |||
self.parent = weakref.ref(parent) | |||
@@ -1143,7 +1147,8 @@ class Collection(UserDict): | |||
self._func = key or self.default | |||
def __getitem__(self, key): | |||
if type(key) is type(1): | |||
NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType) | |||
if isinstance(key, NumberTypes): | |||
return self.list[key] | |||
return self.data[key] | |||
@@ -1164,7 +1169,8 @@ class Collection(UserDict): | |||
class CollectionNS(UserDict): | |||
"""Helper class for maintaining ordered named collections.""" | |||
default = lambda self,k: k.name | |||
default = lambda self, k: k.name | |||
def __init__(self, parent, key=None): | |||
UserDict.__init__(self) | |||
self.parent = weakref.ref(parent) | |||
@@ -1174,10 +1180,10 @@ class CollectionNS(UserDict): | |||
def __getitem__(self, key): | |||
self.targetNamespace = self.parent().targetNamespace | |||
if type(key) is types.IntType: | |||
if isinstance(key, types.IntType): | |||
return self.list[key] | |||
elif self.__isSequence(key): | |||
nsuri,name = key | |||
nsuri, name = key | |||
return self.data[nsuri][name] | |||
return self.data[self.parent().targetNamespace][key] | |||
@@ -1185,17 +1191,17 @@ class CollectionNS(UserDict): | |||
item.parent = weakref.ref(self) | |||
self.list.append(item) | |||
targetNamespace = getattr(item, 'targetNamespace', self.parent().targetNamespace) | |||
if not self.data.has_key(targetNamespace): | |||
if not targetNamespace in self.data: | |||
self.data[targetNamespace] = {} | |||
self.data[targetNamespace][key] = item | |||
def __isSequence(self, key): | |||
return (type(key) in (types.TupleType,types.ListType) and len(key) == 2) | |||
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())) | |||
keys.append(map(lambda i: (tns, self._func(i)), self.data[tns].values())) | |||
return keys | |||
def items(self): | |||
@@ -1205,12 +1211,10 @@ class CollectionNS(UserDict): | |||
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): | |||
@@ -1222,7 +1226,7 @@ if 1: | |||
PullDOM.startPrefixMapping = startPrefixMapping | |||
def startElementNS(self, name, tagName , attrs): | |||
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) | |||
@@ -1253,7 +1257,7 @@ if 1: | |||
else: | |||
node = self.buildDocument(None, localname) | |||
for aname,value in attrs.items(): | |||
for aname, value in attrs.items(): | |||
a_uri, a_localname = aname | |||
if a_uri == xmlns_uri: | |||
if a_localname == 'xmlns': | |||
@@ -1294,7 +1298,7 @@ if 1: | |||
# ('http://www.w3.org/2000/xmlns/', 'xmlns') <xml.dom.minidom.Attr instance at 0x8414b3c> | |||
# | |||
# xml.dom.minidom.Attr.nodeName = xmlns:xsd | |||
# xml.dom.minidom.Attr.value = = http://www.w3.org/2001/XMLSchema | |||
# xml.dom.minidom.Attr.value = = http://www.w3.org/2001/XMLSchema | |||
if 1: | |||
def _clone_node(node, deep, newOwnerDocument): | |||
@@ -1385,4 +1389,3 @@ if 1: | |||
return clone | |||
xml.dom.minidom._clone_node = _clone_node | |||
@@ -20,7 +20,7 @@ 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 | |||
# 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): | |||
@@ -55,6 +55,7 @@ class WSDLReader: | |||
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 | |||
@@ -82,7 +83,7 @@ class WSDL: | |||
version = '1.1' | |||
def addService(self, name, documentation='', targetNamespace=None): | |||
if self.services.has_key(name): | |||
if name in self.services: | |||
raise WSDLError( | |||
'Duplicate service element: %s' % name | |||
) | |||
@@ -93,7 +94,7 @@ class WSDL: | |||
return item | |||
def addMessage(self, name, documentation='', targetNamespace=None): | |||
if self.messages.has_key(name): | |||
if name in self.messages: | |||
raise WSDLError( | |||
'Duplicate message element: %s.' % name | |||
) | |||
@@ -104,7 +105,7 @@ class WSDL: | |||
return item | |||
def addPortType(self, name, documentation='', targetNamespace=None): | |||
if self.portTypes.has_key(name): | |||
if name in self.portTypes: | |||
raise WSDLError( | |||
'Duplicate portType element: name' | |||
) | |||
@@ -115,7 +116,7 @@ class WSDL: | |||
return item | |||
def addBinding(self, name, type, documentation='', targetNamespace=None): | |||
if self.bindings.has_key(name): | |||
if name in self.bindings: | |||
raise WSDLError( | |||
'Duplicate binding element: %s' % name | |||
) | |||
@@ -133,11 +134,11 @@ class WSDL: | |||
def toDom(self): | |||
""" Generate a DOM representation of the WSDL instance. | |||
Not dealing with generating XML Schema, thus the targetNamespace | |||
of all XML Schema elements or types used by WSDL message parts | |||
of all XML Schema elements or types used by WSDL message parts | |||
needs to be specified via import information items. | |||
""" | |||
namespaceURI = DOM.GetWSDLUri(self.version) | |||
self.document = DOM.createDocument(namespaceURI ,'wsdl:definitions') | |||
self.document = DOM.createDocument(namespaceURI, 'wsdl:definitions') | |||
# Set up a couple prefixes for easy reading. | |||
child = DOM.getElement(self.document, None) | |||
@@ -146,12 +147,12 @@ class WSDL: | |||
child.setAttributeNS(XMLNS.BASE, 'xmlns:xsd', 'http://www.w3.org/1999/XMLSchema') | |||
child.setAttributeNS(XMLNS.BASE, 'xmlns:soap', 'http://schemas.xmlsoap.org/wsdl/soap/') | |||
child.setAttributeNS(XMLNS.BASE, 'xmlns:tns', self.targetNamespace) | |||
if self.name: | |||
child.setAttributeNS(None, 'name', self.name) | |||
# wsdl:import | |||
for item in self.imports: | |||
for item in self.imports: | |||
item.toDom() | |||
# wsdl:message | |||
for item in self.messages: | |||
@@ -186,13 +187,13 @@ class WSDL: | |||
self.name = DOM.getAttr(definitions, 'name', None, None) | |||
self.documentation = GetDocumentation(definitions) | |||
# | |||
# | |||
# Retrieve all <wsdl:import>'s, append all children of imported | |||
# document to main document. First iteration grab all original | |||
# <wsdl:import>'s from document, second iteration grab all | |||
# "imported" <wsdl:imports> from document, etc break out when | |||
# document to main document. First iteration grab all original | |||
# <wsdl:import>'s from document, second iteration grab all | |||
# "imported" <wsdl:imports> from document, etc break out when | |||
# no more <wsdl:import>'s. | |||
# | |||
# | |||
imported = [] | |||
base_location = self.location | |||
do_it = True | |||
@@ -203,7 +204,7 @@ class WSDL: | |||
if base_location is not None: | |||
location = basejoin(base_location, location) | |||
if location not in imported: | |||
do_it = True | |||
self._import(document, element, base_location) | |||
@@ -213,10 +214,10 @@ class WSDL: | |||
base_location = None | |||
# | |||
# No more <wsdl:import>'s, now load up all other | |||
# | |||
# No more <wsdl:import>'s, now load up all other | |||
# WSDL information items. | |||
# | |||
# | |||
for element in DOM.getElements(definitions, None, None): | |||
targetNamespace = DOM.getAttr(element, 'targetNamespace') | |||
localName = element.localName | |||
@@ -296,15 +297,15 @@ class WSDL: | |||
def _import(self, document, element, base_location=None): | |||
'''Algo take <import> element's children, clone them, | |||
and add them to the main document. Support for relative | |||
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 <types>, by creating a special temporary | |||
representing <types>, by creating a special temporary | |||
"base-location" attribute, and <import>, by resolving | |||
the relative "location" and storing it as "location". | |||
document -- document we are loading | |||
element -- DOM Element representing <import> | |||
element -- DOM Element representing <import> | |||
base_location -- location of document from which this | |||
<import> was gleaned. | |||
''' | |||
@@ -344,7 +345,7 @@ class WSDL: | |||
parent = element.parentNode | |||
parent.removeChild(element) | |||
for node in imported_nodes: | |||
if node.nodeType != node.ELEMENT_NODE: | |||
continue | |||
@@ -369,6 +370,7 @@ class WSDL: | |||
importdoc.unlink() | |||
return location | |||
class Element: | |||
"""A class that provides common functions for WSDL element classes.""" | |||
def __init__(self, name=None, documentation=''): | |||
@@ -379,7 +381,7 @@ class Element: | |||
def addExtension(self, item): | |||
item.parent = weakref.ref(self) | |||
self.extensions.append(item) | |||
def getWSDL(self): | |||
"""Return the WSDL object that contains this information item.""" | |||
parent = self | |||
@@ -387,9 +389,11 @@ class Element: | |||
# skip any collections | |||
if isinstance(parent, WSDL): | |||
return parent | |||
try: parent = parent.parent() | |||
except: break | |||
try: | |||
parent = parent.parent() | |||
except: | |||
break | |||
return None | |||
@@ -413,7 +417,8 @@ class ImportElement(Element): | |||
class Types(Collection): | |||
default = lambda self,k: k.targetNamespace | |||
default = lambda self, k: k.targetNamespace | |||
def __init__(self, parent): | |||
Collection.__init__(self, parent) | |||
self.documentation = '' | |||
@@ -434,7 +439,7 @@ class Message(Element): | |||
self.parts = Collection(self) | |||
def addPart(self, name, type=None, element=None): | |||
if self.parts.has_key(name): | |||
if name in self.parts: | |||
raise WSDLError( | |||
'Duplicate message part element: %s' % name | |||
) | |||
@@ -510,13 +515,13 @@ class MessagePart(Element): | |||
def getTypeDefinition(self): | |||
wsdl = self.getWSDL() | |||
nsuri,name = self.type | |||
nsuri, name = self.type | |||
schema = wsdl.types.get(nsuri, {}) | |||
return schema.get(name) | |||
def getElementDeclaration(self): | |||
wsdl = self.getWSDL() | |||
nsuri,name = self.element | |||
nsuri, name = self.element | |||
schema = wsdl.types.get(nsuri, {}) | |||
return schema.get(name) | |||
@@ -528,13 +533,13 @@ class MessagePart(Element): | |||
epc.setAttributeNS(None, 'name', self.name) | |||
if self.element is not None: | |||
ns,name = self.element | |||
ns, name = self.element | |||
prefix = epc.getPrefix(ns) | |||
epc.setAttributeNS(None, 'element', '%s:%s'%(prefix,name)) | |||
epc.setAttributeNS(None, 'element', '%s:%s' % (prefix, name)) | |||
elif self.type is not None: | |||
ns,name = self.type | |||
ns, name = self.type | |||
prefix = epc.getPrefix(ns) | |||
epc.setAttributeNS(None, 'type', '%s:%s'%(prefix,name)) | |||
epc.setAttributeNS(None, 'type', '%s:%s' % (prefix, name)) | |||
class PortType(Element): | |||
@@ -598,7 +603,8 @@ class PortType(Element): | |||
message = ParseQName(msgref, item) | |||
for WSA in WSA_LIST + WSAW_LIST: | |||
action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None) | |||
if action: break | |||
if action: | |||
break | |||
operation.setInput(message, name, docs, action) | |||
item = DOM.getElement(element, 'output', None, None) | |||
@@ -609,7 +615,8 @@ class PortType(Element): | |||
message = ParseQName(msgref, item) | |||
for WSA in WSA_LIST + WSAW_LIST: | |||
action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None) | |||
if action: break | |||
if action: | |||
break | |||
operation.setOutput(message, name, docs, action) | |||
for item in DOM.getElements(element, 'fault', None): | |||
@@ -619,9 +626,10 @@ class PortType(Element): | |||
message = ParseQName(msgref, item) | |||
for WSA in WSA_LIST + WSAW_LIST: | |||
action = DOM.getAttr(item, 'Action', WSA.ADDRESS, None) | |||
if action: break | |||
if action: | |||
break | |||
operation.addFault(message, name, docs, action) | |||
def toDom(self): | |||
wsdl = self.getWSDL() | |||
@@ -629,16 +637,15 @@ class PortType(Element): | |||
epc = ep.createAppendElement(DOM.GetWSDLUri(wsdl.version), 'portType') | |||
epc.setAttributeNS(None, 'name', self.name) | |||
if self.resourceProperties: | |||
ns,name = self.resourceProperties | |||
ns, name = self.resourceProperties | |||
prefix = epc.getPrefix(ns) | |||
epc.setAttributeNS(WSRF.PROPERTIES.LATEST, 'ResourceProperties', | |||
'%s:%s'%(prefix,name)) | |||
epc.setAttributeNS(WSRF.PROPERTIES.LATEST, 'ResourceProperties', | |||
'%s:%s' % (prefix, name)) | |||
for op in self.operations: | |||
op.toDom(epc._getNode()) | |||
class Operation(Element): | |||
def __init__(self, name, documentation='', parameterOrder=None): | |||
Element.__init__(self, name, documentation) | |||
@@ -683,7 +690,7 @@ class Operation(Element): | |||
return wsdl.messages[self.faults[name].message] | |||
def addFault(self, message, name, documentation='', action=None): | |||
if self.faults.has_key(name): | |||
if name in self.faults: | |||
raise WSDLError( | |||
'Duplicate fault element: %s' % name | |||
) | |||
@@ -709,11 +716,11 @@ class Operation(Element): | |||
epc.setAttributeNS(None, 'name', self.name) | |||
node = epc._getNode() | |||
if self.input: | |||
self.input.toDom(node) | |||
self.input.toDom(node) | |||
if self.output: | |||
self.output.toDom(node) | |||
self.output.toDom(node) | |||
for fault in self.faults: | |||
fault.toDom(node) | |||
fault.toDom(node) | |||
class MessageRole(Element): | |||
@@ -722,7 +729,7 @@ class MessageRole(Element): | |||
self.message = message | |||
self.type = type | |||
self.action = action | |||
def getWSDL(self): | |||
"""Return the WSDL object that contains this information item.""" | |||
parent = self | |||
@@ -730,13 +737,15 @@ class MessageRole(Element): | |||
# skip any collections | |||
if isinstance(parent, WSDL): | |||
return parent | |||
try: parent = parent.parent() | |||
except: break | |||
try: | |||
parent = parent.parent() | |||
except: | |||
break | |||
return None | |||
def getMessage(self): | |||
"""Return the WSDL object that represents the attribute message | |||
"""Return the WSDL object that represents the attribute message | |||
(namespaceURI, name) tuple | |||
""" | |||
wsdl = self.getWSDL() | |||
@@ -748,18 +757,18 @@ class MessageRole(Element): | |||
ep = ElementProxy(None, node) | |||
epc = ep.createAppendElement(DOM.GetWSDLUri(wsdl.version), self.type) | |||
if not isinstance(self.message, basestring) and len(self.message) == 2: | |||
ns,name = self.message | |||
ns, name = self.message | |||
prefix = epc.getPrefix(ns) | |||
epc.setAttributeNS(None, 'message', '%s:%s' %(prefix,name)) | |||
epc.setAttributeNS(None, 'message', '%s:%s' % (prefix, name)) | |||
else: | |||
epc.setAttributeNS(None, 'message', self.message) | |||
if self.action: | |||
epc.setAttributeNS(WSA.ADDRESS, 'Action', self.action) | |||
if self.name: | |||
epc.setAttributeNS(None, 'name', self.name) | |||
class Binding(Element): | |||
def __init__(self, name, type, documentation=''): | |||
@@ -782,7 +791,7 @@ class Binding(Element): | |||
return None | |||
def findBindings(self, kind): | |||
return [ item for item in self.extensions if isinstance(item, kind) ] | |||
return [item for item in self.extensions if isinstance(item, kind)] | |||
def addOperationBinding(self, name, documentation=''): | |||
item = OperationBinding(name, documentation) | |||
@@ -844,9 +853,9 @@ class Binding(Element): | |||
epc = ep.createAppendElement(DOM.GetWSDLUri(wsdl.version), 'binding') | |||
epc.setAttributeNS(None, 'name', self.name) | |||
ns,name = self.type | |||
ns, name = self.type | |||
prefix = epc.getPrefix(ns) | |||
epc.setAttributeNS(None, 'type', '%s:%s' %(prefix,name)) | |||
epc.setAttributeNS(None, 'type', '%s:%s' % (prefix, name)) | |||
node = epc._getNode() | |||
for ext in self.extensions: | |||
@@ -866,7 +875,6 @@ class OperationBinding(Element): | |||
# """Return the WSDL object that contains this binding.""" | |||
# return self.parent().parent().parent().parent() | |||
def getBinding(self): | |||
"""Return the parent Binding object of the operation binding.""" | |||
return self.parent().parent() | |||
@@ -874,7 +882,7 @@ class OperationBinding(Element): | |||
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): | |||
@@ -882,7 +890,7 @@ class OperationBinding(Element): | |||
return None | |||
def findBindings(self, kind): | |||
return [ item for item in self.extensions if isinstance(item, kind) ] | |||
return [item for item in self.extensions if isinstance(item, kind)] | |||
def addInputBinding(self, binding): | |||
if self.input is None: | |||
@@ -951,7 +959,7 @@ class MessageRoleBinding(Element): | |||
return None | |||
def findBindings(self, kind): | |||
return [ item for item in self.extensions if isinstance(item, kind) ] | |||
return [item for item in self.extensions if isinstance(item, kind)] | |||
def load_ex(self, elements): | |||
for e in elements: | |||
@@ -1038,7 +1046,8 @@ class MessageRoleBinding(Element): | |||
node = epc._getNode() | |||
for item in self.extensions: | |||
if item: item.toDom(node) | |||
if item: | |||
item.toDom(node) | |||
class Service(Element): | |||
@@ -1138,9 +1147,9 @@ class Port(Element): | |||
epc = ep.createAppendElement(DOM.GetWSDLUri(wsdl.version), "port") | |||
epc.setAttributeNS(None, "name", self.name) | |||
ns,name = self.binding | |||
ns, name = self.binding | |||
prefix = epc.getPrefix(ns) | |||
epc.setAttributeNS(None, "binding", "%s:%s" %(prefix,name)) | |||
epc.setAttributeNS(None, "binding", "%s:%s" % (prefix, name)) | |||
node = epc._getNode() | |||
for ext in self.extensions: | |||
@@ -1164,6 +1173,7 @@ class SoapBinding: | |||
if self.style: | |||
epc.setAttributeNS(None, "style", self.style) | |||
class SoapAddressBinding: | |||
def __init__(self, location): | |||
self.location = location | |||
@@ -1230,10 +1240,10 @@ class SoapFaultBinding: | |||
self.namespace = namespace | |||
self.name = name | |||
self.use = use | |||
def getWSDL(self): | |||
return self.parent().getWSDL() | |||
def toDom(self, node): | |||
wsdl = self.getWSDL() | |||
ep = ElementProxy(None, node) | |||
@@ -1260,6 +1270,7 @@ class SoapHeaderBinding: | |||
tagname = 'header' | |||
class SoapHeaderFaultBinding(SoapHeaderBinding): | |||
tagname = 'headerfault' | |||
@@ -1268,6 +1279,7 @@ class HttpBinding: | |||
def __init__(self, verb): | |||
self.verb = verb | |||
class HttpAddressBinding: | |||
def __init__(self, location): | |||
self.location = location | |||
@@ -1277,6 +1289,7 @@ class HttpOperationBinding: | |||
def __init__(self, location): | |||
self.location = location | |||
class HttpUrlReplacementBinding: | |||
pass | |||
@@ -1346,12 +1359,12 @@ 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: | |||
@@ -1359,6 +1372,7 @@ def ParseTypeRef(value, element): | |||
nsuri = DOM.findNamespaceURI(parts[0], element) | |||
return (nsuri, parts[1]) | |||
def ParseQName(value, element): | |||
nameref = value.split(':', 1) | |||
if len(nameref) == 2: | |||
@@ -1366,18 +1380,21 @@ def ParseQName(value, element): | |||
name = nameref[-1] | |||
else: | |||
nsuri = DOM.findTargetNS(element) | |||
name = nameref[-1] | |||
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 ] | |||
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 | |||
@@ -1388,6 +1405,7 @@ def GetWSAActionFault(operation, name): | |||
return attr | |||
return WSA.FAULT | |||
def GetWSAActionInput(operation): | |||
"""Find wsa:Action attribute, and return value or the default.""" | |||
attr = operation.input.action | |||
@@ -1400,8 +1418,9 @@ def GetWSAActionInput(operation): | |||
if not msgName: | |||
msgName = operation.name + 'Request' | |||
if targetNamespace.endswith('/'): | |||
return '%s%s/%s' %(targetNamespace, ptName, msgName) | |||
return '%s/%s/%s' %(targetNamespace, ptName, msgName) | |||
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.""" | |||
@@ -1414,26 +1433,28 @@ def GetWSAActionOutput(operation): | |||
if not msgName: | |||
msgName = operation.name + 'Response' | |||
if targetNamespace.endswith('/'): | |||
return '%s%s/%s' %(targetNamespace, ptName, msgName) | |||
return '%s/%s/%s' %(targetNamespace, ptName, msgName) | |||
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 | |||
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) ] | |||
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: | |||
and DOM.nsUriMatch(namespaceURI, item.namespaceURI) \ | |||
and item.name == name: | |||
return item | |||
else: | |||
for item in object.extensions: | |||
@@ -1443,7 +1464,7 @@ def FindExtension(object, kind, t_type=type(())): | |||
class SOAPCallInfo: | |||
"""SOAPCallInfo captures the important binding information about a | |||
"""SOAPCallInfo captures the important binding information about a | |||
SOAP operation, in a structure that is easier to work with than | |||
raw WSDL structures.""" | |||
@@ -1557,12 +1578,12 @@ def callInfoFromWSDL(port, name): | |||
addrbinding = port.getAddressBinding() | |||
if not isinstance(addrbinding, SoapAddressBinding): | |||
raise ValueError, 'Unsupported binding type.' | |||
raise ValueError('Unsupported binding type.') | |||
callinfo.location = addrbinding.location | |||
soapbinding = binding.findBinding(SoapBinding) | |||
if soapbinding is None: | |||
raise ValueError, 'Missing soap:binding element.' | |||
raise ValueError('Missing soap:binding element.') | |||
callinfo.transport = soapbinding.transport | |||
callinfo.style = soapbinding.style or 'document' | |||
@@ -1579,7 +1600,7 @@ def callInfoFromWSDL(port, name): | |||
mime = msgrole.findBinding(MimeMultipartRelatedBinding) | |||
if mime is not None: | |||
raise ValueError, 'Mime bindings are not supported.' | |||
raise ValueError('Mime bindings are not supported.') | |||
else: | |||
for item in msgrole.findBindings(SoapHeaderBinding): | |||
part = messages[item.message].parts[item.part] | |||
@@ -1587,13 +1608,13 @@ def callInfoFromWSDL(port, name): | |||
part.name, | |||
part.element or part.type, | |||
item.namespace, | |||
element_type = part.element and 1 or 0 | |||
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.' | |||
raise ValueError('Missing soap:body binding.') | |||
callinfo.encodingStyle = body.encodingStyle | |||
callinfo.namespace = body.namespace | |||
callinfo.use = body.use | |||
@@ -1609,7 +1630,7 @@ def callInfoFromWSDL(port, name): | |||
callinfo.addInParameter( | |||
part.name, | |||
part.element or part.type, | |||
element_type = part.element and 1 or 0 | |||
element_type=part.element and 1 or 0 | |||
) | |||
if operation.output is not None: | |||
@@ -1626,12 +1647,12 @@ def callInfoFromWSDL(port, name): | |||
"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.' | |||
raise ValueError('Mime bindings are not supported.') | |||
else: | |||
for item in msgrole.findBindings(SoapHeaderBinding): | |||
part = messages[item.message].parts[item.part] | |||
@@ -1639,13 +1660,13 @@ def callInfoFromWSDL(port, name): | |||
part.name, | |||
part.element or part.type, | |||
item.namespace, | |||
element_type = part.element and 1 or 0 | |||
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.' | |||
raise ValueError('Missing soap:body binding.') | |||
callinfo.encodingStyle = body.encodingStyle | |||
callinfo.namespace = body.namespace | |||
callinfo.use = body.use | |||
@@ -1662,7 +1683,7 @@ def callInfoFromWSDL(port, name): | |||
callinfo.addOutParameter( | |||
part.name, | |||
part.element or part.type, | |||
element_type = part.element and 1 or 0 | |||
element_type=part.element and 1 or 0 | |||
) | |||
return callinfo |
@@ -19,59 +19,68 @@ from re import * | |||
def _NCNameChar(x): | |||
return x.isalpha() or x.isdigit() or x=="." or x=='-' or x=="_" | |||
return x.isalpha() or x.isdigit() or x == "." or x == '-' or x == "_" | |||
def _NCNameStartChar(x): | |||
return x.isalpha() or 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 + "_" | |||
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]+'"' ) | |||
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) | |||
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 = [] | |||
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' ): | |||
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])): | |||
elif (not _NCNameChar(T[i])) or (i == 0 and not _NCNameStartChar(T[i])): | |||
X.append(_toUnicodeHex(T[i])) | |||
else: | |||
X.append(T[i]) | |||
if prefix: | |||
return "%s:%s" % (prefix, u''.join(X)) | |||
return u''.join(X) | |||
@@ -80,12 +89,11 @@ def toXMLname(string): | |||
def fromXMLname(string): | |||
"""Convert XML name to unicode string.""" | |||
retval = sub(r'_xFFFF_','', string ) | |||
retval = sub(r'_xFFFF_', '', string) | |||
def fun( matchobj ): | |||
return _fromUnicodeHex( matchobj.group(0) ) | |||
def fun(matchobj): | |||
return _fromUnicodeHex(matchobj.group(0)) | |||
retval = sub(r'_x[0-9A-Fa-f]{4}_', fun, retval) | |||
retval = sub(r'_x[0-9A-Fa-f]{4}_', fun, retval ) | |||
return retval |
@@ -6,4 +6,3 @@ ident = "$Id$" | |||
import WSDLTools | |||
import XMLname | |||
import logging | |||
@@ -5,10 +5,10 @@ Patches Applied to xml.dom.ext.c14n: | |||
http://sourceforge.net/projects/pyxml/ | |||
[ 1444526 ] c14n.py: http://www.w3.org/TR/xml-exc-c14n/ fix | |||
-- includes [ 829905 ] c14n.py fix for bug #825115, | |||
-- includes [ 829905 ] c14n.py fix for bug #825115, | |||
Date Submitted: 2003-10-24 23:43 | |||
-- include dependent namespace declarations declared in ancestor nodes | |||
(checking attributes and tags), | |||
-- include dependent namespace declarations declared in ancestor nodes | |||
(checking attributes and tags), | |||
-- handle InclusiveNamespaces PrefixList parameter | |||
This module generates canonical XML of a document or element. | |||
@@ -64,30 +64,35 @@ except ImportError: | |||
_attrs = lambda E: (E.attributes and E.attributes.values()) or [] | |||
_children = lambda E: E.childNodes or [] | |||
_IN_XML_NS = lambda n: n.name.startswith("xmlns") | |||
_inclusive = lambda n: n.unsuppressedPrefixes == None | |||
_inclusive = lambda n: n.unsuppressedPrefixes is None | |||
# Does a document/PI has lesser/greater document order than the | |||
# first element? | |||
_LesserElement, _Element, _GreaterElement = range(3) | |||
def _sorter(n1,n2): | |||
def _sorter(n1, n2): | |||
'''_sorter(n1,n2) -> int | |||
Sorting predicate for non-NS attributes.''' | |||
i = cmp(n1.namespaceURI, n2.namespaceURI) | |||
if i: return i | |||
if i: | |||
return i | |||
return cmp(n1.localName, n2.localName) | |||
def _sorter_ns(n1,n2): | |||
def _sorter_ns(n1, n2): | |||
'''_sorter_ns((n,v),(n,v)) -> int | |||
"(an empty namespace URI is lexicographically least)."''' | |||
if n1[0] == 'xmlns': return -1 | |||
if n2[0] == 'xmlns': return 1 | |||
if n1[0] == 'xmlns': | |||
return -1 | |||
if n2[0] == 'xmlns': | |||
return 1 | |||
return cmp(n1[0], n2[0]) | |||
def _utilized(n, node, other_attrs, unsuppressedPrefixes): | |||
'''_utilized(n, node, other_attrs, unsuppressedPrefixes) -> boolean | |||
Return true if that nodespace is utilized within the node''' | |||
@@ -95,32 +100,35 @@ def _utilized(n, node, other_attrs, unsuppressedPrefixes): | |||
n = n[6:] | |||
elif n.startswith('xmlns'): | |||
n = n[5:] | |||
if (n=="" and node.prefix in ["#default", None]) or \ | |||
n == node.prefix or n in unsuppressedPrefixes: | |||
if (n == "" and node.prefix in ["#default", None]) or \ | |||
n == node.prefix or n in unsuppressedPrefixes: | |||
return 1 | |||
for attr in other_attrs: | |||
if n == attr.prefix: return 1 | |||
if n == attr.prefix: | |||
return 1 | |||
# For exclusive need to look at attributes | |||
if unsuppressedPrefixes is not None: | |||
for attr in _attrs(node): | |||
if n == attr.prefix: return 1 | |||
if n == attr.prefix: | |||
return 1 | |||
return 0 | |||
def _inclusiveNamespacePrefixes(node, context, unsuppressedPrefixes): | |||
'''http://www.w3.org/TR/xml-exc-c14n/ | |||
InclusiveNamespaces PrefixList parameter, which lists namespace prefixes that | |||
'''http://www.w3.org/TR/xml-exc-c14n/ | |||
InclusiveNamespaces PrefixList parameter, which lists namespace prefixes that | |||
are handled in the manner described by the Canonical XML Recommendation''' | |||
inclusive = [] | |||
if node.prefix: | |||
usedPrefixes = ['xmlns:%s' %node.prefix] | |||
usedPrefixes = ['xmlns:%s' % node.prefix] | |||
else: | |||
usedPrefixes = ['xmlns'] | |||
for a in _attrs(node): | |||
if a.nodeName.startswith('xmlns') or not a.prefix: continue | |||
usedPrefixes.append('xmlns:%s' %a.prefix) | |||
if a.nodeName.startswith('xmlns') or not a.prefix: | |||
continue | |||
usedPrefixes.append('xmlns:%s' % a.prefix) | |||
unused_namespace_dict = {} | |||
for attr in context: | |||
@@ -139,7 +147,7 @@ def _inclusiveNamespacePrefixes(node, context, unsuppressedPrefixes): | |||
return inclusive, unused_namespace_dict | |||
#_in_subset = lambda subset, node: not subset or node in subset | |||
_in_subset = lambda subset, node: subset is None or node in subset # rich's tweak | |||
_in_subset = lambda subset, node: subset is None or node in subset # rich's tweak | |||
class _implementation: | |||
@@ -155,17 +163,17 @@ class _implementation: | |||
self.subset = kw.get('subset') | |||
self.comments = kw.get('comments', 0) | |||
self.unsuppressedPrefixes = kw.get('unsuppressedPrefixes') | |||
nsdict = kw.get('nsdict', { 'xml': XMLNS.XML, 'xmlns': XMLNS.BASE }) | |||
nsdict = kw.get('nsdict', {'xml': XMLNS.XML, 'xmlns': XMLNS.BASE}) | |||
# Processing state. | |||
self.state = (nsdict, {'xml':''}, {}, {}) #0422 | |||
self.state = (nsdict, {'xml': ''}, {}, {}) # 0422 | |||
if node.nodeType == Node.DOCUMENT_NODE: | |||
self._do_document(node) | |||
elif node.nodeType == Node.ELEMENT_NODE: | |||
self.documentOrder = _Element # At document element | |||
if not _inclusive(self): | |||
inherited,unused = _inclusiveNamespacePrefixes(node, self._inherit_context(node), | |||
inherited, unused = _inclusiveNamespacePrefixes(node, self._inherit_context(node), | |||
self.unsuppressedPrefixes) | |||
self._do_element(node, inherited, unused=unused) | |||
else: | |||
@@ -174,8 +182,7 @@ class _implementation: | |||
elif node.nodeType == Node.DOCUMENT_TYPE_NODE: | |||
pass | |||
else: | |||
raise TypeError, str(node) | |||
raise TypeError(str(node)) | |||
def _inherit_context(self, node): | |||
'''_inherit_context(self, node) -> list | |||
@@ -197,7 +204,6 @@ class _implementation: | |||
parent = parent.parentNode | |||
return inherited | |||
def _do_document(self, node): | |||
'''_do_document(self, node) -> None | |||
Process a document node. documentOrder holds whether the document | |||
@@ -209,7 +215,7 @@ class _implementation: | |||
if child.nodeType == Node.ELEMENT_NODE: | |||
self.documentOrder = _Element # At document element | |||
self._do_element(child) | |||
self.documentOrder = _GreaterElement # After document element | |||
self.documentOrder = _GreaterElement # After document element | |||
elif child.nodeType == Node.PROCESSING_INSTRUCTION_NODE: | |||
self._do_pi(child) | |||
elif child.nodeType == Node.COMMENT_NODE: | |||
@@ -217,33 +223,35 @@ class _implementation: | |||
elif child.nodeType == Node.DOCUMENT_TYPE_NODE: | |||
pass | |||
else: | |||
raise TypeError, str(child) | |||
raise TypeError(str(child)) | |||
handlers[Node.DOCUMENT_NODE] = _do_document | |||
def _do_text(self, node): | |||
'''_do_text(self, node) -> None | |||
Process a text or CDATA node. Render various special characters | |||
as their C14N entity representations.''' | |||
if not _in_subset(self.subset, node): return | |||
if not _in_subset(self.subset, node): | |||
return | |||
s = string.replace(node.data, "&", "&") | |||
s = string.replace(s, "<", "<") | |||
s = string.replace(s, ">", ">") | |||
s = string.replace(s, "\015", "
") | |||
if s: self.write(s) | |||
if s: | |||
self.write(s) | |||
handlers[Node.TEXT_NODE] = _do_text | |||
handlers[Node.CDATA_SECTION_NODE] = _do_text | |||
def _do_pi(self, node): | |||
'''_do_pi(self, node) -> None | |||
Process a PI node. Render a leading or trailing #xA if the | |||
document order of the PI is greater or lesser (respectively) | |||
than the document element. | |||
''' | |||
if not _in_subset(self.subset, node): return | |||
if not _in_subset(self.subset, node): | |||
return | |||
W = self.write | |||
if self.documentOrder == _GreaterElement: W('\n') | |||
if self.documentOrder == _GreaterElement: | |||
W('\n') | |||
W('<?') | |||
W(node.nodeName) | |||
s = node.data | |||
@@ -251,27 +259,29 @@ class _implementation: | |||
W(' ') | |||
W(s) | |||
W('?>') | |||
if self.documentOrder == _LesserElement: W('\n') | |||
if self.documentOrder == _LesserElement: | |||
W('\n') | |||
handlers[Node.PROCESSING_INSTRUCTION_NODE] = _do_pi | |||
def _do_comment(self, node): | |||
'''_do_comment(self, node) -> None | |||
Process a comment node. Render a leading or trailing #xA if the | |||
document order of the comment is greater or lesser (respectively) | |||
than the document element. | |||
''' | |||
if not _in_subset(self.subset, node): return | |||
if not _in_subset(self.subset, node): | |||
return | |||
if self.comments: | |||
W = self.write | |||
if self.documentOrder == _GreaterElement: W('\n') | |||
if self.documentOrder == _GreaterElement: | |||
W('\n') | |||
W('<!--') | |||
W(node.data) | |||
W('-->') | |||
if self.documentOrder == _LesserElement: W('\n') | |||
if self.documentOrder == _LesserElement: | |||
W('\n') | |||
handlers[Node.COMMENT_NODE] = _do_comment | |||
def _do_attr(self, n, value): | |||
''''_do_attr(self, node) -> None | |||
Process an attribute.''' | |||
@@ -289,8 +299,7 @@ class _implementation: | |||
W(s) | |||
W('"') | |||
def _do_element(self, node, initial_other_attrs = [], unused = None): | |||
def _do_element(self, node, initial_other_attrs=[], unused=None): | |||
'''_do_element(self, node, initial_other_attrs = [], unused = {}) -> None | |||
Process an element (and its children).''' | |||
@@ -300,14 +309,14 @@ class _implementation: | |||
# ns_local -- NS declarations relevant to this element | |||
# xml_attrs -- Attributes in XML namespace from parent | |||
# xml_attrs_local -- Local attributes in XML namespace. | |||
# ns_unused_inherited -- not rendered namespaces, used for exclusive | |||
# ns_unused_inherited -- not rendered namespaces, used for exclusive | |||
ns_parent, ns_rendered, xml_attrs = \ | |||
self.state[0], self.state[1].copy(), self.state[2].copy() #0422 | |||
self.state[0], self.state[1].copy(), self.state[2].copy() # 0422 | |||
ns_unused_inherited = unused | |||
if unused is None: | |||
ns_unused_inherited = self.state[3].copy() | |||
ns_local = ns_parent.copy() | |||
inclusive = _inclusive(self) | |||
xml_attrs_local = {} | |||
@@ -318,15 +327,16 @@ class _implementation: | |||
for a in initial_other_attrs + _attrs(node): | |||
if a.namespaceURI == XMLNS.BASE: | |||
n = a.nodeName | |||
if n == "xmlns:": n = "xmlns" # DOM bug workaround | |||
if n == "xmlns:": | |||
n = "xmlns" # DOM bug workaround | |||
ns_local[n] = a.nodeValue | |||
elif a.namespaceURI == XMLNS.XML: | |||
if inclusive or (in_subset and _in_subset(self.subset, a)): #020925 Test to see if attribute node in subset | |||
xml_attrs_local[a.nodeName] = a #0426 | |||
if inclusive or (in_subset and _in_subset(self.subset, a)): # 020925 Test to see if attribute node in subset | |||
xml_attrs_local[a.nodeName] = a # 0426 | |||
else: | |||
if _in_subset(self.subset, a): #020925 Test to see if attribute node in subset | |||
if _in_subset(self.subset, a): # 020925 Test to see if attribute node in subset | |||
other_attrs.append(a) | |||
# # TODO: exclusive, might need to define xmlns:prefix here | |||
# if not inclusive and a.prefix is not None and not ns_rendered.has_key('xmlns:%s' %a.prefix): | |||
# ns_local['xmlns:%s' %a.prefix] = ?? | |||
@@ -336,47 +346,45 @@ class _implementation: | |||
# Render the node | |||
W, name = self.write, None | |||
if in_subset: | |||
if in_subset: | |||
name = node.nodeName | |||
if not inclusive: | |||
if node.prefix is not None: | |||
prefix = 'xmlns:%s' %node.prefix | |||
prefix = 'xmlns:%s' % node.prefix | |||
else: | |||
prefix = 'xmlns' | |||
if not ns_rendered.has_key(prefix) and not ns_local.has_key(prefix): | |||
if not ns_unused_inherited.has_key(prefix): | |||
raise RuntimeError,\ | |||
'For exclusive c14n, unable to map prefix "%s" in %s' %( | |||
prefix, node) | |||
if prefix not in ns_rendered and prefix not in ns_local: | |||
if not prefix in ns_unused_inherited: | |||
raise RuntimeError('For exclusive c14n, unable to map prefix "%s" in %s' % ( | |||
prefix, node)) | |||
ns_local[prefix] = ns_unused_inherited[prefix] | |||
del ns_unused_inherited[prefix] | |||
W('<') | |||
W(name) | |||
# Create list of NS attributes to render. | |||
ns_to_render = [] | |||
for n,v in ns_local.items(): | |||
for n, v in ns_local.items(): | |||
# If default namespace is XMLNS.BASE or empty, | |||
# and if an ancestor was the same | |||
if n == "xmlns" and v in [ XMLNS.BASE, '' ] \ | |||
and ns_rendered.get('xmlns') in [ XMLNS.BASE, '', None ]: | |||
if n == "xmlns" and v in [XMLNS.BASE, ''] \ | |||
and ns_rendered.get('xmlns') in [XMLNS.BASE, '', None]: | |||
continue | |||
# "omit namespace node with local name xml, which defines | |||
# the xml prefix, if its string value is | |||
# http://www.w3.org/XML/1998/namespace." | |||
if n in ["xmlns:xml", "xml"] \ | |||
and v in [ 'http://www.w3.org/XML/1998/namespace' ]: | |||
and v in ['http://www.w3.org/XML/1998/namespace']: | |||
continue | |||
# If not previously rendered | |||
# and it's inclusive or utilized | |||
if (n,v) not in ns_rendered.items(): | |||
if (n, v) not in ns_rendered.items(): | |||
if inclusive or _utilized(n, node, other_attrs, self.unsuppressedPrefixes): | |||
ns_to_render.append((n, v)) | |||
elif not inclusive: | |||
@@ -384,14 +392,14 @@ class _implementation: | |||
# Sort and render the ns, marking what was rendered. | |||
ns_to_render.sort(_sorter_ns) | |||
for n,v in ns_to_render: | |||
for n, v in ns_to_render: | |||
self._do_attr(n, v) | |||
ns_rendered[n]=v #0417 | |||
ns_rendered[n] = v # 0417 | |||
# If exclusive or the parent is in the subset, add the local xml attributes | |||
# Else, add all local and ancestor xml attributes | |||
# Sort and render the attributes. | |||
if not inclusive or _in_subset(self.subset,node.parentNode): #0426 | |||
if not inclusive or _in_subset(self.subset, node.parentNode): # 0426 | |||
other_attrs.extend(xml_attrs_local.values()) | |||
else: | |||
other_attrs.extend(xml_attrs.values()) | |||
@@ -406,7 +414,8 @@ class _implementation: | |||
_implementation.handlers[c.nodeType](self, c) | |||
self.state = state | |||
if name: W('</%s>' % name) | |||
if name: | |||
W('</%s>' % name) | |||
handlers[Node.ELEMENT_NODE] = _do_element | |||
@@ -1,11 +1,12 @@ | |||
# 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. | |||
# reserved. | |||
# | |||
"""Logging""" | |||
ident = "$Id$" | |||
import os, sys | |||
import os | |||
import sys | |||
WARN = 1 | |||
DEBUG = 2 | |||
@@ -16,80 +17,92 @@ class ILogger: | |||
will be used and logging calls are no-ops. | |||
''' | |||
level = 0 | |||
def __init__(self, msg): | |||
return | |||
def warning(self, *args, **kw): | |||
return | |||
def debug(self, *args, **kw): | |||
return | |||
def error(self, *args, **kw): | |||
return | |||
def setLevel(cls, level): | |||
cls.level = level | |||
setLevel = classmethod(setLevel) | |||
debugOn = lambda self: self.level >= DEBUG | |||
warnOn = lambda self: self.level >= WARN | |||
class BasicLogger(ILogger): | |||
last = '' | |||
def __init__(self, msg, out=sys.stdout): | |||
self.msg, self.out = msg, out | |||
def warning(self, msg, *args, **kw): | |||
if self.warnOn() is False: return | |||
if self.warnOn() is False: | |||
return | |||
if BasicLogger.last != self.msg: | |||
BasicLogger.last = self.msg | |||
print >>self, "---- ", self.msg, " ----" | |||
print >>self, " %s " %self.WARN, | |||
print >>self, msg %args | |||
print >>self, " %s " % self.WARN, | |||
print >>self, msg % args | |||
WARN = '[WARN]' | |||
def debug(self, msg, *args, **kw): | |||
if self.debugOn() is False: return | |||
if self.debugOn() is False: | |||
return | |||
if BasicLogger.last != self.msg: | |||
BasicLogger.last = self.msg | |||
print >>self, "---- ", self.msg, " ----" | |||
print >>self, " %s " %self.DEBUG, | |||
print >>self, msg %args | |||
print >>self, " %s " % self.DEBUG, | |||
print >>self, msg % args | |||
DEBUG = '[DEBUG]' | |||
def error(self, msg, *args, **kw): | |||
if BasicLogger.last != self.msg: | |||
BasicLogger.last = self.msg | |||
print >>self, "---- ", self.msg, " ----" | |||
print >>self, " %s " %self.ERROR, | |||
print >>self, msg %args | |||
print >>self, " %s " % self.ERROR, | |||
print >>self, msg % args | |||
ERROR = '[ERROR]' | |||
def write(self, *args): | |||
'''Write convenience function; writes strings. | |||
''' | |||
for s in args: self.out.write(s) | |||
for s in args: | |||
self.out.write(s) | |||
event = ''.join(*args) | |||
_LoggerClass = BasicLogger | |||
class GridLogger(ILogger): | |||
def debug(self, msg, *args, **kw): | |||
kw['component'] = self.msg | |||
gridLog(event=msg %args, level='DEBUG', **kw) | |||
gridLog(event=msg % args, level='DEBUG', **kw) | |||
def warning(self, msg, *args, **kw): | |||
kw['component'] = self.msg | |||
gridLog(event=msg %args, level='WARNING', **kw) | |||
gridLog(event=msg % args, level='WARNING', **kw) | |||
def error(self, msg, *args, **kw): | |||
kw['component'] = self.msg | |||
gridLog(event=msg %args, level='ERROR', **kw) | |||
gridLog(event=msg % args, level='ERROR', **kw) | |||
# | |||
# | |||
# Registry of send functions for gridLog | |||
# | |||
# | |||
GLRegistry = {} | |||
class GLRecord(dict): | |||
"""Grid Logging Best Practices Record, Distributed Logging Utilities | |||
@@ -97,8 +110,8 @@ class GLRecord(dict): | |||
event -- log event name | |||
Below is EBNF for the event name part of a log message. | |||
name = <nodot> ( "." <name> )? | |||
nodot = {RFC3896-chars except "."} | |||
name = <nodot> ( "." <name> )? | |||
nodot = {RFC3896-chars except "."} | |||
Suffixes: | |||
start: Immediately before the first action in a task. | |||
@@ -108,14 +121,14 @@ class GLRecord(dict): | |||
ts -- timestamp | |||
level -- logging level (see levels below) | |||
status -- integer status code | |||
gid -- global grid identifier | |||
gid -- global grid identifier | |||
gid, cgid -- parent/child identifiers | |||
prog -- program name | |||
More info: http://www.cedps.net/wiki/index.php/LoggingBestPractices#Python | |||
reserved -- list of reserved names, | |||
reserved -- list of reserved names, | |||
omitname -- list of reserved names, output only values ('ts', 'event',) | |||
levels -- dict of levels and description | |||
""" | |||
@@ -129,8 +142,7 @@ class GLRecord(dict): | |||
NOTICE='Normal but significant condition.', | |||
INFO='Informational messages that would be useful to a deployer or administrator.', | |||
DEBUG='Lower level information concerning program logic decisions, internal state, etc.', | |||
TRACE='Finest granularity, similar to "stepping through" the component or system.', | |||
) | |||
TRACE='Finest granularity, similar to "stepping through" the component or system.',) | |||
def __init__(self, date=None, **kw): | |||
kw['ts'] = date or self.GLDate() | |||
@@ -141,31 +153,34 @@ class GLRecord(dict): | |||
""" | |||
""" | |||
from cStringIO import StringIO | |||
s = StringIO(); n = " " | |||
reserved = self.reserved; omitname = self.omitname; levels = self.levels | |||
s = StringIO() | |||
n = " " | |||
reserved = self.reserved | |||
omitname = self.omitname | |||
levels = self.levels | |||
for k in ( list(filter(lambda i: self.has_key(i), reserved)) + | |||
for k in (list(filter(lambda i: i in self, reserved)) + | |||
list(filter(lambda i: i not in reserved, self.keys())) | |||
): | |||
v = self[k] | |||
if k in omitname: | |||
s.write( "%s " %self.format[type(v)](v) ) | |||
if k in omitname: | |||
s.write("%s " % self.format[type(v)](v)) | |||
continue | |||
if k == reserved[2] and v not in levels: | |||
pass | |||
s.write( "%s=%s " %(k, self.format[type(v)](v) ) ) | |||
s.write("%s=%s " % (k, self.format[type(v)](v))) | |||
s.write("\n") | |||
return s.getvalue() | |||
class GLDate(str): | |||
"""Grid logging Date Format | |||
all timestamps should all be in the same time zone (UTC). | |||
all timestamps should all be in the same time zone (UTC). | |||
Grid timestamp value format that is a highly readable variant of the ISO8601 time standard [1]: | |||
YYYY-MM-DDTHH:MM:SS.SSSSSSZ | |||
YYYY-MM-DDTHH:MM:SS.SSSSSSZ | |||
""" | |||
def __new__(self, args=None): | |||
@@ -173,13 +188,13 @@ class GLRecord(dict): | |||
""" | |||
import datetime | |||
args = args or datetime.datetime.utcnow() | |||
l = (args.year, args.month, args.day, args.hour, args.minute, args.second, | |||
l = (args.year, args.month, args.day, args.hour, args.minute, args.second, | |||
args.microsecond, args.tzinfo or 'Z') | |||
return str.__new__(self, "%04d-%02d-%02dT%02d:%02d:%02d.%06d%s" %l) | |||
return str.__new__(self, "%04d-%02d-%02dT%02d:%02d:%02d.%06d%s" % l) | |||
format = { int:str, float:lambda x: "%lf" % x, long:str, str:lambda x:x, | |||
unicode:str, GLDate:str, } | |||
format = {int: str, float: lambda x: "%lf" % x, long: str, str: lambda x: x, | |||
unicode: str, GLDate: str, } | |||
def gridLog(**kw): | |||
@@ -193,29 +208,32 @@ def gridLog(**kw): | |||
""" | |||
import os | |||
if not bool( int(os.environ.get('GRIDLOG_ON', 0)) ): | |||
if not bool(int(os.environ.get('GRIDLOG_ON', 0))): | |||
return | |||
url = os.environ.get('GRIDLOG_DEST') | |||
if url is None: | |||
if url is None: | |||
return | |||
## NOTE: urlparse problem w/customized schemes | |||
## NOTE: urlparse problem w/customized schemes | |||
try: | |||
scheme = url[:url.find('://')] | |||
send = GLRegistry[scheme] | |||
send( url, str(GLRecord(**kw)), ) | |||
send(url, str(GLRecord(**kw)), ) | |||
except Exception, ex: | |||
print >>sys.stderr, "*** gridLog failed -- %s" %(str(kw)) | |||
print >>sys.stderr, "*** gridLog failed -- %s" % (str(kw)) | |||
def sendUDP(url, outputStr): | |||
from socket import socket, AF_INET, SOCK_DGRAM | |||
idx1 = url.find('://') + 3; idx2 = url.find('/', idx1) | |||
if idx2 < idx1: idx2 = len(url) | |||
idx1 = url.find('://') + 3 | |||
idx2 = url.find('/', idx1) | |||
if idx2 < idx1: | |||
idx2 = len(url) | |||
netloc = url[idx1:idx2] | |||
host,port = (netloc.split(':')+[80])[0:2] | |||
socket(AF_INET, SOCK_DGRAM).sendto( outputStr, (host,int(port)), ) | |||
host, port = (netloc.split(':') + [80])[0:2] | |||
socket(AF_INET, SOCK_DGRAM).sendto(outputStr, (host, int(port)), ) | |||
def writeToFile(url, outputStr): | |||
print >> open(url.split('://')[1], 'a+'), outputStr | |||
@@ -225,32 +243,37 @@ GLRegistry["file"] = writeToFile | |||
def setBasicLogger(): | |||
'''Use Basic Logger. | |||
'''Use Basic Logger. | |||
''' | |||
setLoggerClass(BasicLogger) | |||
BasicLogger.setLevel(0) | |||
def setGridLogger(): | |||
'''Use GridLogger for all logging events. | |||
''' | |||
setLoggerClass(GridLogger) | |||
def setBasicLoggerWARN(): | |||
'''Use Basic Logger. | |||
''' | |||
setLoggerClass(BasicLogger) | |||
BasicLogger.setLevel(WARN) | |||
def setBasicLoggerDEBUG(): | |||
'''Use Basic Logger. | |||
''' | |||
setLoggerClass(BasicLogger) | |||
BasicLogger.setLevel(DEBUG) | |||
def setLoggerClass(loggingClass): | |||
'''Set Logging Class. | |||
''' | |||
def setLoggerClass(loggingClass): | |||
'''Set Logging Class. | |||
''' | |||
@@ -258,17 +281,18 @@ def setLoggerClass(loggingClass): | |||
global _LoggerClass | |||
_LoggerClass = loggingClass | |||
def setLevel(level=0): | |||
'''Set Global Logging Level. | |||
''' | |||
ILogger.level = level | |||
def getLevel(): | |||
return ILogger.level | |||
def getLogger(msg): | |||
'''Return instance of Logging class. | |||
''' | |||
return _LoggerClass(msg) | |||
@@ -6,15 +6,16 @@ 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() | |||
if __name__ == "__main__": | |||
main() |
@@ -5,7 +5,8 @@ | |||
# See LBNLCopyright for copyright notice! | |||
########################################################################### | |||
import sys, unittest | |||
import sys | |||
import unittest | |||
import ConfigParser | |||
import os | |||
from wstools.Utility import DOM | |||
@@ -15,6 +16,7 @@ from wstools.TimeoutSocket import TimeoutError | |||
from wstools import tests | |||
cwd = os.path.dirname(tests.__file__) | |||
class WSDLToolsTestCase(unittest.TestCase): | |||
def __init__(self, methodName='runTest'): | |||
@@ -28,7 +30,7 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
def __str__(self): | |||
teststr = unittest.TestCase.__str__(self) | |||
if hasattr(self, "path"): | |||
return "%s: %s" % (teststr, self.path ) | |||
return "%s: %s" % (teststr, self.path) | |||
else: | |||
return "%s" % (teststr) | |||
@@ -41,12 +43,12 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
for node in DOM.getElements(definition, tag_name, nspname): | |||
name = DOM.getAttr(node, key) | |||
comp = component[name] | |||
self.failUnlessEqual(eval('comp.%s' %key), 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] | |||
component[name] | |||
def test_all(self): | |||
try: | |||
@@ -88,13 +90,14 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
raise | |||
try: | |||
self.checkWSDLCollection('import', self.wsdl.imports, key='namespace') | |||
self.checkWSDLCollection('import', self.wsdl.imports, \ | |||
key='namespace') | |||
except: | |||
self.path = self.path + ": wsdl.imports" | |||
raise | |||
try: | |||
for key in self.wsdl.types.keys(): | |||
for key in self.wsdl.types.keys(): | |||
schema = self.wsdl.types[key] | |||
self.failUnlessEqual(key, schema.getTargetNamespace()) | |||
@@ -114,8 +117,9 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
raise | |||
if self.wsdl.extensions: | |||
print 'No check for WSDLTools(%s) Extensions:' %(self.wsdl.name) | |||
for ext in self.wsdl.extensions: print '\t', ext | |||
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) | |||
@@ -133,7 +137,7 @@ class WSDLToolsTestCase(unittest.TestCase): | |||
def setUpOptions(section): | |||
cp = ConfigParser.ConfigParser() | |||
cp.read(cwd+'/config.txt') | |||
cp.read(cwd + '/config.txt') | |||
if not cp.sections(): | |||
print 'fatal error: configuration file config.txt not present' | |||
sys.exit(0) | |||
@@ -142,10 +146,12 @@ def setUpOptions(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 | |||
@@ -159,6 +165,7 @@ def makeTestSuite(section='services_by_file'): | |||
def main(): | |||
unittest.main(defaultTest="makeTestSuite") | |||
if __name__ == "__main__" : main() | |||
if __name__ == "__main__": | |||
main() |
@@ -5,13 +5,17 @@ | |||
# See LBNLCopyright for copyright notice! | |||
########################################################################### | |||
import unittest, tarfile, os, ConfigParser | |||
import unittest | |||
import tarfile | |||
import os | |||
import ConfigParser | |||
import test_wsdl | |||
SECTION='files' | |||
SECTION = 'files' | |||
CONFIG_FILE = 'config.txt' | |||
def extractFiles(section, option): | |||
config = ConfigParser.ConfigParser() | |||
config.read(CONFIG_FILE) | |||
@@ -20,18 +24,19 @@ def extractFiles(section, option): | |||
for file in archives: | |||
tar = tarfile.open(file) | |||
if not os.access(tar.membernames[0], os.R_OK): | |||
for i in tar.getnames(): | |||
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() | |||
if __name__ == "__main__": | |||
main() |
@@ -7,14 +7,15 @@ | |||
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() | |||
if __name__ == "__main__": | |||
main() |