Skip to content

Commit

Permalink
Provides the unmarshaller part of the 'enhanced soap encoded array su…
Browse files Browse the repository at this point in the history
…pport'. Flattens soap encoded arrays returned by rpc/encoded servers into python lists. ** IMPORTANT: This changes (improves) the form of returned soap encoded arrays. They are now flattened. Old, person.pets=(Pets)pets[]=[pet,], New person.pets=[pet,].

git-svn-id: http://svn.fedorahosted.org/svn/suds/trunk@607 0b8c961e-115e-4cb0-8d11-a7d6dae58e8c
  • Loading branch information
jortel committed Nov 24, 2009
1 parent 8481d87 commit ed87a5b
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 15 deletions.
14 changes: 13 additions & 1 deletion suds/bindings/rpc.py
Expand Up @@ -21,6 +21,7 @@
from logging import getLogger
from suds import *
from suds.mx.encoded import Encoded as MxEncoded
from suds.umx.encoded import Encoded as UmxEncoded
from suds.bindings.binding import Binding, envns
from suds.sax.element import Element

Expand Down Expand Up @@ -83,4 +84,15 @@ class Encoded(RPC):
"""

def marshaller(self):
return MxEncoded(self.schema)
return MxEncoded(self.schema)

def unmarshaller(self, typed=True):
"""
Get the appropriate XML decoder.
@return: Either the (basic|typed) unmarshaller.
@rtype: L{UmxTyped}
"""
if typed:
return UmxEncoded(self.schema)
else:
return RPC.unmarshaller(self, typed)
92 changes: 92 additions & 0 deletions suds/umx/encoded.py
@@ -0,0 +1,92 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the (LGPL) GNU Lesser General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library Lesser General Public License for more details at
# ( http://www.gnu.org/licenses/lgpl.html ).
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# written by: Jeff Ortel ( jortel@redhat.com )

"""
Provides soap encoded unmarshaller classes.
"""

from logging import getLogger
from suds import *
from suds.umx import *
from suds.umx.typed import Typed
from suds.sax import splitPrefix
from suds.xsd.query import TypeQuery

log = getLogger(__name__)


Content.extensions.append('aty')


class Encoded(Typed):
"""
A SOAP section (5) encoding unmarshaller.
This marshaller supports rpc/encoded soap styles.
"""

def start(self, content):
#
# Grab the array type and continue
#
start = Typed.start(self, content)
self.setaty(content)
return start

def end(self, content):
#
# Squash soap encoded arrays into python lists. This is
# also where we insure that empty arrays are represented
# as empty python lists.
#
aty = content.aty
if aty is not None:
pylist = []
if len(content.data):
items = content.data[0]
for x in items:
pylist.append(aty.translate(x))
content.data = pylist
return Typed.end(self, content)

def postprocess(self, content):
#
# Ensure proper rendering of empty arrays.
#
if content.aty is None:
return Typed.postprocess(self, content)
else:
return content.data

def setaty(self, content):
"""
Grab the (aty) soap-enc:arrayType and attach it to the
content for proper array processing later in end().
@param content: The current content being unmarshalled.
@type content: L{Content}
@return: self
@rtype: L{Encoded}
"""
spns = (None, 'http://schemas.xmlsoap.org/soap/encoding/')
aty = content.node.get('arrayType', spns)
if aty is None:
return
aty = aty.split('[')[0]
p,t = splitPrefix(aty)
ns = content.node.resolvePrefix(p)
qref = (t, ns[1])
query = TypeQuery(qref)
content.aty = query.execute(self.resolver.schema)
return self
5 changes: 3 additions & 2 deletions tests/axis1.py
Expand Up @@ -37,7 +37,7 @@
setup_logging()


logging.getLogger('suds.client').setLevel(logging.DEBUG)
#logging.getLogger('suds.client').setLevel(logging.DEBUG)

def start(url):
global errors
Expand All @@ -48,7 +48,7 @@ def start(url):
url = 'http://localhost:8081/axis/services/basic-rpc-encoded?wsdl'
start(url)
t = HttpAuthenticated(**credentials)
client = Client(url, transport=t)
client = Client(url, transport=t, cache=None)
print client
#
# create a name object using the wsdl
Expand Down Expand Up @@ -193,6 +193,7 @@ def start(url):
print 'getList(%s, %d)' % (s, n)
result = client.service.getList(s, n)
print '\nreply( %s )\n' % str(result)
assert ( isinstance(result, list) and len(result) == n )
except WebFault, f:
errors += 1
print f
Expand Down
14 changes: 6 additions & 8 deletions tests/axis2.py
Expand Up @@ -29,7 +29,7 @@

setup_logging()

logging.getLogger('suds.client').setLevel(logging.DEBUG)
#logging.getLogger('suds.client').setLevel(logging.DEBUG)

url = 'http://localhost:8080/axis2/services/BasicService?wsdl'

Expand Down Expand Up @@ -172,13 +172,11 @@
#
# test list returned
#
print 'getList(str, 1)'
result = client.service.getList('hello', 1)
print '\nreply( %s )\n' % str(result)

print 'getList(str, 3)'
result = client.service.getList('hello', 3)
print '\nreply( %s )\n' % str(result)
for n in range(0, 3):
print 'getList(str, %d)' % n
result = client.service.getList('hello', n)
print '\nreply( %s )\n' % str(result)
assert ( isinstance(result, list) and len(result) == n )

print 'addPet()'
dog = client.factory.create('ns2:Dog')
Expand Down
9 changes: 5 additions & 4 deletions tests/public.py
Expand Up @@ -59,13 +59,14 @@ def start(url):
result = client.service.echoFloat(input)
print 'echoFloat() = %s' % result
assert result == input
input = [1,2,3,4]
# suds 0.3.8+
result = client.service.echoIntegerArray([])
print 'echoIntegerArray() = %s' % result
assert result is None
input = [1,2,3,4]
result = client.service.echoIntegerArray(input)
print 'echoIntegerArray() = %s' % result
# looks like umx package needs an 'encoded' unmarshaller
# that respects arrayType="" and creates a python [].
# assert result == input
assert result == input
except WebFault, f:
errors += 1
print f
Expand Down

0 comments on commit ed87a5b

Please sign in to comment.