home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / fnb101.zip / Lib / site-packages / Fnorb / compiler / SkelGenerator.py < prev    next >
Text File  |  1999-06-28  |  14KB  |  410 lines

  1. #!/usr/bin/env python
  2. #############################################################################
  3. # Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999
  4. # All Rights Reserved.
  5. #
  6. # The software contained on this media is the property of the DSTC Pty
  7. # Ltd.  Use of this software is strictly in accordance with the
  8. # license agreement in the accompanying LICENSE.HTML file.  If your
  9. # distribution of this software does not contain a LICENSE.HTML file
  10. # then you have no rights to use this software in any manner and
  11. # should contact DSTC at the address below to determine an appropriate
  12. # licensing arrangement.
  13. #      DSTC Pty Ltd
  14. #      Level 7, GP South
  15. #      Staff House Road
  16. #      University of Queensland
  17. #      St Lucia, 4072
  18. #      Australia
  19. #      Tel: +61 7 3365 4310
  20. #      Fax: +61 7 3365 4311
  21. #      Email: enquiries@dstc.edu.au
  22. # This software is being provided "AS IS" without warranty of any
  23. # kind.  In no event shall DSTC Pty Ltd be liable for damage of any
  24. # kind arising out of or in connection with the use or performance of
  25. # this software.
  26. #
  27. # Project:      Fnorb
  28. # File:         $Source: /units/arch/src/Fnorb/compiler/RCS/SkelGenerator.py,v $
  29. # Version:      @(#)$RCSfile: SkelGenerator.py,v $ $Revision: 1.7 $
  30. #
  31. #############################################################################
  32. """ Python skeleton generator for CORBA IDL. """
  33.  
  34.  
  35. # Standard/built-in modules.
  36. import string
  37.  
  38. # Fnorb modules.
  39. from Fnorb.orb import CORBA, Util
  40.  
  41. # Compiler modules.
  42. import CodeGenerator
  43.  
  44.  
  45. # Prefix for skeleton methods,
  46. SKEL_PREFIX = '_skel_'
  47.  
  48.  
  49. class SkelGenerator(CodeGenerator.CodeGenerator):
  50.     """ Python skeleton generator for CORBA IDL. """
  51.  
  52.     #########################################################################
  53.     # CodeGenerator protected interface.
  54.     #########################################################################
  55.  
  56.     def _generate_attribute(self, context, file, ifr_object, indent):
  57.     """ Generate Python code for an IDL attribute. """
  58.  
  59.     # Get the description of the attribute.
  60.     description = ifr_object.describe()
  61.     attribute_desc = description.value.value()
  62.  
  63.         #####################################################################
  64.     # Accessor.
  65.         #####################################################################
  66.  
  67.     # Method header.
  68.     file.write(self._indent(indent))
  69.     file.write('def %s_get_%s' % (SKEL_PREFIX, attribute_desc.name))
  70.     file.write('(self, server_request):\n')
  71.  
  72.     # Indent.
  73.     indent = indent + 1
  74.  
  75.     # Documentation string.
  76.     file.write(self._indent(indent))
  77.     file.write('""" Attribute: %s """\n\n' % attribute_desc.id)
  78.  
  79.     # Create the output typecode.
  80.     file.write(self._indent(indent))
  81.     file.write('# Typecode for the attribute value.\n')
  82.     file.write(self._indent(indent))
  83.     file.write('outputs = []\n')
  84.     file.write(self._indent(indent))
  85.     file.write('outputs.append(')
  86.     file.write(self._get_typecode(attribute_desc.type))
  87.     file.write(')\n\n')
  88.  
  89.     # Boiler plate.
  90.     file.write(self._indent(indent))
  91.     file.write('# Initialise the server request object.\n')
  92.     file.write(self._indent(indent))
  93.     file.write('server_request.initialise([], outputs, [])\n\n')
  94.  
  95.     # Invoke the operation on the implementation.
  96.     file.write(self._indent(indent))
  97.     file.write('# Invoke the implementation.\n')
  98.     file.write(self._indent(indent))
  99.     file.write('results = self._get_%s()\n\n' % attribute_desc.name)
  100.  
  101.     file.write(self._indent(indent))
  102.     file.write('# Create the reply.\n')
  103.     file.write(self._indent(indent))
  104.     file.write('server_request.results(results)\n\n')
  105.  
  106.     file.write(self._indent(indent))
  107.     file.write('return\n\n')
  108.  
  109.     # Outdent.
  110.     indent = indent - 1
  111.  
  112.         #####################################################################
  113.     # Modifier (unless the attribute is read only ;^).
  114.         #####################################################################
  115.  
  116.     if attribute_desc.mode != CORBA.ATTR_READONLY:
  117.         # Method header.
  118.         file.write(self._indent(indent))
  119.         file.write('def %s_set_%s' % (SKEL_PREFIX, attribute_desc.name))
  120.         file.write('(self, server_request):\n')
  121.  
  122.         # Indent.
  123.         indent = indent + 1
  124.  
  125.         # Documentation string.
  126.         file.write(self._indent(indent))
  127.         file.write('""" Attribute: %s """\n\n' % attribute_desc.id)
  128.  
  129.         # Create the input typecode.
  130.         file.write(self._indent(indent))
  131.         file.write("# Typecode for the attribute value.\n")
  132.         file.write(self._indent(indent))
  133.         file.write('inputs = []\n')
  134.  
  135.         file.write(self._indent(indent))
  136.         file.write('inputs.append(')
  137.         file.write(self._get_typecode(attribute_desc.type))
  138.         file.write(')\n\n')
  139.  
  140.         # Boiler plate.
  141.         file.write(self._indent(indent))
  142.         file.write('# Initialise the server request object.\n')
  143.         file.write(self._indent(indent))
  144.         file.write('server_request.initialise(inputs, [], [])\n\n')
  145.  
  146.         # Unmarshal the parameter.
  147.         file.write(self._indent(indent))
  148.         file.write('# Unmarshal the attribute value.\n')
  149.         file.write(self._indent(indent))
  150.         file.write('value = server_request.arguments()[0]\n\n')
  151.  
  152.         # Invoke the operation on the implementation.
  153.         file.write(self._indent(indent))
  154.         file.write('# Invoke the implementation.\n')
  155.         file.write(self._indent(indent))
  156.         file.write('results = self._set_%s(value)' % attribute_desc.name)
  157.         file.write('\n\n')
  158.  
  159.         file.write(self._indent(indent))
  160.         file.write('# Create the reply.\n')
  161.         file.write(self._indent(indent))
  162.         file.write('server_request.results(results)\n\n')
  163.  
  164.         file.write(self._indent(indent))
  165.         file.write('return\n\n')
  166.  
  167.     return
  168.  
  169.     def _generate_interface(self, context, file, ifr_object, indent):
  170.     """ Generate Python code to represent an IDL interface. """
  171.  
  172.     # Get the description of the interface.
  173.     description = ifr_object.describe()
  174.     interface_desc = description.value.value()
  175.  
  176.     # Make sure that the interface name is not a Python keyword.
  177.     py_interface_name = Util.python_name(interface_desc.name)
  178.  
  179.     # Get the scoped name of the interface.
  180.     interface_scoped_name =Util.ScopedName(ifr_object._get_absolute_name())
  181.  
  182.     # Fix up any clashes with Python keywords.
  183.     interface_scoped_name.pythonise()
  184.  
  185.     # Base interfaces.
  186.     bases = ['Fnorb.orb.CORBA.Object_skel']
  187.     packages = []
  188.  
  189.     for base in ifr_object._get_base_interfaces():
  190.         # Get the scoped name of the base interface.
  191.         base_scoped_name = Util.ScopedName(base._get_absolute_name())
  192.  
  193.         # Fix up any clashes with Python keywords.
  194.         base_scoped_name.pythonise()
  195.  
  196.         # If the base interface is defined in a different IDL module (ie.
  197.         # in a different Python package).
  198.         if base_scoped_name[:-1] != interface_scoped_name[:-1]:
  199.         # If the base interface is defined at the global scope then
  200.         # add the name of global package.
  201.         if len(base_scoped_name) == 1:
  202.             base_scoped_name.insert(0, context.globals())
  203.  
  204.         # Use the full scoped name in the Python class header.
  205.         base_python_name = base_scoped_name.join('_skel.') + '_skel'
  206.  
  207.         # Add the Python package that the base interface is defined in
  208.         # to the list of packages to import.
  209.         packages.append(base_scoped_name[:-1].join('_skel.') + '_skel')
  210.  
  211.         # Otherwise, the base interface is defined in the same IDL module
  212.         # as the interface itself, so we just use the base interface name
  213.         # in the Python class header.
  214.         else:
  215.         base_python_name = base_scoped_name[-1] + '_skel'
  216.  
  217.         # Add to the list of base classes for the class header.
  218.         bases.append(base_python_name)
  219.  
  220.     # Import base interface packages.
  221.     if len(packages) > 0:
  222.         file.write(self._indent(indent))
  223.         file.write('# Import base interface packages.\n')
  224.         for package in packages:
  225.         file.write(self._indent(indent))
  226.         file.write(context.create_import_statement(package))
  227.         file.write('\n')
  228.  
  229.         file.write('\n')
  230.         
  231.     # Class header.
  232.     file.write(self._indent(indent))
  233.     file.write('class %s_skel' % py_interface_name)
  234.     file.write('(%s):\n' % string.join(bases, ', '))
  235.  
  236.     # Indent.
  237.     indent = indent + 1
  238.  
  239.     # Documentation string.
  240.     file.write(self._indent(indent))
  241.     file.write('""" Interface: %s """\n\n' % interface_desc.id)
  242.  
  243.     # Repository id attribute.
  244.     file.write(self._indent(indent))
  245.     file.write('_FNORB_ID = "%s"\n\n' % interface_desc.id)
  246.  
  247.     # Generate code for every definition contained in the interface
  248.     # (ignoring inherited definitions).
  249.     contents = ifr_object.contents(CORBA.dk_all, 1)
  250.     if len(contents) > 0:
  251.         for contained in contents:
  252.         self.generate(context, file, contained, indent)
  253.  
  254.     # Empty interface.
  255.     else:
  256.         file.write(self._indent(indent))
  257.         file.write('pass\n\n')
  258.  
  259.     return
  260.  
  261.     def _generate_module(self, context, file, ifr_object, indent):
  262.     """ Generate Python code to represent an IDL module. """
  263.  
  264.     # Get the description of the module.
  265.     description = ifr_object.describe()
  266.     module_desc = description.value.value()
  267.  
  268.     # Make sure that the module name is not a Python keyword.
  269.     py_module_name = Util.python_name(module_desc.name)
  270.  
  271.     # Get the scoped name of the module.
  272.     scoped_name = Util.ScopedName(ifr_object._get_absolute_name())
  273.  
  274.     # Fix up any clashes with Python keywords.
  275.     scoped_name.pythonise()
  276.  
  277.     # Make the 'skeleton' package name (by appending '_skel' to each
  278.     # component of the scoped name).
  279.     package = Util.ScopedName(scoped_name.join('_skel::') + '_skel')
  280.  
  281.     # Create a Python package to represent the IDL module.
  282.     file = self._create_package(context, package.join('/'), module_desc.id)
  283.     
  284.      # Generate code for every definition contained in the module.
  285.      for contained in ifr_object.contents(CORBA.dk_all, 0):
  286.          self.generate(context, file, contained, 0)
  287.  
  288.      # End of the package.
  289.      self._end_package(file, indent)
  290.  
  291.     # All done!
  292.     file.close()
  293.  
  294.     return
  295.  
  296.     def _generate_operation(self, context, file, ifr_object, indent):
  297.     """ Generate Python code to represent an IDL operation. """
  298.  
  299.     # Get the description of the operation.
  300.     description = ifr_object.describe()
  301.     operation_desc = description.value.value()
  302.  
  303.     # Make sure that the operation name is not a Python keyword.
  304.     py_operation_name = Util.python_name(operation_desc.name)
  305.  
  306.     # Method header.
  307.     file.write(self._indent(indent))
  308.     file.write('def %s%s' % (SKEL_PREFIX, operation_desc.name))
  309.     file.write('(self, server_request):\n')
  310.  
  311.     # Indent.
  312.     indent = indent + 1
  313.  
  314.     # Documentation string.
  315.     file.write(self._indent(indent))
  316.     file.write('""" Operation: %s """\n\n' % operation_desc.id)
  317.  
  318.     # Create the input typecodes.
  319.     file.write(self._indent(indent))
  320.     file.write("# Typecodes for 'in' and 'inout' parameters.\n")
  321.     file.write(self._indent(indent))
  322.     file.write('inputs = []\n')
  323.  
  324.     no_of_inputs = 0
  325.     for p in operation_desc.parameters:
  326.         if p.mode == CORBA.PARAM_IN or p.mode == CORBA.PARAM_INOUT:
  327.         file.write(self._indent(indent))
  328.         file.write('inputs.append(%s)' % self._get_typecode(p.type))
  329.         file.write('\n')
  330.         no_of_inputs = no_of_inputs + 1
  331.  
  332.     file.write('\n')
  333.         
  334.     # Create the output typecodes.
  335.     file.write(self._indent(indent))
  336.     file.write("# Typecodes for the result, 'inout' and 'out' parameters.")
  337.     file.write('\n')
  338.     file.write(self._indent(indent))
  339.     file.write('outputs = []\n')
  340.  
  341.     # The result.
  342.     if operation_desc.result.kind() != CORBA.tk_void:
  343.         file.write(self._indent(indent))
  344.         file.write('outputs.append(')
  345.         file.write(self._get_typecode(operation_desc.result))
  346.         file.write(')\n')
  347.  
  348.     # 'inout' and 'out' parameters.
  349.     for p in operation_desc.parameters:
  350.         if p.mode == CORBA.PARAM_INOUT or p.mode == CORBA.PARAM_OUT:
  351.         file.write(self._indent(indent))
  352.         file.write('outputs.append(%s)' % self._get_typecode(p.type))
  353.         file.write('\n')
  354.  
  355.     file.write('\n')
  356.  
  357.     # Create the exception typecodes.
  358.     file.write(self._indent(indent))
  359.     file.write("# Typecodes for user exceptions.\n")
  360.     file.write(self._indent(indent))
  361.     file.write('exceptions = []\n')
  362.  
  363.     for ex in operation_desc.exceptions:
  364.         file.write(self._indent(indent))
  365.         file.write('exceptions.append(Fnorb.orb.CORBA.typecode("%s"))\n' \
  366.                % ex.id)
  367.  
  368.     file.write('\n')
  369.  
  370.     # Boiler plate.
  371.     file.write(self._indent(indent))
  372.     file.write('# Initialise the server request object.\n')
  373.     file.write(self._indent(indent))
  374.     file.write('server_request.initialise(inputs, outputs, exceptions)\n')
  375.     file.write('\n')
  376.  
  377.     # Unmarshal all 'in' and 'inout' parameters.
  378.     if no_of_inputs > 0:
  379.         file.write(self._indent(indent))
  380.         file.write('# Unmarshal the arguments to the request.\n')
  381.         file.write(self._indent(indent))
  382.         file.write('arguments = server_request.arguments()\n\n')
  383.  
  384.     else:
  385.         file.write(self._indent(indent))
  386.         file.write('# This operation has no arguments.\n')
  387.         file.write(self._indent(indent))
  388.         file.write('arguments = ()\n\n')
  389.  
  390.     # Invoke the operation on the implementation.
  391.       file.write(self._indent(indent))
  392.     file.write('# Invoke the implementation.\n')
  393.     file.write(self._indent(indent))
  394.     file.write('results = apply(self.%s, arguments)' % py_operation_name)
  395.     file.write('\n\n')
  396.  
  397.     file.write(self._indent(indent))
  398.     file.write('# Create the reply.\n')
  399.     file.write(self._indent(indent))
  400.     file.write('server_request.results(results)\n\n')
  401.  
  402.     file.write(self._indent(indent))
  403.     file.write('return\n\n')
  404.  
  405.     return
  406.  
  407. #############################################################################
  408.