#!/usr/bin/env python ############################################################################# # Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999, 2000 # 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/cos/naming/NamingService.py,v $ # Version: @(#)$RCSfile: NamingService.py,v $ $Revision: 1.10 $ # ############################################################################# """ A COS Naming service! """ # Standard/built-in modules. import errno, getopt, os, shelve, sys # Fnorb modules. from Fnorb.orb import uuid, BOA, CORBA # Naming service modules. import NamingContext def PersistentNamingContextFactory_init(db_dir): """ Initialise the Persistent Naming Contect Factory. This is a factory function for the PersistentNamingContextFactory class (the factory is a singleton (ie. there can only be one instance per process)). """ try: ncf = PersistentNamingContextFactory(db_dir) except PersistentNamingContextFactory, ncf: pass return ncf class PersistentNamingContextFactory(NamingContext.NamingContextFactory): """ A factory for persistent naming contexts! The factory is a singleton (ie. there can only be one instance per process). """ # Singleton instance. __instance = None def __init__(self, database): """ Constructor. 'database' is the name of the directory in which to store the naming context databases. """ # The factory is a singleton (ie. there can only be one instance per # process). if PersistentNamingContextFactory.__instance is not None: raise PersistentNamingContextFactory.__instance PersistentNamingContextFactory.__instance = self # The directory in which to store naming context databases. self.__database = database return def create_naming_context(self, object_key=None): """ Create and return a new *persistent* naming context. """ # Create an object key for the context. if object_key is None: # Generate a unique object key for the context. object_key = uuid.uuid() # Create/open the context's persistent dictionary. pathname = '%s/%s' % (self.__database, object_key) bindings = shelve.open(pathname) # Create an instance of the implementation class. impl = NamingContext.NamingContext(self, bindings) # Get a reference to the object adapter. boa = BOA.BOA_init() # Create an object reference with a random object key. ref = boa.create(object_key, NamingContext.NamingContext._FNORB_ID) # Activate the implementation (ie. connect the generated object # reference to the implementation). boa.obj_is_ready(ref, impl) return impl class NamingService: """ A COS Naming service! """ # Object key for the root context of the Naming Service. ROOT_OBJECT_KEY = 'NameService' def __init__(self, argv): """ Constructor. """ # Process command line options. # # The only options currently allowed are:- # # '-?, -h, --help' to print the usage message on stdout. # '--ior' to print the IOR of the root context on stdout. # '--iorf=filepath' to print the IOR of the root context to file # located at 'filepath' # '--database=pathname' to specify the directory name of a persistent # naming service 'database'. options = self.__get_options(argv) # If a 'database' directory *was* specified then create a *persistent* # naming service. if options.has_key('--database'): database = options['--database'] root = self.__create_persistent_naming_service(database) # Otherwise, create a transient naming service. else: root = self.__create_transient_naming_service() # store ior orb = CORBA.ORB_init() self.ior = orb.object_to_string(root) # If requested (via a command line option) then print the stringified # IOR of the root context on stdout. if options.has_key('--ior'): sys.stdout.write(self.ior + '\n') sys.stdout.flush() # if requested, print stringified IOR of the root context to file if options.has_key('--iorf'): fp = open(options['--iorf'], 'w') fp.write(self.ior + '\n') fp.close() return ######################################################################### # Internal interface. ######################################################################### def __get_options(self, argv): """ Process command line options. """ # Parse the command line arguments/options. try: (options, rest) = getopt.getopt(argv[1:], 'h', ['help', 'ior', 'database=', 'iorf=']) except getopt.error: self.__usage() # Put the options in a dictionary for convenience. dictionary = {} for (name, value) in options: dictionary[name] = value # If the help option was specified then just print the usage and exit! if dictionary.has_key('-?') \ or dictionary.has_key('-h') \ or dictionary.has_key('--help'): self.__usage() return dictionary def __usage(self): """ Print the 'usage' message on stdout and exit! """ print 'Usage: fnaming [options]' print print 'Options:' print '-?, -h, --help ', print 'Show this message.' print '--ior ', print 'Print the IOR of the name service on stdout.' print '--iorf=filepath ', print 'Specify the pathname of a file to write the IOR to.' print '--database=pathname ', print 'Specify the pathname of the name service database.' sys.exit(0) def __create_persistent_naming_service(self, database): """ Create/Re-create a persistent naming service! 'database' is the directory name of the naming service database. """ # Create the naming service's 'database' directory. try: os.mkdir(database) # If the directory already exists then carry on! except os.error, (code, message): if code != errno.EEXIST: raise os.error, (code, message) # Create a factory for creating *persistent* naming contexts. factory = PersistentNamingContextFactory_init(database) # (Re)create the root context. root = factory.create_naming_context(NamingService.ROOT_OBJECT_KEY) # (Re)create all of the other naming contexts in the naming service # (Ok, so this approach is not exactly scaleable ;^) # # If the executing Python interpreter is using the 'dumbdbm' module # then the database directory will contain 3 files for each context # (.dat, .dir, .bak). If any other 'db' module is being used then # there will be only 1 file per context. # # To allow for both cases we list the entire contents of the database # directory and then create a list of unique contexts. contexts = {} for filename in os.listdir(database): (base, ext) = os.path.splitext(filename) if base != NamingService.ROOT_OBJECT_KEY: contexts[base] = None # Create each unique context. for context in contexts.keys(): factory.create_naming_context(context) return root def __create_transient_naming_service(self): """ Create a transient naming service. A transient naming service loses all of its information when it is closed down. """ # Create a factory for creating *transient* naming contexts. factory = NamingContext.NamingContextFactory_init() # Create the root context. return factory.create_naming_context(NamingService.ROOT_OBJECT_KEY) #############################################################################