home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
fnb101.zip
/
Lib
/
site-packages
/
Fnorb
/
cos
/
naming
/
NamingContext.py
< prev
next >
Wrap
Text File
|
1999-06-28
|
15KB
|
516 lines
#!/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/cos/naming/RCS/NamingContext.py,v $
# Version: @(#)$RCSfile: NamingContext.py,v $ $Revision: 1.10 $
#
#############################################################################
""" COS Naming Service Naming Contexts. """
# Standard/built-in modules.
import string
# Fnorb modules.
from Fnorb.orb import fnorb_thread, uuid, BOA, CORBA
# Stubs and skeletons.
import CosNaming, CosNaming_skel
# Naming service modules.
import BindingIterator
def NamingContextFactory_init():
""" Initialise the Naming Contect Factory.
This is a factory function for the NamingContextFactory class (the factory
is a singleton (ie. there can only be one instance per process)).
"""
try:
ncf = NamingContextFactory()
except NamingContextFactory, ncf:
pass
return ncf
class NamingContextFactory:
""" A factory for naming contexts!
The factory is a singleton (ie. there can only be one instance per
process).
"""
# Singleton instance.
__instance = None
def __init__(self):
""" Constructor. """
# The factory is a singleton (ie. there can only be one instance per
# process).
if NamingContextFactory.__instance is not None:
raise NamingContextFactory.__instance
NamingContextFactory.__instance = self
return
def create_naming_context(self, object_key=None):
""" Create and return a new 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 an instance of the implementation class.
impl = NamingContext()
# Create an object reference.
boa = BOA.BOA_init()
nc = boa.create(object_key, NamingContext._FNORB_ID)
# Activate the implementation (ie. connect the generated object
# reference to the implementation).
boa.obj_is_ready(nc, impl)
return impl
class NamingContext(CosNaming_skel.NamingContext_skel):
""" Naming context implementation. """
# A binding iterator factory that is shared by every context instance.
bif = BindingIterator.BindingIteratorFactory_init()
def __init__(self, nc_factory=None, d_bindings=None):
""" Constructor. """
# A factory responsible for creating new naming contexts.
if nc_factory is None:
self.__nc_factory = NamingContextFactory_init()
else:
self.__nc_factory = nc_factory
# A dictionary containing the bindings in the context, in the form:-
# {(NameComponentId, NameComponentKind): (Binding, StringifiedIOR)}.
#
# We cannot key the dictionary directly on a NameComponent instance
# because the NameComponent class is generated automatically by the
# IDL compiler and therefore has no '__hash__' method.
if d_bindings is None:
self.__d_bindings = {}
else:
self.__d_bindings = d_bindings
# A mutex to make access to the binding dictionary safe in threaded
# environments.
self.__lk = fnorb_thread.allocate_lock()
return
#########################################################################
# CORBA interface.
#########################################################################
def bind(self, n, obj):
""" Bind the name 'n' to the object reference obj. """
# An 'empty' name is invalid.
if len(n) == 0:
raise CosNaming.NamingContext.InvalidName()
# Get the first component of the name.
component = n[0]
# The binding dictionary is keyed on (ComponentId, ComponentKind).
key = str((component.id, component.kind))
# If there is exactly one component in the name then the operation
# takes place in *this* context.
if len(n) == 1:
self.__lk.acquire()
try:
# Is the component already bound?
if self.__d_bindings.has_key(key):
raise CosNaming.NamingContext.AlreadyBound()
# Create the binding.
binding = CosNaming.Binding(n, CosNaming.nobject)
# Stringify the object reference.
orb = CORBA.ORB_init()
stringified_ior = orb.object_to_string(obj)
# Add it to the binding dictionary.
self.__d_bindings[key] = (binding, stringified_ior)
finally:
self.__lk.release()
# Otherwise, attempt to continue resolution into the next context.
else:
self.__resolve('bind', key, n, obj)
return
def rebind(self, n, obj):
""" Rebind the name 'n' to the object reference obj. """
# An 'empty' name is invalid.
if len(n) == 0:
raise CosNaming.NamingContext.InvalidName()
# Get the first component of the name.
component = n[0]
# The binding dictionary is keyed on (ComponentId, ComponentKind).
key = str((component.id, component.kind))
# If there is exactly one component in the name then the operation
# takes place in *this* context.
if len(n) == 1:
# Create the binding.
binding = CosNaming.Binding(n, CosNaming.nobject)
# Stringify the object reference.
orb = CORBA.ORB_init()
stringified_ior = orb.object_to_string(obj)
# Add it to the binding dictionary.
self.__lk.acquire()
self.__d_bindings[key] = (binding, stringified_ior)
self.__lk.release()
# Otherwise, attempt to continue resolution into the next context.
else:
self.__resolve('rebind', key, n, obj)
return
def bind_context(self, n, nc):
""" Bind the name 'n' to the naming context nc. """
# An 'empty' name is invalid.
if len(n) == 0:
raise CosNaming.NamingContext.InvalidName()
# Get the first component of the name.
component = n[0]
# The binding dictionary is keyed on (ComponentId, ComponentKind).
key = str((component.id, component.kind))
# If there is exactly one component in the name then the operation
# takes place in *this* context.
if len(n) == 1:
self.__lk.acquire()
try:
# Is the component already bound?
if self.__d_bindings.has_key(key):
raise CosNaming.NamingContext.AlreadyBound()
# Create the binding.
binding = CosNaming.Binding(n, CosNaming.ncontext)
# Stringify the object reference.
orb = CORBA.ORB_init()
stringified_ior = orb.object_to_string(nc)
# Add it to the binding dictionary.
self.__d_bindings[key] = (binding, stringified_ior)
finally:
self.__lk.release()
# Otherwise, attempt to continue resolution into the next context.
else:
self.__resolve('bind_context', key, n, nc)
return
def rebind_context(self, n, nc):
""" Rebind the name 'n' to the naming context nc. """
# An 'empty' name is invalid.
if len(n) == 0:
raise CosNaming.NamingContext.InvalidName()
# Get the first component of the name.
component = n[0]
# The binding dictionary is keyed on (ComponentId, ComponentKind).
key = str((component.id, component.kind))
# If there is exactly one component in the name then the operation
# takes place in *this* context.
if len(n) == 1:
# Create the binding.
binding = CosNaming.Binding(n, CosNaming.ncontext)
# Stringify the object reference.
orb = CORBA.ORB_init()
stringified_ior = orb.object_to_string(nc)
# Add it to the binding dictionary.
self.__lk.acquire()
self.__d_bindings[key] = (binding, stringified_ior)
self.__lk.release()
# Otherwise, attempt to continue resolution into the next context.
else:
self.__resolve('rebind_context', key, n, nc)
return
def resolve(self, n):
""" Resolve the name 'n'. """
# An 'empty' name is invalid.
if len(n) == 0:
raise CosNaming.NamingContext.InvalidName()
# Get the first component of the name.
component = n[0]
# The binding dictionary is keyed on (ComponentId, ComponentKind).
key = str((component.id, component.kind))
# If there is exactly one component in the name then the operation
# takes place in *this* context.
if len(n) == 1:
self.__lk.acquire()
try:
# Is the component bound in this context?
if not self.__d_bindings.has_key(key):
raise CosNaming.NamingContext.NotFound \
(CosNaming.NamingContext.missing_node, n)
# Get the stringified IOR bound to the component.
(binding, stringified_ior) = self.__d_bindings[key]
# Convert the stringified IOR into an active object reference.
orb = CORBA.ORB_init()
result = orb.string_to_object(stringified_ior)
finally:
self.__lk.release()
# Otherwise, attempt to continue resolution into the next context.
else:
result = self.__resolve('resolve', key, n)
return result
def unbind(self, n):
""" Unbind the name 'n'. """
# An 'empty' name is invalid.
if len(n) == 0:
raise CosNaming.NamingContext.InvalidName()
# Get the first component of the name.
component = n[0]
# The binding dictionary is keyed on (ComponentId, ComponentKind).
key = str((component.id, component.kind))
# If there is exactly one component in the name then the operation
# takes place in *this* context.
if len(n) == 1:
self.__lk.acquire()
try:
# Is the component bound in this context?
if not self.__d_bindings.has_key(key):
raise CosNaming.NamingContext.NotFound()
# Delete the binding.
del self.__d_bindings[key]
finally:
self.__lk.release()
# Otherwise, attempt to continue resolution into the next context.
else:
self.__resolve('unbind', key, n)
return
def new_context(self):
""" Create a new naming context. """
# Ask the factory to create a new naming context for us.
return self.__nc_factory.create_naming_context()
def bind_new_context(self, n):
""" Create a new naming context and bind it to the name 'n'. """
# An 'empty' name is invalid.
if len(n) == 0:
raise CosNaming.NamingContext.NotFound()
# Get the first component of the name.
component = n[0]
# The binding dictionary is keyed on (ComponentId, ComponentKind).
key = str((component.id, component.kind))
# If there is exactly one component in the name then the operation
# takes place in *this* context.
if len(n) == 1:
self.__lk.acquire()
try:
# Is the component already bound?
if self.__d_bindings.has_key(key):
raise CosNaming.NamingContext.AlreadyBound()
# Create the binding.
binding = CosNaming.Binding(n, CosNaming.ncontext)
# Create a new context.
nc = self.new_context()
# Stringify the object reference.
orb = CORBA.ORB_init()
stringified_ior = orb.object_to_string(nc)
# Add it to the binding dictionary.
self.__d_bindings[key] = (binding, stringified_ior)
finally:
self.__lk.release()
# Otherwise, attempt to continue resolution into the next context.
else:
nc = self.__resolve('bind_new_context', key, n)
return nc
def destroy(self):
""" Destroy the naming context. """
self.__lk.acquire()
try:
# Naming contexts must be empty to be destroyed!
if len(self.__d_bindings.keys()) > 0:
raise CosNaming.NamingContext.NotEmpty()
finally:
self.__lk.release()
# Unregister myself from the BOA.
boa = BOA.BOA_init()
boa.deactivate_obj(self)
return
def list(self, how_many):
""" List the bindings in a context. """
# Create a list of the bindings in the context.
#
# Note that we do not use 'self.__d_bindings.values()' to get at the
# dictionary contents; this is a small concession to allow Python
# shelves to be used for creating persistent contexts (shelves do not
# implement the 'values' method).
self.__lk.acquire()
bl = []
for key in self.__d_bindings.keys():
(binding, obj) = self.__d_bindings[key]
bl.append(binding)
self.__lk.release()
# If there are more bindings than have been requested, then return a
# binding iterator.
if len(bl) > how_many:
iterator = NamingContext.bif.create_binding_iterator(bl[how_many:])
# Otherwise return a nil reference for the iterator.
else:
## orb = CORBA.ORB_init()
## iterator = orb.nil()
iterator = None
return (bl[:how_many], iterator)
#########################################################################
# Internal interface.
#########################################################################
def __resolve(self, op, key, n, *args):
""" Resolve a naming operation through a naming graph. """
self.__lk.acquire()
try:
# If the component is not bound in this context then we can go no
# further!
if not self.__d_bindings.has_key(key):
raise CosNaming.NamingContext.NotFound \
(CosNaming.NamingContext.missing_node, n)
# Get the binding!
(binding, stringified_ior) = self.__d_bindings[key]
finally:
self.__lk.release()
# If the binding contains another naming context then continue the
# resolution.
if binding.binding_type == CosNaming.ncontext:
# Convert the stringified IOR into an active object reference.
orb = CORBA.ORB_init()
next = orb.string_to_object(stringified_ior)
# Find the appropriate method on the context.
method = getattr(next, op)
# Invoke the method translating CORBA system exceptions into
# 'CannotProceed' exceptions.
try:
result = apply(method, (n[1:],) + args)
except CORBA.SystemException:
raise CosNaming.NamingContext.CannotProceed(self, n)
# Otherwise, the binding contains some other object reference and
# therefore we cannot continue the resolution.
else:
raise CosNaming.NamingContext.NotFound \
(CosNaming.NamingContext.not_context, n)
return result
#############################################################################