#!/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/orb/DII.py,v $ # Version: @(#)$RCSfile: DII.py,v $ $Revision: 1.15 $ # ############################################################################# """ Implementation of the Dynamic Invocation Interface (DII). """ import IOP class Request: """ Implementation of the PIDL Request interface. Request objects are not thread-safe. This is not a problem as it really only makes sense to handle requests from within a single thread. If you are trying to do otherwise I suggest you take a step back and have a good, long, hard look at yourself ;^) """ def __init__(self, object, operation, inputs, outputs, exceptions, **kw): """ Constructor. """ self.__object = object self.__operation = operation self.__inputs = inputs self.__outputs = outputs self.__exceptions = exceptions # Keyword arguments (as specified in the language mapping document). # # The 'flags' keyword argument is currently ignored as it is only # used in compiled languages to specify memory management policy. try: self.__flags = kw['flags'] except KeyError: self.__flags = 0 try: self.__context = kw['context'] except KeyError: self.__context = [] # Request arguments can be specified either at invocation time, or via # a call to the 'arguments' method. self.__arguments = () return ######################################################################### # CORBA Request interface. ######################################################################### def object(self): """ Return the object reference that we invoke the request on. """ return self.__object def operation(self): """ Return the operation name. """ return self.__operation def inputs(self): """ Return the input typecodes. """ return self.__inputs def outputs(self): """ Return the output typecodes. """ return self.__outputs def exceptions(self): """ Return the exception typecodes. """ return self.__exceptions def flags(self): """ Return the request flags. Request flags are currently ignored in Fnorb! """ return self.__flags def context(self): """ Return the request context. Contexts are currently ignored in Fnorb! """ return self.__context def arguments(self, *args): """ Initialise the request arguments. """ self.__arguments = args return def results(self): """ Return the results of the previous invocation. """ # fixme: Raise an exception here if we have not been invoked!!!!!!!!! return self.__results ## def invoke(self, *args, **kw): ## """ Invoke the request (synchronous). """ ## apply(self.send, args, kw) ## return self.get_response() def invoke(self, *args, **kw): """ Invoke the request (synchronous). """ # Request arguments can be specified either at invocation time, or via # a call to the 'arguments' method. if len(args) == 0: args = self.__arguments else: self.__arguments = args # Make sure we have the right number of arguments! if len(args) != len(self.__inputs): raise TypeError, 'Wrong number of arguments' # Get the object's GIOP client. client = self.__object._fnorb_client() # Ask the client to make the request, and to wait for the reply. (forwarded, self.__results) = client.synchronous(self, args) # If we have been forwarded/unforwarded then try again. if forwarded: # Try again. self.__results = self.invoke() # Return the results for convenience. return self.__results def send(self, *args, **kw): """ Invoke the request (deferred synchronous). """ # Request arguments can be specified either at invocation time, or via # a call to the 'arguments' method. if len(args) == 0: args = self.__arguments else: self.__arguments = args # Make sure we have the right number of arguments! if len(args) != len(self.__inputs): raise TypeError, 'Wrong number of arguments' # Get the object's GIOP client. client = self.__object._fnorb_client() # Ask the client to make the request. self.__request_id = client.deferred(self, args) return def get_response(self): """ Get the response for a deferred request. """ # Get the object's GIOP client. client = self.__object._fnorb_client() # Get the reply to the last operation request. (forwarded, self.__results) = client.reply(self) # If we have been forwarded/unforwarded then try again. if forwarded: # Try again. self.__results = self.invoke() # Return the results for convenience. return self.__results def poll_response(self): """ Has a reply been received? """ # Get the object's GIOP client. client = self.__object._fnorb_client() # Poll for the reply to the last operation request. (forwarded, result) = client.poll(self) # If we have been forwarded/unforwarded then try again. if forwarded: # Try again. self.send() return result def invoke_oneway(self, *args, **kw): """ Invoke the request as 'oneway'. """ # Request arguments can be specified either at invocation time, or via # a call to the 'arguments' method. if len(args) == 0: args = self.__arguments else: self.__arguments = args # Make sure we have the right number of arguments! if len(args) != len(self.__inputs): raise TypeError, 'Wrong number of arguments' # Get the object's GIOP client. client = self.__object._fnorb_client() # Ask the client to make the request. client.oneway(self, args) return ######################################################################### # Fnorb-specific interface. ######################################################################### def _fnorb_request_id(self): """ Return the request id of the current request. """ return self.__request_id def _fnorb_check_codeset_context(self, connection): """Compare the connection's current negotiated codeset with the one of the connection. If the context of the connection is not set, propagate the one from the request. If both are present and different, raise a MARSHAL exception. If they are both equal, remove the context from this message.""" for c in self.__context: if c.context_id == IOP.CodeSets: break else: return negotiated = connection.get_negotiated_codeset() if negotiated: if negotiated.context_data != c.context_data: raise CORBA.MARSHAL self.__context.remove(c) return connection.set_negotiated_codeset(c) class LocalRequest(Request): """ Request interface for local requests (ie. in same address space). """ ######################################################################### # CORBA Request interface. ######################################################################### def invoke(self, *args): """ Invoke the request (synchronous). """ # Request arguments can be specified either at invocation time, or via # a call to the 'arguments' method. if len(args) == 0: args = self.__arguments # Make sure we have the right number of arguments! if len(args) != len(self.__inputs): raise TypeError, 'Wrong number of arguments' # Find the method on the implementation (via the 'LocalObject' # instance). method = getattr(self.__object, self.__operation) # Invoke the operation! self.__results = apply(method, args) # Return the results for convenience! return self.__results def invoke_oneway(self, *args): """ Invoke the request as 'oneway'. """ # Request arguments can be specified either at invocation time, or via # a call to the 'arguments' method. if len(args) == 0: args = self.__arguments # Make sure we have the right number of arguments! if len(args) != len(self.__inputs): raise TypeError # Find the method on the implementation (via the 'LocalObject' # instance). method = getattr(self.__object, self.__operation) # Invoke the operation and throw away any results! apply(method, args) return def send(self, *args): """ Invoke the request (deferred synchronous). """ # Request arguments can be specified either at invocation time, or via # a call to the 'arguments' method. if len(args) == 0: args = self.__arguments # Make sure we have the right number of arguments! if len(args) != len(self.__inputs): raise TypeError # Find the method on the implementation (via the 'LocalObject' # instance). method = getattr(self.__object, self.__operation) # Invoke the operation! self.__results = apply(method, args) return def poll_response(self): """ Has a reply been received? """ return 1 def get_response(self): """ Get the response for a deferred request. """ return self.__results #############################################################################