Browse Source

----------------------------------------------------------------------

Modified Files:
 	WSDLTools.py -- Commented out the "imports" collection,
           which isn't of much use.

        Now URLs are resolved relative to the importing document.

        Support for this scenario:

            --- /Users/boverhof/Desktop/Wsdl/Service/whatever.wsdl
            <definition>
                <import location="../hello/hello.wsdl"/>
                ...
            </definition>

            --- /Users/boverhof/Desktop/Wsdl/hello/hello.wsdl
            <definition>
                <import location="goodbye.wsdl"/>
                ...
            </definition>

            --- /Users/boverhof/Desktop/Wsdl/hello/goodbye.wsdl
            <definition>
                ...
            </definition>




 ----------------------------------------------------------------------
main
Joshua Boverhof 20 years ago
parent
commit
1b14bde4bd
1 changed files with 57 additions and 18 deletions
  1. +57
    -18
      WSDLTools.py

+ 57
- 18
WSDLTools.py View File

@@ -15,6 +15,7 @@ from Namespaces import WSR, WSA
from StringIO import StringIO from StringIO import StringIO
import urllib import urllib



class WSDLReader: class WSDLReader:
"""A WSDLReader creates WSDL instances from urls and xml data.""" """A WSDLReader creates WSDL instances from urls and xml data."""


@@ -69,7 +70,7 @@ class WSDL:
self.messages = CollectionNS(self) self.messages = CollectionNS(self)
self.portTypes = CollectionNS(self) self.portTypes = CollectionNS(self)
self.bindings = CollectionNS(self) self.bindings = CollectionNS(self)
self.imports = Collection(self)
#self.imports = Collection(self)
self.types = Types(self) self.types = Types(self)
self.extensions = [] self.extensions = []
self.strict = strict self.strict = strict
@@ -77,7 +78,6 @@ class WSDL:
def __del__(self): def __del__(self):
if self.document is not None: if self.document is not None:
self.document.unlink() self.document.unlink()
self.document = None


version = '1.1' version = '1.1'


@@ -125,10 +125,10 @@ class WSDL:
self.bindings[name] = item self.bindings[name] = item
return item return item


def addImport(self, namespace, location):
item = ImportElement(namespace, location)
self.imports[namespace] = item
return item
#def addImport(self, namespace, location):
# item = ImportElement(namespace, location)
# self.imports[namespace] = item
# return item


def load(self, document): def load(self, document):
# We save a reference to the DOM document to ensure that elements # We save a reference to the DOM document to ensure that elements
@@ -152,26 +152,35 @@ class WSDL:


# Resolve (recursively) any import elements in the document. # Resolve (recursively) any import elements in the document.
imported = {} imported = {}
base_location = self.location
while 1: while 1:
#XXX
imports = [] imports = []
for element in DOM.getElements(definitions, 'import', NS_WSDL): for element in DOM.getElements(definitions, 'import', NS_WSDL):
location = DOM.getAttr(element, 'location') location = DOM.getAttr(element, 'location')
# Resolve relative location, and save
location = urllib.basejoin(base_location, location)

if not imported.has_key(location): if not imported.has_key(location):
imports.append(element) imports.append(element)

if not imports: if not imports:
break break
for element in imports: for element in imports:
self._import(document, element)
location = DOM.getAttr(element, 'location') location = DOM.getAttr(element, 'location')
self._import(document, element, base_location)
location = urllib.basejoin(base_location, location)
imported[location] = 1 imported[location] = 1
base_location = ''


reader = SchemaReader(base_url=self.location)
#reader = SchemaReader(base_url=self.location)
for element in DOM.getElements(definitions, None, None): for element in DOM.getElements(definitions, None, None):
targetNamespace = DOM.getAttr(element, 'targetNamespace') targetNamespace = DOM.getAttr(element, 'targetNamespace')
localName = element.localName localName = element.localName


if not DOM.nsUriMatch(element.namespaceURI, NS_WSDL): if not DOM.nsUriMatch(element.namespaceURI, NS_WSDL):
if localName == 'schema': if localName == 'schema':
reader = SchemaReader(base_url=self.location)
schema = reader.loadFromNode(WSDLToolsAdapter(self), element) schema = reader.loadFromNode(WSDLToolsAdapter(self), element)
schema.setBaseUrl(self.location) schema.setBaseUrl(self.location)
self.types.addSchema(schema) self.types.addSchema(schema)
@@ -222,30 +231,51 @@ class WSDL:


elif localName == 'types': elif localName == 'types':
self.types.documentation = GetDocumentation(element) self.types.documentation = GetDocumentation(element)
base_location = DOM.getAttr(element, 'base-location')
if base_location:
element.removeAttribute('base-location')
base_location = base_location or self.location
reader = SchemaReader(base_url=base_location)
for item in DOM.getElements(element, None, None): for item in DOM.getElements(element, None, None):
if item.localName == 'schema': if item.localName == 'schema':
schema = reader.loadFromNode(WSDLToolsAdapter(self), item) schema = reader.loadFromNode(WSDLToolsAdapter(self), item)
schema.setBaseUrl(self.location)
# XXX <types> could have been imported
#schema.setBaseUrl(self.location)
schema.setBaseUrl(base_location)
self.types.addSchema(schema) self.types.addSchema(schema)
else: else:
self.types.addExtension(item) self.types.addExtension(item)
# XXX remove the attribute
# element.removeAttribute('base-location')
continue continue


def _import(self, document, element):
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
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
"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>
base_location -- location of document from which this
<import> was gleaned.
'''
namespace = DOM.getAttr(element, 'namespace', default=None) namespace = DOM.getAttr(element, 'namespace', default=None)
location = DOM.getAttr(element, 'location', default=None) location = DOM.getAttr(element, 'location', default=None)
if namespace is None or location is None: if namespace is None or location is None:
raise WSDLError( raise WSDLError(
'Invalid import element (missing namespace or location).' 'Invalid import element (missing namespace or location).'
) )
if base_location:
location = urllib.basejoin(base_location, location)
element.setAttributeNS(None, 'location', location)


# Sort-of support relative locations to simplify unit testing. The
# WSDL specification actually doesn't allow relative URLs, so its
# ok that this only works with urls relative to the initial document.
location = urllib.basejoin(self.location, location)

obimport = self.addImport(namespace, location)
obimport._loaded = 1
#location = urllib.basejoin(self.location, location)
#obimport = self.addImport(namespace, location)
#obimport._loaded = 1


importdoc = DOM.loadFromURL(location) importdoc = DOM.loadFromURL(location)
try: try:
@@ -279,9 +309,18 @@ class WSDL:
if attrkey[0] == DOM.NS_XMLNS: if attrkey[0] == DOM.NS_XMLNS:
attr = attrsNS[attrkey].cloneNode(1) attr = attrsNS[attrkey].cloneNode(1)
child.setAttributeNode(attr) child.setAttributeNode(attr)

#XXX Quick Hack, should be in WSDL Namespace.
if child.localName == 'import':
rlocation = child.getAttributeNS(None, 'location')
alocation = urllib.basejoin(location, rlocation)
child.setAttribute('location', alocation)
elif child.localName == 'types':
child.setAttribute('base-location', location)

finally: finally:
importdoc.unlink() importdoc.unlink()

return location


class Element: class Element:
"""A class that provides common functions for WSDL element classes.""" """A class that provides common functions for WSDL element classes."""


Loading…
Cancel
Save