• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/opal/ZSI/build/lib/ZSI/generate/containers.py

00001 ############################################################################
00002 # Monte M. Goode, LBNL
00003 # See LBNLCopyright for copyright notice!
00004 ###########################################################################
00005 
00006 # contains text container classes for new generation generator
00007 
00008 # $Id: containers.py 1420 2007-10-31 19:51:00Z boverhof $
00009 import types, warnings
00010 from utility import StringWriter, TextProtect, TextProtectAttributeName,\
00011     GetPartsSubNames
00012 from utility import NamespaceAliasDict as NAD, NCName_to_ClassName as NC_to_CN
00013 
00014 import ZSI
00015 from ZSI.TC import _is_xsd_or_soap_ns
00016 from ZSI.wstools import XMLSchema, WSDLTools
00017 from ZSI.wstools.Namespaces import SCHEMA, SOAP, WSDL
00018 from ZSI.wstools.logging import getLogger as _GetLogger
00019 from ZSI.typeinterpreter import BaseTypeInterpreter
00020 from ZSI.generate import WSISpec, WSInteropError, Wsdl2PythonError,\
00021     WsdlGeneratorError, WSDLFormatError
00022 
00023 ID1 = '    '
00024 ID2 = 2*ID1
00025 ID3 = 3*ID1
00026 ID4 = 4*ID1
00027 ID5 = 5*ID1
00028 ID6 = 6*ID1
00029 
00030 KW = {'ID1':ID1, 'ID2':ID2, 'ID3':ID3,'ID4':ID4, 'ID5':ID5, 'ID6':ID6,}
00031 
00032 DEC = '_Dec'
00033 DEF = '_Def'
00034 
00035 """
00036 type_class_name -- function to return the name formatted as a type class.
00037 element_class_name -- function to return the name formatted as an element class.
00038 """
00039 type_class_name = lambda n: '%s%s' %(NC_to_CN(n), DEF)
00040 element_class_name = lambda n: '%s%s' %(NC_to_CN(n), DEC)
00041 
00042 
00043 def IsRPC(item):
00044     """item -- OperationBinding instance.
00045     """
00046     if not isinstance(item, WSDLTools.OperationBinding):
00047         raise TypeError, 'IsRPC takes 1 argument of type WSDLTools.OperationBinding'
00048     soapbinding = item.getBinding().findBinding(WSDLTools.SoapBinding)
00049     sob = item.findBinding(WSDLTools.SoapOperationBinding)
00050     style = soapbinding.style
00051     if sob is not None:
00052         style = sob.style or soapbinding.style
00053     return style == 'rpc'
00054 
00055 
00056 def IsLiteral(item):
00057     """item -- MessageRoleBinding instance.
00058     """
00059     if not isinstance(item, WSDLTools.MessageRoleBinding):
00060         raise TypeError, 'IsLiteral takes 1 argument of type WSDLTools.MessageRoleBinding'
00061     sbb = None
00062     if item.type == 'input' or item.type == 'output':
00063         sbb = item.findBinding(WSDLTools.SoapBodyBinding)
00064     if sbb is None:
00065         raise ValueError, 'Missing soap:body binding.'
00066     return sbb.use == 'literal'
00067 
00068 
00069 def SetTypeNameFunc(func):
00070     global type_class_name
00071     type_class_name = func
00072 
00073 def SetElementNameFunc(func):
00074     global element_class_name
00075     element_class_name = func
00076 
00077 def GetClassNameFromSchemaItem(item,do_extended=False):
00078     '''
00079     '''
00080     assert isinstance(item, XMLSchema.XMLSchemaComponent), 'must be a schema item.'
00081     alias = NAD.getAlias(item.getTargetNamespace())
00082     if item.isDefinition() is True:
00083         return '%s.%s' %(alias, NC_to_CN('%s' %type_class_name(item.getAttributeName())))
00084     return None
00085 
00086 def FromMessageGetSimpleElementDeclaration(message):
00087     '''If message consists of one part with an element attribute,
00088     and this element is a simpleType return a string representing 
00089     the python type, else return None.
00090 
00091     '''
00092     assert isinstance(message, WSDLTools.Message), 'expecting WSDLTools.Message'
00093 
00094     if len(message.parts) == 1 and message.parts[0].element is not None:
00095        part = message.parts[0]
00096        nsuri,name = part.element
00097        wsdl = message.getWSDL()
00098        types = wsdl.types
00099        if types.has_key(nsuri) and types[nsuri].elements.has_key(name):
00100             e = types[nsuri].elements[name]
00101             if isinstance(e, XMLSchema.ElementDeclaration) is True and e.getAttribute('type'):
00102                 typ = e.getAttribute('type')
00103                 bt = BaseTypeInterpreter()
00104                 ptype = bt.get_pythontype(typ[1], typ[0])
00105                 return ptype
00106 
00107     return None
00108 
00109 
00110 class AttributeMixIn:
00111     '''for containers that can declare attributes.
00112     Class Attributes:
00113         attribute_typecode -- typecode attribute name typecode dict
00114         built_in_refs -- attribute references that point to built-in
00115             types.  Skip resolving them into attribute declarations.
00116     '''
00117     attribute_typecode = 'self.attribute_typecode_dict'
00118     built_in_refs = [(SOAP.ENC, 'arrayType'),]
00119     
00120     def _setAttributes(self, attributes):
00121         '''parameters
00122         attributes -- a flat list of all attributes, 
00123         from this list all items in attribute_typecode_dict will
00124         be generated into attrComponents.
00125         
00126         returns a list of strings representing the attribute_typecode_dict.
00127         '''
00128         atd = self.attribute_typecode
00129         atd_list = formatted_attribute_list = []
00130         if not attributes:
00131             return formatted_attribute_list
00132         
00133         atd_list.append('# attribute handling code')
00134         idx = 0
00135         while(idx < len(attributes)):
00136             a = attributes[idx] 
00137             idx += 1
00138             if a.isWildCard() and a.isDeclaration():
00139                 atd_list.append(\
00140                     '%s[("%s","anyAttribute")] = ZSI.TC.AnyElement()'\
00141                     % (atd, SCHEMA.XSD3)
00142                     )
00143             elif a.isDeclaration():
00144                 tdef = a.getTypeDefinition('type')
00145                 if tdef is not None:
00146                     tc = '%s.%s(None)' %(NAD.getAlias(tdef.getTargetNamespace()),
00147                         self.mangle(type_class_name(tdef.getAttributeName()))
00148                         )
00149                 else:
00150                     # built-in
00151                     t = a.getAttribute('type')
00152                     try:
00153                         tc = BTI.get_typeclass(t[1], t[0])
00154                     except:
00155                         # hand back a string by default.
00156                         tc = ZSI.TC.String
00157                             
00158                     if tc is not None: 
00159                         tc = '%s()' %tc
00160                             
00161                 key = None
00162                 if a.getAttribute('form') == 'qualified':
00163                     key = '("%s","%s")' % ( a.getTargetNamespace(),
00164                                             a.getAttribute('name') )
00165                 elif a.getAttribute('form') == 'unqualified':
00166                     key = '"%s"' % a.getAttribute('name')
00167                 else:
00168                     raise ContainerError, \
00169                           'attribute form must be un/qualified %s' \
00170                           % a.getAttribute('form')
00171                           
00172                 atd_list.append(\
00173                     '%s[%s] = %s' % (atd, key, tc)
00174                     )
00175             elif a.isReference() and a.isAttributeGroup():
00176                 # flatten 'em out....
00177                 for ga in a.getAttributeGroup().getAttributeContent():
00178                     attributes += (ga,)
00179 
00180             elif a.isReference():
00181                 try:
00182                     ga = a.getAttributeDeclaration()
00183                 except XMLSchema.SchemaError:
00184                     key = a.getAttribute('ref')
00185                     self.logger.debug('No schema item for attribute ref (%s, %s)' %key)
00186                     if key in self.built_in_refs: continue
00187                     raise
00188                         
00189                 tp = None
00190                 if ga is not None:
00191                     tp = ga.getTypeDefinition('type')           
00192                     key = '("%s","%s")' %(ga.getTargetNamespace(),
00193                              ga.getAttribute('name'))
00194                              
00195                 if ga is None:
00196                     # TODO: probably SOAPENC:arrayType
00197                     key = '("%s","%s")' %(
00198                              a.getAttribute('ref').getTargetNamespace(),
00199                              a.getAttribute('ref').getName())
00200                     atd_list.append(\
00201                         '%s[%s] = ZSI.TC.String()' %(atd, key)
00202                         )
00203                 elif tp is None:
00204                     # built in simple type
00205                     try:
00206                         namespace,typeName = ga.getAttribute('type')
00207                     except TypeError, ex:
00208                         # TODO: attribute declaration could be anonymous type
00209                         # hack in something to work
00210                         atd_list.append(\
00211                             '%s[%s] = ZSI.TC.String()' %(atd, key)
00212                             )
00213                     else:
00214                         atd_list.append(\
00215                             '%s[%s] = %s()' %(atd, key, 
00216                                  BTI.get_typeclass(typeName, namespace))
00217                             )
00218                 else:
00219                     typeName = tp.getAttribute('name')
00220                     namespace = tp.getTargetNamespace()
00221                     alias = NAD.getAlias(namespace)
00222                     key = '("%s","%s")' \
00223                           % (ga.getTargetNamespace(),ga.getAttribute('name'))
00224                     atd_list.append(\
00225                         '%s[%s] = %s.%s(None)' \
00226                         % (atd, key, alias, type_class_name(typeName))
00227                         )
00228             else:
00229                 raise TypeError, 'expecting an attribute: %s' %a.getItemTrace()
00230             
00231         return formatted_attribute_list
00232 
00233 
00234 class ContainerError(Exception):
00235     pass
00236 
00237 
00238 class ContainerBase:
00239     '''Base class for all Containers.
00240         func_aname -- function that takes name, and returns aname.
00241     '''
00242     func_aname = staticmethod(TextProtectAttributeName)
00243     logger = _GetLogger("ContainerBase")
00244 
00245     def __init__(self):
00246         self.content = StringWriter('\n')
00247         self.__setup   = False
00248         self.ns    = None
00249 
00250     def __str__(self):
00251         return self.getvalue()
00252 
00253     # - string content methods
00254     def mangle(self, s):
00255         '''class/variable name illegalities
00256         '''
00257         return TextProtect(s)
00258 
00259     def write(self, s):
00260         self.content.write(s)
00261 
00262     def writeArray(self, a):
00263         self.content.write('\n'.join(a))
00264 
00265     def _setContent(self):
00266         '''override in subclasses.  formats the content in the desired way.
00267         '''
00268         raise NotImplementedError, 'abstract method not implemented'
00269 
00270     def getvalue(self):
00271         if not self.__setup:
00272             self._setContent()
00273             self.__setup = True
00274             
00275         return self.content.getvalue()
00276 
00277     # - namespace utility methods
00278     def getNSAlias(self):
00279         if self.ns is not None:
00280             return NAD.getAlias(self.ns)
00281         raise ContainerError, 'no self.ns attr defined in %s' % self.__class__
00282 
00283     def getNSModuleName(self):
00284         if self.ns:
00285             return NAD.getModuleName(self.ns)
00286         raise ContainerError, 'no self.ns attr defined in %s' % self.__class__
00287 
00288     def getAttributeName(self, name):
00289         '''represents the aname
00290         '''
00291         if self.func_aname is None:
00292             return name
00293         assert callable(self.func_aname), \
00294             'expecting callable method for attribute func_aname, not %s' %type(self.func_aname)
00295         f = self.func_aname
00296         return f(name)
00297 
00298 
00299 # -- containers for services file components
00300 
00301 class ServiceContainerBase(ContainerBase):
00302     clientClassSuffix = "SOAP"
00303     logger = _GetLogger("ServiceContainerBase")
00304     
00305     
00306 class ServiceHeaderContainer(ServiceContainerBase):
00307     imports = ['\nimport urlparse, types',
00308               'from ZSI.TCcompound import ComplexType, Struct',
00309               'from ZSI import client',
00310               'from ZSI.schema import GED, GTD',
00311               'import ZSI'
00312               ]
00313     logger = _GetLogger("ServiceHeaderContainer")
00314                
00315     def __init__(self, do_extended=False):
00316         ServiceContainerBase.__init__(self)
00317         
00318         self.basic = self.imports[:]
00319         self.types = None
00320         self.messages = None
00321         self.extras = []
00322         self.do_extended = do_extended
00323 
00324     def setTypesModuleName(self, module):
00325         self.types = module
00326 
00327     def setMessagesModuleName(self, module):
00328         self.messages = module
00329 
00330     def appendImport(self, statement):
00331         '''append additional import statement(s).
00332         import_stament -- tuple or list or str 
00333         '''
00334         if type(statement) in (list,tuple):
00335             self.extras += statement
00336         else:
00337             self.extras.append(statement)
00338 
00339     def _setContent(self):
00340         if self.messages:
00341             self.write('from %s import *' % self.messages)
00342         if self.types:
00343             self.write('from %s import *' % self.types)
00344 
00345         imports = self.basic[:]
00346         imports += self.extras
00347         self.writeArray(imports)
00348 
00349 
00350 class ServiceLocatorContainer(ServiceContainerBase):
00351     logger = _GetLogger("ServiceLocatorContainer")
00352 
00353     def __init__(self):
00354         ServiceContainerBase.__init__(self)
00355         self.serviceName = None
00356         self.portInfo = []
00357         self.locatorName = None
00358         self.portMethods = []
00359 
00360     def setUp(self, service):
00361         assert isinstance(service, WSDLTools.Service), \
00362            'expecting WDSLTools.Service instance.'
00363 
00364         self.serviceName = service.name
00365         for p in service.ports:
00366             try:
00367                 ab = p.getAddressBinding()
00368             except WSDLTools.WSDLError, ex:
00369                 self.logger.warning('Skip port(%s), missing address binding' %p.name)
00370                 continue
00371             if isinstance(ab, WSDLTools.SoapAddressBinding) is False:
00372                 self.logger.warning('Skip port(%s), not a SOAP-1.1 address binding' %p.name)
00373                 continue
00374 
00375             #info = (p.getBinding().getPortType().name, p.getBinding().name, ab.location)
00376             self.portInfo.append( (NC_to_CN(p.name), 
00377                  NC_to_CN(p.getBinding().name), 
00378                  ab.location)
00379             )
00380 
00381     def getLocatorName(self):
00382         '''return class name of generated locator.
00383         '''
00384         return self.locatorName
00385 
00386     def getPortMethods(self):
00387         '''list of get port accessor methods of generated locator class.
00388         '''
00389         return self.portMethods
00390 
00391     def _setContent(self):
00392         if not self.serviceName:
00393             raise ContainerError, 'no service name defined!'
00394 
00395         self.serviceName = self.mangle(self.serviceName)
00396         self.locatorName = '%sLocator' %self.serviceName
00397         locator = ['# Locator', 'class %s:' %self.locatorName, ]
00398         self.portMethods = []
00399         kwargs = KW.copy()
00400         for port,bind,addr in self.portInfo:
00401             # access method each port
00402             method = 'get%s' %port
00403             kwargs.update(dict(port=port, bind=bind, addr=addr, 
00404                 service=self.serviceName, suffix=self.clientClassSuffix, method=method))
00405 
00406             locator += [
00407                 '%(ID1)s%(port)s_address = "%(addr)s"' %kwargs,
00408                 '%(ID1)sdef get%(port)sAddress(self):' %kwargs,
00409                 '%(ID2)sreturn %(service)sLocator.%(port)s_address' %kwargs,
00410                 '%(ID1)sdef %(method)s(self, url=None, **kw):' %kwargs,
00411                 '%(ID2)sreturn %(bind)s%(suffix)s(url or %(service)sLocator.%(port)s_address, **kw)' %kwargs,
00412                 ]
00413 
00414             self.portMethods.append(method)
00415 
00416         self.writeArray(locator)
00417 
00418 
00419 class ServiceOperationContainer(ServiceContainerBase):
00420     logger = _GetLogger("ServiceOperationContainer")
00421 
00422     def __init__(self, useWSA=False, do_extended=False):
00423         '''Parameters:
00424               useWSA -- boolean, enable ws-addressing
00425               do_extended -- boolean
00426         '''
00427         ServiceContainerBase.__init__(self)
00428         self.useWSA  = useWSA
00429         self.do_extended = do_extended
00430     
00431     def hasInput(self):
00432         return self.inputName is not None
00433 
00434     def hasOutput(self):
00435         return self.outputName is not None
00436 
00437     def isRPC(self):
00438         return IsRPC(self.binding_operation)
00439 
00440     def isLiteral(self, input=True):
00441         msgrole = self.binding_operation.input
00442         if input is False:
00443             msgrole = self.binding_operation.output
00444         return IsLiteral(msgrole)
00445     
00446     def isSimpleType(self, input=True):
00447         if input is False:
00448             return self.outputSimpleType
00449         return self.inputSimpleType
00450 
00451     def getOperation(self):
00452         return self.port.operations.get(self.name)
00453 
00454     def getBOperation(self):
00455         return self.port.get(self.name)
00456 
00457     def getOperationName(self):
00458         return self.name
00459 
00460     def setUp(self, item):
00461         '''
00462         Parameters:
00463             item -- WSDLTools BindingOperation instance.
00464         '''
00465         if not isinstance(item, WSDLTools.OperationBinding):
00466             raise TypeError, 'Expecting WSDLTools Operation instance'
00467 
00468         if not item.input:
00469             raise WSDLFormatError('No <input/> in <binding name="%s"><operation name="%s">' %(
00470                 item.getBinding().name, item.name))
00471         
00472         self.name = None
00473         self.port = None
00474         self.soapaction = None
00475         self.inputName  = None
00476         self.outputName = None
00477         self.inputSimpleType  = None
00478         self.outputSimpleType = None
00479         self.inputAction  = None
00480         self.outputAction = None
00481         self.port = port = item.getBinding().getPortType()
00482         self._wsdl = item.getWSDL()
00483         self.name = name = item.name
00484         self.binding_operation = bop = item
00485         
00486         self.soap_input_headers = None
00487         self.soap_output_headers = None
00488         
00489         op = port.operations.get(name)
00490         if op is None:
00491             raise WSDLFormatError(
00492                 '<portType name="%s"/> no match for <binding name="%s"><operation name="%s">' %(
00493                 port.name, item.getBinding().name, item.name))
00494 
00495         soap_bop = bop.findBinding(WSDLTools.SoapOperationBinding)
00496         if soap_bop is None: 
00497             raise SOAPBindingError, 'expecting SOAP Bindings'
00498 
00499         self.soapaction = soap_bop.soapAction
00500         sbody = bop.input.findBinding(WSDLTools.SoapBodyBinding)
00501         if not sbody:
00502             raise SOAPBindingError('Missing <binding name="%s"><operation name="%s"><input><soap:body>' %(
00503                 port.binding.name, bop.name))
00504 
00505         self.encodingStyle = None
00506         if sbody.use == 'encoded':
00507             assert sbody.encodingStyle == SOAP.ENC,\
00508                 'Supporting encodingStyle=%s, not %s'%(SOAP.ENC, sbody.encodingStyle)
00509             self.encodingStyle = sbody.encodingStyle
00510 
00511         self.inputName  = op.getInputMessage().name
00512         self.inputSimpleType = \
00513             FromMessageGetSimpleElementDeclaration(op.getInputMessage())
00514         self.inputAction = op.getInputAction()
00515         self.soap_input_headers = bop.input.findBindings(WSDLTools.SoapHeaderBinding)
00516 
00517         if bop.output is not None:
00518             sbody = bop.output.findBinding(WSDLTools.SoapBodyBinding)
00519             if not item.output:
00520                 raise WSDLFormatError, "Operation %s, no match for output binding"  %name
00521 
00522             self.outputName = op.getOutputMessage().name
00523             self.outputSimpleType = \
00524                 FromMessageGetSimpleElementDeclaration(op.getOutputMessage())
00525             self.outputAction = op.getOutputAction()
00526             self.soap_output_headers = bop.output.findBindings(WSDLTools.SoapHeaderBinding)    
00527         
00528     def _setContent(self):
00529         '''create string representation of operation.
00530         '''
00531         kwstring = 'kw = {}'
00532         tCheck = 'if isinstance(request, %s) is False:' % self.inputName
00533         bindArgs = ''
00534         if self.encodingStyle is not None:
00535             bindArgs = 'encodingStyle="%s", ' %self.encodingStyle
00536 
00537         if self.useWSA:
00538             wsactionIn = 'wsaction = "%s"' % self.inputAction
00539             wsactionOut = 'wsaction = "%s"' % self.outputAction
00540             bindArgs += 'wsaction=wsaction, endPointReference=self.endPointReference, '
00541             responseArgs = ', wsaction=wsaction'
00542         else:
00543             wsactionIn = '# no input wsaction'
00544             wsactionOut = '# no output wsaction'
00545             responseArgs = ''
00546 
00547         bindArgs += '**kw)'
00548 
00549         if self.do_extended:
00550             inputName = self.getOperation().getInputMessage().name
00551             wrap_str = ""
00552             partsList = self.getOperation().getInputMessage().parts.values()
00553             try:
00554                 subNames = GetPartsSubNames(partsList, self._wsdl)
00555             except TypeError, ex:
00556                 raise Wsdl2PythonError,\
00557                     "Extended generation failure: only supports doc/lit, "\
00558                     +"and all element attributes (<message><part element="\
00559                     +"\"my:GED\"></message>) must refer to single global "\
00560                     +"element declaration with complexType content.  "\
00561                     +"\n\n**** TRY WITHOUT EXTENDED ****\n"
00562                 
00563             args = []
00564             for pa in subNames:
00565                 args += pa
00566 
00567             for arg in args:
00568                 wrap_str += "%srequest.%s = %s\n" % (ID2,
00569                                                      self.getAttributeName(arg),
00570                                                      self.mangle(arg))
00571 
00572             #args = [pa.name for pa in self.getOperation().getInputMessage().parts.values()]
00573             argsStr = ",".join(args)
00574             if len(argsStr) > 1: # add inital comma if args exist
00575                 argsStr = ", " + argsStr
00576 
00577             method = [
00578                 '%s# op: %s' % (ID1, self.getOperation().getInputMessage()),
00579                 '%sdef %s(self%s):' % (ID1, self.name, argsStr),
00580                 '\n%srequest = %s()' % (ID2, self.inputName),
00581                 '%s' % (wrap_str),
00582                 '%s%s' % (ID2, kwstring),
00583                 '%s%s' % (ID2, wsactionIn),
00584                 '%sself.binding.Send(None, None, request, soapaction="%s", %s'\
00585                 %(ID2, self.soapaction, bindArgs),
00586             ]
00587         elif self.soap_input_headers:
00588             method = [
00589                 '%s# op: %s' % (ID1, self.name),
00590                 '%sdef %s(self, request, soapheaders=(), **kw):' % (ID1, self.name),
00591                 '%s%s' % (ID2, tCheck),
00592                 '%sraise TypeError, "%%s incorrect request type" %% (%s)' %(ID3, 'request.__class__'),
00593                 '%s%s' % (ID2, wsactionIn),
00594                 '%s# TODO: Check soapheaders' % (ID2),
00595                 '%sself.binding.Send(None, None, request, soapaction="%s", soapheaders=soapheaders, %s'\
00596                 %(ID2, self.soapaction, bindArgs),
00597             ]
00598         else:
00599             method = [
00600                 '%s# op: %s' % (ID1, self.name),
00601                 '%sdef %s(self, request, **kw):' % (ID1, self.name),
00602                 '%s%s' % (ID2, tCheck),
00603                 '%sraise TypeError, "%%s incorrect request type" %% (%s)' %(ID3, 'request.__class__'),
00604                 '%s%s' % (ID2, wsactionIn),
00605                 '%sself.binding.Send(None, None, request, soapaction="%s", %s'\
00606                 %(ID2, self.soapaction, bindArgs),
00607             ]
00608         #
00609         # BP 1.0: rpc/literal
00610         # WSDL 1.1 Section 3.5 could be interpreted to mean the RPC response 
00611         # wrapper element must be named identical to the name of the 
00612         # wsdl:operation.
00613         # R2729
00614 
00615         #    
00616         # SOAP-1.1 Note: rpc/encoded
00617         # Each parameter accessor has a name corresponding to the name of the 
00618         # parameter and type corresponding to the type of the parameter. The name of 
00619         # the return value accessor is not significant. Likewise, the name of the struct is 
00620         # not significant. However, a convention is to name it after the method name 
00621         # with the string "Response" appended.
00622         #   
00623         if not self.outputName:
00624             method.append('%s#check for soap, assume soap:fault' %(ID2,))
00625             method.append('%sif self.binding.IsSOAP(): self.binding.Receive(None, **kw)' % (ID2,))
00626             self.writeArray(method)
00627             return
00628         
00629         response = ['%s%s' % (ID2, wsactionOut),]
00630         if self.isRPC() and not self.isLiteral():
00631             # rpc/encoded Replace wrapper name with None
00632             response.append(\
00633                 '%stypecode = Struct(pname=None, ofwhat=%s.typecode.ofwhat, pyclass=%s.typecode.pyclass)' %(
00634                      ID2, self.outputName, self.outputName)
00635                 )
00636             response.append(\
00637                 '%sresponse = self.binding.Receive(typecode%s)' %(
00638                      ID2, responseArgs)
00639                 )
00640         else:
00641             response.append(\
00642                 '%sresponse = self.binding.Receive(%s.typecode%s)' %(
00643                      ID2, self.outputName, responseArgs)
00644                 )
00645 
00646         # only support lit
00647         if self.soap_output_headers:
00648             sh = '['
00649             for shb in self.soap_output_headers:
00650                 #shb.encodingStyle, shb.use, shb.namespace
00651                 shb.message
00652                 shb.part
00653                 try:
00654                     msg = self._wsdl.messages[shb.message]
00655                     part = msg.parts[shb.part]
00656                     if part.element is not None:
00657                         sh += 'GED%s,' %str(part.element)
00658                     else:
00659                         warnings.warn('skipping soap output header in Message "%s"' %str(msg))
00660                 except:
00661                     raise WSDLFormatError(
00662                       'failure processing output header typecodes, ' +
00663                       'could not find message "%s" or its part "%s"' %(
00664                                shb.message, shb.part)
00665                     )
00666                                  
00667             sh += ']'
00668             if len(sh) > 2:
00669                 response.append(\
00670                 '%sself.soapheaders = self.binding.ps.ParseHeaderElements(%s)' %(ID2, sh)
00671                 )
00672 
00673         if self.outputSimpleType:
00674             response.append('%sreturn %s(response)' %(ID2, self.outputName))
00675         else: 
00676             if self.do_extended:
00677                 partsList = self.getOperation().getOutputMessage().parts.values()
00678                 subNames = GetPartsSubNames(partsList, self._wsdl)
00679                 args = []
00680                 for pa in subNames:
00681                     args += pa
00682 
00683                 for arg in args:
00684                     response.append('%s%s = response.%s' % (ID2, self.mangle(arg), self.getAttributeName(arg)) )
00685                 margs = ",".join(args)
00686                 response.append("%sreturn %s" % (ID2, margs) )
00687             else:
00688                 response.append('%sreturn response' %ID2)
00689         method += response
00690 
00691         self.writeArray(method)
00692 
00693 
00694 class BindingDescription(ServiceContainerBase):
00695     '''writes out SOAP Binding class
00696 
00697     class variables:
00698         readerclass --  
00699         writerclass --
00700         operationclass -- representation of each operation.
00701     '''
00702     readerclass = None
00703     writerclass = None
00704     operationclass = ServiceOperationContainer
00705     logger = _GetLogger("BindingDescription")
00706     
00707     def __init__(self, useWSA=False, do_extended=False, wsdl=None):
00708         '''Parameters:
00709         name -- binding name
00710         property -- resource properties
00711         useWSA   -- boolean, enable ws-addressing
00712         name -- binding name
00713         '''
00714         ServiceContainerBase.__init__(self)
00715         self.useWSA = useWSA
00716         self.rProp = None
00717         #self.bName = None
00718         self.operations = None
00719         self.do_extended = do_extended
00720         self._wsdl = wsdl # None unless do_extended == True
00721 
00722     def setReaderClass(cls, className):
00723         '''specify a reader class name, this must be imported
00724         in service module.
00725         '''
00726         cls.readerclass = className
00727     setReaderClass = classmethod(setReaderClass)
00728 
00729     def setWriterClass(cls, className):
00730         '''specify a writer class name, this must be imported
00731         in service module.
00732         '''
00733         cls.writerclass = className 
00734     setWriterClass = classmethod(setWriterClass)
00735     
00736     def setOperationClass(cls, className):
00737         '''specify an operation container class name.
00738         '''
00739         cls.operationclass = className
00740     setOperationClass = classmethod(setOperationClass)
00741 
00742     def setUp(self, item):
00743         '''This method finds all SOAP Binding Operations, it will skip 
00744         all bindings that are not SOAP.  
00745         item -- WSDL.Binding instance
00746         '''
00747         assert isinstance(item, WSDLTools.Binding), \
00748               'expecting WSDLTools Binding instance'
00749 
00750         portType = item.getPortType()
00751         self._kwargs = KW.copy()
00752         self._kwargs['bind'] = NC_to_CN(item.name)
00753         self.operations = []
00754         self.rProp = portType.getResourceProperties() 
00755         soap_binding = item.findBinding(WSDLTools.SoapBinding)
00756         if soap_binding is None:
00757             raise Wsdl2PythonError,\
00758                 'Binding(%s) missing WSDLTools.SoapBinding' %item.name
00759 
00760         for bop in item.operations:
00761             soap_bop = bop.findBinding(WSDLTools.SoapOperationBinding)
00762             if soap_bop is None:
00763                 self.logger.warning(\
00764                     'Skip Binding(%s) operation(%s) no SOAP Binding Operation'\
00765                     %(item.name, bop.name),
00766                 )
00767                 continue
00768 
00769             #soapAction = soap_bop.soapAction
00770             if bop.input is not None:
00771                 soapBodyBind = bop.input.findBinding(WSDLTools.SoapBodyBinding)
00772                 if soapBodyBind is None:
00773                     self.logger.warning(\
00774                         'Skip Binding(%s) operation(%s) Bindings(%s) not supported'\
00775                         %(item.name, bop.name, bop.extensions)
00776                     )
00777                     continue
00778                 
00779             op = portType.operations.get(bop.name)
00780             if op is None:
00781                 raise Wsdl2PythonError,\
00782                     'no matching portType/Binding operation(%s)' % bop.name
00783                     
00784             c = self.operationclass(useWSA=self.useWSA, 
00785                     do_extended=self.do_extended)
00786             c.setUp(bop)
00787             self.operations.append(c)
00788 
00789     def _setContent(self):
00790         if self.useWSA is True:
00791             args = 'endPointReference=None, **kw'
00792             epr = 'self.endPointReference = endPointReference'
00793         else:
00794             args = '**kw'
00795             epr      = '# no ws-addressing'
00796 
00797         if self.rProp:
00798             rp = 'kw.setdefault("ResourceProperties", ("%s","%s"))'\
00799                 %(self.rProp[0], self.rProp[1])
00800         else:
00801             rp = '# no resource properties'
00802 
00803         kwargs = self._kwargs
00804         kwargs.update(dict(suffix=self.clientClassSuffix, 
00805             args=args, epr=epr, rp=rp, readerclass=self.readerclass, 
00806             writerclass=self.writerclass,))
00807 
00808         methods = [
00809             '# Methods',
00810             'class %(bind)s%(suffix)s:' %kwargs,
00811             '%(ID1)sdef __init__(self, url, %(args)s):' %kwargs,
00812             '%(ID2)skw.setdefault("readerclass", %(readerclass)s)' %kwargs,
00813             '%(ID2)skw.setdefault("writerclass", %(writerclass)s)' %kwargs,
00814             '%(ID2)s%(rp)s' % kwargs,
00815             '%(ID2)sself.binding = client.Binding(url=url, **kw)' %kwargs,
00816             '%(ID2)s%(epr)s' % kwargs,
00817             ]
00818 
00819         for op in self.operations:
00820             methods += [ op.getvalue() ]
00821 
00822         self.writeArray(methods)
00823 
00824 ServiceOperationsClassContainer = BindingDescription
00825 
00826 
00827 class MessageContainerInterface:
00828     logger = _GetLogger("MessageContainerInterface")
00829     
00830     def setUp(self, port, soc, input):
00831         '''sets the attribute _simple which represents a 
00832         primitive type message represents, or None if not primitive.
00833  
00834         soc -- WSDLTools.ServiceOperationContainer instance
00835         port -- WSDLTools.Port instance
00836         input-- boolean, input messasge or output message of operation.
00837         '''
00838         raise NotImplementedError, 'Message container must implemented setUp.'
00839 
00840 
00841 class ServiceDocumentLiteralMessageContainer(ServiceContainerBase, 
00842                                              MessageContainerInterface):
00843     logger = _GetLogger("ServiceDocumentLiteralMessageContainer")
00844 
00845     def __init__(self, do_extended=False):
00846 
00847         ServiceContainerBase.__init__(self)
00848         self.do_extended=do_extended
00849 
00850     def setUp(self, port, soc, input):
00851         content = self.content
00852         # TODO: check soapbody for part name
00853         simple = self._simple = soc.isSimpleType(soc.getOperationName())
00854         name = soc.getOperationName()
00855 
00856         # Document/literal
00857         operation = port.getBinding().getPortType().operations.get(name)
00858         bop = port.getBinding().operations.get(name)
00859         soapBodyBind = None
00860         if input is True:
00861             soapBodyBind = bop.input.findBinding(WSDLTools.SoapBodyBinding)
00862             message = operation.getInputMessage()
00863         else:
00864             soapBodyBind = bop.output.findBinding(WSDLTools.SoapBodyBinding)
00865             message = operation.getOutputMessage()
00866             
00867         # using underlying data structure to avoid phantom problem.
00868         # with message.parts.data.values() 
00869         if len(message.parts) == 0:
00870             raise Wsdl2PythonError, 'must specify part for doc/lit msg'        
00871         
00872         p = None
00873         if soapBodyBind.parts is not None:
00874             if len(soapBodyBind.parts) > 1:
00875                 raise Wsdl2PythonError,\
00876                     'not supporting multiple parts in soap body'
00877             if len(soapBodyBind.parts) == 0:
00878                 return
00879             
00880             p = message.parts.get(soapBodyBind.parts[0])
00881         
00882         # XXX: Allow for some slop
00883         p = p or message.parts[0]
00884     
00885         if p.type:
00886             raise  Wsdl2PythonError, 'no doc/lit suport for <part type>'
00887         
00888         if not p.element:
00889             return
00890         
00891         self.ns = p.element[0]
00892         content.ns = p.element[0]
00893         content.pName = p.element[1]
00894         content.mName = message.name
00895         
00896     def _setContent(self):
00897         '''create string representation of doc/lit message container.  If 
00898         message element is simple(primitive), use python type as base class.
00899         '''
00900         try:
00901             simple = self._simple
00902         except AttributeError:
00903             raise RuntimeError, 'call setUp first'
00904         
00905         # TODO: Hidden contract.  Must set self.ns before getNSAlias...
00906         #  File "/usr/local/python/lib/python2.4/site-packages/ZSI/generate/containers.py", line 625, in _setContent
00907         #    kw['message'],kw['prefix'],kw['typecode'] = \
00908         #  File "/usr/local/python/lib/python2.4/site-packages/ZSI/generate/containers.py", line 128, in getNSAlias
00909         #    raise ContainerError, 'no self.ns attr defined in %s' % self.__class__
00910         # ZSI.generate.containers.ContainerError: no self.ns attr defined in ZSI.generate.containers.ServiceDocumentLiteralMessageContainer
00911         #            
00912 #        self.ns = self.content.ns
00913         
00914         
00915         kw = KW.copy()
00916         kw.update(dict(message=self.content.mName, nsuri=self.content.ns,
00917                        name=self.content.pName))
00918         
00919 #        kw['message'],kw['prefix'],kw['typecode'] = \
00920 #            self.content.mName, self.getNSAlias(), element_class_name(self.content.pName)
00921 #        
00922         # These messsages are just global element declarations
00923 #        self.writeArray(['%(message)s = %(prefix)s.%(typecode)s().pyclass' %kw])
00924         self.writeArray(['%(message)s = GED("%(nsuri)s", "%(name)s").pyclass' %kw])
00925 
00926 class ServiceRPCEncodedMessageContainer(ServiceContainerBase, MessageContainerInterface):
00927     logger = _GetLogger("ServiceRPCEncodedMessageContainer")
00928 
00929     def setUp(self, port, soc, input):
00930         '''
00931         Instance Data: 
00932            op    -- WSDLTools Operation instance
00933            bop   -- WSDLTools BindingOperation instance
00934            input -- boolean input/output
00935         '''
00936         name = soc.getOperationName()
00937         bop = port.getBinding().operations.get(name)
00938         op = port.getBinding().getPortType().operations.get(name)
00939 
00940         assert op is not None, 'port has no operation %s' %name
00941         assert bop is not None, 'port has no binding operation %s' %name
00942 
00943         self.input = input
00944         self.op = op
00945         self.bop = bop
00946 
00947     def _setContent(self):
00948         try: 
00949             self.op
00950         except AttributeError:
00951             raise RuntimeError, 'call setUp first'
00952 
00953         pname = self.op.name
00954         msgRole = self.op.input
00955         msgRoleB = self.bop.input
00956         if self.input is False:
00957             pname = '%sResponse' %self.op.name
00958             msgRole = self.op.output
00959             msgRoleB = self.bop.output
00960 
00961         sbody = msgRoleB.findBinding(WSDLTools.SoapBodyBinding)
00962         if not sbody or not sbody.namespace:
00963             raise WSInteropError, WSISpec.R2717
00964 
00965         assert sbody.use == 'encoded', 'Expecting use=="encoded"'
00966         encodingStyle = sbody.encodingStyle
00967 
00968         assert encodingStyle == SOAP.ENC,\
00969             'Supporting encodingStyle=%s, not %s' %(SOAP.ENC, encodingStyle)
00970 
00971         namespace = sbody.namespace
00972         tcb = MessageTypecodeContainer(\
00973                   tuple(msgRole.getMessage().parts.list),
00974               )
00975         ofwhat = '[%s]' %tcb.getTypecodeList()
00976         pyclass = msgRole.getMessage().name
00977 
00978         fdict = KW.copy()
00979         fdict['nspname'] = sbody.namespace
00980         fdict['pname'] = pname
00981         fdict['pyclass'] = None
00982         fdict['ofwhat'] = ofwhat
00983         fdict['encoded'] = namespace
00984  
00985         #if self.input is False:
00986         #    fdict['typecode'] = \
00987         #        'Struct(pname=None, ofwhat=%(ofwhat)s, pyclass=%(pyclass)s, encoded="%(encoded)s")'
00988         #else:
00989         fdict['typecode'] = \
00990             'Struct(pname=("%(nspname)s","%(pname)s"), ofwhat=%(ofwhat)s, pyclass=%(pyclass)s, encoded="%(encoded)s")'
00991 
00992         message = ['class %(pyclass)s:',
00993                     '%(ID1)sdef __init__(self, **kw):',
00994                     '%(ID2)s"""Keyword parameters:',
00995                     ]
00996                     
00997         idx = len(message)
00998         for a,p in zip(tcb.getAttributeNames(), tcb.getParameterNames()):
00999             message.insert(idx, '%(ID2)s' + p + ' -- part ' + p)
01000             message.append('%(ID2)sself.' + a + ' =  kw.get("%s")' %p)
01001             idx += 1
01002             
01003         message.insert(idx, '%(ID2)s"""')
01004                     
01005         # TODO: This isn't a TypecodeContainerBase instance but it
01006         #    certaintly generates a pyclass and typecode.
01007         #if self.metaclass is None:
01008         if TypecodeContainerBase.metaclass is None:
01009             fdict['pyclass'] = pyclass
01010             fdict['typecode'] = fdict['typecode'] %fdict
01011             message.append('%(pyclass)s.typecode = %(typecode)s')
01012         else:
01013             # Need typecode to be available when class is constructed.
01014             fdict['typecode'] = fdict['typecode'] %fdict
01015             fdict['pyclass'] = pyclass
01016             fdict['metaclass'] = TypecodeContainerBase.metaclass
01017             message.insert(0, '_%(pyclass)sTypecode = %(typecode)s')
01018             message.insert(2, '%(ID1)stypecode = _%(pyclass)sTypecode')
01019             message.insert(3, '%(ID1)s__metaclass__ = %(metaclass)s')
01020             message.append('%(pyclass)s.typecode.pyclass = %(pyclass)s')
01021  
01022         self.writeArray(map(lambda l: l %fdict, message))
01023 
01024 
01025 class ServiceRPCLiteralMessageContainer(ServiceContainerBase, MessageContainerInterface):
01026     logger = _GetLogger("ServiceRPCLiteralMessageContainer")
01027 
01028     def setUp(self, port, soc, input):
01029         '''
01030         Instance Data: 
01031            op    -- WSDLTools Operation instance
01032            bop   -- WSDLTools BindingOperation instance
01033            input -- boolean input/output
01034         '''
01035         name = soc.getOperationName()
01036         bop = port.getBinding().operations.get(name)
01037         op = port.getBinding().getPortType().operations.get(name)
01038 
01039         assert op is not None, 'port has no operation %s' %name
01040         assert bop is not None, 'port has no binding operation %s' %name
01041 
01042         self.op = op
01043         self.bop = bop
01044         self.input = input
01045 
01046     def _setContent(self):
01047         try:
01048             self.op
01049         except AttributeError:
01050             raise RuntimeError, 'call setUp first' 
01051 
01052         operation = self.op
01053         input = self.input
01054         pname = operation.name
01055         msgRole = operation.input
01056         msgRoleB = self.bop.input
01057         if input is False:
01058             pname = '%sResponse' %operation.name
01059             msgRole = operation.output
01060             msgRoleB = self.bop.output
01061 
01062         sbody = msgRoleB.findBinding(WSDLTools.SoapBodyBinding)
01063         if not sbody or not sbody.namespace:            
01064             raise WSInteropError, WSISpec.R2717
01065         
01066         namespace = sbody.namespace
01067         tcb = MessageTypecodeContainer(\
01068                   tuple(msgRole.getMessage().parts.list),
01069               )
01070         ofwhat = '[%s]' %tcb.getTypecodeList()
01071         pyclass = msgRole.getMessage().name
01072 
01073         fdict = KW.copy()
01074         fdict['nspname'] = sbody.namespace
01075         fdict['pname'] = pname
01076         fdict['pyclass'] = None
01077         fdict['ofwhat'] = ofwhat
01078         fdict['encoded'] = namespace
01079         fdict['typecode'] = \
01080             'Struct(pname=("%(nspname)s","%(pname)s"), ofwhat=%(ofwhat)s, pyclass=%(pyclass)s, encoded="%(encoded)s")'
01081 
01082         message = ['class %(pyclass)s:',
01083                     '%(ID1)sdef __init__(self, **kw):',
01084                     '%(ID2)s"""Keyword parameters:',
01085                     ]
01086         
01087         idx = len(message)
01088         for a,p in zip(tcb.getAttributeNames(), tcb.getParameterNames()):
01089             message.insert(idx, '%(ID2)s' + p + ' -- part ' + p)
01090             message.append('%(ID2)sself.' + a + ' =  kw.get("%s")' %p)
01091             idx += 1
01092         
01093         message.insert(idx, '%(ID2)s"""')
01094                     
01095         # TODO: This isn't a TypecodeContainerBase instance but it
01096         #    certaintly generates a pyclass and typecode.
01097         #if self.metaclass is None:
01098         if TypecodeContainerBase.metaclass is None:
01099             fdict['pyclass'] = pyclass
01100             fdict['typecode'] = fdict['typecode'] %fdict
01101             message.append('%(pyclass)s.typecode = %(typecode)s')
01102         else:
01103             # Need typecode to be available when class is constructed.
01104             fdict['typecode'] = fdict['typecode'] %fdict
01105             fdict['pyclass'] = pyclass
01106             fdict['metaclass'] = TypecodeContainerBase.metaclass
01107             message.insert(0, '_%(pyclass)sTypecode = %(typecode)s')
01108             message.insert(2, '%(ID1)stypecode = _%(pyclass)sTypecode')
01109             message.insert(3, '%(ID1)s__metaclass__ = %(metaclass)s')
01110             message.append('%(pyclass)s.typecode.pyclass = %(pyclass)s')
01111  
01112         self.writeArray(map(lambda l: l %fdict, message))
01113         
01114 
01115 TypesContainerBase = ContainerBase
01116 
01117 
01118 class TypesHeaderContainer(TypesContainerBase):
01119     '''imports for all generated types modules.
01120     '''
01121     imports = [
01122         'import ZSI',
01123         'import ZSI.TCcompound',
01124         'from ZSI.schema import LocalElementDeclaration, ElementDeclaration, TypeDefinition, GTD, GED',
01125     ]
01126     logger = _GetLogger("TypesHeaderContainer")
01127 
01128     def _setContent(self):
01129         self.writeArray(TypesHeaderContainer.imports)
01130 
01131 
01132 NamespaceClassContainerBase = TypesContainerBase
01133  
01134 
01135 class NamespaceClassHeaderContainer(NamespaceClassContainerBase):
01136     logger = _GetLogger("NamespaceClassHeaderContainer")
01137 
01138     def _setContent(self):
01139 
01140         head = [
01141             '#' * 30,
01142             '# targetNamespace',
01143             '# %s' % self.ns,
01144             '#' * 30 + '\n',
01145             'class %s:' % self.getNSAlias(),
01146             '%stargetNamespace = "%s"' % (ID1, self.ns)
01147             ]
01148 
01149         self.writeArray(head)
01150 
01151 class NamespaceClassFooterContainer(NamespaceClassContainerBase):
01152     logger = _GetLogger("NamespaceClassFooterContainer")
01153 
01154     def _setContent(self):
01155 
01156         foot = [
01157             '# end class %s (tns: %s)' % (self.getNSAlias(), self.ns),
01158             ]
01159 
01160         self.writeArray(foot)
01161 
01162 
01163 BTI = BaseTypeInterpreter()
01164 class TypecodeContainerBase(TypesContainerBase):
01165     '''Base class for all classes representing anything
01166     with element content.
01167 
01168     class variables:
01169         mixed_content_aname -- text content will be placed in this attribute.
01170         attributes_aname -- attributes will be placed in this attribute.
01171         metaclass -- set this attribute to specify a pyclass __metaclass__
01172     '''
01173     mixed_content_aname = 'text'
01174     attributes_aname = 'attrs'
01175     metaclass = None
01176     lazy = False
01177     logger = _GetLogger("TypecodeContainerBase")
01178 
01179     def __init__(self, do_extended=False, extPyClasses=None):
01180         TypesContainerBase.__init__(self)    
01181         self.name = None
01182 
01183         # attrs for model groups and others with elements, tclists, etc...
01184         self.allOptional = False
01185         self.mgContent = None
01186         self.contentFlattened = False
01187         self.elementAttrs = []
01188         self.tcListElements = []
01189         self.tcListSet = False
01190 
01191         self.localTypes = []
01192 
01193         # used when processing nested anonymous types
01194         self.parentClass = None
01195 
01196         # used when processing attribute content
01197         self.mixed = False
01198         self.extraFlags = ''
01199         self.attrComponents = None
01200 
01201         # --> EXTENDED
01202         # Used if an external pyclass was specified for this type.
01203         self.do_extended = do_extended
01204         if extPyClasses is None:
01205             self.extPyClasses = {}
01206         else:
01207             self.extPyClasses = extPyClasses
01208         # <--
01209 
01210     def getvalue(self):
01211         out = ContainerBase.getvalue(self)
01212         for item in self.localTypes:
01213             content = None
01214             assert True is item.isElement() is item.isLocal(), 'expecting local elements only'
01215 
01216             etp = item.content
01217             qName = item.getAttribute('type')
01218             if not qName:
01219                 etp = item.content
01220                 local = True
01221             else:
01222                 etp = item.getTypeDefinition('type')
01223 
01224             if etp is None:
01225                 if local is True:
01226                     content = ElementLocalComplexTypeContainer(do_extended=self.do_extended)
01227                 else:
01228                     content = ElementSimpleTypeContainer()
01229             elif etp.isLocal() is False:
01230                 content = ElementGlobalDefContainer()
01231             elif etp.isSimple() is True:
01232                 content = ElementLocalSimpleTypeContainer()
01233             elif etp.isComplex():
01234                 content = ElementLocalComplexTypeContainer(do_extended=self.do_extended)
01235             else:
01236                 raise Wsdl2PythonError, "Unknown element declaration: %s" %item.getItemTrace()
01237 
01238             content.setUp(item)
01239 
01240             out += '\n\n'
01241             if self.parentClass:
01242                 content.parentClass = \
01243                     '%s.%s' %(self.parentClass, self.getClassName())
01244             else:
01245                 content.parentClass = '%s.%s' %(self.getNSAlias(), self.getClassName())
01246 
01247             for l in content.getvalue().split('\n'):
01248                 if l: out += '%s%s\n' % (ID1, l)
01249                 else: out += '\n'
01250 
01251             out += '\n\n'
01252 
01253         return out
01254 
01255     def getAttributeName(self, name):
01256         '''represents the aname
01257         '''
01258         if self.func_aname is None:
01259             return name
01260         assert callable(self.func_aname), \
01261             'expecting callable method for attribute func_aname, not %s' %type(self.func_aname)
01262         f = self.func_aname
01263         return f(name)
01264 
01265     def getMixedTextAName(self):
01266         '''returns an aname representing mixed text content.
01267         '''
01268         return self.getAttributeName(self.mixed_content_aname)
01269 
01270     def getClassName(self):
01271 
01272         if not self.name:
01273             raise ContainerError, 'self.name not defined!'
01274         if not hasattr(self.__class__, 'type'):
01275             raise ContainerError, 'container type not defined!'
01276 
01277         #suffix = self.__class__.type
01278         if self.__class__.type == DEF:
01279             classname = type_class_name(self.name)
01280         elif self.__class__.type == DEC:
01281             classname = element_class_name(self.name)
01282 
01283         return self.mangle( classname )
01284 
01285     # --> EXTENDED
01286     def hasExtPyClass(self):
01287         if self.name in self.extPyClasses:
01288             return True
01289         else:
01290             return False
01291     # <--
01292 
01293     def getPyClass(self):
01294         '''Name of generated inner class that will be specified as pyclass.
01295         '''
01296         # --> EXTENDED
01297         if self.hasExtPyClass():
01298             classInfo = self.extPyClasses[self.name]
01299             return ".".join(classInfo)
01300         # <-- 
01301         
01302         return 'Holder'
01303     
01304     def getPyClassDefinition(self):
01305         '''Return a list containing pyclass definition.
01306         '''
01307         kw = KW.copy()
01308         
01309         # --> EXTENDED
01310         if self.hasExtPyClass():
01311             classInfo = self.extPyClasses[self.name]
01312             kw['classInfo'] = classInfo[0]
01313             return ["%(ID3)simport %(classInfo)s" %kw ]
01314         # <--
01315         
01316         kw['pyclass'] = self.getPyClass()
01317         definition = []
01318         definition.append('%(ID3)sclass %(pyclass)s:' %kw)
01319         if self.metaclass is not None:
01320             kw['type'] = self.metaclass
01321             definition.append('%(ID4)s__metaclass__ = %(type)s' %kw)
01322         definition.append('%(ID4)stypecode = self' %kw)
01323         
01324         #TODO: Remove pyclass holder __init__ -->
01325         definition.append('%(ID4)sdef __init__(self):' %kw)
01326         definition.append('%(ID5)s# pyclass' %kw)
01327 
01328         # JRB HACK need to call _setElements via getElements
01329         self._setUpElements()
01330         
01331         # JRB HACK need to indent additional one level
01332         for el in self.elementAttrs:
01333             kw['element'] = el
01334             definition.append('%(ID2)s%(element)s' %kw)
01335         definition.append('%(ID5)sreturn' %kw)
01336         # <--
01337         
01338         # pyclass descriptive name
01339         if self.name is not None:
01340             kw['name'] = self.name
01341             definition.append(\
01342                 '%(ID3)s%(pyclass)s.__name__ = "%(name)s_Holder"' %kw
01343                 )
01344 
01345         return definition
01346 
01347     def nsuriLogic(self):
01348         '''set a variable "ns" that represents the targetNamespace in
01349         which this item is defined.  Used for namespacing local elements.
01350         '''
01351         if self.parentClass:
01352             return 'ns = %s.%s.schema' %(self.parentClass, self.getClassName())
01353         return 'ns = %s.%s.schema' %(self.getNSAlias(), self.getClassName())
01354 
01355     def schemaTag(self):
01356         if self.ns is not None:
01357             return 'schema = "%s"' % self.ns
01358         raise ContainerError, 'failed to set schema targetNamespace(%s)' %(self.__class__)
01359     
01360     def typeTag(self):
01361         if self.name is not None:
01362             return 'type = (schema, "%s")' % self.name
01363         raise ContainerError, 'failed to set type name(%s)' %(self.__class__)
01364     
01365     def literalTag(self):
01366         if self.name is not None:
01367             return 'literal = "%s"' % self.name
01368         raise ContainerError, 'failed to set element name(%s)' %(self.__class__)
01369 
01370     def getExtraFlags(self):
01371         if self.mixed:
01372             self.extraFlags += 'mixed=True, mixed_aname="%s", ' %self.getMixedTextAName()
01373 
01374         return self.extraFlags
01375 
01376     def simpleConstructor(self, superclass=None):
01377 
01378         if superclass:
01379             return '%s.__init__(self, **kw)' % superclass
01380         else:
01381             return 'def __init__(self, **kw):'
01382 
01383     def pnameConstructor(self, superclass=None):
01384 
01385         if superclass:
01386             return '%s.__init__(self, pname, **kw)' % superclass
01387         else:
01388             return 'def __init__(self, pname, **kw):'
01389 
01390 
01391     def _setUpElements(self):
01392         """TODO: Remove this method
01393         
01394         This method ONLY sets up the instance attributes.
01395         Dependency instance attribute:
01396             mgContent -- expected to be either a complex definition
01397                 with model group content, a model group, or model group 
01398                 content.  TODO: should only support the first two.
01399         """
01400         self.logger.debug("_setUpElements: %s" %self._item.getItemTrace())
01401         if hasattr(self, '_done'):
01402             #return '\n'.join(self.elementAttrs)
01403             return
01404         
01405         self._done = True
01406         flat = []
01407         content = self.mgContent
01408         if type(self.mgContent) is not tuple:
01409             mg = self.mgContent
01410             if not mg.isModelGroup(): 
01411                 mg = mg.content
01412                 
01413             content = mg.content
01414             if mg.isAll():
01415                 flat = content
01416                 content = [] 
01417             elif mg.isModelGroup() and mg.isDefinition():
01418                 mg = mg.content
01419                 content = mg.content            
01420     
01421         idx = 0
01422         content = list(content)
01423         while idx < len(content):
01424             c = orig = content[idx]
01425             if c.isElement():
01426                 flat.append(c)
01427                 idx += 1
01428                 continue
01429             
01430             if c.isReference() and c.isModelGroup():
01431                 c = c.getModelGroupReference()
01432                 
01433             if c.isDefinition() and c.isModelGroup():
01434                 c = c.content
01435 
01436             if c.isSequence() or c.isChoice():
01437                 begIdx = idx
01438                 endIdx = begIdx + len(c.content)
01439                 for i in range(begIdx, endIdx):
01440                     content.insert(i, c.content[i-begIdx])
01441                     
01442                 content.remove(orig)
01443                 continue
01444             
01445             raise ContainerError, 'unexpected schema item: %s' %c.getItemTrace()
01446                 
01447         for c in flat:
01448             if c.isDeclaration() and c.isElement():
01449                 defaultValue = "None"
01450                 parent = c
01451                 defs = []
01452                 # stop recursion via global ModelGroupDefinition 
01453                 while defs.count(parent) <= 1:
01454                     maxOccurs = parent.getAttribute('maxOccurs')
01455                     if maxOccurs == 'unbounded' or int(maxOccurs) > 1:
01456                         defaultValue = "[]"
01457                         break
01458                         
01459                     parent = parent._parent()
01460                     if not parent.isModelGroup():
01461                         break
01462                     
01463                     if parent.isReference():
01464                         parent = parent.getModelGroupReference()
01465                         
01466                     if parent.isDefinition():
01467                         parent = parent.content
01468                         defs.append(parent)                
01469                 
01470                 if None ==  c.getAttribute('name') and c.isWildCard():
01471                     e = '%sself.%s = %s' %(ID3, 
01472                             self.getAttributeName('any'), defaultValue)
01473                 else:
01474                     e = '%sself.%s = %s' %(ID3, 
01475                             self.getAttributeName(c.getAttribute('name')), defaultValue)
01476                 self.elementAttrs.append(e)
01477                 continue
01478                         
01479             # TODO: This seems wrong 
01480             if c.isReference():
01481                 e = '%sself._%s = None' %(ID3,
01482                         self.mangle(c.getAttribute('ref')[1]))
01483                 self.elementAttrs.append(e)
01484                 continue
01485             
01486             raise ContainerError, 'unexpected item: %s' % c.getItemTrace()
01487 
01488         #return '\n'.join(self.elementAttrs)
01489         return
01490 
01491     def _setTypecodeList(self):
01492         """generates ofwhat content, minOccurs/maxOccurs facet generation.
01493         Dependency instance attribute:
01494             mgContent -- expected to be either a complex definition
01495                 with model group content, a model group, or model group 
01496                 content.  TODO: should only support the first two.
01497             localTypes -- produce local class definitions later
01498             tcListElements -- elements, local/global 
01499         """
01500         self.logger.debug("_setTypecodeList(%r): %s" %
01501                           (self.mgContent, self._item.getItemTrace()))
01502         
01503         flat = []
01504         content = self.mgContent
01505         
01506         #TODO: too much slop permitted here, impossible
01507         # to tell what is going on.
01508         
01509         if type(content) is not tuple:
01510             mg = content
01511             if not mg.isModelGroup():
01512                 raise Wsdl2PythonErr("Expecting ModelGroup: %s" %
01513                                      mg.getItemTrace())
01514                 
01515             self.logger.debug("ModelGroup(%r) contents(%r): %s" %
01516                   (mg, mg.content, mg.getItemTrace()))
01517             
01518             #<group ref>
01519             if mg.isReference():
01520                 raise RuntimeError("Unexpected modelGroup reference: %s" %
01521                                    mg.getItemTrace())
01522             
01523             #<group name>
01524             if mg.isDefinition():
01525                 mg = mg.content
01526                 
01527             if mg.isAll():
01528                 flat = mg.content
01529                 content = [] 
01530             elif mg.isSequence():
01531                 content = mg.content
01532             elif mg.isChoice():
01533                 content = mg.content
01534             else:
01535                 raise RuntimeError("Unknown schema item")
01536                 
01537         idx = 0
01538         content = list(content)
01539         self.logger.debug("content: %r" %content)
01540         while idx < len(content):
01541             c = orig = content[idx]
01542             if c.isElement():
01543                 flat.append(c)
01544                 idx += 1
01545                 continue
01546             
01547             if c.isReference() and c.isModelGroup():
01548                 c = c.getModelGroupReference()
01549                 
01550             if c.isDefinition() and c.isModelGroup():
01551                 c = c.content
01552                 
01553             if c.isSequence() or c.isChoice():
01554                 begIdx = idx
01555                 endIdx = begIdx + len(c.content)
01556                 for i in range(begIdx, endIdx):
01557                     content.insert(i, c.content[i-begIdx])
01558                     
01559                 content.remove(orig)
01560                 continue
01561             
01562             raise ContainerError, 'unexpected schema item: %s' %c.getItemTrace()
01563 
01564         # TODO: Need to store "parents" in a dict[id] = list(),
01565         #    because cannot follow references, but not currently
01566         #    a big concern. 
01567         
01568         self.logger.debug("flat: %r" %list(flat))
01569         for c in flat:
01570             tc = TcListComponentContainer()
01571             # TODO: Remove _getOccurs
01572             min,max,nil = self._getOccurs(c)
01573             min = max = None
01574             maxOccurs = 1
01575             
01576             parent = c
01577             defs = []
01578             # stop recursion via global ModelGroupDefinition 
01579             while defs.count(parent) <= 1:
01580                 max = parent.getAttribute('maxOccurs')
01581                 if max == 'unbounded':
01582                     maxOccurs = '"%s"' %max 
01583                     break
01584                 
01585                 maxOccurs = int(max) * maxOccurs
01586                 parent = parent._parent()
01587                 if not parent.isModelGroup():
01588                     break
01589                 
01590                 if parent.isReference():
01591                     parent = parent.getModelGroupReference()
01592                     
01593                 if parent.isDefinition():
01594                     parent = parent.content
01595                     defs.append(parent)
01596                 
01597             del defs
01598             parent = c
01599             while 1:
01600                 minOccurs = int(parent.getAttribute('minOccurs'))
01601                 if minOccurs == 0 or parent.isChoice():
01602                     minOccurs = 0
01603                     break
01604                 
01605                 parent = parent._parent()
01606                 if not parent.isModelGroup():
01607                     minOccurs = int(c.getAttribute('minOccurs'))
01608                     break
01609                 
01610                 if parent.isReference():
01611                     parent = parent.getModelGroupReference()
01612                     
01613                 if parent.isDefinition():
01614                     parent = parent.content       
01615             
01616             tc.setOccurs(minOccurs, maxOccurs, nil)
01617             processContents = self._getProcessContents(c)
01618             tc.setProcessContents(processContents)
01619             if c.isDeclaration() and c.isElement():
01620                 global_type = c.getAttribute('type')
01621                 content = getattr(c, 'content', None)
01622                 if c.isLocal() and c.isQualified() is False:
01623                     tc.unQualified()
01624 
01625                 if c.isWildCard():
01626                     tc.setStyleAnyElement()
01627                 elif global_type is not None:
01628                     tc.name = c.getAttribute('name')
01629                     ns = global_type[0]
01630                     if ns in SCHEMA.XSD_LIST:
01631                         tpc = BTI.get_typeclass(global_type[1],global_type[0])
01632                         tc.klass = tpc
01633 #                    elif (self.ns,self.name) == global_type:
01634 #                        # elif self._isRecursiveElement(c)
01635 #                        # TODO: Remove this, it only works for 1 level.
01636 #                        tc.setStyleRecursion()
01637                     else:
01638                         tc.setGlobalType(*global_type)
01639 #                        tc.klass = '%s.%s' % (NAD.getAlias(ns),
01640 #                            type_class_name(global_type[1]))
01641                     del ns
01642                 elif content is not None and content.isLocal() and content.isComplex():
01643                     tc.name = c.getAttribute('name')
01644                     tc.klass = 'self.__class__.%s' % (element_class_name(tc.name))
01645                     #TODO: Not an element reference, confusing nomenclature
01646                     tc.setStyleElementReference()
01647                     self.localTypes.append(c)
01648                 elif content is not None and content.isLocal() and content.isSimple():
01649                     # Local Simple Type
01650                     tc.name = c.getAttribute('name')
01651                     tc.klass = 'self.__class__.%s' % (element_class_name(tc.name))
01652                     #TODO: Not an element reference, confusing nomenclature
01653                     tc.setStyleElementReference()
01654                     self.localTypes.append(c)
01655                 else:
01656                     raise ContainerError, 'unexpected item: %s' % c.getItemTrace()
01657 
01658             elif c.isReference():
01659                 # element references
01660                 ref = c.getAttribute('ref')
01661 #                tc.klass = '%s.%s' % (NAD.getAlias(ref[0]),
01662 #                                          element_class_name(ref[1]) )
01663                 tc.setStyleElementReference()
01664                 tc.setGlobalType(*ref)
01665             else:
01666                 raise ContainerError, 'unexpected item: %s' % c.getItemTrace()
01667 
01668             self.tcListElements.append(tc)
01669 
01670     def getTypecodeList(self):
01671         if not self.tcListSet:
01672 #            self._flattenContent()
01673             self._setTypecodeList()
01674             self.tcListSet = True
01675 
01676         list = []
01677         for e in self.tcListElements:
01678             list.append(str(e))
01679 
01680         return ', '.join(list)
01681 
01682     # the following _methods() are utility methods used during
01683     # TCList generation, et al.
01684     
01685     def _getOccurs(self, e):
01686         
01687         nillable = e.getAttribute('nillable')
01688         if nillable == 'true':
01689             nillable = True
01690         else:
01691             nillable = False
01692             
01693         maxOccurs = e.getAttribute('maxOccurs')
01694         if maxOccurs == 'unbounded':
01695             maxOccurs = '"%s"' %maxOccurs
01696             
01697         minOccurs = e.getAttribute('minOccurs')
01698         
01699         if self.allOptional is True:
01700             #JRB Hack
01701             minOccurs = '0'
01702             maxOccurs = '"unbounded"'
01703 
01704         return minOccurs,maxOccurs,nillable
01705 
01706     def _getProcessContents(self, e):
01707         processContents = e.getAttribute('processContents')
01708         return processContents
01709 
01710     def getBasesLogic(self, indent):
01711         try:
01712             prefix = NAD.getAlias(self.sKlassNS)
01713         except WsdlGeneratorError, ex:
01714             # XSD or SOAP
01715             raise
01716 
01717         bases = []
01718         bases.append(\
01719             'if %s.%s not in %s.%s.__bases__:'\
01720             %(NAD.getAlias(self.sKlassNS), type_class_name(self.sKlass), self.getNSAlias(), self.getClassName()),
01721         )
01722         bases.append(\
01723             '%sbases = list(%s.%s.__bases__)'\
01724             %(ID1,self.getNSAlias(),self.getClassName()),
01725         )
01726         bases.append(\
01727             '%sbases.insert(0, %s.%s)'\
01728             %(ID1,NAD.getAlias(self.sKlassNS), type_class_name(self.sKlass) ),
01729         )
01730         bases.append(\
01731             '%s%s.%s.__bases__ = tuple(bases)'\
01732             %(ID1, self.getNSAlias(), self.getClassName())
01733         )
01734 
01735         s = ''
01736         for b in bases:
01737             s += '%s%s\n' % (indent, b)
01738 
01739         return s
01740 
01741 
01742 class MessageTypecodeContainer(TypecodeContainerBase):
01743     '''Used for RPC style messages, where we have 
01744     serveral parts serialized within a rpc wrapper name.
01745     '''
01746     logger = _GetLogger("MessageTypecodeContainer")
01747 
01748     def __init__(self, parts=None):
01749         TypecodeContainerBase.__init__(self)
01750         self.mgContent = parts
01751 
01752     def _getOccurs(self, e):
01753         '''return a 3 item tuple 
01754         '''
01755         minOccurs = maxOccurs = '1'
01756         nillable = True
01757         return minOccurs,maxOccurs,nillable
01758 
01759     def _setTypecodeList(self):
01760         self.logger.debug("_setTypecodeList: %s" %
01761             str(self.mgContent))
01762         
01763         assert type(self.mgContent) is tuple,\
01764             'expecting tuple for mgContent not: %s' %type(self.mgContent)
01765 
01766         for p in self.mgContent:
01767             # JRB
01768             #   not sure what needs to be set for tc, this should be
01769             #   the job of the constructor or a setUp method.
01770             min,max,nil = self._getOccurs(p)
01771             if p.element:
01772                 raise  WSInteropError, WSISpec.R2203
01773             elif p.type: 
01774                 nsuri,name = p.type
01775                 tc = RPCMessageTcListComponentContainer(qualified=False)
01776                 tc.setOccurs(min, max, nil)
01777                 tc.name = p.name
01778                 if nsuri in [SOAP.ENC] + SCHEMA.XSD_LIST:
01779                     tpc = BTI.get_typeclass(name, nsuri)
01780                     tc.klass = tpc
01781                 else:
01782                     tc.klass = '%s.%s' % (NAD.getAlias(nsuri), type_class_name(name) )
01783             else:
01784                 raise ContainerError, 'part must define an element or type attribute'
01785 
01786             self.tcListElements.append(tc)
01787 
01788     def getTypecodeList(self):
01789         if not self.tcListSet:
01790             self._setTypecodeList()
01791             self.tcListSet = True
01792 
01793         list = []
01794         for e in self.tcListElements:
01795             list.append(str(e))
01796         return ', '.join(list)
01797 
01798     def getAttributeNames(self):
01799         '''returns a list of anames representing the parts
01800         of the message.
01801         '''
01802         return map(lambda e: self.getAttributeName(e.name), self.tcListElements)
01803 
01804     def getParameterNames(self):
01805         '''returns a list of pnames representing the parts
01806         of the message.
01807         '''
01808         return map(lambda e: e.name, self.tcListElements)
01809     
01810     def setParts(self, parts):
01811         self.mgContent = parts
01812 
01813 
01814 class TcListComponentContainer(ContainerBase):
01815     '''Encapsulates a single value in the TClist list.
01816     it inherits TypecodeContainerBase only to get the mangle() method,
01817     it does not call the baseclass ctor.
01818     
01819     TODO: Change this inheritance scheme.
01820     '''
01821     logger = _GetLogger("TcListComponentContainer")
01822     
01823     def __init__(self, qualified=True):
01824         '''
01825         qualified -- qualify element.  All GEDs should be qualified,
01826             but local element declarations qualified if form attribute
01827             is qualified, else they are unqualified. Only relevant for
01828             standard style.
01829         '''
01830         #TypecodeContainerBase.__init__(self)
01831         ContainerBase.__init__(self)
01832 
01833         self.qualified = qualified
01834         self.name = None
01835         self.klass = None
01836         self.global_type = None
01837         
01838         self.min = None
01839         self.max = None
01840         self.nil = None
01841         self.style = None
01842         self.setStyleElementDeclaration()
01843 
01844     def setOccurs(self, min, max, nil):
01845         self.min = min
01846         self.max = max
01847         self.nil = nil
01848 
01849     def setProcessContents(self, processContents):
01850         self.processContents = processContents
01851 
01852     def setGlobalType(self, namespace, name):
01853         self.global_type = (namespace, name)
01854         
01855     def setStyleElementDeclaration(self):
01856         '''set the element style.
01857             standard -- GED or local element
01858         '''
01859         self.style = 'standard'
01860 
01861     def setStyleElementReference(self):
01862         '''set the element style.
01863             ref -- element reference
01864         '''
01865         self.style = 'ref'
01866 
01867     def setStyleAnyElement(self):
01868         '''set the element style.
01869             anyElement -- <any> element wildcard
01870         '''
01871         self.name = 'any'
01872         self.style = 'anyElement'
01873 
01874 #    def setStyleRecursion(self):
01875 #        '''TODO: Remove.  good for 1 level 
01876 #        '''
01877 #        self.style = 'recursion'
01878 
01879     def unQualified(self):
01880         '''Do not qualify element.
01881         '''
01882         self.qualified = False
01883 
01884     def _getOccurs(self):
01885         return 'minOccurs=%s, maxOccurs=%s, nillable=%s' \
01886                % (self.min, self.max, self.nil)
01887 
01888     def _getProcessContents(self):
01889         return 'processContents="%s"' \
01890                % (self.processContents)
01891 
01892     def _getvalue(self):
01893         kw = {'occurs':self._getOccurs(), 
01894               'aname':self.getAttributeName(self.name),
01895               'klass':self.klass,
01896               'lazy':TypecodeContainerBase.lazy,
01897               'typed':'typed=False',
01898               'encoded':'encoded=kw.get("encoded")'}
01899         
01900         gt = self.global_type
01901         if gt is not None:
01902             kw['nsuri'],kw['type'] = gt
01903             
01904         if self.style == 'standard':
01905             kw['pname'] = '"%s"' %self.name
01906             if self.qualified is True:
01907                 kw['pname'] =  '(ns,"%s")' %self.name
01908             if gt is None:
01909                 return '%(klass)s(pname=%(pname)s, aname="%(aname)s", %(occurs)s, %(typed)s, %(encoded)s)' %kw
01910             return 'GTD("%(nsuri)s","%(type)s",lazy=%(lazy)s)(pname=%(pname)s, aname="%(aname)s", %(occurs)s, %(typed)s, %(encoded)s)' %kw
01911         
01912         if self.style == 'ref':
01913             if gt is None:
01914                 return '%(klass)s(%(occurs)s, %(encoded)s)' %kw
01915             return 'GED("%(nsuri)s","%(type)s",lazy=%(lazy)s, isref=True)(%(occurs)s, %(encoded)s)' %kw
01916         
01917         kw['process'] = self._getProcessContents()
01918         if self.style == 'anyElement':
01919             return 'ZSI.TC.AnyElement(aname="%(aname)s", %(occurs)s, %(process)s)' %kw
01920                   
01921 #        if self.style == 'recursion':
01922 #            return 'ZSI.TC.AnyElement(aname="%(aname)s", %(occurs)s, %(process)s)' %kw
01923 
01924         raise RuntimeError, 'Must set style for typecode list generation'
01925     
01926     def __str__(self):
01927         return self._getvalue()
01928    
01929  
01930 class RPCMessageTcListComponentContainer(TcListComponentContainer):
01931     '''Container for rpc/literal rpc/encoded message typecode.
01932     '''
01933     logger = _GetLogger("RPCMessageTcListComponentContainer")
01934 
01935     def __init__(self, qualified=True, encoded=None):
01936         '''
01937         encoded -- encoded namespaceURI, if None treat as rpc/literal.
01938         '''
01939         TcListComponentContainer.__init__(self, qualified=qualified)
01940         self._encoded = encoded
01941  
01942     def _getvalue(self):
01943         encoded = self._encoded
01944         if encoded is not None:
01945             encoded = '"%s"' %self._encoded
01946 
01947         if self.style == 'standard':
01948             pname = '"%s"' %self.name
01949             if self.qualified is True:
01950                 pname = '(ns,"%s")' %self.name
01951             return '%s(pname=%s, aname="%s", typed=False, encoded=%s, %s)' \
01952                    %(self.klass, pname, self.getAttributeName(self.name), 
01953                      encoded, self._getOccurs())
01954         elif self.style == 'ref':
01955             return '%s(encoded=%s, %s)' % (self.klass, encoded, self._getOccurs())
01956         elif self.style == 'anyElement':
01957             return 'ZSI.TC.AnyElement(aname="%s", %s, %s)' \
01958                 %(self.getAttributeName(self.name), self._getOccurs(), self._getProcessContents())
01959 #        elif self.style == 'recursion':
01960 #            return 'ZSI.TC.AnyElement(aname="%s", %s, %s)' \
01961 #                % (self.getAttributeName(self.name), self._getOccurs(), self._getProcessContents())
01962 
01963         raise RuntimeError('Must set style(%s) for typecode list generation' %
01964                            self.style)
01965    
01966 
01967 class ElementSimpleTypeContainer(TypecodeContainerBase):
01968     type = DEC
01969     logger = _GetLogger("ElementSimpleTypeContainer")
01970 
01971     def _substitutionGroupTag(self):
01972         value = self.substitutionGroup
01973         if not value:
01974             return 'substitutionGroup = None'
01975   
01976         nsuri,ncname = value
01977         return 'substitutionGroup = ("%s","%s")' %(nsuri, ncname)
01978         
01979     def _setContent(self):
01980         aname = self.getAttributeName(self.name)
01981         pyclass = self.pyclass
01982 
01983         # bool cannot be subclassed
01984         if pyclass == 'bool': pyclass = 'int'
01985         kw = KW.copy()
01986         kw.update(dict(aname=aname, ns=self.ns, name=self.name, 
01987                        substitutionGroup=self._substitutionGroupTag(),
01988                        subclass=self.sKlass,literal=self.literalTag(),
01989                        schema=self.schemaTag(), init=self.simpleConstructor(),
01990                        klass=self.getClassName(), element="ElementDeclaration"))
01991 
01992         if self.local:
01993             kw['element'] = 'LocalElementDeclaration'
01994         
01995         element = map(lambda i: i %kw, [
01996             '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):',
01997             '%(ID2)s%(literal)s',
01998             '%(ID2)s%(schema)s',
01999             '%(ID2)s%(init)s',
02000             '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")',
02001             '%(ID3)skw["aname"] = "%(aname)s"',
02002             ]
02003         )
02004 
02005         # TODO: What about getPyClass and getPyClassDefinition?
02006         #     I want to add pyclass metaclass here but this needs to be 
02007         #     corrected first.
02008         #
02009         # anyType (?others) has no pyclass.
02010         app = element.append
02011         if pyclass is not None:
02012             app('%sclass IHolder(%s): typecode=self' % (ID3, pyclass),)
02013             app('%skw["pyclass"] = IHolder' %(ID3),)
02014             app('%sIHolder.__name__ = "%s_immutable_holder"' %(ID3, aname),)
02015 
02016         app('%s%s' % (ID3, self.simpleConstructor(self.sKlass)),)
02017 
02018         self.writeArray(element)
02019 
02020     def setUp(self, tp):
02021         self._item = tp
02022         self.local = tp.isLocal()
02023         try:
02024             self.name = tp.getAttribute('name')
02025             self.substitutionGroup = tp.getAttribute('substitutionGroup')
02026             self.ns = tp.getTargetNamespace()
02027             qName = tp.getAttribute('type')
02028         except Exception, ex:
02029             raise Wsdl2PythonError('Error occured processing element: %s' %(
02030                 tp.getItemTrace()), *ex.args)
02031 
02032         if qName is None:
02033             raise Wsdl2PythonError('Missing QName for element type attribute: %s' %tp.getItemTrace())
02034 
02035         tns,local = qName.getTargetNamespace(),qName.getName()
02036         self.sKlass = BTI.get_typeclass(local, tns)
02037         if self.sKlass is None:
02038             raise Wsdl2PythonError('No built-in typecode for type definition("%s","%s"): %s' %(tns,local,tp.getItemTrace()))
02039 
02040         try:
02041             self.pyclass = BTI.get_pythontype(None, None, typeclass=self.sKlass)
02042         except Exception, ex:
02043             raise Wsdl2PythonError('Error occured processing element: %s' %(
02044                 tp.getItemTrace()), *ex.args)
02045 
02046 
02047 class ElementLocalSimpleTypeContainer(TypecodeContainerBase):
02048     '''local simpleType container
02049     '''
02050     type = DEC 
02051     logger = _GetLogger("ElementLocalSimpleTypeContainer")
02052 
02053     def _setContent(self):
02054         kw = KW.copy()
02055         kw.update(dict(aname=self.getAttributeName(self.name), ns=self.ns, name=self.name, 
02056                        subclass=self.sKlass,literal=self.literalTag(),
02057                        schema=self.schemaTag(), init=self.simpleConstructor(),
02058                        klass=self.getClassName(), element="ElementDeclaration",
02059                        baseinit=self.simpleConstructor(self.sKlass)))
02060 
02061         if self.local:
02062             kw['element'] = 'LocalElementDeclaration'
02063         
02064         element = map(lambda i: i %kw, [
02065             '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):',
02066             '%(ID2)s%(literal)s',
02067             '%(ID2)s%(schema)s',
02068             '%(ID2)s%(init)s',
02069             '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")',
02070             '%(ID3)skw["aname"] = "%(aname)s"',
02071             '%(ID3)s%(baseinit)s',
02072             ]
02073         )
02074 
02075         app = element.append
02076         pyclass = self.pyclass        
02077         if pyclass is not None:
02078             # bool cannot be subclassed
02079             if pyclass == 'bool': pyclass = 'int'
02080             kw['pyclass'] = pyclass
02081             app('%(ID3)sclass IHolder(%(pyclass)s): typecode=self' %kw)
02082             app('%(ID3)sself.pyclass = IHolder' %kw)
02083             app('%(ID3)sIHolder.__name__ = "%(aname)s_immutable_holder"' %kw)
02084         
02085         self.writeArray(element)
02086 
02087     def _setup_pyclass(self):
02088         try:
02089             self.pyclass = BTI.get_pythontype(None, None, 
02090                                               typeclass=self.sKlass)
02091         except Exception, ex:
02092             raise Wsdl2PythonError('Error occured processing element: %s' %(
02093                 self._item.getItemTrace()), *ex.args)
02094 
02095     def setUp(self, tp):
02096         self._item = tp
02097         assert tp.isElement() is True and tp.content is not None and \
02098             tp.content.isLocal() is True and tp.content.isSimple() is True ,\
02099             'expecting local simple type: %s' %tp.getItemTrace()
02100 
02101         self.local = tp.isLocal()
02102         self.name = tp.getAttribute('name')
02103         self.ns = tp.getTargetNamespace()
02104         content = tp.content.content
02105         if content.isRestriction():
02106             try:
02107                  base = content.getTypeDefinition()
02108             except XMLSchema.SchemaError, ex:
02109                  base = None
02110 
02111             qName = content.getAttributeBase()
02112             if base is None:
02113                 self.sKlass = BTI.get_typeclass(qName[1], qName[0])
02114                 self._setup_pyclass()
02115                 return
02116 
02117             raise Wsdl2PythonError, 'unsupported local simpleType restriction: %s' \
02118                 %tp.content.getItemTrace()
02119 
02120         if content.isList():
02121             try:
02122                  base = content.getTypeDefinition()
02123             except XMLSchema.SchemaError, ex:
02124                  base = None
02125 
02126             if base is None:
02127                 qName = content.getItemType()
02128                 self.sKlass = BTI.get_typeclass(qName[1], qName[0])
02129                 self._setup_pyclass()
02130                 return
02131 
02132             raise Wsdl2PythonError, 'unsupported local simpleType List: %s' \
02133                 %tp.content.getItemTrace()
02134 
02135         if content.isUnion():
02136             raise Wsdl2PythonError, 'unsupported local simpleType Union: %s' \
02137                 %tp.content.getItemTrace()
02138 
02139         raise Wsdl2PythonError, 'unexpected schema item: %s' \
02140             %tp.content.getItemTrace()
02141 
02142 
02143 class ElementLocalComplexTypeContainer(TypecodeContainerBase, AttributeMixIn):
02144     type = DEC
02145     logger = _GetLogger("ElementLocalComplexTypeContainer")
02146 
02147     def _setContent(self):
02148         kw = KW.copy()
02149         try:
02150             kw.update(dict(klass=self.getClassName(),
02151                        subclass='ZSI.TCcompound.ComplexType',
02152                        element='ElementDeclaration',
02153                        literal=self.literalTag(),
02154                        schema=self.schemaTag(), 
02155                        init=self.simpleConstructor(),
02156                        ns=self.ns, name=self.name,
02157                        aname=self.getAttributeName(self.name),  
02158                        nsurilogic=self.nsuriLogic(),
02159                        ofwhat=self.getTypecodeList(),
02160                        atypecode=self.attribute_typecode,
02161                        pyclass=self.getPyClass(),
02162                        ))
02163         except Exception, ex:
02164             args = ['Failure processing an element w/local complexType: %s' %(
02165                           self._item.getItemTrace())]
02166             args += ex.args
02167             ex.args = tuple(args)
02168             raise
02169 
02170         if self.local:
02171             kw['element'] = 'LocalElementDeclaration'
02172         
02173         element = [
02174             '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):',
02175             '%(ID2)s%(literal)s',
02176             '%(ID2)s%(schema)s',
02177             '%(ID2)s%(init)s',
02178             '%(ID3)s%(nsurilogic)s',
02179             '%(ID3)sTClist = [%(ofwhat)s]',
02180             '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")',
02181             '%(ID3)skw["aname"] = "%(aname)s"',
02182             '%(ID3)s%(atypecode)s = {}',
02183             '%(ID3)sZSI.TCcompound.ComplexType.__init__(self,None,TClist,inorder=0,**kw)',
02184             ]
02185         for l in self.attrComponents: element.append('%(ID3)s'+str(l))
02186         element += self.getPyClassDefinition()
02187         element.append('%(ID3)sself.pyclass = %(pyclass)s' %kw)  
02188         self.writeArray(map(lambda l: l %kw, element))
02189 
02190     def setUp(self, tp):
02191         '''
02192         {'xsd':['annotation', 'simpleContent', 'complexContent',\
02193         'group', 'all', 'choice', 'sequence', 'attribute', 'attributeGroup',\
02194         'anyAttribute', 'any']}
02195         '''
02196         # 
02197         # TODO: Need a Recursive solution, this is incomplete will ignore many
02198         #  extensions, restrictions, etc.
02199         # 
02200         self._item = tp
02201         # JRB HACK SUPPORTING element/no content.
02202         assert tp.isElement() is True and \
02203             (tp.content is None or (tp.content.isComplex() is True and tp.content.isLocal() is True)),\
02204             'expecting element w/local complexType not: %s' %tp.content.getItemTrace()
02205 
02206         self.name = tp.getAttribute('name')
02207         self.ns = tp.getTargetNamespace()
02208         self.local = tp.isLocal()
02209 
02210         complex = tp.content
02211         # JRB HACK SUPPORTING element/no content.
02212         if complex is None:
02213             self.mgContent = ()
02214             return
02215         
02216         #attributeContent = complex.getAttributeContent()
02217         #self.mgContent = None
02218         if complex.content is None:
02219             self.mgContent = ()
02220             self.attrComponents = self._setAttributes(complex.getAttributeContent())
02221             return 
02222 
02223         is_simple = complex.content.isSimple()
02224         if is_simple and complex.content.content.isExtension():
02225             # TODO: Not really supported just passing thru
02226             self.mgContent = ()
02227             self.attrComponents = self._setAttributes(complex.getAttributeContent())
02228             return
02229 
02230         if is_simple and complex.content.content.isRestriction():
02231             # TODO: Not really supported just passing thru
02232             self.mgContent = ()
02233             self.attrComponents = self._setAttributes(complex.getAttributeContent())
02234             return
02235 
02236         if is_simple:
02237             raise ContainerError, 'not implemented local complexType/simpleContent: %s'\
02238                %tp.getItemTrace()
02239 
02240         is_complex = complex.content.isComplex()
02241         if is_complex and complex.content.content is None:
02242             # TODO: Recursion...
02243             self.mgContent = ()
02244             self.attrComponents = self._setAttributes(complex.getAttributeContent())
02245             return
02246 
02247         if (is_complex and complex.content.content.isExtension() and 
02248             complex.content.content.content is not None and
02249             complex.content.content.content.isModelGroup()):
02250 
02251             self.mgContent = complex.content.content.content.content
02252             self.attrComponents = self._setAttributes(
02253                     complex.content.content.getAttributeContent()
02254                 )
02255             return
02256 
02257         if (is_complex and complex.content.content.isRestriction() and
02258             complex.content.content.content is not None and 
02259             complex.content.content.content.isModelGroup()):
02260 
02261             self.mgContent = complex.content.content.content.content
02262             self.attrComponents = self._setAttributes(
02263                     complex.content.content.getAttributeContent()
02264                 )
02265             return
02266 
02267         if is_complex:
02268             self.mgContent = ()
02269             self.attrComponents = self._setAttributes(complex.getAttributeContent())
02270             return
02271 
02272         if complex.content.isModelGroup():
02273             self.mgContent = complex.content.content
02274             self.attrComponents = self._setAttributes(complex.getAttributeContent())
02275             return
02276 
02277         # TODO: Scary Fallthru
02278         self.mgContent = ()
02279         self.attrComponents = self._setAttributes(complex.getAttributeContent())
02280         
02281         
02282 class ElementGlobalDefContainer(TypecodeContainerBase):
02283     type = DEC
02284     logger = _GetLogger("ElementGlobalDefContainer")
02285 
02286     def _substitutionGroupTag(self):
02287         value = self.substitutionGroup
02288         if not value:
02289             return 'substitutionGroup = None'
02290   
02291         nsuri,ncname = value
02292         return 'substitutionGroup = ("%s","%s")' %(nsuri, ncname)
02293 
02294     def _setContent(self):
02295         '''GED defines element name, so also define typecode aname
02296         '''
02297         kw = KW.copy()
02298         try:
02299             kw.update(dict(klass=self.getClassName(),
02300                        element='ElementDeclaration',
02301                        literal=self.literalTag(),
02302                        substitutionGroup=self._substitutionGroupTag(),
02303                        schema=self.schemaTag(), 
02304                        init=self.simpleConstructor(),
02305                        ns=self.ns, name=self.name,
02306                        aname=self.getAttributeName(self.name),  
02307                        baseslogic=self.getBasesLogic(ID3),
02308                        #ofwhat=self.getTypecodeList(),
02309                        #atypecode=self.attribute_typecode,
02310                        #pyclass=self.getPyClass(),
02311                        alias=NAD.getAlias(self.sKlassNS),
02312                        subclass=type_class_name(self.sKlass),
02313                        ))
02314         except Exception, ex:
02315             args = ['Failure processing an element w/local complexType: %s' %(
02316                           self._item.getItemTrace())]
02317             args += ex.args
02318             ex.args = tuple(args)
02319             raise
02320         
02321         if self.local:
02322             kw['element'] = 'LocalElementDeclaration'
02323         
02324         element = [
02325             '%(ID1)sclass %(klass)s(%(element)s):',
02326             '%(ID2)s%(literal)s',
02327             '%(ID2)s%(schema)s',
02328             '%(ID2)s%(substitutionGroup)s',
02329             '%(ID2)s%(init)s',
02330             '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")',
02331             '%(ID3)skw["aname"] = "%(aname)s"',
02332             '%(baseslogic)s',
02333             '%(ID3)s%(alias)s.%(subclass)s.__init__(self, **kw)',
02334             '%(ID3)sif self.pyclass is not None: self.pyclass.__name__ = "%(klass)s_Holder"',
02335             ]
02336 
02337         self.writeArray(map(lambda l: l %kw, element))
02338 
02339     def setUp(self, element):
02340         # Save for debugging
02341         self._item = element
02342         self.local = element.isLocal()
02343         self.name = element.getAttribute('name')
02344         self.substitutionGroup = element.getAttribute('substitutionGroup')
02345         self.ns = element.getTargetNamespace()
02346         tp = element.getTypeDefinition('type')
02347         self.sKlass = tp.getAttribute('name')
02348         self.sKlassNS = tp.getTargetNamespace()
02349 
02350 
02351 class ComplexTypeComplexContentContainer(TypecodeContainerBase, AttributeMixIn):
02352     '''Represents ComplexType with ComplexContent.
02353     '''
02354     type = DEF
02355     logger = _GetLogger("ComplexTypeComplexContentContainer")
02356 
02357     def __init__(self, do_extended=False):
02358         TypecodeContainerBase.__init__(self, do_extended=do_extended)
02359 
02360     def setUp(self, tp):
02361         '''complexContent/[extension,restriction]
02362             restriction
02363             extension
02364             extType -- used in figuring attrs for extensions
02365         '''
02366         self._item = tp
02367         assert tp.content.isComplex() is True and \
02368             (tp.content.content.isRestriction() or tp.content.content.isExtension() is True),\
02369             'expecting complexContent/[extension,restriction]'
02370             
02371         self.extType = None
02372         self.restriction = False
02373         self.extension = False
02374         self._kw_array = None
02375         self._is_array = False
02376         self.name = tp.getAttribute('name')
02377         self.ns = tp.getTargetNamespace()
02378         
02379         # xxx: what is this for?
02380         #self.attribute_typecode = 'attributes'
02381         
02382         derivation = tp.content.content
02383         # Defined in Schema instance?
02384         try:
02385             base = derivation.getTypeDefinition('base')
02386         except XMLSchema.SchemaError, ex:
02387             base = None
02388 
02389         # anyType, arrayType, etc...
02390         if base is None:
02391             base = derivation.getAttributeQName('base')
02392             if base is None:
02393                 raise ContainerError, 'Unsupported derivation: %s'\
02394                         %derivation.getItemTrace()
02395                         
02396             if base != (SOAP.ENC,'Array') and base != (SCHEMA.XSD3,'anyType'):
02397                 raise ContainerError, 'Unsupported base(%s): %s' %(
02398                     base, derivation.getItemTrace()
02399                     )
02400                 
02401         if base == (SOAP.ENC,'Array'):
02402             # SOAP-ENC:Array expecting arrayType attribute reference
02403             self.logger.debug("Derivation of soapenc:Array")
02404             self._is_array = True
02405             self._kw_array = {'atype':None, 'id3':ID3, 'ofwhat':None}
02406             self.sKlass = BTI.get_typeclass(base[1], base[0])
02407             self.sKlassNS = base[0]
02408 
02409             for a in derivation.getAttributeContent():
02410 
02411                 assert a.isAttribute() is True,\
02412                     'only attribute content expected: %s' %a.getItemTrace()
02413 
02414                 if a.isReference() is False:
02415                     continue
02416 
02417                 if a.getAttribute('ref') != (SOAP.ENC,'arrayType'):
02418                     continue
02419 
02420                 attr = a.getAttributeQName((WSDL.BASE, 'arrayType'))
02421                 if attr is None:
02422                     warnings.warn('soapenc:array derivation declares attribute reference ("%s","%s"), does not define attribute ("%s","%s")' %(
02423                         SOAP.ENC,'arrayType',WSDL.BASE, 'arrayType'))
02424                     break
02425                 
02426                 self._kw_array['atype'] = attr
02427                 qname = self._kw_array.get('atype')
02428                 if a is not None:
02429                     ncname = qname[1].strip('[]')
02430                     namespace = qname[0]
02431                     try:
02432                         ofwhat = a.getSchemaItem(XMLSchema.TYPES, namespace, ncname)
02433                     except XMLSchema.SchemaError, ex:
02434                         ofwhat = None
02435 
02436                     if ofwhat is None:
02437                         self._kw_array['ofwhat'] = BTI.get_typeclass(ncname, namespace)
02438                     else:
02439                         self._kw_array['ofwhat'] = GetClassNameFromSchemaItem(ofwhat, do_extended=self.do_extended)
02440 
02441                     if self._kw_array['ofwhat'] is None:
02442                         raise ContainerError, 'For Array could not resolve ofwhat typecode(%s,%s): %s'\
02443                             %(namespace, ncname, derivation.getItemTrace())
02444                     
02445                     self.logger.debug('Attribute soapenc:arrayType="%s"' %
02446                                       str(self._kw_array['ofwhat']))
02447 
02448                     break
02449 
02450             #else:
02451             #    raise Wsdl2PythonError, \
02452             #        'derivation of soapenc:array must declare attribute reference ("%s","%s")' %(
02453             #        SOAP.ENC,'arrayType')
02454 
02455        
02456         elif isinstance(base, XMLSchema.XMLSchemaComponent):
02457             self.sKlass = base.getAttribute('name')
02458             self.sKlassNS = base.getTargetNamespace()
02459         else:
02460             # TypeDescriptionComponent
02461             self.sKlass = base.getName()
02462             self.sKlassNS = base.getTargetNamespace()
02463 
02464         attrs = []
02465         if derivation.isRestriction():
02466             self.restriction = True
02467             self.extension = False
02468             # derivation.getAttributeContent subset of tp.getAttributeContent 
02469             attrs += derivation.getAttributeContent() or ()
02470         else:
02471             self.restriction = False
02472             self.extension = True
02473             attrs += tp.getAttributeContent() or ()
02474             if isinstance(derivation, XMLSchema.XMLSchemaComponent):
02475                 attrs += derivation.getAttributeContent() or ()
02476                 
02477         # XXX: not sure what this is doing
02478         if attrs:
02479             self.extType = derivation
02480 
02481         if derivation.content is not None \
02482             and derivation.content.isModelGroup():
02483             group = derivation.content
02484             if group.isReference():
02485                 group = group.getModelGroupReference()
02486             self.mgContent = group.content
02487         elif derivation.content:
02488             raise Wsdl2PythonError, \
02489                 'expecting model group, not: %s' %derivation.content.getItemTrace()
02490         else:
02491             self.mgContent = ()
02492 
02493         self.attrComponents = self._setAttributes(tuple(attrs))
02494                 
02495     def _setContent(self):
02496         '''JRB What is the difference between instance data
02497         ns, name, -- type definition?
02498         sKlass, sKlassNS? -- element declaration?
02499         '''
02500         kw = KW.copy()
02501         definition = []
02502         if self._is_array:
02503             # SOAP-ENC:Array
02504             if _is_xsd_or_soap_ns(self.sKlassNS) is False and self.sKlass == 'Array':
02505                 raise ContainerError, 'unknown type: (%s,%s)'\
02506                     %(self.sKlass, self.sKlassNS)
02507                     
02508             # No need to xsi:type array items since specify with
02509             # SOAP-ENC:arrayType attribute.
02510             definition += [\
02511                 '%sclass %s(ZSI.TC.Array, TypeDefinition):' % (ID1, self.getClassName()),
02512                 '%s#complexType/complexContent base="SOAP-ENC:Array"' %(ID2),
02513                 '%s%s' % (ID2, self.schemaTag()),
02514                 '%s%s' % (ID2, self.typeTag()),
02515                 '%s%s' % (ID2, self.pnameConstructor()),
02516                 ]
02517 
02518             append = definition.append
02519             if  self._kw_array.get('ofwhat') is None:
02520                 append('%s%s.__init__(self, None, None, pname=pname, childnames=\'item\', undeclared=True, **kw)' %(ID3, self.sKlass))
02521             else:
02522                 append('%(id3)sofwhat = %(ofwhat)s(None, typed=False)' %self._kw_array)
02523                 append('%(id3)satype = %(atype)s' %self._kw_array)
02524                 append('%s%s.__init__(self, atype, ofwhat, pname=pname, childnames=\'item\', **kw)' %(ID3, self.sKlass))
02525 
02526             self.writeArray(definition)
02527             return
02528     
02529         definition += [\
02530             '%sclass %s(TypeDefinition):' % (ID1, self.getClassName()),
02531             '%s%s' % (ID2, self.schemaTag()),
02532             '%s%s' % (ID2, self.typeTag()),
02533             '%s%s' % (ID2, self.pnameConstructor()),
02534             '%s%s' % (ID3, self.nsuriLogic()),
02535             '%sTClist = [%s]' % (ID3, self.getTypecodeList()),
02536             ]
02537                 
02538         definition.append(
02539             '%(ID3)sattributes = %(atc)s = attributes or {}' %{
02540                 'ID3':ID3, 'atc':self.attribute_typecode}
02541         )
02542 
02543         #
02544         # Special case: anyType restriction
02545         isAnyType = (self.sKlassNS, self.sKlass) == (SCHEMA.XSD3, 'anyType')
02546         if isAnyType:
02547             del definition[0]
02548             definition.insert(0,
02549                 '%sclass %s(ZSI.TC.ComplexType, TypeDefinition):' % (
02550                              ID1, self.getClassName())
02551             )
02552             definition.insert(1, 
02553                 '%s#complexType/complexContent restrict anyType' %(
02554                                ID2)
02555             )
02556         
02557         # derived type support
02558         definition.append('%sif extend: TClist += ofwhat'%(ID3))
02559         definition.append('%sif restrict: TClist = ofwhat' %(ID3))
02560         if len(self.attrComponents) > 0:
02561             definition.append('%selse:' %(ID3))
02562             for l in self.attrComponents: 
02563                 definition.append('%s%s'%(ID4, l))
02564                 
02565         if isAnyType:
02566             definition.append(\
02567                 '%sZSI.TC.ComplexType.__init__(self, None, TClist, pname=pname, **kw)' %(
02568                     ID3),
02569             )
02570             
02571             # pyclass class definition
02572             definition += self.getPyClassDefinition()
02573             kw['pyclass'] = self.getPyClass()
02574             definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw)  
02575             self.writeArray(definition)
02576             return
02577             
02578         definition.append('%s'   % self.getBasesLogic(ID3))
02579         prefix = NAD.getAlias(self.sKlassNS)
02580         typeClassName = type_class_name(self.sKlass)
02581         if self.restriction:
02582             definition.append(\
02583                 '%s%s.%s.__init__(self, pname, ofwhat=TClist, restrict=True, **kw)' %(
02584                     ID3, prefix, typeClassName),
02585             )
02586             definition.insert(1, '%s#complexType/complexContent restriction' %ID2)
02587             self.writeArray(definition)
02588             return
02589         
02590         if self.extension:
02591             definition.append(\
02592                 '%s%s.%s.__init__(self, pname, ofwhat=TClist, extend=True, attributes=attributes, **kw)'%(
02593                     ID3, prefix, typeClassName),
02594             )
02595             definition.insert(1, '%s#complexType/complexContent extension' %(ID2))
02596             self.writeArray(definition)
02597             return
02598             
02599         raise Wsdl2PythonError,\
02600             'ComplexContent must be a restriction or extension'
02601 
02602     def pnameConstructor(self, superclass=None):
02603         if superclass:
02604             return '%s.__init__(self, pname, ofwhat=(), extend=False, restrict=False, attributes=None, **kw)' % superclass
02605         
02606         return 'def __init__(self, pname, ofwhat=(), extend=False, restrict=False, attributes=None, **kw):'
02607       
02608 
02609 class ComplexTypeContainer(TypecodeContainerBase, AttributeMixIn):
02610     '''Represents a global complexType definition.
02611     '''
02612     type = DEF
02613     logger = _GetLogger("ComplexTypeContainer")
02614 
02615     def setUp(self, tp, empty=False):
02616         '''Problematic, loose all model group information.
02617         <all>, <choice>, <sequence> ..
02618 
02619            tp -- type definition
02620            empty -- no model group, just use as a dummy holder.
02621         '''
02622         self._item = tp
02623         
02624         self.name = tp.getAttribute('name')
02625         self.ns = tp.getTargetNamespace()
02626         self.mixed = tp.isMixed()
02627         self.mgContent = ()
02628         self.attrComponents = self._setAttributes(tp.getAttributeContent())
02629         
02630         # Save reference to type for debugging
02631         self._item = tp
02632         
02633         if empty:
02634             return
02635         
02636         model = tp.content
02637         if model.isReference(): 
02638             model = model.getModelGroupReference()
02639         
02640         if model is None:
02641             return
02642         
02643         if model.content is None:
02644             return
02645        
02646         # sequence, all or choice
02647         #self.mgContent = model.content
02648         self.mgContent = model
02649         
02650     def _setContent(self):
02651         try:
02652             definition = [
02653                 '%sclass %s(ZSI.TCcompound.ComplexType, TypeDefinition):'
02654                 % (ID1, self.getClassName()),
02655                 '%s%s' % (ID2, self.schemaTag()),
02656                 '%s%s' % (ID2, self.typeTag()),
02657                 '%s%s' % (ID2, self.pnameConstructor()),
02658                 #'%s'   % self.getElements(),
02659                 '%s%s' % (ID3, self.nsuriLogic()),
02660                 '%sTClist = [%s]' % (ID3, self.getTypecodeList()),
02661                 ]
02662         except Exception, ex:
02663             args = ["Failure processing %s" %self._item.getItemTrace()]
02664             args += ex.args
02665             ex.args = tuple(args)
02666             raise
02667 
02668         definition.append('%s%s = attributes or {}' %(ID3, 
02669                            self.attribute_typecode))
02670         # IF EXTEND
02671         definition.append('%sif extend: TClist += ofwhat'%(ID3))
02672         # IF RESTRICT
02673         definition.append('%sif restrict: TClist = ofwhat' %(ID3))
02674         # ELSE
02675         if len(self.attrComponents) > 0:
02676             definition.append('%selse:' %(ID3))
02677             for l in self.attrComponents:  definition.append('%s%s'%(ID4, l))
02678         
02679         definition.append(\
02680             '%sZSI.TCcompound.ComplexType.__init__(self, None, TClist, pname=pname, inorder=0, %s**kw)' \
02681             %(ID3, self.getExtraFlags())
02682         )
02683 
02684         # pyclass class definition
02685         definition += self.getPyClassDefinition()
02686 
02687         # set pyclass
02688         kw = KW.copy()
02689         kw['pyclass'] = self.getPyClass()
02690         definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw)
02691         self.writeArray(definition)
02692 
02693     def pnameConstructor(self, superclass=None):
02694         ''' TODO: Logic is a little tricky.  If superclass is ComplexType this is not used.
02695         '''
02696         if superclass:
02697             return '%s.__init__(self, pname, ofwhat=(), attributes=None, extend=False, restrict=False, **kw)' % superclass
02698 
02699         return 'def __init__(self, pname, ofwhat=(), attributes=None, extend=False, restrict=False, **kw):'
02700         
02701         
02702 class SimpleTypeContainer(TypecodeContainerBase):
02703     type = DEF
02704     logger = _GetLogger("SimpleTypeContainer")
02705 
02706     def __init__(self):
02707         '''
02708         Instance Data From TypecodeContainerBase NOT USED...
02709            mgContent
02710         '''
02711         TypecodeContainerBase.__init__(self)
02712 
02713     def setUp(self, tp):
02714         raise NotImplementedError, 'abstract method not implemented'
02715 
02716     def _setContent(self, tp):
02717         raise NotImplementedError, 'abstract method not implemented'
02718 
02719     def getPythonType(self):
02720         pyclass = eval(str(self.sKlass))
02721         if issubclass(pyclass, ZSI.TC.String):
02722             return 'str'
02723         if issubclass(pyclass, ZSI.TC.Ilong) or issubclass(pyclass, ZSI.TC.IunsignedLong):
02724             return 'long'
02725         if issubclass(pyclass, ZSI.TC.Boolean) or issubclass(pyclass, ZSI.TC.Integer):
02726             return 'int'
02727         if issubclass(pyclass, ZSI.TC.Decimal):
02728             return 'float'
02729         if issubclass(pyclass, ZSI.TC.Gregorian) or issubclass(pyclass, ZSI.TC.Duration):
02730             return 'tuple'
02731         return None
02732 
02733     def getPyClassDefinition(self):
02734         definition = []
02735         pt = self.getPythonType()
02736         if pt is not None:
02737             definition.append('%sclass %s(%s):' %(ID3,self.getPyClass(),pt))
02738             definition.append('%stypecode = self' %ID4)
02739         return definition
02740 
02741 
02742 class RestrictionContainer(SimpleTypeContainer):
02743     '''
02744        simpleType/restriction
02745     '''
02746     logger = _GetLogger("RestrictionContainer")
02747 
02748     def setUp(self, tp):
02749         self._item = tp
02750         
02751         assert tp.isSimple() is True and tp.isDefinition() is True and \
02752             tp.content.isRestriction() is True,\
02753             'expecting simpleType restriction, not: %s' %tp.getItemTrace()
02754 
02755         if tp.content is None:
02756             raise Wsdl2PythonError, \
02757                   'empty simpleType defintion: %s' %tp.getItemTrace()
02758 
02759         self.name = tp.getAttribute('name')
02760         self.ns = tp.getTargetNamespace()
02761         self.sKlass = None
02762 
02763         base = tp.content.getAttribute('base')
02764         if base is not None:
02765             try:
02766                 item = tp.content.getTypeDefinition('base')
02767             except XMLSchema.SchemaError, ex:
02768                 item = None
02769 
02770             if item is None:
02771                 self.sKlass = BTI.get_typeclass(base.getName(), base.getTargetNamespace())
02772                 if self.sKlass is not None: 
02773                     return
02774 
02775                 raise Wsdl2PythonError('no built-in type nor schema instance type for base attribute("%s","%s"): %s' %(
02776                     base.getTargetNamespace(), base.getName(), tp.getItemTrace()))
02777 
02778             raise Wsdl2PythonError, \
02779                 'Not Supporting simpleType/Restriction w/User-Defined Base: %s %s' %(tp.getItemTrace(),item.getItemTrace())
02780 
02781         sc = tp.content.getSimpleTypeContent()
02782         if sc is not None and True is sc.isSimple() is sc.isLocal() is sc.isDefinition():
02783             base = None
02784             if sc.content.isRestriction() is True:
02785                 try:
02786                     item = tp.content.getTypeDefinition('base')
02787                 except XMLSchema.SchemaError, ex:
02788                     pass
02789 
02790                 if item is None:
02791                     base = sc.content.getAttribute('base')
02792                     if base is not None:
02793                         self.sKlass = BTI.get_typeclass(base.getTargetNamespace(), base.getName())
02794                         return
02795                     raise Wsdl2PythonError, \
02796                         'Not Supporting simpleType/Restriction w/User-Defined Base: '\
02797                         %item.getItemTrace()
02798 
02799                 raise Wsdl2PythonError, \
02800                     'Not Supporting simpleType/Restriction w/User-Defined Base: '\
02801                     %item.getItemTrace()
02802 
02803             if sc.content.isList() is True:
02804                 raise Wsdl2PythonError, \
02805                       'iction base in subtypes: %s'\
02806                       %sc.getItemTrace()
02807 
02808             if sc.content.isUnion() is True:
02809                 raise Wsdl2PythonError, \
02810                       'could not get restriction base in subtypes: %s'\
02811                       %sc.getItemTrace()
02812 
02813             return
02814 
02815         raise Wsdl2PythonError, 'No Restriction @base/simpleType: %s' %tp.getItemTrace()
02816 
02817     def _setContent(self):
02818 
02819         definition = [
02820             '%sclass %s(%s, TypeDefinition):' %(ID1, self.getClassName(), 
02821                          self.sKlass),
02822             '%s%s' % (ID2, self.schemaTag()),
02823             '%s%s' % (ID2, self.typeTag()),
02824             '%s%s' % (ID2, self.pnameConstructor()),
02825         ]
02826         if self.getPythonType() is None:
02827             definition.append('%s%s.__init__(self, pname, **kw)' %(ID3,
02828                                self.sKlass))
02829         else:
02830             definition.append('%s%s.__init__(self, pname, pyclass=None, **kw)' \
02831                                %(ID3, self.sKlass,))
02832           
02833             # pyclass class definition
02834             definition += self.getPyClassDefinition()
02835                 
02836             # set pyclass
02837             kw = KW.copy()
02838             kw['pyclass'] = self.getPyClass()
02839             definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw)    
02840 
02841         self.writeArray(definition)
02842 
02843 
02844 class ComplexTypeSimpleContentContainer(SimpleTypeContainer, AttributeMixIn):
02845     '''Represents a ComplexType with simpleContent.
02846     '''
02847     type = DEF
02848     logger = _GetLogger("ComplexTypeSimpleContentContainer")
02849 
02850     def setUp(self, tp):
02851         '''tp -- complexType/simpleContent/[Exention,Restriction]
02852         '''
02853         self._item = tp
02854         
02855         assert tp.isComplex() is True and tp.content.isSimple() is True,\
02856             'expecting complexType/simpleContent not: %s' %tp.content.getItemTrace()
02857 
02858         simple = tp.content
02859         dv = simple.content
02860         assert dv.isExtension() is True or dv.isRestriction() is True,\
02861             'expecting complexType/simpleContent/[Extension,Restriction] not: %s' \
02862             %tp.content.getItemTrace()
02863 
02864         self.name = tp.getAttribute('name')
02865         self.ns = tp.getTargetNamespace()
02866         # TODO: Why is this being set?
02867         self.content.attributeContent = dv.getAttributeContent()
02868         
02869         base = dv.getAttribute('base')
02870         if base is not None:
02871             self.sKlass = BTI.get_typeclass( base[1], base[0] )
02872             if not self.sKlass:
02873                 self.sKlass,self.sKlassNS = base[1], base[0]
02874                 
02875             self.attrComponents = self._setAttributes(
02876                                       self.content.attributeContent
02877                                       )
02878             return
02879 
02880         raise Wsdl2PythonError,\
02881             'simple content derivation bad base attribute: ' %tp.getItemTrace()
02882 
02883     def _setContent(self):
02884         # TODO: Add derivation logic to constructors. 
02885         if type(self.sKlass) in (types.ClassType, type):
02886             definition = [
02887                 '%sclass %s(%s, TypeDefinition):' \
02888                 % (ID1, self.getClassName(), self.sKlass),
02889                 '%s# ComplexType/SimpleContent derivation of built-in type' %ID2,
02890                 '%s%s' % (ID2, self.schemaTag()),
02891                 '%s%s' % (ID2, self.typeTag()),
02892                 '%s%s' % (ID2, self.pnameConstructor()),
02893                 '%sif getattr(self, "attribute_typecode_dict", None) is None: %s = {}' %(
02894                     ID3, self.attribute_typecode),
02895                 ]
02896     
02897             for l in self.attrComponents: 
02898                 definition.append('%s%s'%(ID3, l))
02899 
02900             definition.append('%s%s.__init__(self, pname, **kw)' %(ID3, self.sKlass))
02901             if self.getPythonType() is not None:
02902                 definition += self.getPyClassDefinition()
02903                 kw = KW.copy()
02904                 kw['pyclass'] = self.getPyClass()
02905                 definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw)    
02906 
02907             self.writeArray(definition)
02908             return
02909         
02910         definition = [
02911             '%sclass %s(TypeDefinition):' % (ID1, self.getClassName()),
02912             '%s# ComplexType/SimpleContent derivation of user-defined type' %ID2,
02913             '%s%s' % (ID2, self.schemaTag()),
02914             '%s%s' % (ID2, self.typeTag()),
02915             '%s%s' % (ID2, self.pnameConstructor()),
02916             '%s%s' % (ID3, self.nsuriLogic()),
02917             '%s'   % self.getBasesLogic(ID3),
02918             '%sif getattr(self, "attribute_typecode_dict", None) is None: %s = {}' %(
02919                 ID3, self.attribute_typecode),
02920             ]
02921 
02922         for l in self.attrComponents:
02923             definition.append('%s%s'%(ID3, l))
02924 
02925         definition.append('%s%s.%s.__init__(self, pname, **kw)' %(
02926             ID3, NAD.getAlias(self.sKlassNS), type_class_name(self.sKlass)))
02927 
02928         self.writeArray(definition)
02929 
02930     def getPyClassDefinition(self):
02931         definition = []
02932         pt = self.getPythonType()
02933         if pt is not None:
02934             definition.append('%sclass %s(%s):' %(ID3,self.getPyClass(),pt))
02935             if self.metaclass is not None:
02936                 definition.append('%s__metaclass__ = %s' %(ID4, self.metaclass))
02937 
02938             definition.append('%stypecode = self' %ID4)
02939         return definition
02940 
02941 
02942 
02943 
02944 
02945 class UnionContainer(SimpleTypeContainer):
02946     '''SimpleType Union
02947     '''
02948     type = DEF
02949     logger = _GetLogger("UnionContainer")
02950 
02951     def __init__(self):
02952         SimpleTypeContainer.__init__(self)
02953         self.memberTypes = None
02954 
02955     def setUp(self, tp):
02956         self._item = tp
02957         
02958         if tp.content.isUnion() is False:
02959             raise ContainerError, 'content must be a Union: %s' %tp.getItemTrace()
02960         self.name = tp.getAttribute('name')
02961         self.ns = tp.getTargetNamespace()
02962         self.sKlass = 'ZSI.TC.Union'
02963         self.memberTypes = tp.content.getAttribute('memberTypes')
02964 
02965     def _setContent(self):
02966         definition = [
02967             '%sclass %s(%s, TypeDefinition):' \
02968             % (ID1, self.getClassName(), self.sKlass),
02969             '%smemberTypes = %s' % (ID2, self.memberTypes),
02970             '%s%s' % (ID2, self.schemaTag()),
02971             '%s%s' % (ID2, self.typeTag()),
02972             '%s%s' % (ID2, self.pnameConstructor()),
02973             '%s%s' % (ID3, self.pnameConstructor(self.sKlass)),
02974             ]
02975 
02976         # TODO: Union pyclass is None
02977         self.writeArray(definition)
02978 
02979 
02980 class ListContainer(SimpleTypeContainer):
02981     '''SimpleType List
02982     '''
02983     type = DEF
02984     logger = _GetLogger("ListContainer")
02985 
02986     def setUp(self, tp):
02987         self._item = tp
02988         
02989         if tp.content.isList() is False:
02990             raise ContainerError, 'content must be a List: %s' %tp.getItemTrace()
02991         self.name = tp.getAttribute('name')
02992         self.ns = tp.getTargetNamespace()
02993         self.sKlass = 'ZSI.TC.List'
02994         self.itemType = tp.content.getAttribute('itemType')
02995 
02996     def _setContent(self):
02997         definition = [
02998             '%sclass %s(%s, TypeDefinition):' \
02999             % (ID1, self.getClassName(), self.sKlass),
03000             '%sitemType = %s' % (ID2, self.itemType),
03001             '%s%s' % (ID2, self.schemaTag()),
03002             '%s%s' % (ID2, self.typeTag()),
03003             '%s%s' % (ID2, self.pnameConstructor()),
03004             '%s%s' % (ID3, self.pnameConstructor(self.sKlass)),
03005             ]
03006         self.writeArray(definition)
03007 
03008 

Generated on Wed Oct 20 2010 11:12:15 for APBS by  doxygen 1.7.2