#!/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: /cvsroot/fnorb/fnorb/compiler/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 #############################################################################