Package suds :: Package bindings :: Module document
[hide private]
[frames] | no frames]

Source Code for Module suds.bindings.document

  1  # This program is free software; you can redistribute it and/or modify 
  2  # it under the terms of the (LGPL) GNU Lesser General Public License as 
  3  # published by the Free Software Foundation; either version 3 of the  
  4  # License, or (at your option) any later version. 
  5  # 
  6  # This program is distributed in the hope that it will be useful, 
  7  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  8  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  9  # GNU Library Lesser General Public License for more details at 
 10  # ( http://www.gnu.org/licenses/lgpl.html ). 
 11  # 
 12  # You should have received a copy of the GNU Lesser General Public License 
 13  # along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 15  # written by: Jeff Ortel ( jortel@redhat.com ) 
 16   
 17  """ 
 18  Provides classes for the (WS) SOAP I{document/literal}. 
 19  """ 
 20   
 21  from logging import getLogger 
 22  from suds import * 
 23  from suds.bindings.binding import Binding 
 24  from suds.sax.element import Element 
 25   
 26  log = getLogger(__name__) 
 27   
 28   
29 -class Document(Binding):
30 """ 31 The document/literal style. Literal is the only (@use) supported 32 since document/encoded is pretty much dead. 33 Although the soap specification supports multiple documents within the soap 34 <body/>, it is very uncommon. As such, suds presents an I{RPC} view of 35 service methods defined with a single document parameter. This is done so 36 that the user can pass individual parameters instead of one, single document. 37 To support the complete specification, service methods defined with multiple documents 38 (multiple message parts), must present a I{document} view for that method. 39 """ 40
41 - def bodycontent(self, method, args, kwargs):
42 # 43 # The I{wrapped} vs I{bare} style is detected in 2 ways. 44 # If there is 2+ parts in the message then it is I{bare}. 45 # If there is only (1) part and that part resolves to a builtin then 46 # it is I{bare}. Otherwise, it is I{wrapped}. 47 # 48 if not len(method.soap.input.body.parts): 49 return () 50 wrapped = method.soap.input.body.wrapped 51 if wrapped: 52 pts = self.bodypart_types(method) 53 root = self.document(pts[0]) 54 else: 55 root = [] 56 n = 0 57 for pd in self.param_defs(method): 58 if n < len(args): 59 value = args[n] 60 else: 61 value = kwargs.get(pd[0]) 62 n += 1 63 p = self.mkparam(method, pd, value) 64 if p is None: 65 continue 66 if not wrapped: 67 ns = pd[1].namespace('ns0') 68 p.setPrefix(ns[0], ns[1]) 69 root.append(p) 70 return root
71
72 - def replycontent(self, method, body):
73 wrapped = method.soap.output.body.wrapped 74 if wrapped: 75 return body[0].children 76 else: 77 return body.children
78
79 - def document(self, wrapper):
80 """ 81 Get the document root. For I{document/literal}, this is the 82 name of the wrapper element qualifed by the schema tns. 83 @param wrapper: The method name. 84 @type wrapper: L{xsd.sxbase.SchemaObject} 85 @return: A root element. 86 @rtype: L{Element} 87 """ 88 tag = wrapper[1].name 89 ns = wrapper[1].namespace('ns0') 90 d = Element(tag, ns=ns) 91 return d
92
93 - def mkparam(self, method, pdef, object):
94 # 95 # Expand list parameters into individual parameters 96 # each with the type information. This is because in document 97 # arrays are simply unbounded elements. 98 # 99 if isinstance(object, (list, tuple)): 100 tags = [] 101 for item in object: 102 tags.append(self.mkparam(method, pdef, item)) 103 return tags 104 else: 105 return Binding.mkparam(self, method, pdef, object)
106
107 - def param_defs(self, method):
108 # 109 # Get parameter definitions for document literal. 110 # The I{wrapped} vs I{bare} style is detected in 2 ways. 111 # If there is 2+ parts in the message then it is I{bare}. 112 # If there is only (1) part and that part resolves to a builtin then 113 # it is I{bare}. Otherwise, it is I{wrapped}. 114 # 115 pts = self.bodypart_types(method) 116 wrapped = method.soap.input.body.wrapped 117 if not wrapped: 118 return pts 119 result = [] 120 # wrapped 121 for p in pts: 122 resolved = p[1].resolve() 123 for child, ancestry in resolved: 124 if child.isattr(): 125 continue 126 if self.bychoice(ancestry): 127 log.debug( 128 '%s\ncontained by <choice/>, excluded as param for %s()', 129 child, 130 method.name) 131 continue 132 result.append((child.name, child)) 133 return result
134
135 - def returned_types(self, method):
136 result = [] 137 wrapped = method.soap.output.body.wrapped 138 rts = self.bodypart_types(method, input=False) 139 if wrapped: 140 for pt in rts: 141 resolved = pt.resolve(nobuiltin=True) 142 for child, ancestry in resolved: 143 result.append(child) 144 break 145 else: 146 result += rts 147 return result
148
149 - def bychoice(self, ancestry):
150 """ 151 The ancestry contains a <choice/> 152 @param ancestry: A list of ancestors. 153 @type ancestry: list 154 @return: True if contains <choice/> 155 @rtype: boolean 156 """ 157 for x in ancestry: 158 if x.choice(): 159 return True 160 return False
161