1############################################################################ 2# Monte M. Goode, LBNL 3# See LBNLCopyright for copyright notice! 4########################################################################### 5 6# contains text container classes for new generation generator 7 8# $Id: containers.py 1420 2007-10-31 19:51:00Z boverhof $ 9import types, warnings 10from utility import StringWriter, TextProtect, TextProtectAttributeName,\ 11 GetPartsSubNames 12from utility import NamespaceAliasDict as NAD, NCName_to_ClassName as NC_to_CN 13 14import ZSI 15from ZSI.TC import _is_xsd_or_soap_ns 16from ZSI.wstools import XMLSchema, WSDLTools 17from ZSI.wstools.Namespaces import SCHEMA, SOAP, WSDL 18from ZSI.wstools.logging import getLogger as _GetLogger 19from ZSI.typeinterpreter import BaseTypeInterpreter 20from ZSI.generate import WSISpec, WSInteropError, Wsdl2PythonError,\ 21 WsdlGeneratorError, WSDLFormatError 22 23ID1 = ' ' 24ID2 = 2*ID1 25ID3 = 3*ID1 26ID4 = 4*ID1 27ID5 = 5*ID1 28ID6 = 6*ID1 29 30KW = {'ID1':ID1, 'ID2':ID2, 'ID3':ID3,'ID4':ID4, 'ID5':ID5, 'ID6':ID6,} 31 32DEC = '_Dec' 33DEF = '_Def' 34 35""" 36type_class_name -- function to return the name formatted as a type class. 37element_class_name -- function to return the name formatted as an element class. 38""" 39type_class_name = lambda n: '%s%s' %(NC_to_CN(n), DEF) 40element_class_name = lambda n: '%s%s' %(NC_to_CN(n), DEC) 41 42 43def IsRPC(item): 44 """item -- OperationBinding instance. 45 """ 46 if not isinstance(item, WSDLTools.OperationBinding): 47 raise TypeError, 'IsRPC takes 1 argument of type WSDLTools.OperationBinding' 48 soapbinding = item.getBinding().findBinding(WSDLTools.SoapBinding) 49 sob = item.findBinding(WSDLTools.SoapOperationBinding) 50 style = soapbinding.style 51 if sob is not None: 52 style = sob.style or soapbinding.style 53 return style == 'rpc' 54 55 56def IsLiteral(item): 57 """item -- MessageRoleBinding instance. 58 """ 59 if not isinstance(item, WSDLTools.MessageRoleBinding): 60 raise TypeError, 'IsLiteral takes 1 argument of type WSDLTools.MessageRoleBinding' 61 sbb = None 62 if item.type == 'input' or item.type == 'output': 63 sbb = item.findBinding(WSDLTools.SoapBodyBinding) 64 if sbb is None: 65 raise ValueError, 'Missing soap:body binding.' 66 return sbb.use == 'literal' 67 68 69def SetTypeNameFunc(func): 70 global type_class_name 71 type_class_name = func 72 73def SetElementNameFunc(func): 74 global element_class_name 75 element_class_name = func 76 77def GetClassNameFromSchemaItem(item,do_extended=False): 78 ''' 79 ''' 80 assert isinstance(item, XMLSchema.XMLSchemaComponent), 'must be a schema item.' 81 alias = NAD.getAlias(item.getTargetNamespace()) 82 if item.isDefinition() is True: 83 return '%s.%s' %(alias, NC_to_CN('%s' %type_class_name(item.getAttributeName()))) 84 return None 85 86def FromMessageGetSimpleElementDeclaration(message): 87 '''If message consists of one part with an element attribute, 88 and this element is a simpleType return a string representing 89 the python type, else return None. 90 91 ''' 92 assert isinstance(message, WSDLTools.Message), 'expecting WSDLTools.Message' 93 94 if len(message.parts) == 1 and message.parts[0].element is not None: 95 part = message.parts[0] 96 nsuri,name = part.element 97 wsdl = message.getWSDL() 98 types = wsdl.types 99 if types.has_key(nsuri) and types[nsuri].elements.has_key(name): 100 e = types[nsuri].elements[name] 101 if isinstance(e, XMLSchema.ElementDeclaration) is True and e.getAttribute('type'): 102 typ = e.getAttribute('type') 103 bt = BaseTypeInterpreter() 104 ptype = bt.get_pythontype(typ[1], typ[0]) 105 return ptype 106 107 return None 108 109 110class AttributeMixIn: 111 '''for containers that can declare attributes. 112 Class Attributes: 113 attribute_typecode -- typecode attribute name typecode dict 114 built_in_refs -- attribute references that point to built-in 115 types. Skip resolving them into attribute declarations. 116 ''' 117 attribute_typecode = 'self.attribute_typecode_dict' 118 built_in_refs = [(SOAP.ENC, 'arrayType'),] 119 120 def _setAttributes(self, attributes): 121 '''parameters 122 attributes -- a flat list of all attributes, 123 from this list all items in attribute_typecode_dict will 124 be generated into attrComponents. 125 126 returns a list of strings representing the attribute_typecode_dict. 127 ''' 128 atd = self.attribute_typecode 129 atd_list = formatted_attribute_list = [] 130 if not attributes: 131 return formatted_attribute_list 132 133 atd_list.append('# attribute handling code') 134 idx = 0 135 while(idx < len(attributes)): 136 a = attributes[idx] 137 idx += 1 138 if a.isWildCard() and a.isDeclaration(): 139 atd_list.append(\ 140 '%s[("%s","anyAttribute")] = ZSI.TC.AnyElement()'\ 141 % (atd, SCHEMA.XSD3) 142 ) 143 elif a.isDeclaration(): 144 tdef = a.getTypeDefinition('type') 145 if tdef is not None: 146 tc = '%s.%s(None)' %(NAD.getAlias(tdef.getTargetNamespace()), 147 self.mangle(type_class_name(tdef.getAttributeName())) 148 ) 149 else: 150 # built-in 151 t = a.getAttribute('type') 152 try: 153 tc = BTI.get_typeclass(t[1], t[0]) 154 except: 155 # hand back a string by default. 156 tc = ZSI.TC.String 157 158 if tc is not None: 159 tc = '%s()' %tc 160 161 key = None 162 if a.getAttribute('form') == 'qualified': 163 key = '("%s","%s")' % ( a.getTargetNamespace(), 164 a.getAttribute('name') ) 165 elif a.getAttribute('form') == 'unqualified': 166 key = '"%s"' % a.getAttribute('name') 167 else: 168 raise ContainerError, \ 169 'attribute form must be un/qualified %s' \ 170 % a.getAttribute('form') 171 172 atd_list.append(\ 173 '%s[%s] = %s' % (atd, key, tc) 174 ) 175 elif a.isReference() and a.isAttributeGroup(): 176 # flatten 'em out.... 177 for ga in a.getAttributeGroup().getAttributeContent(): 178 attributes += (ga,) 179 180 elif a.isReference(): 181 try: 182 ga = a.getAttributeDeclaration() 183 except XMLSchema.SchemaError: 184 key = a.getAttribute('ref') 185 self.logger.debug('No schema item for attribute ref (%s, %s)' %key) 186 if key in self.built_in_refs: continue 187 raise 188 189 tp = None 190 if ga is not None: 191 tp = ga.getTypeDefinition('type') 192 key = '("%s","%s")' %(ga.getTargetNamespace(), 193 ga.getAttribute('name')) 194 195 if ga is None: 196 # TODO: probably SOAPENC:arrayType 197 key = '("%s","%s")' %( 198 a.getAttribute('ref').getTargetNamespace(), 199 a.getAttribute('ref').getName()) 200 atd_list.append(\ 201 '%s[%s] = ZSI.TC.String()' %(atd, key) 202 ) 203 elif tp is None: 204 # built in simple type 205 try: 206 namespace,typeName = ga.getAttribute('type') 207 except TypeError, ex: 208 # TODO: attribute declaration could be anonymous type 209 # hack in something to work 210 atd_list.append(\ 211 '%s[%s] = ZSI.TC.String()' %(atd, key) 212 ) 213 else: 214 atd_list.append(\ 215 '%s[%s] = %s()' %(atd, key, 216 BTI.get_typeclass(typeName, namespace)) 217 ) 218 else: 219 typeName = tp.getAttribute('name') 220 namespace = tp.getTargetNamespace() 221 alias = NAD.getAlias(namespace) 222 key = '("%s","%s")' \ 223 % (ga.getTargetNamespace(),ga.getAttribute('name')) 224 atd_list.append(\ 225 '%s[%s] = %s.%s(None)' \ 226 % (atd, key, alias, type_class_name(typeName)) 227 ) 228 else: 229 raise TypeError, 'expecting an attribute: %s' %a.getItemTrace() 230 231 return formatted_attribute_list 232 233 234class ContainerError(Exception): 235 pass 236 237 238class ContainerBase: 239 '''Base class for all Containers. 240 func_aname -- function that takes name, and returns aname. 241 ''' 242 func_aname = staticmethod(TextProtectAttributeName) 243 logger = _GetLogger("ContainerBase") 244 245 def __init__(self): 246 self.content = StringWriter('\n') 247 self.__setup = False 248 self.ns = None 249 250 def __str__(self): 251 return self.getvalue() 252 253 # - string content methods 254 def mangle(self, s): 255 '''class/variable name illegalities 256 ''' 257 return TextProtect(s) 258 259 def write(self, s): 260 self.content.write(s) 261 262 def writeArray(self, a): 263 self.content.write('\n'.join(a)) 264 265 def _setContent(self): 266 '''override in subclasses. formats the content in the desired way. 267 ''' 268 raise NotImplementedError, 'abstract method not implemented' 269 270 def getvalue(self): 271 if not self.__setup: 272 self._setContent() 273 self.__setup = True 274 275 return self.content.getvalue() 276 277 # - namespace utility methods 278 def getNSAlias(self): 279 if self.ns is not None: 280 return NAD.getAlias(self.ns) 281 raise ContainerError, 'no self.ns attr defined in %s' % self.__class__ 282 283 def getNSModuleName(self): 284 if self.ns: 285 return NAD.getModuleName(self.ns) 286 raise ContainerError, 'no self.ns attr defined in %s' % self.__class__ 287 288 def getAttributeName(self, name): 289 '''represents the aname 290 ''' 291 if self.func_aname is None: 292 return name 293 assert callable(self.func_aname), \ 294 'expecting callable method for attribute func_aname, not %s' %type(self.func_aname) 295 f = self.func_aname 296 return f(name) 297 298 299# -- containers for services file components 300 301class ServiceContainerBase(ContainerBase): 302 clientClassSuffix = "SOAP" 303 logger = _GetLogger("ServiceContainerBase") 304 305 306class ServiceHeaderContainer(ServiceContainerBase): 307 imports = ['\nimport urlparse, types', 308 'from ZSI.TCcompound import ComplexType, Struct', 309 'from ZSI import client', 310 'from ZSI.schema import GED, GTD', 311 'import ZSI' 312 ] 313 logger = _GetLogger("ServiceHeaderContainer") 314 315 def __init__(self, do_extended=False): 316 ServiceContainerBase.__init__(self) 317 318 self.basic = self.imports[:] 319 self.types = None 320 self.messages = None 321 self.extras = [] 322 self.do_extended = do_extended 323 324 def setTypesModuleName(self, module): 325 self.types = module 326 327 def setMessagesModuleName(self, module): 328 self.messages = module 329 330 def appendImport(self, statement): 331 '''append additional import statement(s). 332 import_stament -- tuple or list or str 333 ''' 334 if type(statement) in (list,tuple): 335 self.extras += statement 336 else: 337 self.extras.append(statement) 338 339 def _setContent(self): 340 if self.messages: 341 self.write('from %s import *' % self.messages) 342 if self.types: 343 self.write('from %s import *' % self.types) 344 345 imports = self.basic[:] 346 imports += self.extras 347 self.writeArray(imports) 348 349 350class ServiceLocatorContainer(ServiceContainerBase): 351 logger = _GetLogger("ServiceLocatorContainer") 352 353 def __init__(self): 354 ServiceContainerBase.__init__(self) 355 self.serviceName = None 356 self.portInfo = [] 357 self.locatorName = None 358 self.portMethods = [] 359 360 def setUp(self, service): 361 assert isinstance(service, WSDLTools.Service), \ 362 'expecting WDSLTools.Service instance.' 363 364 self.serviceName = service.name 365 for p in service.ports: 366 try: 367 ab = p.getAddressBinding() 368 except WSDLTools.WSDLError, ex: 369 self.logger.warning('Skip port(%s), missing address binding' %p.name) 370 continue 371 if isinstance(ab, WSDLTools.SoapAddressBinding) is False: 372 self.logger.warning('Skip port(%s), not a SOAP-1.1 address binding' %p.name) 373 continue 374 375 #info = (p.getBinding().getPortType().name, p.getBinding().name, ab.location) 376 self.portInfo.append( (NC_to_CN(p.name), 377 NC_to_CN(p.getBinding().name), 378 ab.location) 379 ) 380 381 def getLocatorName(self): 382 '''return class name of generated locator. 383 ''' 384 return self.locatorName 385 386 def getPortMethods(self): 387 '''list of get port accessor methods of generated locator class. 388 ''' 389 return self.portMethods 390 391 def _setContent(self): 392 if not self.serviceName: 393 raise ContainerError, 'no service name defined!' 394 395 self.serviceName = self.mangle(self.serviceName) 396 self.locatorName = '%sLocator' %self.serviceName 397 locator = ['# Locator', 'class %s:' %self.locatorName, ] 398 self.portMethods = [] 399 kwargs = KW.copy() 400 for port,bind,addr in self.portInfo: 401 # access method each port 402 method = 'get%s' %port 403 kwargs.update(dict(port=port, bind=bind, addr=addr, 404 service=self.serviceName, suffix=self.clientClassSuffix, method=method)) 405 406 locator += [ 407 '%(ID1)s%(port)s_address = "%(addr)s"' %kwargs, 408 '%(ID1)sdef get%(port)sAddress(self):' %kwargs, 409 '%(ID2)sreturn %(service)sLocator.%(port)s_address' %kwargs, 410 '%(ID1)sdef %(method)s(self, url=None, **kw):' %kwargs, 411 '%(ID2)sreturn %(bind)s%(suffix)s(url or %(service)sLocator.%(port)s_address, **kw)' %kwargs, 412 ] 413 414 self.portMethods.append(method) 415 416 self.writeArray(locator) 417 418 419class ServiceOperationContainer(ServiceContainerBase): 420 logger = _GetLogger("ServiceOperationContainer") 421 422 def __init__(self, useWSA=False, do_extended=False): 423 '''Parameters: 424 useWSA -- boolean, enable ws-addressing 425 do_extended -- boolean 426 ''' 427 ServiceContainerBase.__init__(self) 428 self.useWSA = useWSA 429 self.do_extended = do_extended 430 431 def hasInput(self): 432 return self.inputName is not None 433 434 def hasOutput(self): 435 return self.outputName is not None 436 437 def isRPC(self): 438 return IsRPC(self.binding_operation) 439 440 def isLiteral(self, input=True): 441 msgrole = self.binding_operation.input 442 if input is False: 443 msgrole = self.binding_operation.output 444 return IsLiteral(msgrole) 445 446 def isSimpleType(self, input=True): 447 if input is False: 448 return self.outputSimpleType 449 return self.inputSimpleType 450 451 def getOperation(self): 452 return self.port.operations.get(self.name) 453 454 def getBOperation(self): 455 return self.port.get(self.name) 456 457 def getOperationName(self): 458 return self.name 459 460 def setUp(self, item): 461 ''' 462 Parameters: 463 item -- WSDLTools BindingOperation instance. 464 ''' 465 if not isinstance(item, WSDLTools.OperationBinding): 466 raise TypeError, 'Expecting WSDLTools Operation instance' 467 468 if not item.input: 469 raise WSDLFormatError('No <input/> in <binding name="%s"><operation name="%s">' %( 470 item.getBinding().name, item.name)) 471 472 self.name = None 473 self.port = None 474 self.soapaction = None 475 self.inputName = None 476 self.outputName = None 477 self.inputSimpleType = None 478 self.outputSimpleType = None 479 self.inputAction = None 480 self.outputAction = None 481 self.port = port = item.getBinding().getPortType() 482 self._wsdl = item.getWSDL() 483 self.name = name = item.name 484 self.binding_operation = bop = item 485 486 self.soap_input_headers = None 487 self.soap_output_headers = None 488 489 op = port.operations.get(name) 490 if op is None: 491 raise WSDLFormatError( 492 '<portType name="%s"/> no match for <binding name="%s"><operation name="%s">' %( 493 port.name, item.getBinding().name, item.name)) 494 495 soap_bop = bop.findBinding(WSDLTools.SoapOperationBinding) 496 if soap_bop is None: 497 raise SOAPBindingError, 'expecting SOAP Bindings' 498 499 self.soapaction = soap_bop.soapAction 500 sbody = bop.input.findBinding(WSDLTools.SoapBodyBinding) 501 if not sbody: 502 raise SOAPBindingError('Missing <binding name="%s"><operation name="%s"><input><soap:body>' %( 503 port.binding.name, bop.name)) 504 505 self.encodingStyle = None 506 if sbody.use == 'encoded': 507 assert sbody.encodingStyle == SOAP.ENC,\ 508 'Supporting encodingStyle=%s, not %s'%(SOAP.ENC, sbody.encodingStyle) 509 self.encodingStyle = sbody.encodingStyle 510 511 self.inputName = op.getInputMessage().name 512 self.inputSimpleType = \ 513 FromMessageGetSimpleElementDeclaration(op.getInputMessage()) 514 self.inputAction = op.getInputAction() 515 self.soap_input_headers = bop.input.findBindings(WSDLTools.SoapHeaderBinding) 516 517 if bop.output is not None: 518 sbody = bop.output.findBinding(WSDLTools.SoapBodyBinding) 519 if not item.output: 520 raise WSDLFormatError, "Operation %s, no match for output binding" %name 521 522 self.outputName = op.getOutputMessage().name 523 self.outputSimpleType = \ 524 FromMessageGetSimpleElementDeclaration(op.getOutputMessage()) 525 self.outputAction = op.getOutputAction() 526 self.soap_output_headers = bop.output.findBindings(WSDLTools.SoapHeaderBinding) 527 528 def _setContent(self): 529 '''create string representation of operation. 530 ''' 531 kwstring = 'kw = {}' 532 tCheck = 'if isinstance(request, %s) is False:' % self.inputName 533 bindArgs = '' 534 if self.encodingStyle is not None: 535 bindArgs = 'encodingStyle="%s", ' %self.encodingStyle 536 537 if self.useWSA: 538 wsactionIn = 'wsaction = "%s"' % self.inputAction 539 wsactionOut = 'wsaction = "%s"' % self.outputAction 540 bindArgs += 'wsaction=wsaction, endPointReference=self.endPointReference, ' 541 responseArgs = ', wsaction=wsaction' 542 else: 543 wsactionIn = '# no input wsaction' 544 wsactionOut = '# no output wsaction' 545 responseArgs = '' 546 547 bindArgs += '**kw)' 548 549 if self.do_extended: 550 inputName = self.getOperation().getInputMessage().name 551 wrap_str = "" 552 partsList = self.getOperation().getInputMessage().parts.values() 553 try: 554 subNames = GetPartsSubNames(partsList, self._wsdl) 555 except TypeError, ex: 556 raise Wsdl2PythonError,\ 557 "Extended generation failure: only supports doc/lit, "\ 558 +"and all element attributes (<message><part element="\ 559 +"\"my:GED\"></message>) must refer to single global "\ 560 +"element declaration with complexType content. "\ 561 +"\n\n**** TRY WITHOUT EXTENDED ****\n" 562 563 args = [] 564 for pa in subNames: 565 args += pa 566 567 for arg in args: 568 wrap_str += "%srequest.%s = %s\n" % (ID2, 569 self.getAttributeName(arg), 570 self.mangle(arg)) 571 572 #args = [pa.name for pa in self.getOperation().getInputMessage().parts.values()] 573 argsStr = ",".join(args) 574 if len(argsStr) > 1: # add inital comma if args exist 575 argsStr = ", " + argsStr 576 577 method = [ 578 '%s# op: %s' % (ID1, self.getOperation().getInputMessage()), 579 '%sdef %s(self%s):' % (ID1, self.name, argsStr), 580 '\n%srequest = %s()' % (ID2, self.inputName), 581 '%s' % (wrap_str), 582 '%s%s' % (ID2, kwstring), 583 '%s%s' % (ID2, wsactionIn), 584 '%sself.binding.Send(None, None, request, soapaction="%s", %s'\ 585 %(ID2, self.soapaction, bindArgs), 586 ] 587 elif self.soap_input_headers: 588 method = [ 589 '%s# op: %s' % (ID1, self.name), 590 '%sdef %s(self, request, soapheaders=(), **kw):' % (ID1, self.name), 591 '%s%s' % (ID2, tCheck), 592 '%sraise TypeError, "%%s incorrect request type" %% (%s)' %(ID3, 'request.__class__'), 593 '%s%s' % (ID2, wsactionIn), 594 '%s# TODO: Check soapheaders' % (ID2), 595 '%sself.binding.Send(None, None, request, soapaction="%s", soapheaders=soapheaders, %s'\ 596 %(ID2, self.soapaction, bindArgs), 597 ] 598 else: 599 method = [ 600 '%s# op: %s' % (ID1, self.name), 601 '%sdef %s(self, request, **kw):' % (ID1, self.name), 602 '%s%s' % (ID2, tCheck), 603 '%sraise TypeError, "%%s incorrect request type" %% (%s)' %(ID3, 'request.__class__'), 604 '%s%s' % (ID2, wsactionIn), 605 '%sself.binding.Send(None, None, request, soapaction="%s", %s'\ 606 %(ID2, self.soapaction, bindArgs), 607 ] 608 # 609 # BP 1.0: rpc/literal 610 # WSDL 1.1 Section 3.5 could be interpreted to mean the RPC response 611 # wrapper element must be named identical to the name of the 612 # wsdl:operation. 613 # R2729 614 615 # 616 # SOAP-1.1 Note: rpc/encoded 617 # Each parameter accessor has a name corresponding to the name of the 618 # parameter and type corresponding to the type of the parameter. The name of 619 # the return value accessor is not significant. Likewise, the name of the struct is 620 # not significant. However, a convention is to name it after the method name 621 # with the string "Response" appended. 622 # 623 if not self.outputName: 624 method.append('%s#check for soap, assume soap:fault' %(ID2,)) 625 method.append('%sif self.binding.IsSOAP(): self.binding.Receive(None, **kw)' % (ID2,)) 626 self.writeArray(method) 627 return 628 629 response = ['%s%s' % (ID2, wsactionOut),] 630 if self.isRPC() and not self.isLiteral(): 631 # rpc/encoded Replace wrapper name with None 632 response.append(\ 633 '%stypecode = Struct(pname=None, ofwhat=%s.typecode.ofwhat, pyclass=%s.typecode.pyclass)' %( 634 ID2, self.outputName, self.outputName) 635 ) 636 response.append(\ 637 '%sresponse = self.binding.Receive(typecode%s)' %( 638 ID2, responseArgs) 639 ) 640 else: 641 response.append(\ 642 '%sresponse = self.binding.Receive(%s.typecode%s)' %( 643 ID2, self.outputName, responseArgs) 644 ) 645 646 # only support lit 647 if self.soap_output_headers: 648 sh = '[' 649 for shb in self.soap_output_headers: 650 #shb.encodingStyle, shb.use, shb.namespace 651 shb.message 652 shb.part 653 try: 654 msg = self._wsdl.messages[shb.message] 655 part = msg.parts[shb.part] 656 if part.element is not None: 657 sh += 'GED%s,' %str(part.element) 658 else: 659 warnings.warn('skipping soap output header in Message "%s"' %str(msg)) 660 except: 661 raise WSDLFormatError( 662 'failure processing output header typecodes, ' + 663 'could not find message "%s" or its part "%s"' %( 664 shb.message, shb.part) 665 ) 666 667 sh += ']' 668 if len(sh) > 2: 669 response.append(\ 670 '%sself.soapheaders = self.binding.ps.ParseHeaderElements(%s)' %(ID2, sh) 671 ) 672 673 if self.outputSimpleType: 674 response.append('%sreturn %s(response)' %(ID2, self.outputName)) 675 else: 676 if self.do_extended: 677 partsList = self.getOperation().getOutputMessage().parts.values() 678 subNames = GetPartsSubNames(partsList, self._wsdl) 679 args = [] 680 for pa in subNames: 681 args += pa 682 683 for arg in args: 684 response.append('%s%s = response.%s' % (ID2, self.mangle(arg), self.getAttributeName(arg)) ) 685 margs = ",".join(args) 686 response.append("%sreturn %s" % (ID2, margs) ) 687 else: 688 response.append('%sreturn response' %ID2) 689 method += response 690 691 self.writeArray(method) 692 693 694class BindingDescription(ServiceContainerBase): 695 '''writes out SOAP Binding class 696 697 class variables: 698 readerclass -- 699 writerclass -- 700 operationclass -- representation of each operation. 701 ''' 702 readerclass = None 703 writerclass = None 704 operationclass = ServiceOperationContainer 705 logger = _GetLogger("BindingDescription") 706 707 def __init__(self, useWSA=False, do_extended=False, wsdl=None): 708 '''Parameters: 709 name -- binding name 710 property -- resource properties 711 useWSA -- boolean, enable ws-addressing 712 name -- binding name 713 ''' 714 ServiceContainerBase.__init__(self) 715 self.useWSA = useWSA 716 self.rProp = None 717 #self.bName = None 718 self.operations = None 719 self.do_extended = do_extended 720 self._wsdl = wsdl # None unless do_extended == True 721 722 def setReaderClass(cls, className): 723 '''specify a reader class name, this must be imported 724 in service module. 725 ''' 726 cls.readerclass = className 727 setReaderClass = classmethod(setReaderClass) 728 729 def setWriterClass(cls, className): 730 '''specify a writer class name, this must be imported 731 in service module. 732 ''' 733 cls.writerclass = className 734 setWriterClass = classmethod(setWriterClass) 735 736 def setOperationClass(cls, className): 737 '''specify an operation container class name. 738 ''' 739 cls.operationclass = className 740 setOperationClass = classmethod(setOperationClass) 741 742 def setUp(self, item): 743 '''This method finds all SOAP Binding Operations, it will skip 744 all bindings that are not SOAP. 745 item -- WSDL.Binding instance 746 ''' 747 assert isinstance(item, WSDLTools.Binding), \ 748 'expecting WSDLTools Binding instance' 749 750 portType = item.getPortType() 751 self._kwargs = KW.copy() 752 self._kwargs['bind'] = NC_to_CN(item.name) 753 self.operations = [] 754 self.rProp = portType.getResourceProperties() 755 soap_binding = item.findBinding(WSDLTools.SoapBinding) 756 if soap_binding is None: 757 raise Wsdl2PythonError,\ 758 'Binding(%s) missing WSDLTools.SoapBinding' %item.name 759 760 for bop in item.operations: 761 soap_bop = bop.findBinding(WSDLTools.SoapOperationBinding) 762 if soap_bop is None: 763 self.logger.warning(\ 764 'Skip Binding(%s) operation(%s) no SOAP Binding Operation'\ 765 %(item.name, bop.name), 766 ) 767 continue 768 769 #soapAction = soap_bop.soapAction 770 if bop.input is not None: 771 soapBodyBind = bop.input.findBinding(WSDLTools.SoapBodyBinding) 772 if soapBodyBind is None: 773 self.logger.warning(\ 774 'Skip Binding(%s) operation(%s) Bindings(%s) not supported'\ 775 %(item.name, bop.name, bop.extensions) 776 ) 777 continue 778 779 op = portType.operations.get(bop.name) 780 if op is None: 781 raise Wsdl2PythonError,\ 782 'no matching portType/Binding operation(%s)' % bop.name 783 784 c = self.operationclass(useWSA=self.useWSA, 785 do_extended=self.do_extended) 786 c.setUp(bop) 787 self.operations.append(c) 788 789 def _setContent(self): 790 if self.useWSA is True: 791 args = 'endPointReference=None, **kw' 792 epr = 'self.endPointReference = endPointReference' 793 else: 794 args = '**kw' 795 epr = '# no ws-addressing' 796 797 if self.rProp: 798 rp = 'kw.setdefault("ResourceProperties", ("%s","%s"))'\ 799 %(self.rProp[0], self.rProp[1]) 800 else: 801 rp = '# no resource properties' 802 803 kwargs = self._kwargs 804 kwargs.update(dict(suffix=self.clientClassSuffix, 805 args=args, epr=epr, rp=rp, readerclass=self.readerclass, 806 writerclass=self.writerclass,)) 807 808 methods = [ 809 '# Methods', 810 'class %(bind)s%(suffix)s:' %kwargs, 811 '%(ID1)sdef __init__(self, url, %(args)s):' %kwargs, 812 '%(ID2)skw.setdefault("readerclass", %(readerclass)s)' %kwargs, 813 '%(ID2)skw.setdefault("writerclass", %(writerclass)s)' %kwargs, 814 '%(ID2)s%(rp)s' % kwargs, 815 '%(ID2)sself.binding = client.Binding(url=url, **kw)' %kwargs, 816 '%(ID2)s%(epr)s' % kwargs, 817 ] 818 819 for op in self.operations: 820 methods += [ op.getvalue() ] 821 822 self.writeArray(methods) 823 824ServiceOperationsClassContainer = BindingDescription 825 826 827class MessageContainerInterface: 828 logger = _GetLogger("MessageContainerInterface") 829 830 def setUp(self, port, soc, input): 831 '''sets the attribute _simple which represents a 832 primitive type message represents, or None if not primitive. 833 834 soc -- WSDLTools.ServiceOperationContainer instance 835 port -- WSDLTools.Port instance 836 input-- boolean, input messasge or output message of operation. 837 ''' 838 raise NotImplementedError, 'Message container must implemented setUp.' 839 840 841class ServiceDocumentLiteralMessageContainer(ServiceContainerBase, 842 MessageContainerInterface): 843 logger = _GetLogger("ServiceDocumentLiteralMessageContainer") 844 845 def __init__(self, do_extended=False): 846 847 ServiceContainerBase.__init__(self) 848 self.do_extended=do_extended 849 850 def setUp(self, port, soc, input): 851 content = self.content 852 # TODO: check soapbody for part name 853 simple = self._simple = soc.isSimpleType(soc.getOperationName()) 854 name = soc.getOperationName() 855 856 # Document/literal 857 operation = port.getBinding().getPortType().operations.get(name) 858 bop = port.getBinding().operations.get(name) 859 soapBodyBind = None 860 if input is True: 861 soapBodyBind = bop.input.findBinding(WSDLTools.SoapBodyBinding) 862 message = operation.getInputMessage() 863 else: 864 soapBodyBind = bop.output.findBinding(WSDLTools.SoapBodyBinding) 865 message = operation.getOutputMessage() 866 867 # using underlying data structure to avoid phantom problem. 868 # with message.parts.data.values() 869 if len(message.parts) == 0: 870 raise Wsdl2PythonError, 'must specify part for doc/lit msg' 871 872 p = None 873 if soapBodyBind.parts is not None: 874 if len(soapBodyBind.parts) > 1: 875 raise Wsdl2PythonError,\ 876 'not supporting multiple parts in soap body' 877 if len(soapBodyBind.parts) == 0: 878 return 879 880 p = message.parts.get(soapBodyBind.parts[0]) 881 882 # XXX: Allow for some slop 883 p = p or message.parts[0] 884 885 if p.type: 886 raise Wsdl2PythonError, 'no doc/lit suport for <part type>' 887 888 if not p.element: 889 return 890 891 self.ns = p.element[0] 892 content.ns = p.element[0] 893 content.pName = p.element[1] 894 content.mName = message.name 895 896 def _setContent(self): 897 '''create string representation of doc/lit message container. If 898 message element is simple(primitive), use python type as base class. 899 ''' 900 try: 901 simple = self._simple 902 except AttributeError: 903 raise RuntimeError, 'call setUp first' 904 905 # TODO: Hidden contract. Must set self.ns before getNSAlias... 906 # File "/usr/local/python/lib/python2.4/site-packages/ZSI/generate/containers.py", line 625, in _setContent 907 # kw['message'],kw['prefix'],kw['typecode'] = \ 908 # File "/usr/local/python/lib/python2.4/site-packages/ZSI/generate/containers.py", line 128, in getNSAlias 909 # raise ContainerError, 'no self.ns attr defined in %s' % self.__class__ 910 # ZSI.generate.containers.ContainerError: no self.ns attr defined in ZSI.generate.containers.ServiceDocumentLiteralMessageContainer 911 # 912# self.ns = self.content.ns 913 914 915 kw = KW.copy() 916 kw.update(dict(message=self.content.mName, nsuri=self.content.ns, 917 name=self.content.pName)) 918 919# kw['message'],kw['prefix'],kw['typecode'] = \ 920# self.content.mName, self.getNSAlias(), element_class_name(self.content.pName) 921# 922 # These messsages are just global element declarations 923# self.writeArray(['%(message)s = %(prefix)s.%(typecode)s().pyclass' %kw]) 924 self.writeArray(['%(message)s = GED("%(nsuri)s", "%(name)s").pyclass' %kw]) 925 926class ServiceRPCEncodedMessageContainer(ServiceContainerBase, MessageContainerInterface): 927 logger = _GetLogger("ServiceRPCEncodedMessageContainer") 928 929 def setUp(self, port, soc, input): 930 ''' 931 Instance Data: 932 op -- WSDLTools Operation instance 933 bop -- WSDLTools BindingOperation instance 934 input -- boolean input/output 935 ''' 936 name = soc.getOperationName() 937 bop = port.getBinding().operations.get(name) 938 op = port.getBinding().getPortType().operations.get(name) 939 940 assert op is not None, 'port has no operation %s' %name 941 assert bop is not None, 'port has no binding operation %s' %name 942 943 self.input = input 944 self.op = op 945 self.bop = bop 946 947 def _setContent(self): 948 try: 949 self.op 950 except AttributeError: 951 raise RuntimeError, 'call setUp first' 952 953 pname = self.op.name 954 msgRole = self.op.input 955 msgRoleB = self.bop.input 956 if self.input is False: 957 pname = '%sResponse' %self.op.name 958 msgRole = self.op.output 959 msgRoleB = self.bop.output 960 961 sbody = msgRoleB.findBinding(WSDLTools.SoapBodyBinding) 962 if not sbody or not sbody.namespace: 963 raise WSInteropError, WSISpec.R2717 964 965 assert sbody.use == 'encoded', 'Expecting use=="encoded"' 966 encodingStyle = sbody.encodingStyle 967 968 assert encodingStyle == SOAP.ENC,\ 969 'Supporting encodingStyle=%s, not %s' %(SOAP.ENC, encodingStyle) 970 971 namespace = sbody.namespace 972 tcb = MessageTypecodeContainer(\ 973 tuple(msgRole.getMessage().parts.list), 974 ) 975 ofwhat = '[%s]' %tcb.getTypecodeList() 976 pyclass = msgRole.getMessage().name 977 978 fdict = KW.copy() 979 fdict['nspname'] = sbody.namespace 980 fdict['pname'] = pname 981 fdict['pyclass'] = None 982 fdict['ofwhat'] = ofwhat 983 fdict['encoded'] = namespace 984 985 #if self.input is False: 986 # fdict['typecode'] = \ 987 # 'Struct(pname=None, ofwhat=%(ofwhat)s, pyclass=%(pyclass)s, encoded="%(encoded)s")' 988 #else: 989 fdict['typecode'] = \ 990 'Struct(pname=("%(nspname)s","%(pname)s"), ofwhat=%(ofwhat)s, pyclass=%(pyclass)s, encoded="%(encoded)s")' 991 992 message = ['class %(pyclass)s:', 993 '%(ID1)sdef __init__(self, **kw):', 994 '%(ID2)s"""Keyword parameters:', 995 ] 996 997 idx = len(message) 998 for a,p in zip(tcb.getAttributeNames(), tcb.getParameterNames()): 999 message.insert(idx, '%(ID2)s' + p + ' -- part ' + p) 1000 message.append('%(ID2)sself.' + a + ' = kw.get("%s")' %p) 1001 idx += 1 1002 1003 message.insert(idx, '%(ID2)s"""') 1004 1005 # TODO: This isn't a TypecodeContainerBase instance but it 1006 # certaintly generates a pyclass and typecode. 1007 #if self.metaclass is None: 1008 if TypecodeContainerBase.metaclass is None: 1009 fdict['pyclass'] = pyclass 1010 fdict['typecode'] = fdict['typecode'] %fdict 1011 message.append('%(pyclass)s.typecode = %(typecode)s') 1012 else: 1013 # Need typecode to be available when class is constructed. 1014 fdict['typecode'] = fdict['typecode'] %fdict 1015 fdict['pyclass'] = pyclass 1016 fdict['metaclass'] = TypecodeContainerBase.metaclass 1017 message.insert(0, '_%(pyclass)sTypecode = %(typecode)s') 1018 message.insert(2, '%(ID1)stypecode = _%(pyclass)sTypecode') 1019 message.insert(3, '%(ID1)s__metaclass__ = %(metaclass)s') 1020 message.append('%(pyclass)s.typecode.pyclass = %(pyclass)s') 1021 1022 self.writeArray(map(lambda l: l %fdict, message)) 1023 1024 1025class ServiceRPCLiteralMessageContainer(ServiceContainerBase, MessageContainerInterface): 1026 logger = _GetLogger("ServiceRPCLiteralMessageContainer") 1027 1028 def setUp(self, port, soc, input): 1029 ''' 1030 Instance Data: 1031 op -- WSDLTools Operation instance 1032 bop -- WSDLTools BindingOperation instance 1033 input -- boolean input/output 1034 ''' 1035 name = soc.getOperationName() 1036 bop = port.getBinding().operations.get(name) 1037 op = port.getBinding().getPortType().operations.get(name) 1038 1039 assert op is not None, 'port has no operation %s' %name 1040 assert bop is not None, 'port has no binding operation %s' %name 1041 1042 self.op = op 1043 self.bop = bop 1044 self.input = input 1045 1046 def _setContent(self): 1047 try: 1048 self.op 1049 except AttributeError: 1050 raise RuntimeError, 'call setUp first' 1051 1052 operation = self.op 1053 input = self.input 1054 pname = operation.name 1055 msgRole = operation.input 1056 msgRoleB = self.bop.input 1057 if input is False: 1058 pname = '%sResponse' %operation.name 1059 msgRole = operation.output 1060 msgRoleB = self.bop.output 1061 1062 sbody = msgRoleB.findBinding(WSDLTools.SoapBodyBinding) 1063 if not sbody or not sbody.namespace: 1064 raise WSInteropError, WSISpec.R2717 1065 1066 namespace = sbody.namespace 1067 tcb = MessageTypecodeContainer(\ 1068 tuple(msgRole.getMessage().parts.list), 1069 ) 1070 ofwhat = '[%s]' %tcb.getTypecodeList() 1071 pyclass = msgRole.getMessage().name 1072 1073 fdict = KW.copy() 1074 fdict['nspname'] = sbody.namespace 1075 fdict['pname'] = pname 1076 fdict['pyclass'] = None 1077 fdict['ofwhat'] = ofwhat 1078 fdict['encoded'] = namespace 1079 fdict['typecode'] = \ 1080 'Struct(pname=("%(nspname)s","%(pname)s"), ofwhat=%(ofwhat)s, pyclass=%(pyclass)s, encoded="%(encoded)s")' 1081 1082 message = ['class %(pyclass)s:', 1083 '%(ID1)sdef __init__(self, **kw):', 1084 '%(ID2)s"""Keyword parameters:', 1085 ] 1086 1087 idx = len(message) 1088 for a,p in zip(tcb.getAttributeNames(), tcb.getParameterNames()): 1089 message.insert(idx, '%(ID2)s' + p + ' -- part ' + p) 1090 message.append('%(ID2)sself.' + a + ' = kw.get("%s")' %p) 1091 idx += 1 1092 1093 message.insert(idx, '%(ID2)s"""') 1094 1095 # TODO: This isn't a TypecodeContainerBase instance but it 1096 # certaintly generates a pyclass and typecode. 1097 #if self.metaclass is None: 1098 if TypecodeContainerBase.metaclass is None: 1099 fdict['pyclass'] = pyclass 1100 fdict['typecode'] = fdict['typecode'] %fdict 1101 message.append('%(pyclass)s.typecode = %(typecode)s') 1102 else: 1103 # Need typecode to be available when class is constructed. 1104 fdict['typecode'] = fdict['typecode'] %fdict 1105 fdict['pyclass'] = pyclass 1106 fdict['metaclass'] = TypecodeContainerBase.metaclass 1107 message.insert(0, '_%(pyclass)sTypecode = %(typecode)s') 1108 message.insert(2, '%(ID1)stypecode = _%(pyclass)sTypecode') 1109 message.insert(3, '%(ID1)s__metaclass__ = %(metaclass)s') 1110 message.append('%(pyclass)s.typecode.pyclass = %(pyclass)s') 1111 1112 self.writeArray(map(lambda l: l %fdict, message)) 1113 1114 1115TypesContainerBase = ContainerBase 1116 1117 1118class TypesHeaderContainer(TypesContainerBase): 1119 '''imports for all generated types modules. 1120 ''' 1121 imports = [ 1122 'import ZSI', 1123 'import ZSI.TCcompound', 1124 'from ZSI.schema import LocalElementDeclaration, ElementDeclaration, TypeDefinition, GTD, GED', 1125 ] 1126 logger = _GetLogger("TypesHeaderContainer") 1127 1128 def _setContent(self): 1129 self.writeArray(TypesHeaderContainer.imports) 1130 1131 1132NamespaceClassContainerBase = TypesContainerBase 1133 1134 1135class NamespaceClassHeaderContainer(NamespaceClassContainerBase): 1136 logger = _GetLogger("NamespaceClassHeaderContainer") 1137 1138 def _setContent(self): 1139 1140 head = [ 1141 '#' * 30, 1142 '# targetNamespace', 1143 '# %s' % self.ns, 1144 '#' * 30 + '\n', 1145 'class %s:' % self.getNSAlias(), 1146 '%stargetNamespace = "%s"' % (ID1, self.ns) 1147 ] 1148 1149 self.writeArray(head) 1150 1151class NamespaceClassFooterContainer(NamespaceClassContainerBase): 1152 logger = _GetLogger("NamespaceClassFooterContainer") 1153 1154 def _setContent(self): 1155 1156 foot = [ 1157 '# end class %s (tns: %s)' % (self.getNSAlias(), self.ns), 1158 ] 1159 1160 self.writeArray(foot) 1161 1162 1163BTI = BaseTypeInterpreter() 1164class TypecodeContainerBase(TypesContainerBase): 1165 '''Base class for all classes representing anything 1166 with element content. 1167 1168 class variables: 1169 mixed_content_aname -- text content will be placed in this attribute. 1170 attributes_aname -- attributes will be placed in this attribute. 1171 metaclass -- set this attribute to specify a pyclass __metaclass__ 1172 ''' 1173 mixed_content_aname = 'text' 1174 attributes_aname = 'attrs' 1175 metaclass = None 1176 lazy = False 1177 logger = _GetLogger("TypecodeContainerBase") 1178 1179 def __init__(self, do_extended=False, extPyClasses=None): 1180 TypesContainerBase.__init__(self) 1181 self.name = None 1182 1183 # attrs for model groups and others with elements, tclists, etc... 1184 self.allOptional = False 1185 self.mgContent = None 1186 self.contentFlattened = False 1187 self.elementAttrs = [] 1188 self.tcListElements = [] 1189 self.tcListSet = False 1190 1191 self.localTypes = [] 1192 1193 # used when processing nested anonymous types 1194 self.parentClass = None 1195 1196 # used when processing attribute content 1197 self.mixed = False 1198 self.extraFlags = '' 1199 self.attrComponents = None 1200 1201 # --> EXTENDED 1202 # Used if an external pyclass was specified for this type. 1203 self.do_extended = do_extended 1204 if extPyClasses is None: 1205 self.extPyClasses = {} 1206 else: 1207 self.extPyClasses = extPyClasses 1208 # <-- 1209 1210 def getvalue(self): 1211 out = ContainerBase.getvalue(self) 1212 for item in self.localTypes: 1213 content = None 1214 assert True is item.isElement() is item.isLocal(), 'expecting local elements only' 1215 1216 etp = item.content 1217 qName = item.getAttribute('type') 1218 if not qName: 1219 etp = item.content 1220 local = True 1221 else: 1222 etp = item.getTypeDefinition('type') 1223 1224 if etp is None: 1225 if local is True: 1226 content = ElementLocalComplexTypeContainer(do_extended=self.do_extended) 1227 else: 1228 content = ElementSimpleTypeContainer() 1229 elif etp.isLocal() is False: 1230 content = ElementGlobalDefContainer() 1231 elif etp.isSimple() is True: 1232 content = ElementLocalSimpleTypeContainer() 1233 elif etp.isComplex(): 1234 content = ElementLocalComplexTypeContainer(do_extended=self.do_extended) 1235 else: 1236 raise Wsdl2PythonError, "Unknown element declaration: %s" %item.getItemTrace() 1237 1238 content.setUp(item) 1239 1240 out += '\n\n' 1241 if self.parentClass: 1242 content.parentClass = \ 1243 '%s.%s' %(self.parentClass, self.getClassName()) 1244 else: 1245 content.parentClass = '%s.%s' %(self.getNSAlias(), self.getClassName()) 1246 1247 for l in content.getvalue().split('\n'): 1248 if l: out += '%s%s\n' % (ID1, l) 1249 else: out += '\n' 1250 1251 out += '\n\n' 1252 1253 return out 1254 1255 def getAttributeName(self, name): 1256 '''represents the aname 1257 ''' 1258 if self.func_aname is None: 1259 return name 1260 assert callable(self.func_aname), \ 1261 'expecting callable method for attribute func_aname, not %s' %type(self.func_aname) 1262 f = self.func_aname 1263 return f(name) 1264 1265 def getMixedTextAName(self): 1266 '''returns an aname representing mixed text content. 1267 ''' 1268 return self.getAttributeName(self.mixed_content_aname) 1269 1270 def getClassName(self): 1271 1272 if not self.name: 1273 raise ContainerError, 'self.name not defined!' 1274 if not hasattr(self.__class__, 'type'): 1275 raise ContainerError, 'container type not defined!' 1276 1277 #suffix = self.__class__.type 1278 if self.__class__.type == DEF: 1279 classname = type_class_name(self.name) 1280 elif self.__class__.type == DEC: 1281 classname = element_class_name(self.name) 1282 1283 return self.mangle( classname ) 1284 1285 # --> EXTENDED 1286 def hasExtPyClass(self): 1287 if self.name in self.extPyClasses: 1288 return True 1289 else: 1290 return False 1291 # <-- 1292 1293 def getPyClass(self): 1294 '''Name of generated inner class that will be specified as pyclass. 1295 ''' 1296 # --> EXTENDED 1297 if self.hasExtPyClass(): 1298 classInfo = self.extPyClasses[self.name] 1299 return ".".join(classInfo) 1300 # <-- 1301 1302 return 'Holder' 1303 1304 def getPyClassDefinition(self): 1305 '''Return a list containing pyclass definition. 1306 ''' 1307 kw = KW.copy() 1308 1309 # --> EXTENDED 1310 if self.hasExtPyClass(): 1311 classInfo = self.extPyClasses[self.name] 1312 kw['classInfo'] = classInfo[0] 1313 return ["%(ID3)simport %(classInfo)s" %kw ] 1314 # <-- 1315 1316 kw['pyclass'] = self.getPyClass() 1317 definition = [] 1318 definition.append('%(ID3)sclass %(pyclass)s:' %kw) 1319 if self.metaclass is not None: 1320 kw['type'] = self.metaclass 1321 definition.append('%(ID4)s__metaclass__ = %(type)s' %kw) 1322 definition.append('%(ID4)stypecode = self' %kw) 1323 1324 #TODO: Remove pyclass holder __init__ --> 1325 definition.append('%(ID4)sdef __init__(self):' %kw) 1326 definition.append('%(ID5)s# pyclass' %kw) 1327 1328 # JRB HACK need to call _setElements via getElements 1329 self._setUpElements() 1330 1331 # JRB HACK need to indent additional one level 1332 for el in self.elementAttrs: 1333 kw['element'] = el 1334 definition.append('%(ID2)s%(element)s' %kw) 1335 definition.append('%(ID5)sreturn' %kw) 1336 # <-- 1337 1338 # pyclass descriptive name 1339 if self.name is not None: 1340 kw['name'] = self.name 1341 definition.append(\ 1342 '%(ID3)s%(pyclass)s.__name__ = "%(name)s_Holder"' %kw 1343 ) 1344 1345 return definition 1346 1347 def nsuriLogic(self): 1348 '''set a variable "ns" that represents the targetNamespace in 1349 which this item is defined. Used for namespacing local elements. 1350 ''' 1351 if self.parentClass: 1352 return 'ns = %s.%s.schema' %(self.parentClass, self.getClassName()) 1353 return 'ns = %s.%s.schema' %(self.getNSAlias(), self.getClassName()) 1354 1355 def schemaTag(self): 1356 if self.ns is not None: 1357 return 'schema = "%s"' % self.ns 1358 raise ContainerError, 'failed to set schema targetNamespace(%s)' %(self.__class__) 1359 1360 def typeTag(self): 1361 if self.name is not None: 1362 return 'type = (schema, "%s")' % self.name 1363 raise ContainerError, 'failed to set type name(%s)' %(self.__class__) 1364 1365 def literalTag(self): 1366 if self.name is not None: 1367 return 'literal = "%s"' % self.name 1368 raise ContainerError, 'failed to set element name(%s)' %(self.__class__) 1369 1370 def getExtraFlags(self): 1371 if self.mixed: 1372 self.extraFlags += 'mixed=True, mixed_aname="%s", ' %self.getMixedTextAName() 1373 1374 return self.extraFlags 1375 1376 def simpleConstructor(self, superclass=None): 1377 1378 if superclass: 1379 return '%s.__init__(self, **kw)' % superclass 1380 else: 1381 return 'def __init__(self, **kw):' 1382 1383 def pnameConstructor(self, superclass=None): 1384 1385 if superclass: 1386 return '%s.__init__(self, pname, **kw)' % superclass 1387 else: 1388 return 'def __init__(self, pname, **kw):' 1389 1390 1391 def _setUpElements(self): 1392 """TODO: Remove this method 1393 1394 This method ONLY sets up the instance attributes. 1395 Dependency instance attribute: 1396 mgContent -- expected to be either a complex definition 1397 with model group content, a model group, or model group 1398 content. TODO: should only support the first two. 1399 """ 1400 self.logger.debug("_setUpElements: %s" %self._item.getItemTrace()) 1401 if hasattr(self, '_done'): 1402 #return '\n'.join(self.elementAttrs) 1403 return 1404 1405 self._done = True 1406 flat = [] 1407 content = self.mgContent 1408 if type(self.mgContent) is not tuple: 1409 mg = self.mgContent 1410 if not mg.isModelGroup(): 1411 mg = mg.content 1412 1413 content = mg.content 1414 if mg.isAll(): 1415 flat = content 1416 content = [] 1417 elif mg.isModelGroup() and mg.isDefinition(): 1418 mg = mg.content 1419 content = mg.content 1420 1421 idx = 0 1422 content = list(content) 1423 while idx < len(content): 1424 c = orig = content[idx] 1425 if c.isElement(): 1426 flat.append(c) 1427 idx += 1 1428 continue 1429 1430 if c.isReference() and c.isModelGroup(): 1431 c = c.getModelGroupReference() 1432 1433 if c.isDefinition() and c.isModelGroup(): 1434 c = c.content 1435 1436 if c.isSequence() or c.isChoice(): 1437 begIdx = idx 1438 endIdx = begIdx + len(c.content) 1439 for i in range(begIdx, endIdx): 1440 content.insert(i, c.content[i-begIdx]) 1441 1442 content.remove(orig) 1443 continue 1444 1445 raise ContainerError, 'unexpected schema item: %s' %c.getItemTrace() 1446 1447 for c in flat: 1448 if c.isDeclaration() and c.isElement(): 1449 defaultValue = "None" 1450 parent = c 1451 defs = [] 1452 # stop recursion via global ModelGroupDefinition 1453 while defs.count(parent) <= 1: 1454 maxOccurs = parent.getAttribute('maxOccurs') 1455 if maxOccurs == 'unbounded' or int(maxOccurs) > 1: 1456 defaultValue = "[]" 1457 break 1458 1459 parent = parent._parent() 1460 if not parent.isModelGroup(): 1461 break 1462 1463 if parent.isReference(): 1464 parent = parent.getModelGroupReference() 1465 1466 if parent.isDefinition(): 1467 parent = parent.content 1468 defs.append(parent) 1469 1470 if None == c.getAttribute('name') and c.isWildCard(): 1471 e = '%sself.%s = %s' %(ID3, 1472 self.getAttributeName('any'), defaultValue) 1473 else: 1474 e = '%sself.%s = %s' %(ID3, 1475 self.getAttributeName(c.getAttribute('name')), defaultValue) 1476 self.elementAttrs.append(e) 1477 continue 1478 1479 # TODO: This seems wrong 1480 if c.isReference(): 1481 e = '%sself._%s = None' %(ID3, 1482 self.mangle(c.getAttribute('ref')[1])) 1483 self.elementAttrs.append(e) 1484 continue 1485 1486 raise ContainerError, 'unexpected item: %s' % c.getItemTrace() 1487 1488 #return '\n'.join(self.elementAttrs) 1489 return 1490 1491 def _setTypecodeList(self): 1492 """generates ofwhat content, minOccurs/maxOccurs facet generation. 1493 Dependency instance attribute: 1494 mgContent -- expected to be either a complex definition 1495 with model group content, a model group, or model group 1496 content. TODO: should only support the first two. 1497 localTypes -- produce local class definitions later 1498 tcListElements -- elements, local/global 1499 """ 1500 self.logger.debug("_setTypecodeList(%r): %s" % 1501 (self.mgContent, self._item.getItemTrace())) 1502 1503 flat = [] 1504 content = self.mgContent 1505 1506 #TODO: too much slop permitted here, impossible 1507 # to tell what is going on. 1508 1509 if type(content) is not tuple: 1510 mg = content 1511 if not mg.isModelGroup(): 1512 raise Wsdl2PythonErr("Expecting ModelGroup: %s" % 1513 mg.getItemTrace()) 1514 1515 self.logger.debug("ModelGroup(%r) contents(%r): %s" % 1516 (mg, mg.content, mg.getItemTrace())) 1517 1518 #<group ref> 1519 if mg.isReference(): 1520 raise RuntimeError("Unexpected modelGroup reference: %s" % 1521 mg.getItemTrace()) 1522 1523 #<group name> 1524 if mg.isDefinition(): 1525 mg = mg.content 1526 1527 if mg.isAll(): 1528 flat = mg.content 1529 content = [] 1530 elif mg.isSequence(): 1531 content = mg.content 1532 elif mg.isChoice(): 1533 content = mg.content 1534 else: 1535 raise RuntimeError("Unknown schema item") 1536 1537 idx = 0 1538 content = list(content) 1539 self.logger.debug("content: %r" %content) 1540 while idx < len(content): 1541 c = orig = content[idx] 1542 if c.isElement(): 1543 flat.append(c) 1544 idx += 1 1545 continue 1546 1547 if c.isReference() and c.isModelGroup(): 1548 c = c.getModelGroupReference() 1549 1550 if c.isDefinition() and c.isModelGroup(): 1551 c = c.content 1552 1553 if c.isSequence() or c.isChoice(): 1554 begIdx = idx 1555 endIdx = begIdx + len(c.content) 1556 for i in range(begIdx, endIdx): 1557 content.insert(i, c.content[i-begIdx]) 1558 1559 content.remove(orig) 1560 continue 1561 1562 raise ContainerError, 'unexpected schema item: %s' %c.getItemTrace() 1563 1564 # TODO: Need to store "parents" in a dict[id] = list(), 1565 # because cannot follow references, but not currently 1566 # a big concern. 1567 1568 self.logger.debug("flat: %r" %list(flat)) 1569 for c in flat: 1570 tc = TcListComponentContainer() 1571 # TODO: Remove _getOccurs 1572 min,max,nil = self._getOccurs(c) 1573 min = max = None 1574 maxOccurs = 1 1575 1576 parent = c 1577 defs = [] 1578 # stop recursion via global ModelGroupDefinition 1579 while defs.count(parent) <= 1: 1580 max = parent.getAttribute('maxOccurs') 1581 if max == 'unbounded': 1582 maxOccurs = '"%s"' %max 1583 break 1584 1585 maxOccurs = int(max) * maxOccurs 1586 parent = parent._parent() 1587 if not parent.isModelGroup(): 1588 break 1589 1590 if parent.isReference(): 1591 parent = parent.getModelGroupReference() 1592 1593 if parent.isDefinition(): 1594 parent = parent.content 1595 defs.append(parent) 1596 1597 del defs 1598 parent = c 1599 while 1: 1600 minOccurs = int(parent.getAttribute('minOccurs')) 1601 if minOccurs == 0 or parent.isChoice(): 1602 minOccurs = 0 1603 break 1604 1605 parent = parent._parent() 1606 if not parent.isModelGroup(): 1607 minOccurs = int(c.getAttribute('minOccurs')) 1608 break 1609 1610 if parent.isReference(): 1611 parent = parent.getModelGroupReference() 1612 1613 if parent.isDefinition(): 1614 parent = parent.content 1615 1616 tc.setOccurs(minOccurs, maxOccurs, nil) 1617 processContents = self._getProcessContents(c) 1618 tc.setProcessContents(processContents) 1619 if c.isDeclaration() and c.isElement(): 1620 global_type = c.getAttribute('type') 1621 content = getattr(c, 'content', None) 1622 if c.isLocal() and c.isQualified() is False: 1623 tc.unQualified() 1624 1625 if c.isWildCard(): 1626 tc.setStyleAnyElement() 1627 elif global_type is not None: 1628 tc.name = c.getAttribute('name') 1629 ns = global_type[0] 1630 if ns in SCHEMA.XSD_LIST: 1631 tpc = BTI.get_typeclass(global_type[1],global_type[0]) 1632 tc.klass = tpc 1633# elif (self.ns,self.name) == global_type: 1634# # elif self._isRecursiveElement(c) 1635# # TODO: Remove this, it only works for 1 level. 1636# tc.setStyleRecursion() 1637 else: 1638 tc.setGlobalType(*global_type) 1639# tc.klass = '%s.%s' % (NAD.getAlias(ns), 1640# type_class_name(global_type[1])) 1641 del ns 1642 elif content is not None and content.isLocal() and content.isComplex(): 1643 tc.name = c.getAttribute('name') 1644 tc.klass = 'self.__class__.%s' % (element_class_name(tc.name)) 1645 #TODO: Not an element reference, confusing nomenclature 1646 tc.setStyleElementReference() 1647 self.localTypes.append(c) 1648 elif content is not None and content.isLocal() and content.isSimple(): 1649 # Local Simple Type 1650 tc.name = c.getAttribute('name') 1651 tc.klass = 'self.__class__.%s' % (element_class_name(tc.name)) 1652 #TODO: Not an element reference, confusing nomenclature 1653 tc.setStyleElementReference() 1654 self.localTypes.append(c) 1655 else: 1656 raise ContainerError, 'unexpected item: %s' % c.getItemTrace() 1657 1658 elif c.isReference(): 1659 # element references 1660 ref = c.getAttribute('ref') 1661# tc.klass = '%s.%s' % (NAD.getAlias(ref[0]), 1662# element_class_name(ref[1]) ) 1663 tc.setStyleElementReference() 1664 tc.setGlobalType(*ref) 1665 else: 1666 raise ContainerError, 'unexpected item: %s' % c.getItemTrace() 1667 1668 self.tcListElements.append(tc) 1669 1670 def getTypecodeList(self): 1671 if not self.tcListSet: 1672# self._flattenContent() 1673 self._setTypecodeList() 1674 self.tcListSet = True 1675 1676 list = [] 1677 for e in self.tcListElements: 1678 list.append(str(e)) 1679 1680 return ', '.join(list) 1681 1682 # the following _methods() are utility methods used during 1683 # TCList generation, et al. 1684 1685 def _getOccurs(self, e): 1686 1687 nillable = e.getAttribute('nillable') 1688 if nillable == 'true': 1689 nillable = True 1690 else: 1691 nillable = False 1692 1693 maxOccurs = e.getAttribute('maxOccurs') 1694 if maxOccurs == 'unbounded': 1695 maxOccurs = '"%s"' %maxOccurs 1696 1697 minOccurs = e.getAttribute('minOccurs') 1698 1699 if self.allOptional is True: 1700 #JRB Hack 1701 minOccurs = '0' 1702 maxOccurs = '"unbounded"' 1703 1704 return minOccurs,maxOccurs,nillable 1705 1706 def _getProcessContents(self, e): 1707 processContents = e.getAttribute('processContents') 1708 return processContents 1709 1710 def getBasesLogic(self, indent): 1711 try: 1712 prefix = NAD.getAlias(self.sKlassNS) 1713 except WsdlGeneratorError, ex: 1714 # XSD or SOAP 1715 raise 1716 1717 bases = [] 1718 bases.append(\ 1719 'if %s.%s not in %s.%s.__bases__:'\ 1720 %(NAD.getAlias(self.sKlassNS), type_class_name(self.sKlass), self.getNSAlias(), self.getClassName()), 1721 ) 1722 bases.append(\ 1723 '%sbases = list(%s.%s.__bases__)'\ 1724 %(ID1,self.getNSAlias(),self.getClassName()), 1725 ) 1726 bases.append(\ 1727 '%sbases.insert(0, %s.%s)'\ 1728 %(ID1,NAD.getAlias(self.sKlassNS), type_class_name(self.sKlass) ), 1729 ) 1730 bases.append(\ 1731 '%s%s.%s.__bases__ = tuple(bases)'\ 1732 %(ID1, self.getNSAlias(), self.getClassName()) 1733 ) 1734 1735 s = '' 1736 for b in bases: 1737 s += '%s%s\n' % (indent, b) 1738 1739 return s 1740 1741 1742class MessageTypecodeContainer(TypecodeContainerBase): 1743 '''Used for RPC style messages, where we have 1744 serveral parts serialized within a rpc wrapper name. 1745 ''' 1746 logger = _GetLogger("MessageTypecodeContainer") 1747 1748 def __init__(self, parts=None): 1749 TypecodeContainerBase.__init__(self) 1750 self.mgContent = parts 1751 1752 def _getOccurs(self, e): 1753 '''return a 3 item tuple 1754 ''' 1755 minOccurs = maxOccurs = '1' 1756 nillable = True 1757 return minOccurs,maxOccurs,nillable 1758 1759 def _setTypecodeList(self): 1760 self.logger.debug("_setTypecodeList: %s" % 1761 str(self.mgContent)) 1762 1763 assert type(self.mgContent) is tuple,\ 1764 'expecting tuple for mgContent not: %s' %type(self.mgContent) 1765 1766 for p in self.mgContent: 1767 # JRB 1768 # not sure what needs to be set for tc, this should be 1769 # the job of the constructor or a setUp method. 1770 min,max,nil = self._getOccurs(p) 1771 if p.element: 1772 raise WSInteropError, WSISpec.R2203 1773 elif p.type: 1774 nsuri,name = p.type 1775 tc = RPCMessageTcListComponentContainer(qualified=False) 1776 tc.setOccurs(min, max, nil) 1777 tc.name = p.name 1778 if nsuri in [SOAP.ENC] + SCHEMA.XSD_LIST: 1779 tpc = BTI.get_typeclass(name, nsuri) 1780 tc.klass = tpc 1781 else: 1782 tc.klass = '%s.%s' % (NAD.getAlias(nsuri), type_class_name(name) ) 1783 else: 1784 raise ContainerError, 'part must define an element or type attribute' 1785 1786 self.tcListElements.append(tc) 1787 1788 def getTypecodeList(self): 1789 if not self.tcListSet: 1790 self._setTypecodeList() 1791 self.tcListSet = True 1792 1793 list = [] 1794 for e in self.tcListElements: 1795 list.append(str(e)) 1796 return ', '.join(list) 1797 1798 def getAttributeNames(self): 1799 '''returns a list of anames representing the parts 1800 of the message. 1801 ''' 1802 return map(lambda e: self.getAttributeName(e.name), self.tcListElements) 1803 1804 def getParameterNames(self): 1805 '''returns a list of pnames representing the parts 1806 of the message. 1807 ''' 1808 return map(lambda e: e.name, self.tcListElements) 1809 1810 def setParts(self, parts): 1811 self.mgContent = parts 1812 1813 1814class TcListComponentContainer(ContainerBase): 1815 '''Encapsulates a single value in the TClist list. 1816 it inherits TypecodeContainerBase only to get the mangle() method, 1817 it does not call the baseclass ctor. 1818 1819 TODO: Change this inheritance scheme. 1820 ''' 1821 logger = _GetLogger("TcListComponentContainer") 1822 1823 def __init__(self, qualified=True): 1824 ''' 1825 qualified -- qualify element. All GEDs should be qualified, 1826 but local element declarations qualified if form attribute 1827 is qualified, else they are unqualified. Only relevant for 1828 standard style. 1829 ''' 1830 #TypecodeContainerBase.__init__(self) 1831 ContainerBase.__init__(self) 1832 1833 self.qualified = qualified 1834 self.name = None 1835 self.klass = None 1836 self.global_type = None 1837 1838 self.min = None 1839 self.max = None 1840 self.nil = None 1841 self.style = None 1842 self.setStyleElementDeclaration() 1843 1844 def setOccurs(self, min, max, nil): 1845 self.min = min 1846 self.max = max 1847 self.nil = nil 1848 1849 def setProcessContents(self, processContents): 1850 self.processContents = processContents 1851 1852 def setGlobalType(self, namespace, name): 1853 self.global_type = (namespace, name) 1854 1855 def setStyleElementDeclaration(self): 1856 '''set the element style. 1857 standard -- GED or local element 1858 ''' 1859 self.style = 'standard' 1860 1861 def setStyleElementReference(self): 1862 '''set the element style. 1863 ref -- element reference 1864 ''' 1865 self.style = 'ref' 1866 1867 def setStyleAnyElement(self): 1868 '''set the element style. 1869 anyElement -- <any> element wildcard 1870 ''' 1871 self.name = 'any' 1872 self.style = 'anyElement' 1873 1874# def setStyleRecursion(self): 1875# '''TODO: Remove. good for 1 level 1876# ''' 1877# self.style = 'recursion' 1878 1879 def unQualified(self): 1880 '''Do not qualify element. 1881 ''' 1882 self.qualified = False 1883 1884 def _getOccurs(self): 1885 return 'minOccurs=%s, maxOccurs=%s, nillable=%s' \ 1886 % (self.min, self.max, self.nil) 1887 1888 def _getProcessContents(self): 1889 return 'processContents="%s"' \ 1890 % (self.processContents) 1891 1892 def _getvalue(self): 1893 kw = {'occurs':self._getOccurs(), 1894 'aname':self.getAttributeName(self.name), 1895 'klass':self.klass, 1896 'lazy':TypecodeContainerBase.lazy, 1897 'typed':'typed=False', 1898 'encoded':'encoded=kw.get("encoded")'} 1899 1900 gt = self.global_type 1901 if gt is not None: 1902 kw['nsuri'],kw['type'] = gt 1903 1904 if self.style == 'standard': 1905 kw['pname'] = '"%s"' %self.name 1906 if self.qualified is True: 1907 kw['pname'] = '(ns,"%s")' %self.name 1908 if gt is None: 1909 return '%(klass)s(pname=%(pname)s, aname="%(aname)s", %(occurs)s, %(typed)s, %(encoded)s)' %kw 1910 return 'GTD("%(nsuri)s","%(type)s",lazy=%(lazy)s)(pname=%(pname)s, aname="%(aname)s", %(occurs)s, %(typed)s, %(encoded)s)' %kw 1911 1912 if self.style == 'ref': 1913 if gt is None: 1914 return '%(klass)s(%(occurs)s, %(encoded)s)' %kw 1915 return 'GED("%(nsuri)s","%(type)s",lazy=%(lazy)s, isref=True)(%(occurs)s, %(encoded)s)' %kw 1916 1917 kw['process'] = self._getProcessContents() 1918 if self.style == 'anyElement': 1919 return 'ZSI.TC.AnyElement(aname="%(aname)s", %(occurs)s, %(process)s)' %kw 1920 1921# if self.style == 'recursion': 1922# return 'ZSI.TC.AnyElement(aname="%(aname)s", %(occurs)s, %(process)s)' %kw 1923 1924 raise RuntimeError, 'Must set style for typecode list generation' 1925 1926 def __str__(self): 1927 return self._getvalue() 1928 1929 1930class RPCMessageTcListComponentContainer(TcListComponentContainer): 1931 '''Container for rpc/literal rpc/encoded message typecode. 1932 ''' 1933 logger = _GetLogger("RPCMessageTcListComponentContainer") 1934 1935 def __init__(self, qualified=True, encoded=None): 1936 ''' 1937 encoded -- encoded namespaceURI, if None treat as rpc/literal. 1938 ''' 1939 TcListComponentContainer.__init__(self, qualified=qualified) 1940 self._encoded = encoded 1941 1942 def _getvalue(self): 1943 encoded = self._encoded 1944 if encoded is not None: 1945 encoded = '"%s"' %self._encoded 1946 1947 if self.style == 'standard': 1948 pname = '"%s"' %self.name 1949 if self.qualified is True: 1950 pname = '(ns,"%s")' %self.name 1951 return '%s(pname=%s, aname="%s", typed=False, encoded=%s, %s)' \ 1952 %(self.klass, pname, self.getAttributeName(self.name), 1953 encoded, self._getOccurs()) 1954 elif self.style == 'ref': 1955 return '%s(encoded=%s, %s)' % (self.klass, encoded, self._getOccurs()) 1956 elif self.style == 'anyElement': 1957 return 'ZSI.TC.AnyElement(aname="%s", %s, %s)' \ 1958 %(self.getAttributeName(self.name), self._getOccurs(), self._getProcessContents()) 1959# elif self.style == 'recursion': 1960# return 'ZSI.TC.AnyElement(aname="%s", %s, %s)' \ 1961# % (self.getAttributeName(self.name), self._getOccurs(), self._getProcessContents()) 1962 1963 raise RuntimeError('Must set style(%s) for typecode list generation' % 1964 self.style) 1965 1966 1967class ElementSimpleTypeContainer(TypecodeContainerBase): 1968 type = DEC 1969 logger = _GetLogger("ElementSimpleTypeContainer") 1970 1971 def _substitutionGroupTag(self): 1972 value = self.substitutionGroup 1973 if not value: 1974 return 'substitutionGroup = None' 1975 1976 nsuri,ncname = value 1977 return 'substitutionGroup = ("%s","%s")' %(nsuri, ncname) 1978 1979 def _setContent(self): 1980 aname = self.getAttributeName(self.name) 1981 pyclass = self.pyclass 1982 1983 # bool cannot be subclassed 1984 if pyclass == 'bool': pyclass = 'int' 1985 kw = KW.copy() 1986 kw.update(dict(aname=aname, ns=self.ns, name=self.name, 1987 substitutionGroup=self._substitutionGroupTag(), 1988 subclass=self.sKlass,literal=self.literalTag(), 1989 schema=self.schemaTag(), init=self.simpleConstructor(), 1990 klass=self.getClassName(), element="ElementDeclaration")) 1991 1992 if self.local: 1993 kw['element'] = 'LocalElementDeclaration' 1994 1995 element = map(lambda i: i %kw, [ 1996 '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):', 1997 '%(ID2)s%(literal)s', 1998 '%(ID2)s%(schema)s', 1999 '%(ID2)s%(init)s', 2000 '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")', 2001 '%(ID3)skw["aname"] = "%(aname)s"', 2002 ] 2003 ) 2004 2005 # TODO: What about getPyClass and getPyClassDefinition? 2006 # I want to add pyclass metaclass here but this needs to be 2007 # corrected first. 2008 # 2009 # anyType (?others) has no pyclass. 2010 app = element.append 2011 if pyclass is not None: 2012 app('%sclass IHolder(%s): typecode=self' % (ID3, pyclass),) 2013 app('%skw["pyclass"] = IHolder' %(ID3),) 2014 app('%sIHolder.__name__ = "%s_immutable_holder"' %(ID3, aname),) 2015 2016 app('%s%s' % (ID3, self.simpleConstructor(self.sKlass)),) 2017 2018 self.writeArray(element) 2019 2020 def setUp(self, tp): 2021 self._item = tp 2022 self.local = tp.isLocal() 2023 try: 2024 self.name = tp.getAttribute('name') 2025 self.substitutionGroup = tp.getAttribute('substitutionGroup') 2026 self.ns = tp.getTargetNamespace() 2027 qName = tp.getAttribute('type') 2028 except Exception, ex: 2029 raise Wsdl2PythonError('Error occured processing element: %s' %( 2030 tp.getItemTrace()), *ex.args) 2031 2032 if qName is None: 2033 raise Wsdl2PythonError('Missing QName for element type attribute: %s' %tp.getItemTrace()) 2034 2035 tns,local = qName.getTargetNamespace(),qName.getName() 2036 self.sKlass = BTI.get_typeclass(local, tns) 2037 if self.sKlass is None: 2038 raise Wsdl2PythonError('No built-in typecode for type definition("%s","%s"): %s' %(tns,local,tp.getItemTrace())) 2039 2040 try: 2041 self.pyclass = BTI.get_pythontype(None, None, typeclass=self.sKlass) 2042 except Exception, ex: 2043 raise Wsdl2PythonError('Error occured processing element: %s' %( 2044 tp.getItemTrace()), *ex.args) 2045 2046 2047class ElementLocalSimpleTypeContainer(TypecodeContainerBase): 2048 '''local simpleType container 2049 ''' 2050 type = DEC 2051 logger = _GetLogger("ElementLocalSimpleTypeContainer") 2052 2053 def _setContent(self): 2054 kw = KW.copy() 2055 kw.update(dict(aname=self.getAttributeName(self.name), ns=self.ns, name=self.name, 2056 subclass=self.sKlass,literal=self.literalTag(), 2057 schema=self.schemaTag(), init=self.simpleConstructor(), 2058 klass=self.getClassName(), element="ElementDeclaration", 2059 baseinit=self.simpleConstructor(self.sKlass))) 2060 2061 if self.local: 2062 kw['element'] = 'LocalElementDeclaration' 2063 2064 element = map(lambda i: i %kw, [ 2065 '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):', 2066 '%(ID2)s%(literal)s', 2067 '%(ID2)s%(schema)s', 2068 '%(ID2)s%(init)s', 2069 '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")', 2070 '%(ID3)skw["aname"] = "%(aname)s"', 2071 '%(ID3)s%(baseinit)s', 2072 ] 2073 ) 2074 2075 app = element.append 2076 pyclass = self.pyclass 2077 if pyclass is not None: 2078 # bool cannot be subclassed 2079 if pyclass == 'bool': pyclass = 'int' 2080 kw['pyclass'] = pyclass 2081 app('%(ID3)sclass IHolder(%(pyclass)s): typecode=self' %kw) 2082 app('%(ID3)sself.pyclass = IHolder' %kw) 2083 app('%(ID3)sIHolder.__name__ = "%(aname)s_immutable_holder"' %kw) 2084 2085 self.writeArray(element) 2086 2087 def _setup_pyclass(self): 2088 try: 2089 self.pyclass = BTI.get_pythontype(None, None, 2090 typeclass=self.sKlass) 2091 except Exception, ex: 2092 raise Wsdl2PythonError('Error occured processing element: %s' %( 2093 self._item.getItemTrace()), *ex.args) 2094 2095 def setUp(self, tp): 2096 self._item = tp 2097 assert tp.isElement() is True and tp.content is not None and \ 2098 tp.content.isLocal() is True and tp.content.isSimple() is True ,\ 2099 'expecting local simple type: %s' %tp.getItemTrace() 2100 2101 self.local = tp.isLocal() 2102 self.name = tp.getAttribute('name') 2103 self.ns = tp.getTargetNamespace() 2104 content = tp.content.content 2105 if content.isRestriction(): 2106 try: 2107 base = content.getTypeDefinition() 2108 except XMLSchema.SchemaError, ex: 2109 base = None 2110 2111 qName = content.getAttributeBase() 2112 if base is None: 2113 self.sKlass = BTI.get_typeclass(qName[1], qName[0]) 2114 self._setup_pyclass() 2115 return 2116 2117 raise Wsdl2PythonError, 'unsupported local simpleType restriction: %s' \ 2118 %tp.content.getItemTrace() 2119 2120 if content.isList(): 2121 try: 2122 base = content.getTypeDefinition() 2123 except XMLSchema.SchemaError, ex: 2124 base = None 2125 2126 if base is None: 2127 qName = content.getItemType() 2128 self.sKlass = BTI.get_typeclass(qName[1], qName[0]) 2129 self._setup_pyclass() 2130 return 2131 2132 raise Wsdl2PythonError, 'unsupported local simpleType List: %s' \ 2133 %tp.content.getItemTrace() 2134 2135 if content.isUnion(): 2136 raise Wsdl2PythonError, 'unsupported local simpleType Union: %s' \ 2137 %tp.content.getItemTrace() 2138 2139 raise Wsdl2PythonError, 'unexpected schema item: %s' \ 2140 %tp.content.getItemTrace() 2141 2142 2143class ElementLocalComplexTypeContainer(TypecodeContainerBase, AttributeMixIn): 2144 type = DEC 2145 logger = _GetLogger("ElementLocalComplexTypeContainer") 2146 2147 def _setContent(self): 2148 kw = KW.copy() 2149 try: 2150 kw.update(dict(klass=self.getClassName(), 2151 subclass='ZSI.TCcompound.ComplexType', 2152 element='ElementDeclaration', 2153 literal=self.literalTag(), 2154 schema=self.schemaTag(), 2155 init=self.simpleConstructor(), 2156 ns=self.ns, name=self.name, 2157 aname=self.getAttributeName(self.name), 2158 nsurilogic=self.nsuriLogic(), 2159 ofwhat=self.getTypecodeList(), 2160 atypecode=self.attribute_typecode, 2161 pyclass=self.getPyClass(), 2162 )) 2163 except Exception, ex: 2164 args = ['Failure processing an element w/local complexType: %s' %( 2165 self._item.getItemTrace())] 2166 args += ex.args 2167 ex.args = tuple(args) 2168 raise 2169 2170 if self.local: 2171 kw['element'] = 'LocalElementDeclaration' 2172 2173 element = [ 2174 '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):', 2175 '%(ID2)s%(literal)s', 2176 '%(ID2)s%(schema)s', 2177 '%(ID2)s%(init)s', 2178 '%(ID3)s%(nsurilogic)s', 2179 '%(ID3)sTClist = [%(ofwhat)s]', 2180 '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")', 2181 '%(ID3)skw["aname"] = "%(aname)s"', 2182 '%(ID3)s%(atypecode)s = {}', 2183 '%(ID3)sZSI.TCcompound.ComplexType.__init__(self,None,TClist,inorder=0,**kw)', 2184 ] 2185 for l in self.attrComponents: element.append('%(ID3)s'+str(l)) 2186 element += self.getPyClassDefinition() 2187 element.append('%(ID3)sself.pyclass = %(pyclass)s' %kw) 2188 self.writeArray(map(lambda l: l %kw, element)) 2189 2190 def setUp(self, tp): 2191 ''' 2192 {'xsd':['annotation', 'simpleContent', 'complexContent',\ 2193 'group', 'all', 'choice', 'sequence', 'attribute', 'attributeGroup',\ 2194 'anyAttribute', 'any']} 2195 ''' 2196 # 2197 # TODO: Need a Recursive solution, this is incomplete will ignore many 2198 # extensions, restrictions, etc. 2199 # 2200 self._item = tp 2201 # JRB HACK SUPPORTING element/no content. 2202 assert tp.isElement() is True and \ 2203 (tp.content is None or (tp.content.isComplex() is True and tp.content.isLocal() is True)),\ 2204 'expecting element w/local complexType not: %s' %tp.content.getItemTrace() 2205 2206 self.name = tp.getAttribute('name') 2207 self.ns = tp.getTargetNamespace() 2208 self.local = tp.isLocal() 2209 2210 complex = tp.content 2211 # JRB HACK SUPPORTING element/no content. 2212 if complex is None: 2213 self.mgContent = () 2214 return 2215 2216 #attributeContent = complex.getAttributeContent() 2217 #self.mgContent = None 2218 if complex.content is None: 2219 self.mgContent = () 2220 self.attrComponents = self._setAttributes(complex.getAttributeContent()) 2221 return 2222 2223 is_simple = complex.content.isSimple() 2224 if is_simple and complex.content.content.isExtension(): 2225 # TODO: Not really supported just passing thru 2226 self.mgContent = () 2227 self.attrComponents = self._setAttributes(complex.getAttributeContent()) 2228 return 2229 2230 if is_simple and complex.content.content.isRestriction(): 2231 # TODO: Not really supported just passing thru 2232 self.mgContent = () 2233 self.attrComponents = self._setAttributes(complex.getAttributeContent()) 2234 return 2235 2236 if is_simple: 2237 raise ContainerError, 'not implemented local complexType/simpleContent: %s'\ 2238 %tp.getItemTrace() 2239 2240 is_complex = complex.content.isComplex() 2241 if is_complex and complex.content.content is None: 2242 # TODO: Recursion... 2243 self.mgContent = () 2244 self.attrComponents = self._setAttributes(complex.getAttributeContent()) 2245 return 2246 2247 if (is_complex and complex.content.content.isExtension() and 2248 complex.content.content.content is not None and 2249 complex.content.content.content.isModelGroup()): 2250 2251 self.mgContent = complex.content.content.content.content 2252 self.attrComponents = self._setAttributes( 2253 complex.content.content.getAttributeContent() 2254 ) 2255 return 2256 2257 if (is_complex and complex.content.content.isRestriction() and 2258 complex.content.content.content is not None and 2259 complex.content.content.content.isModelGroup()): 2260 2261 self.mgContent = complex.content.content.content.content 2262 self.attrComponents = self._setAttributes( 2263 complex.content.content.getAttributeContent() 2264 ) 2265 return 2266 2267 if is_complex: 2268 self.mgContent = () 2269 self.attrComponents = self._setAttributes(complex.getAttributeContent()) 2270 return 2271 2272 if complex.content.isModelGroup(): 2273 self.mgContent = complex.content.content 2274 self.attrComponents = self._setAttributes(complex.getAttributeContent()) 2275 return 2276 2277 # TODO: Scary Fallthru 2278 self.mgContent = () 2279 self.attrComponents = self._setAttributes(complex.getAttributeContent()) 2280 2281 2282class ElementGlobalDefContainer(TypecodeContainerBase): 2283 type = DEC 2284 logger = _GetLogger("ElementGlobalDefContainer") 2285 2286 def _substitutionGroupTag(self): 2287 value = self.substitutionGroup 2288 if not value: 2289 return 'substitutionGroup = None' 2290 2291 nsuri,ncname = value 2292 return 'substitutionGroup = ("%s","%s")' %(nsuri, ncname) 2293 2294 def _setContent(self): 2295 '''GED defines element name, so also define typecode aname 2296 ''' 2297 kw = KW.copy() 2298 try: 2299 kw.update(dict(klass=self.getClassName(), 2300 element='ElementDeclaration', 2301 literal=self.literalTag(), 2302 substitutionGroup=self._substitutionGroupTag(), 2303 schema=self.schemaTag(), 2304 init=self.simpleConstructor(), 2305 ns=self.ns, name=self.name, 2306 aname=self.getAttributeName(self.name), 2307 baseslogic=self.getBasesLogic(ID3), 2308 #ofwhat=self.getTypecodeList(), 2309 #atypecode=self.attribute_typecode, 2310 #pyclass=self.getPyClass(), 2311 alias=NAD.getAlias(self.sKlassNS), 2312 subclass=type_class_name(self.sKlass), 2313 )) 2314 except Exception, ex: 2315 args = ['Failure processing an element w/local complexType: %s' %( 2316 self._item.getItemTrace())] 2317 args += ex.args 2318 ex.args = tuple(args) 2319 raise 2320 2321 if self.local: 2322 kw['element'] = 'LocalElementDeclaration' 2323 2324 element = [ 2325 '%(ID1)sclass %(klass)s(%(element)s):', 2326 '%(ID2)s%(literal)s', 2327 '%(ID2)s%(schema)s', 2328 '%(ID2)s%(substitutionGroup)s', 2329 '%(ID2)s%(init)s', 2330 '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")', 2331 '%(ID3)skw["aname"] = "%(aname)s"', 2332 '%(baseslogic)s', 2333 '%(ID3)s%(alias)s.%(subclass)s.__init__(self, **kw)', 2334 '%(ID3)sif self.pyclass is not None: self.pyclass.__name__ = "%(klass)s_Holder"', 2335 ] 2336 2337 self.writeArray(map(lambda l: l %kw, element)) 2338 2339 def setUp(self, element): 2340 # Save for debugging 2341 self._item = element 2342 self.local = element.isLocal() 2343 self.name = element.getAttribute('name') 2344 self.substitutionGroup = element.getAttribute('substitutionGroup') 2345 self.ns = element.getTargetNamespace() 2346 tp = element.getTypeDefinition('type') 2347 self.sKlass = tp.getAttribute('name') 2348 self.sKlassNS = tp.getTargetNamespace() 2349 2350 2351class ComplexTypeComplexContentContainer(TypecodeContainerBase, AttributeMixIn): 2352 '''Represents ComplexType with ComplexContent. 2353 ''' 2354 type = DEF 2355 logger = _GetLogger("ComplexTypeComplexContentContainer") 2356 2357 def __init__(self, do_extended=False): 2358 TypecodeContainerBase.__init__(self, do_extended=do_extended) 2359 2360 def setUp(self, tp): 2361 '''complexContent/[extension,restriction] 2362 restriction 2363 extension 2364 extType -- used in figuring attrs for extensions 2365 ''' 2366 self._item = tp 2367 assert tp.content.isComplex() is True and \ 2368 (tp.content.content.isRestriction() or tp.content.content.isExtension() is True),\ 2369 'expecting complexContent/[extension,restriction]' 2370 2371 self.extType = None 2372 self.restriction = False 2373 self.extension = False 2374 self._kw_array = None 2375 self._is_array = False 2376 self.name = tp.getAttribute('name') 2377 self.ns = tp.getTargetNamespace() 2378 2379 # xxx: what is this for? 2380 #self.attribute_typecode = 'attributes' 2381 2382 derivation = tp.content.content 2383 # Defined in Schema instance? 2384 try: 2385 base = derivation.getTypeDefinition('base') 2386 except XMLSchema.SchemaError, ex: 2387 base = None 2388 2389 # anyType, arrayType, etc... 2390 if base is None: 2391 base = derivation.getAttributeQName('base') 2392 if base is None: 2393 raise ContainerError, 'Unsupported derivation: %s'\ 2394 %derivation.getItemTrace() 2395 2396 if base != (SOAP.ENC,'Array') and base != (SCHEMA.XSD3,'anyType'): 2397 raise ContainerError, 'Unsupported base(%s): %s' %( 2398 base, derivation.getItemTrace() 2399 ) 2400 2401 if base == (SOAP.ENC,'Array'): 2402 # SOAP-ENC:Array expecting arrayType attribute reference 2403 self.logger.debug("Derivation of soapenc:Array") 2404 self._is_array = True 2405 self._kw_array = {'atype':None, 'id3':ID3, 'ofwhat':None} 2406 self.sKlass = BTI.get_typeclass(base[1], base[0]) 2407 self.sKlassNS = base[0] 2408 2409 for a in derivation.getAttributeContent(): 2410 2411 assert a.isAttribute() is True,\ 2412 'only attribute content expected: %s' %a.getItemTrace() 2413 2414 if a.isReference() is False: 2415 continue 2416 2417 if a.getAttribute('ref') != (SOAP.ENC,'arrayType'): 2418 continue 2419 2420 attr = a.getAttributeQName((WSDL.BASE, 'arrayType')) 2421 if attr is None: 2422 warnings.warn('soapenc:array derivation declares attribute reference ("%s","%s"), does not define attribute ("%s","%s")' %( 2423 SOAP.ENC,'arrayType',WSDL.BASE, 'arrayType')) 2424 break 2425 2426 self._kw_array['atype'] = attr 2427 qname = self._kw_array.get('atype') 2428 if a is not None: 2429 ncname = qname[1].strip('[]') 2430 namespace = qname[0] 2431 try: 2432 ofwhat = a.getSchemaItem(XMLSchema.TYPES, namespace, ncname) 2433 except XMLSchema.SchemaError, ex: 2434 ofwhat = None 2435 2436 if ofwhat is None: 2437 self._kw_array['ofwhat'] = BTI.get_typeclass(ncname, namespace) 2438 else: 2439 self._kw_array['ofwhat'] = GetClassNameFromSchemaItem(ofwhat, do_extended=self.do_extended) 2440 2441 if self._kw_array['ofwhat'] is None: 2442 raise ContainerError, 'For Array could not resolve ofwhat typecode(%s,%s): %s'\ 2443 %(namespace, ncname, derivation.getItemTrace()) 2444 2445 self.logger.debug('Attribute soapenc:arrayType="%s"' % 2446 str(self._kw_array['ofwhat'])) 2447 2448 break 2449 2450 #else: 2451 # raise Wsdl2PythonError, \ 2452 # 'derivation of soapenc:array must declare attribute reference ("%s","%s")' %( 2453 # SOAP.ENC,'arrayType') 2454 2455 2456 elif isinstance(base, XMLSchema.XMLSchemaComponent): 2457 self.sKlass = base.getAttribute('name') 2458 self.sKlassNS = base.getTargetNamespace() 2459 else: 2460 # TypeDescriptionComponent 2461 self.sKlass = base.getName() 2462 self.sKlassNS = base.getTargetNamespace() 2463 2464 attrs = [] 2465 if derivation.isRestriction(): 2466 self.restriction = True 2467 self.extension = False 2468 # derivation.getAttributeContent subset of tp.getAttributeContent 2469 attrs += derivation.getAttributeContent() or () 2470 else: 2471 self.restriction = False 2472 self.extension = True 2473 attrs += tp.getAttributeContent() or () 2474 if isinstance(derivation, XMLSchema.XMLSchemaComponent): 2475 attrs += derivation.getAttributeContent() or () 2476 2477 # XXX: not sure what this is doing 2478 if attrs: 2479 self.extType = derivation 2480 2481 if derivation.content is not None \ 2482 and derivation.content.isModelGroup(): 2483 group = derivation.content 2484 if group.isReference(): 2485 group = group.getModelGroupReference() 2486 self.mgContent = group.content 2487 elif derivation.content: 2488 raise Wsdl2PythonError, \ 2489 'expecting model group, not: %s' %derivation.content.getItemTrace() 2490 else: 2491 self.mgContent = () 2492 2493 self.attrComponents = self._setAttributes(tuple(attrs)) 2494 2495 def _setContent(self): 2496 '''JRB What is the difference between instance data 2497 ns, name, -- type definition? 2498 sKlass, sKlassNS? -- element declaration? 2499 ''' 2500 kw = KW.copy() 2501 definition = [] 2502 if self._is_array: 2503 # SOAP-ENC:Array 2504 if _is_xsd_or_soap_ns(self.sKlassNS) is False and self.sKlass == 'Array': 2505 raise ContainerError, 'unknown type: (%s,%s)'\ 2506 %(self.sKlass, self.sKlassNS) 2507 2508 # No need to xsi:type array items since specify with 2509 # SOAP-ENC:arrayType attribute. 2510 definition += [\ 2511 '%sclass %s(ZSI.TC.Array, TypeDefinition):' % (ID1, self.getClassName()), 2512 '%s#complexType/complexContent base="SOAP-ENC:Array"' %(ID2), 2513 '%s%s' % (ID2, self.schemaTag()), 2514 '%s%s' % (ID2, self.typeTag()), 2515 '%s%s' % (ID2, self.pnameConstructor()), 2516 ] 2517 2518 append = definition.append 2519 if self._kw_array.get('ofwhat') is None: 2520 append('%s%s.__init__(self, None, None, pname=pname, childnames=\'item\', undeclared=True, **kw)' %(ID3, self.sKlass)) 2521 else: 2522 append('%(id3)sofwhat = %(ofwhat)s(None, typed=False)' %self._kw_array) 2523 append('%(id3)satype = %(atype)s' %self._kw_array) 2524 append('%s%s.__init__(self, atype, ofwhat, pname=pname, childnames=\'item\', **kw)' %(ID3, self.sKlass)) 2525 2526 self.writeArray(definition) 2527 return 2528 2529 definition += [\ 2530 '%sclass %s(TypeDefinition):' % (ID1, self.getClassName()), 2531 '%s%s' % (ID2, self.schemaTag()), 2532 '%s%s' % (ID2, self.typeTag()), 2533 '%s%s' % (ID2, self.pnameConstructor()), 2534 '%s%s' % (ID3, self.nsuriLogic()), 2535 '%sTClist = [%s]' % (ID3, self.getTypecodeList()), 2536 ] 2537 2538 definition.append( 2539 '%(ID3)sattributes = %(atc)s = attributes or {}' %{ 2540 'ID3':ID3, 'atc':self.attribute_typecode} 2541 ) 2542 2543 # 2544 # Special case: anyType restriction 2545 isAnyType = (self.sKlassNS, self.sKlass) == (SCHEMA.XSD3, 'anyType') 2546 if isAnyType: 2547 del definition[0] 2548 definition.insert(0, 2549 '%sclass %s(ZSI.TC.ComplexType, TypeDefinition):' % ( 2550 ID1, self.getClassName()) 2551 ) 2552 definition.insert(1, 2553 '%s#complexType/complexContent restrict anyType' %( 2554 ID2) 2555 ) 2556 2557 # derived type support 2558 definition.append('%sif extend: TClist += ofwhat'%(ID3)) 2559 definition.append('%sif restrict: TClist = ofwhat' %(ID3)) 2560 if len(self.attrComponents) > 0: 2561 definition.append('%selse:' %(ID3)) 2562 for l in self.attrComponents: 2563 definition.append('%s%s'%(ID4, l)) 2564 2565 if isAnyType: 2566 definition.append(\ 2567 '%sZSI.TC.ComplexType.__init__(self, None, TClist, pname=pname, **kw)' %( 2568 ID3), 2569 ) 2570 2571 # pyclass class definition 2572 definition += self.getPyClassDefinition() 2573 kw['pyclass'] = self.getPyClass() 2574 definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw) 2575 self.writeArray(definition) 2576 return 2577 2578 definition.append('%s' % self.getBasesLogic(ID3)) 2579 prefix = NAD.getAlias(self.sKlassNS) 2580 typeClassName = type_class_name(self.sKlass) 2581 if self.restriction: 2582 definition.append(\ 2583 '%s%s.%s.__init__(self, pname, ofwhat=TClist, restrict=True, **kw)' %( 2584 ID3, prefix, typeClassName), 2585 ) 2586 definition.insert(1, '%s#complexType/complexContent restriction' %ID2) 2587 self.writeArray(definition) 2588 return 2589 2590 if self.extension: 2591 definition.append(\ 2592 '%s%s.%s.__init__(self, pname, ofwhat=TClist, extend=True, attributes=attributes, **kw)'%( 2593 ID3, prefix, typeClassName), 2594 ) 2595 definition.insert(1, '%s#complexType/complexContent extension' %(ID2)) 2596 self.writeArray(definition) 2597 return 2598 2599 raise Wsdl2PythonError,\ 2600 'ComplexContent must be a restriction or extension' 2601 2602 def pnameConstructor(self, superclass=None): 2603 if superclass: 2604 return '%s.__init__(self, pname, ofwhat=(), extend=False, restrict=False, attributes=None, **kw)' % superclass 2605 2606 return 'def __init__(self, pname, ofwhat=(), extend=False, restrict=False, attributes=None, **kw):' 2607 2608 2609class ComplexTypeContainer(TypecodeContainerBase, AttributeMixIn): 2610 '''Represents a global complexType definition. 2611 ''' 2612 type = DEF 2613 logger = _GetLogger("ComplexTypeContainer") 2614 2615 def setUp(self, tp, empty=False): 2616 '''Problematic, loose all model group information. 2617 <all>, <choice>, <sequence> .. 2618 2619 tp -- type definition 2620 empty -- no model group, just use as a dummy holder. 2621 ''' 2622 self._item = tp 2623 2624 self.name = tp.getAttribute('name') 2625 self.ns = tp.getTargetNamespace() 2626 self.mixed = tp.isMixed() 2627 self.mgContent = () 2628 self.attrComponents = self._setAttributes(tp.getAttributeContent()) 2629 2630 # Save reference to type for debugging 2631 self._item = tp 2632 2633 if empty: 2634 return 2635 2636 model = tp.content 2637 if model.isReference(): 2638 model = model.getModelGroupReference() 2639 2640 if model is None: 2641 return 2642 2643 if model.content is None: 2644 return 2645 2646 # sequence, all or choice 2647 #self.mgContent = model.content 2648 self.mgContent = model 2649 2650 def _setContent(self): 2651 try: 2652 definition = [ 2653 '%sclass %s(ZSI.TCcompound.ComplexType, TypeDefinition):' 2654 % (ID1, self.getClassName()), 2655 '%s%s' % (ID2, self.schemaTag()), 2656 '%s%s' % (ID2, self.typeTag()), 2657 '%s%s' % (ID2, self.pnameConstructor()), 2658 #'%s' % self.getElements(), 2659 '%s%s' % (ID3, self.nsuriLogic()), 2660 '%sTClist = [%s]' % (ID3, self.getTypecodeList()), 2661 ] 2662 except Exception, ex: 2663 args = ["Failure processing %s" %self._item.getItemTrace()] 2664 args += ex.args 2665 ex.args = tuple(args) 2666 raise 2667 2668 definition.append('%s%s = attributes or {}' %(ID3, 2669 self.attribute_typecode)) 2670 # IF EXTEND 2671 definition.append('%sif extend: TClist += ofwhat'%(ID3)) 2672 # IF RESTRICT 2673 definition.append('%sif restrict: TClist = ofwhat' %(ID3)) 2674 # ELSE 2675 if len(self.attrComponents) > 0: 2676 definition.append('%selse:' %(ID3)) 2677 for l in self.attrComponents: definition.append('%s%s'%(ID4, l)) 2678 2679 definition.append(\ 2680 '%sZSI.TCcompound.ComplexType.__init__(self, None, TClist, pname=pname, inorder=0, %s**kw)' \ 2681 %(ID3, self.getExtraFlags()) 2682 ) 2683 2684 # pyclass class definition 2685 definition += self.getPyClassDefinition() 2686 2687 # set pyclass 2688 kw = KW.copy() 2689 kw['pyclass'] = self.getPyClass() 2690 definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw) 2691 self.writeArray(definition) 2692 2693 def pnameConstructor(self, superclass=None): 2694 ''' TODO: Logic is a little tricky. If superclass is ComplexType this is not used. 2695 ''' 2696 if superclass: 2697 return '%s.__init__(self, pname, ofwhat=(), attributes=None, extend=False, restrict=False, **kw)' % superclass 2698 2699 return 'def __init__(self, pname, ofwhat=(), attributes=None, extend=False, restrict=False, **kw):' 2700 2701 2702class SimpleTypeContainer(TypecodeContainerBase): 2703 type = DEF 2704 logger = _GetLogger("SimpleTypeContainer") 2705 2706 def __init__(self): 2707 ''' 2708 Instance Data From TypecodeContainerBase NOT USED... 2709 mgContent 2710 ''' 2711 TypecodeContainerBase.__init__(self) 2712 2713 def setUp(self, tp): 2714 raise NotImplementedError, 'abstract method not implemented' 2715 2716 def _setContent(self, tp): 2717 raise NotImplementedError, 'abstract method not implemented' 2718 2719 def getPythonType(self): 2720 pyclass = eval(str(self.sKlass)) 2721 if issubclass(pyclass, ZSI.TC.String): 2722 return 'str' 2723 if issubclass(pyclass, ZSI.TC.Ilong) or issubclass(pyclass, ZSI.TC.IunsignedLong): 2724 return 'long' 2725 if issubclass(pyclass, ZSI.TC.Boolean) or issubclass(pyclass, ZSI.TC.Integer): 2726 return 'int' 2727 if issubclass(pyclass, ZSI.TC.Decimal): 2728 return 'float' 2729 if issubclass(pyclass, ZSI.TC.Gregorian) or issubclass(pyclass, ZSI.TC.Duration): 2730 return 'tuple' 2731 return None 2732 2733 def getPyClassDefinition(self): 2734 definition = [] 2735 pt = self.getPythonType() 2736 if pt is not None: 2737 definition.append('%sclass %s(%s):' %(ID3,self.getPyClass(),pt)) 2738 definition.append('%stypecode = self' %ID4) 2739 return definition 2740 2741 2742class RestrictionContainer(SimpleTypeContainer): 2743 ''' 2744 simpleType/restriction 2745 ''' 2746 logger = _GetLogger("RestrictionContainer") 2747 2748 def setUp(self, tp): 2749 self._item = tp 2750 2751 assert tp.isSimple() is True and tp.isDefinition() is True and \ 2752 tp.content.isRestriction() is True,\ 2753 'expecting simpleType restriction, not: %s' %tp.getItemTrace() 2754 2755 if tp.content is None: 2756 raise Wsdl2PythonError, \ 2757 'empty simpleType defintion: %s' %tp.getItemTrace() 2758 2759 self.name = tp.getAttribute('name') 2760 self.ns = tp.getTargetNamespace() 2761 self.sKlass = None 2762 2763 base = tp.content.getAttribute('base') 2764 if base is not None: 2765 try: 2766 item = tp.content.getTypeDefinition('base') 2767 except XMLSchema.SchemaError, ex: 2768 item = None 2769 2770 if item is None: 2771 self.sKlass = BTI.get_typeclass(base.getName(), base.getTargetNamespace()) 2772 if self.sKlass is not None: 2773 return 2774 2775 raise Wsdl2PythonError('no built-in type nor schema instance type for base attribute("%s","%s"): %s' %( 2776 base.getTargetNamespace(), base.getName(), tp.getItemTrace())) 2777 2778 raise Wsdl2PythonError, \ 2779 'Not Supporting simpleType/Restriction w/User-Defined Base: %s %s' %(tp.getItemTrace(),item.getItemTrace()) 2780 2781 sc = tp.content.getSimpleTypeContent() 2782 if sc is not None and True is sc.isSimple() is sc.isLocal() is sc.isDefinition(): 2783 base = None 2784 if sc.content.isRestriction() is True: 2785 try: 2786 item = tp.content.getTypeDefinition('base') 2787 except XMLSchema.SchemaError, ex: 2788 pass 2789 2790 if item is None: 2791 base = sc.content.getAttribute('base') 2792 if base is not None: 2793 self.sKlass = BTI.get_typeclass(base.getTargetNamespace(), base.getName()) 2794 return 2795 raise Wsdl2PythonError, \ 2796 'Not Supporting simpleType/Restriction w/User-Defined Base: '\ 2797 %item.getItemTrace() 2798 2799 raise Wsdl2PythonError, \ 2800 'Not Supporting simpleType/Restriction w/User-Defined Base: '\ 2801 %item.getItemTrace() 2802 2803 if sc.content.isList() is True: 2804 raise Wsdl2PythonError, \ 2805 'iction base in subtypes: %s'\ 2806 %sc.getItemTrace() 2807 2808 if sc.content.isUnion() is True: 2809 raise Wsdl2PythonError, \ 2810 'could not get restriction base in subtypes: %s'\ 2811 %sc.getItemTrace() 2812 2813 return 2814 2815 raise Wsdl2PythonError, 'No Restriction @base/simpleType: %s' %tp.getItemTrace() 2816 2817 def _setContent(self): 2818 2819 definition = [ 2820 '%sclass %s(%s, TypeDefinition):' %(ID1, self.getClassName(), 2821 self.sKlass), 2822 '%s%s' % (ID2, self.schemaTag()), 2823 '%s%s' % (ID2, self.typeTag()), 2824 '%s%s' % (ID2, self.pnameConstructor()), 2825 ] 2826 if self.getPythonType() is None: 2827 definition.append('%s%s.__init__(self, pname, **kw)' %(ID3, 2828 self.sKlass)) 2829 else: 2830 definition.append('%s%s.__init__(self, pname, pyclass=None, **kw)' \ 2831 %(ID3, self.sKlass,)) 2832 2833 # pyclass class definition 2834 definition += self.getPyClassDefinition() 2835 2836 # set pyclass 2837 kw = KW.copy() 2838 kw['pyclass'] = self.getPyClass() 2839 definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw) 2840 2841 self.writeArray(definition) 2842 2843 2844class ComplexTypeSimpleContentContainer(SimpleTypeContainer, AttributeMixIn): 2845 '''Represents a ComplexType with simpleContent. 2846 ''' 2847 type = DEF 2848 logger = _GetLogger("ComplexTypeSimpleContentContainer") 2849 2850 def setUp(self, tp): 2851 '''tp -- complexType/simpleContent/[Exention,Restriction] 2852 ''' 2853 self._item = tp 2854 2855 assert tp.isComplex() is True and tp.content.isSimple() is True,\ 2856 'expecting complexType/simpleContent not: %s' %tp.content.getItemTrace() 2857 2858 simple = tp.content 2859 dv = simple.content 2860 assert dv.isExtension() is True or dv.isRestriction() is True,\ 2861 'expecting complexType/simpleContent/[Extension,Restriction] not: %s' \ 2862 %tp.content.getItemTrace() 2863 2864 self.name = tp.getAttribute('name') 2865 self.ns = tp.getTargetNamespace() 2866 # TODO: Why is this being set? 2867 self.content.attributeContent = dv.getAttributeContent() 2868 2869 base = dv.getAttribute('base') 2870 if base is not None: 2871 self.sKlass = BTI.get_typeclass( base[1], base[0] ) 2872 if not self.sKlass: 2873 self.sKlass,self.sKlassNS = base[1], base[0] 2874 2875 self.attrComponents = self._setAttributes( 2876 self.content.attributeContent 2877 ) 2878 return 2879 2880 raise Wsdl2PythonError,\ 2881 'simple content derivation bad base attribute: ' %tp.getItemTrace() 2882 2883 def _setContent(self): 2884 # TODO: Add derivation logic to constructors. 2885 if type(self.sKlass) in (types.ClassType, type): 2886 definition = [ 2887 '%sclass %s(%s, TypeDefinition):' \ 2888 % (ID1, self.getClassName(), self.sKlass), 2889 '%s# ComplexType/SimpleContent derivation of built-in type' %ID2, 2890 '%s%s' % (ID2, self.schemaTag()), 2891 '%s%s' % (ID2, self.typeTag()), 2892 '%s%s' % (ID2, self.pnameConstructor()), 2893 '%sif getattr(self, "attribute_typecode_dict", None) is None: %s = {}' %( 2894 ID3, self.attribute_typecode), 2895 ] 2896 2897 for l in self.attrComponents: 2898 definition.append('%s%s'%(ID3, l)) 2899 2900 definition.append('%s%s.__init__(self, pname, **kw)' %(ID3, self.sKlass)) 2901 if self.getPythonType() is not None: 2902 definition += self.getPyClassDefinition() 2903 kw = KW.copy() 2904 kw['pyclass'] = self.getPyClass() 2905 definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw) 2906 2907 self.writeArray(definition) 2908 return 2909 2910 definition = [ 2911 '%sclass %s(TypeDefinition):' % (ID1, self.getClassName()), 2912 '%s# ComplexType/SimpleContent derivation of user-defined type' %ID2, 2913 '%s%s' % (ID2, self.schemaTag()), 2914 '%s%s' % (ID2, self.typeTag()), 2915 '%s%s' % (ID2, self.pnameConstructor()), 2916 '%s%s' % (ID3, self.nsuriLogic()), 2917 '%s' % self.getBasesLogic(ID3), 2918 '%sif getattr(self, "attribute_typecode_dict", None) is None: %s = {}' %( 2919 ID3, self.attribute_typecode), 2920 ] 2921 2922 for l in self.attrComponents: 2923 definition.append('%s%s'%(ID3, l)) 2924 2925 definition.append('%s%s.%s.__init__(self, pname, **kw)' %( 2926 ID3, NAD.getAlias(self.sKlassNS), type_class_name(self.sKlass))) 2927 2928 self.writeArray(definition) 2929 2930 def getPyClassDefinition(self): 2931 definition = [] 2932 pt = self.getPythonType() 2933 if pt is not None: 2934 definition.append('%sclass %s(%s):' %(ID3,self.getPyClass(),pt)) 2935 if self.metaclass is not None: 2936 definition.append('%s__metaclass__ = %s' %(ID4, self.metaclass)) 2937 2938 definition.append('%stypecode = self' %ID4) 2939 return definition 2940 2941 2942 2943 2944 2945class UnionContainer(SimpleTypeContainer): 2946 '''SimpleType Union 2947 ''' 2948 type = DEF 2949 logger = _GetLogger("UnionContainer") 2950 2951 def __init__(self): 2952 SimpleTypeContainer.__init__(self) 2953 self.memberTypes = None 2954 2955 def setUp(self, tp): 2956 self._item = tp 2957 2958 if tp.content.isUnion() is False: 2959 raise ContainerError, 'content must be a Union: %s' %tp.getItemTrace() 2960 self.name = tp.getAttribute('name') 2961 self.ns = tp.getTargetNamespace() 2962 self.sKlass = 'ZSI.TC.Union' 2963 self.memberTypes = tp.content.getAttribute('memberTypes') 2964 2965 def _setContent(self): 2966 definition = [ 2967 '%sclass %s(%s, TypeDefinition):' \ 2968 % (ID1, self.getClassName(), self.sKlass), 2969 '%smemberTypes = %s' % (ID2, self.memberTypes), 2970 '%s%s' % (ID2, self.schemaTag()), 2971 '%s%s' % (ID2, self.typeTag()), 2972 '%s%s' % (ID2, self.pnameConstructor()), 2973 '%s%s' % (ID3, self.pnameConstructor(self.sKlass)), 2974 ] 2975 2976 # TODO: Union pyclass is None 2977 self.writeArray(definition) 2978 2979 2980class ListContainer(SimpleTypeContainer): 2981 '''SimpleType List 2982 ''' 2983 type = DEF 2984 logger = _GetLogger("ListContainer") 2985 2986 def setUp(self, tp): 2987 self._item = tp 2988 2989 if tp.content.isList() is False: 2990 raise ContainerError, 'content must be a List: %s' %tp.getItemTrace() 2991 self.name = tp.getAttribute('name') 2992 self.ns = tp.getTargetNamespace() 2993 self.sKlass = 'ZSI.TC.List' 2994 self.itemType = tp.content.getAttribute('itemType') 2995 2996 def _setContent(self): 2997 definition = [ 2998 '%sclass %s(%s, TypeDefinition):' \ 2999 % (ID1, self.getClassName(), self.sKlass), 3000 '%sitemType = %s' % (ID2, self.itemType), 3001 '%s%s' % (ID2, self.schemaTag()), 3002 '%s%s' % (ID2, self.typeTag()), 3003 '%s%s' % (ID2, self.pnameConstructor()), 3004 '%s%s' % (ID3, self.pnameConstructor(self.sKlass)), 3005 ] 3006 self.writeArray(definition) 3007 3008 3009