directory.py
Go to the documentation of this file.
00001 # -*- Python -*-
00002 # -*- coding: utf-8 -*-
00003 
00004 '''rtctree
00005 
00006 Copyright (C) 2009-2014
00007     Geoffrey Biggs
00008     RT-Synthesis Research Group
00009     Intelligent Systems Research Institute,
00010     National Institute of Advanced Industrial Science and Technology (AIST),
00011     Japan
00012     All rights reserved.
00013 Licensed under the Eclipse Public License -v 1.0 (EPL)
00014 http://www.opensource.org/licenses/eclipse-1.0.txt
00015 
00016 Object representing a directory node in the tree.
00017 
00018 '''
00019 
00020 
00021 from copy import deepcopy
00022 import CosNaming
00023 from omniORB import URI, CORBA, TRANSIENT_ConnectFailed
00024 import sys
00025 
00026 from rtctree.component import Component
00027 from rtctree.exceptions import BadPathError
00028 from rtctree.manager import Manager
00029 from rtctree.node import TreeNode
00030 from rtctree.options import Options
00031 from rtctree.unknown import Unknown
00032 from rtctree.zombie import Zombie
00033 from rtctree.utils import filtered, trim_filter
00034 import RTC
00035 import RTM
00036 
00037 
00038 ##############################################################################
00039 ## Directory node object
00040 
00041 class Directory(TreeNode):
00042     '''Node representing a naming context on a name server.
00043 
00044     Name servers contain contexts (including the root context) and objects. For
00045     us, contexts are directories and objects are managers and components. A
00046     directory context may specialise as a name server context, in which case
00047     it represents the root context of a name server.
00048 
00049     '''
00050     def __init__(self, name=None, parent=None, children=None, filter=[], *args,
00051             **kwargs):
00052         '''Constructor. Calls the TreeNode constructor.'''
00053         super(Directory, self).__init__(name=name, parent=parent,
00054                 children=children, filter=filter, *args, **kwargs)
00055 
00056     def reparse(self):
00057         '''Reparse all children of this directory.
00058 
00059         This effectively rebuilds the tree below this node.
00060 
00061         This operation takes an unbounded time to complete; if there are a lot
00062         of objects registered below this directory's context, they will all
00063         need to be parsed.
00064 
00065         '''
00066         self._remove_all_children()
00067         self._parse_context(self._context, self.orb)
00068 
00069     def unbind(self, name):
00070         '''Unbind an object from the context represented by this directory.
00071 
00072         Warning: this is a dangerous operation. You may unlink an entire
00073         section of the tree and be unable to recover it. Be careful what you
00074         unbind.
00075 
00076         The name should be in the format used in paths. For example,
00077         'manager.mgr' or 'ConsoleIn0.rtc'.
00078 
00079         '''
00080         with self._mutex:
00081             id, sep, kind = name.rpartition('.')
00082             if not id:
00083                 id = kind
00084                 kind = ''
00085             name = CosNaming.NameComponent(id=str(id), kind=str(kind))
00086             try:
00087                 self.context.unbind([name])
00088             except CosNaming.NamingContext.NotFound:
00089                 raise BadPathError(name)
00090 
00091     @property
00092     def context(self):
00093         '''The object representing this naming context.'''
00094         with self._mutex:
00095             return self._context
00096 
00097     @property
00098     def is_directory(self):
00099         '''Is this node a directory?'''
00100         return True
00101 
00102     def _parse_context(self, context, orb, filter=[]):
00103         with self._mutex:
00104             # Parse a naming context to fill in the children.
00105             self._context = context
00106             # Get the list of bindings from the context
00107             bindings, bindings_it = context.list(Options().\
00108                                         get_option('max_bindings'))
00109             for binding in bindings:
00110                 # Process the bindings that are within max_bindings
00111                 self._process_binding(binding, orb, filter)
00112             if bindings_it:
00113                 # Handle the iterator containing the remaining bindings
00114                 remaining, bindings = bindings_it.next_n(Options().\
00115                                             get_option('max_bindings'))
00116                 while remaining:
00117                     for binding in bindings:
00118                         self._process_binding(binding, orb, filter)
00119                     remaining, binding = bindings_it.next_n(Options().\
00120                                                 get_option('max_bindings'))
00121                 bindings_it.destroy()
00122 
00123     def _process_binding(self, binding, orb, filter):
00124         if filtered([corba_name_to_string(binding.binding_name)], filter):
00125             # Do not pass anything which does not pass the filter
00126             return
00127         trimmed_filter = trim_filter(deepcopy(filter))
00128         with self._mutex:
00129             # Process a binding, creating the correct child type for it and
00130             # adding that child to this node's children.
00131             if binding.binding_type == CosNaming.nobject:
00132                 # This is a leaf node; either a component or a manager.  The
00133                 # specific type can be determined from the binding name kind.
00134                 if binding.binding_name[0].kind == 'mgr':
00135                     name = corba_name_to_string(binding.binding_name)
00136                     obj = self._context.resolve(binding.binding_name)
00137                     if not obj:
00138                         leaf = Zombie(name, self)
00139                         return
00140                     obj = obj._narrow(RTM.Manager)
00141                     try:
00142                         leaf = Manager(name, self, obj, dynamic=self.dynamic)
00143                     except CORBA.OBJECT_NOT_EXIST:
00144                         # Manager zombie
00145                         leaf = Zombie(name, self)
00146                     except CORBA.TRANSIENT:
00147                         # Manager zombie
00148                         leaf = Zombie(name, self)
00149                     self._add_child(leaf)
00150                 elif binding.binding_name[0].kind == 'rtc':
00151                     name = corba_name_to_string(binding.binding_name)
00152                     obj = self._context.resolve(binding.binding_name)
00153                     try:
00154                         obj = obj._narrow(RTC.RTObject)
00155                     except CORBA.TRANSIENT, e:
00156                         if e.args[0] == TRANSIENT_ConnectFailed:
00157                             self._add_child(Zombie(name, self))
00158                             return
00159                         else:
00160                             raise
00161                     except CORBA.OBJECT_NOT_EXIST:
00162                         self._add_child(Zombie(name, self))
00163                         return
00164                     try:
00165                         leaf = Component(name, self, obj, dynamic=self.dynamic)
00166                     except CORBA.OBJECT_NOT_EXIST:
00167                         # Component zombie
00168                         leaf = Zombie(name, self, dynamic=self.dynamic)
00169                     except CORBA.TRANSIENT, e:
00170                         if e.args[0] == TRANSIENT_ConnectFailed:
00171                             self._add_child(Zombie(name, self))
00172                             return
00173                         else:
00174                             raise
00175                     self._add_child(leaf)
00176                 else:
00177                     # Unknown type - add a plain node
00178                     name = corba_name_to_string(binding.binding_name)
00179                     obj = self._context.resolve(binding.binding_name)
00180                     leaf = Unknown(name, self, obj)
00181                     self._add_child(leaf)
00182             else:
00183                 # This is a context, and therefore a subdirectory.
00184                 subdir_name = corba_name_to_string(binding.binding_name)
00185                 subdir = Directory(subdir_name, self, filter=trimmed_filter,
00186                         dynamic=self.dynamic)
00187                 subdir_context = self._context.resolve(binding.binding_name)
00188                 subdir_context = subdir_context._narrow(CosNaming.NamingContext)
00189                 subdir._parse_context(subdir_context, orb,
00190                         filter=trimmed_filter)
00191                 self._add_child(subdir)
00192 
00193 
00194 def corba_name_to_string(name):
00195     '''Convert a CORBA CosNaming.Name to a string.'''
00196     parts = []
00197     if type(name) is not list and type(name) is not tuple:
00198         raise NotCORBANameError(name)
00199     if len(name) == 0:
00200         raise NotCORBANameError(name)
00201 
00202     for nc in name:
00203         if not nc.kind:
00204             parts.append(nc.id)
00205         else:
00206             parts.append('{0}.{1}'.format(nc.id, nc.kind))
00207     return '/'.join(parts)
00208 
00209 
00210 # vim: tw=79
00211 


rtctree
Author(s): Geoffrey Biggs
autogenerated on Wed Aug 26 2015 16:13:08