Package suds :: Module servicedefinition
[hide private]
[frames] | no frames]

Source Code for Module suds.servicedefinition

  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  The I{service definition} provides a textual representation of a service. 
 19  """ 
 20   
 21  from logging import getLogger 
 22  from suds import * 
 23  import suds.metrics as metrics 
 24  from suds.sax import Namespace 
 25   
 26  log = getLogger(__name__) 
 27   
28 -class ServiceDefinition:
29 """ 30 A service definition provides an object used to generate a textual description 31 of a service. 32 @ivar wsdl: A wsdl. 33 @type wsdl: L{wsdl.Definitions} 34 @ivar service: The service object. 35 @type service: L{suds.wsdl.Service} 36 @ivar ports: A list of port-tuple: (port, [(method-name, pdef)]) 37 @type ports: [port-tuple,..] 38 @ivar prefixes: A list of remapped prefixes. 39 @type prefixes: [(prefix,uri),..] 40 @ivar types: A list of type definitions 41 @type types: [I{Type},..] 42 """ 43
44 - def __init__(self, wsdl, service):
45 """ 46 @param wsdl: A wsdl object 47 @type wsdl: L{Definitions} 48 @param service: A service B{name}. 49 @type service: str 50 """ 51 self.wsdl = wsdl 52 self.service = service 53 self.ports = [] 54 self.params = [] 55 self.types = [] 56 self.prefixes = [] 57 self.addports() 58 self.paramtypes() 59 self.publictypes() 60 self.getprefixes() 61 self.pushprefixes()
62
63 - def pushprefixes(self):
64 """ 65 Add our prefixes to the wsdl so that when users invoke methods 66 and reference the prefixes, the will resolve properly. 67 """ 68 for ns in self.prefixes: 69 self.wsdl.root.addPrefix(ns[0], ns[1])
70
71 - def addports(self):
72 """ 73 Look through the list of service ports and construct a list of tuples where 74 each tuple is used to describe a port and it's list of methods as: 75 (port, [method]). Each method is tuple: (name, [pdef,..] where each pdef is 76 a tuple: (param-name, type). 77 """ 78 timer = metrics.Timer() 79 timer.start() 80 for port in self.service.ports: 81 p = self.findport(port) 82 for op in port.binding.operations.values(): 83 m = p[0].method(op.name) 84 binding = m.binding.input 85 method = (m.name, binding.param_defs(m)) 86 p[1].append(method) 87 metrics.log.debug("method '%s' created: %s", m.name, timer) 88 p[1].sort() 89 timer.stop()
90
91 - def findport(self, port):
92 """ 93 Find and return a port tuple for the specified port. 94 Created and added when not found. 95 @param port: A port. 96 @type port: I{service.Port} 97 @return: A port tuple. 98 @rtype: (port, [method]) 99 """ 100 for p in self.ports: 101 if p[0] == p: return p 102 p = (port, []) 103 self.ports.append(p) 104 return p
105
106 - def getprefixes(self):
107 """ 108 Add prefixes foreach namespace referenced by parameter types. 109 """ 110 namespaces = [] 111 for l in (self.params, self.types): 112 for t,r in l: 113 ns = r.namespace() 114 if ns[1] is None: continue 115 if ns[1] in namespaces: continue 116 if Namespace.xs(ns) or Namespace.xsd(ns): 117 continue 118 namespaces.append(ns[1]) 119 if t == r: continue 120 ns = t.namespace() 121 if ns[1] is None: continue 122 if ns[1] in namespaces: continue 123 namespaces.append(ns[1]) 124 i = 0 125 namespaces.sort() 126 for u in namespaces: 127 p = self.nextprefix() 128 ns = (p, u) 129 self.prefixes.append(ns)
130
131 - def paramtypes(self):
132 """ get all parameter types """ 133 for m in [p[1] for p in self.ports]: 134 for p in [p[1] for p in m]: 135 for pd in p: 136 if pd[1] in self.params: continue 137 item = (pd[1], pd[1].resolve()) 138 self.params.append(item)
139
140 - def publictypes(self):
141 """ get all public types """ 142 for t in self.wsdl.schema.types.values(): 143 if t in self.params: continue 144 if t in self.types: continue 145 item = (t, t) 146 self.types.append(item) 147 tc = lambda x,y: cmp(x[0].name, y[0].name) 148 self.types.sort(cmp=tc)
149
150 - def nextprefix(self):
151 """ 152 Get the next available prefix. This means a prefix starting with 'ns' with 153 a number appended as (ns0, ns1, ..) that is not already defined on the 154 wsdl document. 155 """ 156 used = [ns[0] for ns in self.prefixes] 157 used += [ns[0] for ns in self.wsdl.root.nsprefixes.items()] 158 for n in range(0,1024): 159 p = 'ns%d'%n 160 if p not in used: 161 return p 162 raise Exception('prefixes exhausted')
163
164 - def getprefix(self, u):
165 """ 166 Get the prefix for the specified namespace (uri) 167 @param u: A namespace uri. 168 @type u: str 169 @return: The namspace. 170 @rtype: (prefix, uri). 171 """ 172 for ns in Namespace.all: 173 if u == ns[1]: return ns[0] 174 for ns in self.prefixes: 175 if u == ns[1]: return ns[0] 176 raise Exception('ns (%s) not mapped' % u)
177
178 - def xlate(self, type):
179 """ 180 Get a (namespace) translated I{qualified} name for specified type. 181 @param type: A schema type. 182 @type type: I{suds.xsd.sxbasic.SchemaObject} 183 @return: A translated I{qualified} name. 184 @rtype: str 185 """ 186 resolved = type.resolve() 187 name = resolved.name 188 if type.unbounded(): 189 name += '[]' 190 ns = resolved.namespace() 191 if ns[1] == self.wsdl.tns[1]: 192 return name 193 prefix = self.getprefix(ns[1]) 194 return ':'.join((prefix, name))
195
196 - def description(self):
197 """ 198 Get a textual description of the service for which this object represents. 199 @return: A textual description. 200 @rtype: str 201 """ 202 s = [] 203 indent = (lambda n : '\n%*s'%(n*3,' ')) 204 s.append('Service ( %s ) tns="%s"' % (self.service.name, self.wsdl.tns[1])) 205 s.append(indent(1)) 206 s.append('Prefixes (%d)' % len(self.prefixes)) 207 for p in self.prefixes: 208 s.append(indent(2)) 209 s.append('%s = "%s"' % p) 210 s.append(indent(1)) 211 s.append('Ports (%d):' % len(self.ports)) 212 for p in self.ports: 213 s.append(indent(2)) 214 s.append('(%s)' % p[0].name) 215 s.append(indent(3)) 216 s.append('Methods (%d):' % len(p[1])) 217 for m in p[1]: 218 sig = [] 219 s.append(indent(4)) 220 sig.append(m[0]) 221 sig.append('(') 222 for p in m[1]: 223 sig.append(self.xlate(p[1])) 224 sig.append(' ') 225 sig.append(p[0]) 226 sig.append(', ') 227 sig.append(')') 228 try: 229 s.append(''.join(sig)) 230 except: 231 pass 232 s.append(indent(3)) 233 s.append('Types (%d):' % len(self.types)) 234 for t in self.types: 235 s.append(indent(4)) 236 s.append(self.xlate(t[0])) 237 s.append('\n\n') 238 return ''.join(s)
239
240 - def __str__(self):
241 return unicode(self).encode('utf-8')
242
243 - def __unicode__(self):
244 try: 245 return self.description() 246 except Exception, e: 247 log.exception(e) 248 return tostr(e)
249