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

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

00001 ############################################################################
00002 # Monte M. Goode, LBNL
00003 # See LBNLCopyright for copyright notice!
00004 ###########################################################################
00005 
00006 # main generator engine for new generation generator
00007 
00008 # $Id: wsdl2python.py 1402 2007-07-06 22:51:32Z boverhof $
00009 
00010 import os, sys, warnings
00011 from ZSI import _get_idstr
00012 from ZSI.wstools.logging import getLogger as _GetLogger
00013 from ZSI.wstools import WSDLTools
00014 from ZSI.wstools.WSDLTools import SoapAddressBinding,\
00015     SoapBodyBinding, SoapBinding,MimeContentBinding,\
00016     HttpUrlEncodedBinding
00017 from ZSI.wstools.XMLSchema import SchemaReader, ElementDeclaration, SchemaError
00018 from ZSI.typeinterpreter import BaseTypeInterpreter
00019 from ZSI.generate import WsdlGeneratorError, Wsdl2PythonError
00020 from containers import *
00021 from ZSI.generate import utility
00022 from ZSI.generate.utility import NamespaceAliasDict as NAD
00023 from ZSI.generate.utility import GetModuleBaseNameFromWSDL
00024 
00025 """
00026 classes:
00027     WriteServiceModule 
00028     -- composes/writes out client stubs and types module.
00029 
00030     ServiceDescription
00031     -- represents a single WSDL service.
00032 
00033     MessageWriter
00034     -- represents a single WSDL Message and associated bindings
00035     of the port/binding.
00036 
00037     SchemaDescription 
00038     -- generates classes for defs and decs in the schema instance.
00039 
00040     TypeWriter
00041     -- represents a type definition.
00042 
00043     ElementWriter
00044     -- represents a element declaration.
00045 
00046 """
00047 
00048 class WriteServiceModule:
00049     """top level driver class invoked by wsd2py
00050     class variables:
00051         client_module_suffix -- suffix of client module.
00052         types_module_suffix -- suffix of types module.
00053     """
00054     client_module_suffix = '_client'
00055     messages_module_suffix = '_messages'
00056     types_module_suffix = '_types'
00057     logger = _GetLogger("WriteServiceModule")
00058     
00059     def __init__(self, wsdl, addressing=False, notification=False,
00060                  do_extended=False, extPyClasses=None, configParser = None):
00061         self._wsdl = wsdl
00062         self._addressing = addressing
00063         self._notification = notification
00064         self._configParser = configParser
00065         self.usedNamespaces = None
00066         self.services = []
00067         self.client_module_path = None
00068         self.types_module_name = None
00069         self.types_module_path = None
00070         self.messages_module_path = None # used in extended generation
00071         self.do_extended = do_extended
00072         self.extPyClasses = extPyClasses
00073        
00074     def getClientModuleName(self):
00075         """client module name.
00076         """
00077         name = GetModuleBaseNameFromWSDL(self._wsdl)
00078         if not name:
00079             raise WsdlGeneratorError, 'could not determine a service name'
00080         
00081         if self.client_module_suffix is None:
00082             return name
00083 
00084         return '%s%s' %(name, self.client_module_suffix)
00085 
00086 #    def getMessagesModuleName(self):
00087 #        name = GetModuleBaseNameFromWSDL(self._wsdl)
00088 #        if not name:
00089 #            raise WsdlGeneratorError, 'could not determine a service name'
00090 #        
00091 #        if self.messages_module_suffix is None:
00092 #            return name
00093 #
00094 #        if len(self.messages_module_suffix) == 0:
00095 #            return self.getClientModuleName()
00096 #
00097 #        return '%s%s' %(name, self.messages_module_suffix)
00098 
00099     def setTypesModuleName(self, name):
00100         self.types_module_name = name
00101 
00102     def getTypesModuleName(self):
00103         """types module name.
00104         """
00105         if self.types_module_name is not None:
00106             return self.types_module_name
00107 
00108         name = GetModuleBaseNameFromWSDL(self._wsdl)
00109         if not name:
00110             raise WsdlGeneratorError, 'could not determine a service name'
00111         
00112         if self.types_module_suffix is None:
00113             return name
00114 
00115         return '%s%s' %(name, self.types_module_suffix)
00116 
00117     def setClientModulePath(self, path):
00118         """setup module path to where client module before calling fromWsdl.
00119         module path to types module eg. MyApp.client
00120         """
00121         self.client_module_path = path
00122 
00123     def getTypesModulePath(self):
00124         """module path to types module eg. MyApp.types
00125         """
00126         return self.types_module_path 
00127 
00128 #    def getMessagesModulePath(self):
00129 #        '''module path to messages module
00130 #           same as types path
00131 #        '''
00132 #        return self.messages_module_path 
00133 
00134     def setTypesModulePath(self, path):
00135         """setup module path to where service module before calling fromWsdl.
00136         module path to types module eg. MyApp.types
00137         """
00138         self.types_module_path = path
00139 
00140 #    def setMessagesModulePath(self, path):
00141 #        """setup module path to where message module before calling fromWsdl.
00142 #        module path to types module eg. MyApp.types
00143 #        """
00144 #        self.messages_module_path = path
00145 
00146     def gatherNamespaces(self):
00147         '''This method must execute once..  Grab all schemas
00148         representing each targetNamespace.
00149         '''
00150         if self.usedNamespaces is not None:
00151             return
00152 
00153         self.logger.debug('gatherNamespaces')
00154         self.usedNamespaces = {}
00155             
00156         # Add all schemas defined in wsdl
00157         # to used namespace and to the Alias dict
00158         for schema in self._wsdl.types.values():
00159             tns = schema.getTargetNamespace()
00160             self.logger.debug('Register schema(%s) -- TNS(%s)'\
00161                 %(_get_idstr(schema), tns),)
00162             if self.usedNamespaces.has_key(tns) is False:
00163                 self.usedNamespaces[tns] = []
00164             self.usedNamespaces[tns].append(schema)
00165             NAD.add(tns)
00166             
00167         # Add all xsd:import schema instances
00168         # to used namespace and to the Alias dict
00169         for k,v in SchemaReader.namespaceToSchema.items():
00170             self.logger.debug('Register schema(%s) -- TNS(%s)'\
00171                 %(_get_idstr(v), k),)
00172             if self.usedNamespaces.has_key(k) is False:
00173                 self.usedNamespaces[k] = []
00174             self.usedNamespaces[k].append(v)
00175             NAD.add(k)
00176             
00177     def writeClient(self, fd, sdClass=None, **kw):
00178         """write out client module to file descriptor.
00179         Parameters and Keywords arguments:
00180             fd -- file descriptor
00181             sdClass -- service description class name
00182             imports -- list of imports
00183             readerclass -- class name of ParsedSoap reader
00184             writerclass -- class name of SoapWriter writer
00185         """
00186         sdClass = sdClass or ServiceDescription
00187         assert issubclass(sdClass, ServiceDescription), \
00188             'parameter sdClass must subclass ServiceDescription'
00189 
00190 #        header = '%s \n# %s.py \n# generated by %s\n%s\n'\
00191 #                  %('#'*50, self.getClientModuleName(), self.__module__, '#'*50)
00192         print >>fd, '#'*50
00193         print >>fd, '# file: %s.py' %self.getClientModuleName()
00194         print >>fd, '# '
00195         print >>fd, '# client stubs generated by "%s"' %self.__class__
00196         print >>fd, '#     %s' %' '.join(sys.argv)
00197         print >>fd, '# '
00198         print >>fd, '#'*50
00199 
00200         self.services = []
00201         for service in self._wsdl.services:
00202             sd = sdClass(self._addressing, do_extended=self.do_extended, 
00203                          wsdl=self._wsdl)
00204             if len(self._wsdl.types) > 0:
00205                 sd.setTypesModuleName(self.getTypesModuleName(), 
00206                                       self.getTypesModulePath())
00207 #                sd.setMessagesModuleName(self.getMessagesModuleName(), 
00208 #                                         self.getMessagesModulePath())
00209 
00210             self.gatherNamespaces()
00211             sd.fromWsdl(service, **kw)
00212             sd.write(fd)
00213             self.services.append(sd)
00214 
00215     def writeTypes(self, fd):
00216         """write out types module to file descriptor.
00217         """
00218         print >>fd, '#'*50
00219         print >>fd, '# file: %s.py' %self.getTypesModuleName()
00220         print >>fd, '#'
00221         print >>fd, '# schema types generated by "%s"' %self.__class__
00222         print >>fd, '#    %s' %' '.join(sys.argv)
00223         print >>fd, '#'
00224         print >>fd, '#'*50
00225                   
00226         print >>fd, TypesHeaderContainer()
00227         self.gatherNamespaces()
00228         for l in self.usedNamespaces.values():
00229             sd = SchemaDescription(do_extended=self.do_extended, 
00230                                    extPyClasses=self.extPyClasses)
00231             for schema in l:
00232                 sd.fromSchema(schema)
00233             sd.write(fd)
00234 
00235             
00236 class ServiceDescription:
00237     """client interface - locator, port, etc classes"""
00238     separate_messages = False
00239     logger = _GetLogger("ServiceDescription")
00240 
00241     def __init__(self, addressing=False, do_extended=False, wsdl=None):
00242         self.typesModuleName = None
00243         self.messagesModuleName = None
00244         self.wsAddressing = addressing
00245         self.imports   = ServiceHeaderContainer()
00246         self.messagesImports   = ServiceHeaderContainer()
00247         self.locator   = ServiceLocatorContainer()
00248         self.bindings   = []
00249         self.messages  = []
00250         self.do_extended=do_extended
00251         self._wsdl = wsdl # None unless do_extended == True
00252 
00253     def setTypesModuleName(self, name, modulePath=None):
00254         """The types module to be imported.
00255         Parameters
00256         name -- name of types module
00257         modulePath -- optional path where module is located.
00258         """
00259         self.typesModuleName = '%s' %name
00260         if modulePath is not None:
00261             self.typesModuleName = '%s.%s' %(modulePath,name)
00262 
00263 #    def setMessagesModuleName(self, name, modulePath=None):
00264 #        '''The types module to be imported.
00265 #        Parameters
00266 #        name -- name of types module
00267 #        modulePath -- optional path where module is located.
00268 #        '''
00269 #        self.messagesModuleName = '%s' %name
00270 #        if modulePath is not None:
00271 #            self.messagesModuleName = '%s.%s' %(modulePath,name)
00272 
00273     def fromWsdl(self, service, **kw):
00274         self.imports.setTypesModuleName(self.typesModuleName)
00275 #        if self.separate_messages:
00276 #            self.messagesImports.setMessagesModuleName(self.messagesModuleName)
00277         self.imports.appendImport(kw.get('imports', []))
00278 
00279         self.locator.setUp(service)
00280 
00281         try:
00282             bindings =  map(lambda p: p.binding, service.ports)
00283         except:
00284             warnings.warn('not all ports have binding declared,')
00285             bindings = ()
00286 
00287         for port in service.ports:
00288             if port.binding not in bindings:
00289                 continue
00290             while port.binding in bindings: 
00291                 bindings.remove(port.binding)
00292 
00293             desc = BindingDescription(useWSA=self.wsAddressing, 
00294                                       do_extended=self.do_extended, 
00295                                       wsdl=self._wsdl)
00296             try:
00297                 desc.setUp(port.getBinding())
00298             except Wsdl2PythonError, ex:
00299                 self.logger.warning('Skipping port(%s)' %port.name)
00300                 if len(ex.args): 
00301                     self.logger.warning(ex.args[0])
00302                 continue
00303    
00304             desc.setReaderClass(kw.get('readerclass'))
00305             desc.setWriterClass(kw.get('writerclass'))
00306             for soc in desc.operations:
00307                 if soc.hasInput() is True:
00308                     mw = MessageWriter(do_extended=self.do_extended)
00309                     mw.setUp(soc, port, input=True)
00310                     self.messages.append(mw)
00311 
00312                     if soc.hasOutput() is True:
00313                         mw = MessageWriter(do_extended=self.do_extended)
00314                         mw.setUp(soc, port, input=False)
00315                         self.messages.append(mw)
00316 
00317             self.bindings.append(desc)
00318 
00319  
00320     def write(self, fd, msg_fd=None):
00321         """write out module to file descriptor.
00322         fd -- file descriptor to write out service description.
00323         msg_fd -- optional file descriptor for messages module.
00324         """
00325 #        if msg_fd != None:
00326 #            print >>fd, self.messagesImports
00327 #            print >>msg_fd, self.imports
00328 #        else:
00329         print >>fd, self.imports
00330             
00331         print >>fd, self.locator
00332         for m in self.bindings:
00333             print >>fd, m
00334 
00335 #        if msg_fd != None:
00336 #            for m in self.messages:
00337 #                print >>msg_fd, m
00338 #        else:
00339         for m in self.messages:
00340             print >>fd, m
00341 
00342 
00343 class MessageWriter:
00344     logger = _GetLogger("MessageWriter")
00345 
00346     def __init__(self, do_extended=False):
00347         """Representation of a WSDL Message and associated WSDL Binding.
00348         operation --
00349         boperation --
00350         input --
00351         rpc --
00352         literal --
00353         simple --
00354         """
00355         self.content = None
00356         self.do_extended = do_extended
00357        
00358     def __str__(self):
00359         if not self.content:
00360             raise Wsdl2PythonError, 'Must call setUp.'
00361         return self.content.getvalue()
00362         
00363     def setUp(self, soc, port, input=False):
00364         assert isinstance(soc, ServiceOperationContainer),\
00365             'expecting a ServiceOperationContainer instance'
00366         assert isinstance(port, WSDLTools.Port),\
00367             'expecting a WSDL.Port instance'
00368 
00369         rpc,literal = soc.isRPC(), soc.isLiteral(input)
00370         kw,klass = {}, None
00371         
00372         if rpc and literal:
00373             klass = ServiceRPCLiteralMessageContainer
00374         elif not rpc and literal:
00375             kw['do_extended'] = self.do_extended
00376             klass = ServiceDocumentLiteralMessageContainer
00377         elif rpc and not literal:
00378             klass = ServiceRPCEncodedMessageContainer
00379         else:
00380             raise WsdlGeneratorError, 'doc/enc not supported.'
00381                                 
00382         self.content = klass(**kw)
00383         self.content.setUp(port, soc, input)
00384 
00385 
00386 class SchemaDescription:
00387     """generates classes for defs and decs in the schema instance.
00388     """
00389     logger = _GetLogger("SchemaDescription")
00390 
00391     def __init__(self, do_extended=False, extPyClasses=None):
00392         self.classHead = NamespaceClassHeaderContainer()
00393         self.classFoot = NamespaceClassFooterContainer()
00394         self.items = []
00395         self.__types = []
00396         self.__elements = []
00397         self.targetNamespace = None
00398         self.do_extended=do_extended
00399         self.extPyClasses = extPyClasses
00400 
00401     def fromSchema(self, schema):
00402         ''' Can be called multiple times, but will not redefine a
00403         previously defined type definition or element declaration.
00404         '''  
00405         ns = schema.getTargetNamespace()
00406         assert self.targetNamespace is None or self.targetNamespace == ns,\
00407             'SchemaDescription instance represents %s, not %s'\
00408             %(self.targetNamespace, ns)
00409 
00410         if self.targetNamespace is None:
00411             self.targetNamespace = ns
00412  
00413         self.classHead.ns = self.classFoot.ns = ns
00414         for item in [t for t in schema.types if t.getAttributeName() not in self.__types]:
00415             self.__types.append(item.getAttributeName())
00416             self.items.append(TypeWriter(do_extended=self.do_extended, extPyClasses=self.extPyClasses))
00417             self.items[-1].fromSchemaItem(item)
00418 
00419         for item in [e for e in schema.elements if e.getAttributeName() not in self.__elements]:
00420             self.__elements.append(item.getAttributeName())
00421             self.items.append(ElementWriter(do_extended=self.do_extended))
00422             self.items[-1].fromSchemaItem(item)
00423 
00424     def getTypes(self):
00425         return self.__types
00426 
00427     def getElements(self):
00428         return self.__elements
00429 
00430     def write(self, fd):
00431         """write out to file descriptor.
00432         """
00433         print >>fd, self.classHead
00434         for t in self.items:
00435             print >>fd, t
00436         print >>fd, self.classFoot
00437 
00438 class SchemaItemWriter:
00439     """contains/generates a single declaration"""
00440     logger = _GetLogger("SchemaItemWriter")
00441 
00442     def __init__(self, do_extended=False, extPyClasses=None):
00443         self.content = None
00444         self.do_extended=do_extended
00445         self.extPyClasses=extPyClasses
00446         
00447     def __str__(self):
00448         '''this appears to set up whatever is in self.content.localElements,
00449         local elements simpleType|complexType.
00450         '''
00451         assert self.content is not None, 'Must call fromSchemaItem to setup.'
00452         return str(self.content)
00453 
00454     def fromSchemaItem(self, item):
00455         raise NotImplementedError, ''
00456 
00457 
00458 class ElementWriter(SchemaItemWriter):
00459     """contains/generates a single declaration"""
00460     logger = _GetLogger("ElementWriter")
00461 
00462     def fromSchemaItem(self, item):
00463         """set up global elements.
00464         """
00465         if item.isElement() is False or item.isLocal() is True:
00466             raise TypeError, 'expecting global element declaration: %s' %item.getItemTrace()
00467 
00468         local = False
00469         qName = item.getAttribute('type')
00470         if not qName:
00471             etp = item.content
00472             local = True
00473         else:
00474             etp = item.getTypeDefinition('type')
00475             
00476         if etp is None:
00477             if local is True: 
00478                 self.content = ElementLocalComplexTypeContainer(do_extended=self.do_extended)
00479             else: 
00480                 self.content = ElementSimpleTypeContainer()
00481         elif etp.isLocal() is False:
00482             self.content = ElementGlobalDefContainer()
00483         elif etp.isSimple() is True: 
00484             self.content = ElementLocalSimpleTypeContainer()
00485         elif etp.isComplex():
00486             self.content = ElementLocalComplexTypeContainer(do_extended=self.do_extended)
00487         else:
00488             raise Wsdl2PythonError, "Unknown element declaration: %s" %item.getItemTrace()
00489 
00490         self.logger.debug('ElementWriter setUp container "%r", Schema Item "%s"' %(
00491             self.content, item.getItemTrace()))
00492         
00493         self.content.setUp(item)
00494 
00495 
00496 class TypeWriter(SchemaItemWriter):
00497     """contains/generates a single definition"""
00498     logger = _GetLogger("TypeWriter")
00499         
00500     def fromSchemaItem(self, item):
00501         if item.isDefinition() is False or item.isLocal() is True:
00502             raise TypeError, \
00503                 'expecting global type definition not: %s' %item.getItemTrace()
00504 
00505         self.content = None
00506         if item.isSimple():
00507             if item.content.isRestriction():
00508                 self.content = RestrictionContainer()
00509             elif item.content.isUnion():
00510                 self.content = UnionContainer()
00511             elif item.content.isList():
00512                 self.content = ListContainer()
00513             else:
00514                 raise Wsdl2PythonError,\
00515                     'unknown simple type definition: %s' %item.getItemTrace()
00516                     
00517             self.content.setUp(item)
00518             return
00519         
00520         if item.isComplex():
00521             kw = {}
00522             if item.content is None or item.content.isModelGroup():
00523                 self.content = \
00524                     ComplexTypeContainer(\
00525                         do_extended=self.do_extended, 
00526                         extPyClasses=self.extPyClasses
00527                         )
00528                 kw['empty'] = item.content is None
00529             elif item.content.isSimple():
00530                     self.content = ComplexTypeSimpleContentContainer()
00531             elif item.content.isComplex():
00532                     self.content = \
00533                         ComplexTypeComplexContentContainer(\
00534                             do_extended=self.do_extended
00535                             )
00536             else:
00537                 raise Wsdl2PythonError,\
00538                     'unknown complex type definition: %s' %item.getItemTrace()
00539 
00540             self.logger.debug('TypeWriter setUp container "%r", Schema Item "%s"' %(
00541                 self.content, item.getItemTrace()))
00542             
00543             try:
00544                 self.content.setUp(item, **kw)
00545             except Exception, ex:
00546                 args = ['Failure in setUp: %s' %item.getItemTrace()]
00547                 args += ex.args
00548                 ex.args = tuple(args)
00549                 raise
00550             
00551             return
00552 
00553         raise TypeError,\
00554             'expecting SimpleType or ComplexType: %s' %item.getItemTrace()
00555 
00556         
00557 

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