home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/env python
- #############################################################################
- # Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999
- # All Rights Reserved.
- #
- # The software contained on this media is the property of the DSTC Pty
- # Ltd. Use of this software is strictly in accordance with the
- # license agreement in the accompanying LICENSE.HTML file. If your
- # distribution of this software does not contain a LICENSE.HTML file
- # then you have no rights to use this software in any manner and
- # should contact DSTC at the address below to determine an appropriate
- # licensing arrangement.
- #
- # DSTC Pty Ltd
- # Level 7, GP South
- # Staff House Road
- # University of Queensland
- # St Lucia, 4072
- # Australia
- # Tel: +61 7 3365 4310
- # Fax: +61 7 3365 4311
- # Email: enquiries@dstc.edu.au
- #
- # This software is being provided "AS IS" without warranty of any
- # kind. In no event shall DSTC Pty Ltd be liable for damage of any
- # kind arising out of or in connection with the use or performance of
- # this software.
- #
- # Project: Fnorb
- # File: $Source: /units/arch/src/Fnorb/compiler/RCS/SkelGenerator.py,v $
- # Version: @(#)$RCSfile: SkelGenerator.py,v $ $Revision: 1.7 $
- #
- #############################################################################
- """ Python skeleton generator for CORBA IDL. """
-
-
- # Standard/built-in modules.
- import string
-
- # Fnorb modules.
- from Fnorb.orb import CORBA, Util
-
- # Compiler modules.
- import CodeGenerator
-
-
- # Prefix for skeleton methods,
- SKEL_PREFIX = '_skel_'
-
-
- class SkelGenerator(CodeGenerator.CodeGenerator):
- """ Python skeleton generator for CORBA IDL. """
-
- #########################################################################
- # CodeGenerator protected interface.
- #########################################################################
-
- def _generate_attribute(self, context, file, ifr_object, indent):
- """ Generate Python code for an IDL attribute. """
-
- # Get the description of the attribute.
- description = ifr_object.describe()
- attribute_desc = description.value.value()
-
- #####################################################################
- # Accessor.
- #####################################################################
-
- # Method header.
- file.write(self._indent(indent))
- file.write('def %s_get_%s' % (SKEL_PREFIX, attribute_desc.name))
- file.write('(self, server_request):\n')
-
- # Indent.
- indent = indent + 1
-
- # Documentation string.
- file.write(self._indent(indent))
- file.write('""" Attribute: %s """\n\n' % attribute_desc.id)
-
- # Create the output typecode.
- file.write(self._indent(indent))
- file.write('# Typecode for the attribute value.\n')
- file.write(self._indent(indent))
- file.write('outputs = []\n')
- file.write(self._indent(indent))
- file.write('outputs.append(')
- file.write(self._get_typecode(attribute_desc.type))
- file.write(')\n\n')
-
- # Boiler plate.
- file.write(self._indent(indent))
- file.write('# Initialise the server request object.\n')
- file.write(self._indent(indent))
- file.write('server_request.initialise([], outputs, [])\n\n')
-
- # Invoke the operation on the implementation.
- file.write(self._indent(indent))
- file.write('# Invoke the implementation.\n')
- file.write(self._indent(indent))
- file.write('results = self._get_%s()\n\n' % attribute_desc.name)
-
- file.write(self._indent(indent))
- file.write('# Create the reply.\n')
- file.write(self._indent(indent))
- file.write('server_request.results(results)\n\n')
-
- file.write(self._indent(indent))
- file.write('return\n\n')
-
- # Outdent.
- indent = indent - 1
-
- #####################################################################
- # Modifier (unless the attribute is read only ;^).
- #####################################################################
-
- if attribute_desc.mode != CORBA.ATTR_READONLY:
- # Method header.
- file.write(self._indent(indent))
- file.write('def %s_set_%s' % (SKEL_PREFIX, attribute_desc.name))
- file.write('(self, server_request):\n')
-
- # Indent.
- indent = indent + 1
-
- # Documentation string.
- file.write(self._indent(indent))
- file.write('""" Attribute: %s """\n\n' % attribute_desc.id)
-
- # Create the input typecode.
- file.write(self._indent(indent))
- file.write("# Typecode for the attribute value.\n")
- file.write(self._indent(indent))
- file.write('inputs = []\n')
-
- file.write(self._indent(indent))
- file.write('inputs.append(')
- file.write(self._get_typecode(attribute_desc.type))
- file.write(')\n\n')
-
- # Boiler plate.
- file.write(self._indent(indent))
- file.write('# Initialise the server request object.\n')
- file.write(self._indent(indent))
- file.write('server_request.initialise(inputs, [], [])\n\n')
-
- # Unmarshal the parameter.
- file.write(self._indent(indent))
- file.write('# Unmarshal the attribute value.\n')
- file.write(self._indent(indent))
- file.write('value = server_request.arguments()[0]\n\n')
-
- # Invoke the operation on the implementation.
- file.write(self._indent(indent))
- file.write('# Invoke the implementation.\n')
- file.write(self._indent(indent))
- file.write('results = self._set_%s(value)' % attribute_desc.name)
- file.write('\n\n')
-
- file.write(self._indent(indent))
- file.write('# Create the reply.\n')
- file.write(self._indent(indent))
- file.write('server_request.results(results)\n\n')
-
- file.write(self._indent(indent))
- file.write('return\n\n')
-
- return
-
- def _generate_interface(self, context, file, ifr_object, indent):
- """ Generate Python code to represent an IDL interface. """
-
- # Get the description of the interface.
- description = ifr_object.describe()
- interface_desc = description.value.value()
-
- # Make sure that the interface name is not a Python keyword.
- py_interface_name = Util.python_name(interface_desc.name)
-
- # Get the scoped name of the interface.
- interface_scoped_name =Util.ScopedName(ifr_object._get_absolute_name())
-
- # Fix up any clashes with Python keywords.
- interface_scoped_name.pythonise()
-
- # Base interfaces.
- bases = ['Fnorb.orb.CORBA.Object_skel']
- packages = []
-
- for base in ifr_object._get_base_interfaces():
- # Get the scoped name of the base interface.
- base_scoped_name = Util.ScopedName(base._get_absolute_name())
-
- # Fix up any clashes with Python keywords.
- base_scoped_name.pythonise()
-
- # If the base interface is defined in a different IDL module (ie.
- # in a different Python package).
- if base_scoped_name[:-1] != interface_scoped_name[:-1]:
- # If the base interface is defined at the global scope then
- # add the name of global package.
- if len(base_scoped_name) == 1:
- base_scoped_name.insert(0, context.globals())
-
- # Use the full scoped name in the Python class header.
- base_python_name = base_scoped_name.join('_skel.') + '_skel'
-
- # Add the Python package that the base interface is defined in
- # to the list of packages to import.
- packages.append(base_scoped_name[:-1].join('_skel.') + '_skel')
-
- # Otherwise, the base interface is defined in the same IDL module
- # as the interface itself, so we just use the base interface name
- # in the Python class header.
- else:
- base_python_name = base_scoped_name[-1] + '_skel'
-
- # Add to the list of base classes for the class header.
- bases.append(base_python_name)
-
- # Import base interface packages.
- if len(packages) > 0:
- file.write(self._indent(indent))
- file.write('# Import base interface packages.\n')
- for package in packages:
- file.write(self._indent(indent))
- file.write(context.create_import_statement(package))
- file.write('\n')
-
- file.write('\n')
-
- # Class header.
- file.write(self._indent(indent))
- file.write('class %s_skel' % py_interface_name)
- file.write('(%s):\n' % string.join(bases, ', '))
-
- # Indent.
- indent = indent + 1
-
- # Documentation string.
- file.write(self._indent(indent))
- file.write('""" Interface: %s """\n\n' % interface_desc.id)
-
- # Repository id attribute.
- file.write(self._indent(indent))
- file.write('_FNORB_ID = "%s"\n\n' % interface_desc.id)
-
- # Generate code for every definition contained in the interface
- # (ignoring inherited definitions).
- contents = ifr_object.contents(CORBA.dk_all, 1)
- if len(contents) > 0:
- for contained in contents:
- self.generate(context, file, contained, indent)
-
- # Empty interface.
- else:
- file.write(self._indent(indent))
- file.write('pass\n\n')
-
- return
-
- def _generate_module(self, context, file, ifr_object, indent):
- """ Generate Python code to represent an IDL module. """
-
- # Get the description of the module.
- description = ifr_object.describe()
- module_desc = description.value.value()
-
- # Make sure that the module name is not a Python keyword.
- py_module_name = Util.python_name(module_desc.name)
-
- # Get the scoped name of the module.
- scoped_name = Util.ScopedName(ifr_object._get_absolute_name())
-
- # Fix up any clashes with Python keywords.
- scoped_name.pythonise()
-
- # Make the 'skeleton' package name (by appending '_skel' to each
- # component of the scoped name).
- package = Util.ScopedName(scoped_name.join('_skel::') + '_skel')
-
- # Create a Python package to represent the IDL module.
- file = self._create_package(context, package.join('/'), module_desc.id)
-
- # Generate code for every definition contained in the module.
- for contained in ifr_object.contents(CORBA.dk_all, 0):
- self.generate(context, file, contained, 0)
-
- # End of the package.
- self._end_package(file, indent)
-
- # All done!
- file.close()
-
- return
-
- def _generate_operation(self, context, file, ifr_object, indent):
- """ Generate Python code to represent an IDL operation. """
-
- # Get the description of the operation.
- description = ifr_object.describe()
- operation_desc = description.value.value()
-
- # Make sure that the operation name is not a Python keyword.
- py_operation_name = Util.python_name(operation_desc.name)
-
- # Method header.
- file.write(self._indent(indent))
- file.write('def %s%s' % (SKEL_PREFIX, operation_desc.name))
- file.write('(self, server_request):\n')
-
- # Indent.
- indent = indent + 1
-
- # Documentation string.
- file.write(self._indent(indent))
- file.write('""" Operation: %s """\n\n' % operation_desc.id)
-
- # Create the input typecodes.
- file.write(self._indent(indent))
- file.write("# Typecodes for 'in' and 'inout' parameters.\n")
- file.write(self._indent(indent))
- file.write('inputs = []\n')
-
- no_of_inputs = 0
- for p in operation_desc.parameters:
- if p.mode == CORBA.PARAM_IN or p.mode == CORBA.PARAM_INOUT:
- file.write(self._indent(indent))
- file.write('inputs.append(%s)' % self._get_typecode(p.type))
- file.write('\n')
- no_of_inputs = no_of_inputs + 1
-
- file.write('\n')
-
- # Create the output typecodes.
- file.write(self._indent(indent))
- file.write("# Typecodes for the result, 'inout' and 'out' parameters.")
- file.write('\n')
- file.write(self._indent(indent))
- file.write('outputs = []\n')
-
- # The result.
- if operation_desc.result.kind() != CORBA.tk_void:
- file.write(self._indent(indent))
- file.write('outputs.append(')
- file.write(self._get_typecode(operation_desc.result))
- file.write(')\n')
-
- # 'inout' and 'out' parameters.
- for p in operation_desc.parameters:
- if p.mode == CORBA.PARAM_INOUT or p.mode == CORBA.PARAM_OUT:
- file.write(self._indent(indent))
- file.write('outputs.append(%s)' % self._get_typecode(p.type))
- file.write('\n')
-
- file.write('\n')
-
- # Create the exception typecodes.
- file.write(self._indent(indent))
- file.write("# Typecodes for user exceptions.\n")
- file.write(self._indent(indent))
- file.write('exceptions = []\n')
-
- for ex in operation_desc.exceptions:
- file.write(self._indent(indent))
- file.write('exceptions.append(Fnorb.orb.CORBA.typecode("%s"))\n' \
- % ex.id)
-
- file.write('\n')
-
- # Boiler plate.
- file.write(self._indent(indent))
- file.write('# Initialise the server request object.\n')
- file.write(self._indent(indent))
- file.write('server_request.initialise(inputs, outputs, exceptions)\n')
- file.write('\n')
-
- # Unmarshal all 'in' and 'inout' parameters.
- if no_of_inputs > 0:
- file.write(self._indent(indent))
- file.write('# Unmarshal the arguments to the request.\n')
- file.write(self._indent(indent))
- file.write('arguments = server_request.arguments()\n\n')
-
- else:
- file.write(self._indent(indent))
- file.write('# This operation has no arguments.\n')
- file.write(self._indent(indent))
- file.write('arguments = ()\n\n')
-
- # Invoke the operation on the implementation.
- file.write(self._indent(indent))
- file.write('# Invoke the implementation.\n')
- file.write(self._indent(indent))
- file.write('results = apply(self.%s, arguments)' % py_operation_name)
- file.write('\n\n')
-
- file.write(self._indent(indent))
- file.write('# Create the reply.\n')
- file.write(self._indent(indent))
- file.write('server_request.results(results)\n\n')
-
- file.write(self._indent(indent))
- file.write('return\n\n')
-
- return
-
- #############################################################################
-