CorbaNaming.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: euc-jp -*-
00003 
00004 
00005 ##
00006 # \file CorbaNaming.py
00007 # \brief CORBA naming service helper class
00008 # \author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00009 #
00010 # Copyright (C) 2006-2008
00011 #     Noriaki Ando
00012 #     Task-intelligence Research Group,
00013 #     Intelligent Systems Research Institute,
00014 #     National Institute of
00015 #         Advanced Industrial Science and Technology (AIST), Japan
00016 #     All rights reserved.
00017 
00018 import omniORB.CORBA as CORBA
00019 import CosNaming
00020 import string
00021 
00022 ##
00023 # @if jp
00024 # @class CorbaNaming
00025 # @brief CORBA Naming Service ヘルパークラス
00026 #
00027 # このクラスは、CosNaming::NamingContext に対するラッパークラスである。
00028 # CosNaming::NamingContext が持つオペレーションとほぼ同じ機能の
00029 # オペレーションを提供するとともに、ネームコンポーネント CosNaming::Name
00030 # の代わりに文字列による名前表現を受け付けるオペレーションも提供する。
00031 #
00032 # オブジェクトは生成時、あるいは生成直後に CORBA ネームサーバに接続し
00033 # 以後、このネームサーバのルートコンテキストに対して種々のオペレーション
00034 # を処理する。
00035 # 深い階層のネーミングコンテキストの作成やオブジェクトのバインドにおいて、
00036 # 途中のコンテキストが存在しない場合でも、強制的にコンテキストをバインド
00037 # し目的のコンテキストやオブジェクトのバインドを行うこともできる。
00038 #
00039 # @since 0.4.0
00040 #
00041 # @else
00042 # @class CorbaNaming
00043 # @brief CORBA Naming Service helper class
00044 #
00045 # This class is a wrapper class of CosNaming::NamingContext.
00046 # Almost the same operations which CosNaming::NamingContext has are
00047 # provided, and some operation allows string naming representation of
00048 # context and object instead of CosNaming::Name.
00049 #
00050 # The object of the class would connect to a CORBA naming server at
00051 # the instantiation or immediately after instantiation.
00052 # After that the object invokes operations to the root context of it.
00053 # This class realizes forced binding to deep NamingContext, without binding
00054 # intermediate NamingContexts explicitly.
00055 #
00056 # @since 0.4.0
00057 #
00058 # @endif
00059 class CorbaNaming:
00060   """
00061   """
00062 
00063 
00064 
00065   ##
00066   # @if jp
00067   #
00068   # @brief コンストラクタ
00069   #
00070   # @param self
00071   # @param orb ORB
00072   # @param name_server ネームサーバの名称(デフォルト値:None)
00073   #
00074   # @else
00075   #
00076   # @brief Consructor
00077   #
00078   # @endif
00079   def __init__(self, orb, name_server=None):
00080     self._orb = orb
00081     self._nameServer = ""
00082     self._rootContext = CosNaming.NamingContext._nil
00083     self._blLength = 100
00084 
00085     if name_server:
00086       self._nameServer = "corbaloc::" + name_server + "/NameService"
00087       try:
00088         obj = orb.string_to_object(self._nameServer)
00089         self._rootContext = obj._narrow(CosNaming.NamingContext)
00090         if CORBA.is_nil(self._rootContext):
00091           print "CorbaNaming: Failed to narrow the root naming context."
00092 
00093       except CORBA.ORB.InvalidName:
00094         print "Service required is invalid [does not exist]."
00095 
00096     return
00097   
00098 
00099   ##
00100   # @if jp
00101   #
00102   # @brief デストラクタ
00103   # 
00104   # @param self
00105   # 
00106   # @else
00107   # 
00108   # @brief destructor
00109   # 
00110   # @endif
00111   def __del__(self):
00112     return
00113 
00114 
00115   ##
00116   # @if jp
00117   #
00118   # @brief ネーミングサービスの初期化
00119   # 
00120   # 指定されたネームサーバ上のネーミングサービスを初期化します。
00121   # 
00122   # @param self
00123   # @param name_server ネームサーバの名称
00124   # 
00125   # @else
00126   # 
00127   # @endif
00128   def init(self, name_server):
00129     self._nameServer = "corbaloc::" + name_server + "/NameService"
00130     obj = self._orb.string_to_object(self._nameServer)
00131     self._rootContext = obj._narrow(CosNaming.NamingContext)
00132     if CORBA.is_nil(self._rootContext):
00133       raise MemoryError
00134 
00135     return
00136 
00137 
00138   ##
00139   # @if jp
00140   #
00141   # @brief Object を bind する
00142   #
00143   # CosNaming::bind() とほぼ同等の働きをするが、常に与えられたネームサーバの
00144   # ルートコンテキストに対してbind()が呼び出される点が異なる。
00145   #
00146   # Name <name> と Object <obj> を当該 NamingContext 上にバインドする。
00147   # c_n が n 番目の NameComponent をあらわすとすると、
00148   # name が n 個の NameComponent から成るとき、以下のように扱われる。
00149   #
00150   # cxt->bind(<c_1, c_2, ... c_n>, obj) は以下の操作と同等である。
00151   # cxt->resolve(<c_1, ... c_(n-1)>)->bind(<c_n>, obj)
00152   #
00153   # すなわち、1番目からn-1番目のコンテキストを解決し、n-1番目のコンテキスト
00154   # 上に name <n> として obj を bind する。
00155   # 名前解決に参加する <c_1, ... c_(n-1)> の NemingContext は、
00156   # bindContext() や rebindContext() で既にバインド済みでなければならない。
00157   # もし <c_1, ... c_(n-1)> の NamingContext が存在しない場合には、
00158   # NotFound 例外が発生する。
00159   #
00160   # ただし、強制バインドフラグ force が true の時は、<c_1, ... c_(n-1)>
00161   # が存在しない場合にも、再帰的にコンテキストをバインドしながら、
00162   # 最終的に obj を名前 name <c_n> にバインドする。
00163   #
00164   # いずれの場合でも、n-1番目のコンテキスト上に name<n> のオブジェクト
00165   # (Object あるいは コンテキスト) がバインドされていれば
00166   # AlreadyBound 例外が発生する。
00167   #
00168   # @param self
00169   # @param name_list オブジェクトに付ける名前の NameComponent
00170   # @param obj 関連付けられる Object
00171   # @param force trueの場合、途中のコンテキストを強制的にバインドする
00172   #              (デフォルト値:None)
00173   #
00174   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00175   # @exception CannotProceed 何らかの理由で処理を継続できない。
00176   # @exception InvalidName 引数 name_list の名前が不正。
00177   # @exception AlreadyBound name <c_n> の Object がすでにバインドされている。
00178   #
00179   # @else
00180   #
00181   # @brief
00182   #
00183   # @endif
00184   def bind(self, name_list, obj, force=None):
00185     if force is None :
00186       force = True
00187 
00188     try:
00189       self._rootContext.bind(name_list, obj)
00190     except CosNaming.NamingContext.NotFound:
00191       if force:
00192         self.bindRecursive(self._rootContext, name_list, obj)
00193       else:
00194         raise
00195     except CosNaming.NamingContext.CannotProceed, err:
00196       if force:
00197         self.bindRecursive(err.cxt, err.rest_of_name, obj)
00198       else:
00199         raise
00200     except CosNaming.NamingContext.AlreadyBound:
00201       self._rootContext.rebind(name_list, obj)
00202 
00203 
00204   ##
00205   # @if jp
00206   #
00207   # @brief Object を bind する
00208   #
00209   # Object を bind する際に与える名前が文字列表現であること以外は、bind()
00210   # と同じである。bind(toName(string_name), obj) と等価。
00211   #
00212   # @param self
00213   # @param string_name オブジェクトに付ける名前の文字列表現
00214   # @param obj 関連付けられるオブジェクト
00215   # @param force trueの場合、途中のコンテキストを強制的にバインドする
00216   #              (デフォルト値:true)
00217   #
00218   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00219   # @exception CannotProceed 何らかの理由で処理を継続できない。
00220   # @exception InvalidName 引数 string_name の名前が不正。
00221   # @exception AlreadyBound name <n> の Object がすでにバインドされている。
00222   #
00223   # @else
00224   #
00225   # @brief
00226   #
00227   # @endif
00228   def bindByString(self, string_name, obj, force=True):
00229     self.bind(self.toName(string_name), obj, force)
00230 
00231 
00232   ##
00233   # @if jp
00234   #
00235   # @brief 途中のコンテキストを bind しながら Object を bind する
00236   #
00237   # context で与えられた NamingContext に対して、name で指定された
00238   # ネームコンポーネント <c_1, ... c_(n-1)> を NamingContext として
00239   # 解決しながら、名前 <c_n> に対して obj を bind する。
00240   # もし、<c_1, ... c_(n-1)> に対応する NamingContext がない場合には
00241   # 新たな NamingContext をバインドする。
00242   #
00243   # 最終的に <c_1, c_2, ..., c_(n-1)> に対応する NamingContext が生成
00244   # または解決された上で、CosNaming::bind(<c_n>, object) が呼び出される。
00245   # このとき、すでにバインディングが存在すれば AlreadyBound例外が発生する。
00246   #
00247   # 途中のコンテキストを解決する過程で、解決しようとするコンテキストと
00248   # 同じ名前の NamingContext ではない Binding が存在する場合、
00249   # CannotProceed 例外が発生し処理を中止する。
00250   #
00251   # @param self
00252   # @param context bind を開始する NamingContext
00253   # @param name_list オブジェクトに付ける名前のネームコンポーネント
00254   # @param obj 関連付けられるオブジェクト
00255   #
00256   # @exception CannotProceed <c_1, ..., c_(n-1)> に対応する NamingContext 
00257   #            のうちひとつが、すでに NamingContext 以外の object にバインド
00258   #            されており、処理を継続できない。
00259   # @exception InvalidName 名前 name_list が不正
00260   # @exception AlreadyBound name <c_n> にすでに何らかの object がバインド
00261   #            されている。
00262   # @else
00263   #
00264   # @brief
00265   #
00266   # @endif
00267   def bindRecursive(self, context, name_list, obj):
00268     length = len(name_list)
00269     cxt = context
00270     for i in range(length):
00271       if i == length -1:
00272         try:
00273           cxt.bind(self.subName(name_list, i, i), obj)
00274         except CosNaming.NamingContext.AlreadyBound:
00275           cxt.rebind(self.subName(name_list, i, i), obj)
00276         return
00277       else:
00278         if self.objIsNamingContext(cxt):
00279           cxt = self.bindOrResolveContext(cxt,self.subName(name_list, i, i))
00280         else:
00281           raise CosNaming.NamingContext.CannotProceed(cxt, self.subName(name_list, i))
00282     return
00283 
00284 
00285   ##
00286   # @if jp
00287   #
00288   # @brief Object を rebind する
00289   #
00290   # name_list で指定された Binding がすでに存在する場合を除いて bind() と同じ
00291   # である。バインディングがすでに存在する場合には、新しいバインディングに
00292   # 置き換えられる。
00293   #
00294   # @param self
00295   # @param name_list オブジェクトに付ける名前の NameComponent
00296   # @param obj 関連付けられるオブジェクト
00297   # @param force trueの場合、途中のコンテキストを強制的にバインドする
00298   #              (デフォルト値:true)
00299   #
00300   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00301   # @exception CannotProceed 何らかの理由で処理を継続できない。
00302   # @exception InvalidName 名前 name_list が不正
00303   #
00304   # @else
00305   #
00306   # @brief
00307   #
00308   # @endif
00309   def rebind(self, name_list, obj, force=True):
00310     if force is None:
00311       force = True
00312       
00313     try:
00314       self._rootContext.rebind(name_list, obj)
00315 
00316     except CosNaming.NamingContext.NotFound:
00317       if force:
00318         self.rebindRecursive(self._rootContext, name_list, obj)
00319       else:
00320         raise
00321 
00322     except CosNaming.NamingContext.CannotProceed, err:
00323       if force:
00324         self.rebindRecursive(err.cxt, err,rest_of_name, obj)
00325       else:
00326         raise
00327       
00328     return
00329 
00330 
00331   ##
00332   # @if jp
00333   #
00334   # @brief Object を rebind する
00335   #
00336   # Object を rebind する際に与える名前が文字列表現であること以外は rebind()
00337   # と同じである。rebind(toName(string_name), obj) と等価。
00338   #
00339   # @param self
00340   # @param string_name オブジェクトに付ける名前の文字列表現
00341   # @param obj 関連付けられるオブジェクト
00342   # @param force trueの場合、途中のコンテキストを強制的にバインドする
00343   #              (デフォルト値:true)
00344   #
00345   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00346   # @exception CannotProceed 何らかの理由で処理を継続できない。
00347   # @exception InvalidName 引数 string_name の名前が不正。
00348   #
00349   # @else
00350   #
00351   # @brief
00352   #
00353   # @endif
00354   def rebindByString(self, string_name, obj, force=True):
00355     self.rebind(self.toName(string_name), obj, force)
00356 
00357     return
00358 
00359 
00360   ##
00361   # @if jp
00362   #
00363   # @brief 途中のコンテキストを bind しながら Object を rebind する
00364   #
00365   # name_list <c_n> で指定された NamingContext もしくは Object がすでに存在する
00366   # 場合を除いて bindRecursive() と同じである。
00367   #
00368   # name_list <c_n> で指定されたバインディングがすでに存在する場合には、
00369   # 新しいバインディングに置き換えられる。
00370   #
00371   # @param self
00372   # @param context bind を開始する NamingContext
00373   # @param name_list オブジェクトに付ける名前の NameComponent
00374   # @param obj 関連付けられるオブジェクト
00375   #
00376   # @exception CannotProceed 途中のコンテキストが解決できない。
00377   # @exception InvalidName 与えられた name_list が不正。
00378   #
00379   # @else
00380   #
00381   # @brief
00382   #
00383   # @endif
00384   def rebindRecursive(self, context, name_list, obj):
00385     length = len(name_list)
00386     for i in range(length):
00387       if i == length - 1:
00388         context.rebind(self.subName(name_list, i, i), obj)
00389         return
00390       else:
00391         if self.objIsNamingContext(context):
00392           try:
00393             context = context.bind_new_context(self.subName(name_list, i, i))
00394           except CosNaming.NamingContext.AlreadyBound:
00395             obj_ = context.resolve(self.subName(name_list, i, i))
00396             context = obj_._narrow(CosNaming.NamingContext)
00397         else:
00398           raise CosNaming.NamingContext.CannotProceed(context, self.subName(name_list, i))
00399     return
00400 
00401 
00402   ##
00403   # @if jp
00404   #
00405   # @brief NamingContext を bind する
00406   #
00407   # bind 対象として指定された引数 name が文字列の場合は bindByString() と、
00408   # それ以外の場合は bind() と同じである。
00409   #
00410   # @param self
00411   # @param name オブジェクトに付ける名前
00412   # @param name_cxt 関連付けられる NamingContext
00413   # @param force trueの場合、途中のコンテキストを強制的にバインドする
00414   #              (デフォルト値:True)
00415   #
00416   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00417   # @exception CannotProceed 何らかの理由で処理を継続できない。
00418   # @exception InvalidName 引数 name の名前が不正。
00419   # @exception AlreadyBound name <c_n> の Object がすでにバインドされている。
00420   #
00421   # @else
00422   #
00423   # @brief
00424   #
00425   # @endif
00426   def bindContext(self, name, name_cxt, force=True):
00427     if isinstance(name, basestring):
00428       self.bind(self.toName(name), name_cxt, force)
00429     else:
00430       self.bind(name, name_cxt, force)
00431     return
00432 
00433 
00434   ##
00435   # @if jp
00436   #
00437   # @brief NamingContext を bind する
00438   #
00439   # bind されるオブジェクトが NamingContext であることを除いて
00440   # bindRecursive() と同じである。
00441   #
00442   # @param self
00443   # @param context bind を開始する NamingContext
00444   # @param name_list オブジェクトに付ける名前のネームコンポーネント
00445   # @param name_cxt 関連付けられる NamingContext
00446   #
00447   # @else
00448   #
00449   # @brief
00450   #
00451   # @endif
00452   def bindContextRecursive(self, context, name_list, name_cxt):
00453     self.bindRecursive(context, name_list, name_cxt)
00454     return
00455 
00456 
00457   ##
00458   # @if jp
00459   #
00460   # @brief NamingContext を rebind する
00461   #
00462   # bind 対象として指定された引数 name が文字列の場合は rebindByString() と、
00463   # それ以外の場合は rebind() と同じである。
00464   # どちらの場合もバインディングがすでに存在する場合には、
00465   # 新しいバインディングに置き換えられる。
00466   #
00467   # @param self
00468   # @param name オブジェクトに付ける名前のネームコンポーネント
00469   # @param name_cxt 関連付けられる NamingContext
00470   # @param force trueの場合、途中のコンテキストを強制的にバインドする
00471   #              (デフォルト値:true)
00472   #
00473   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00474   # @exception CannotProceed 何らかの理由で処理を継続できない。
00475   # @exception InvalidName 引数 name の名前が不正。
00476   #
00477   # @else
00478   #
00479   # @endif
00480   def rebindContext(self, name, name_cxt, force=True):
00481     if isinstance(name, basestring):
00482       self.rebind(self.toName(name), name_cxt, force)
00483     else:
00484       self.rebind(name, name_cxt, force)
00485     return
00486 
00487 
00488   ##
00489   # @if jp
00490   #
00491   # @brief 途中のコンテキストを再帰的に rebind し NamingContext を rebind する    #
00492   # bind されるオブジェクトが NamingContext であることを除いて
00493   # rebindRecursive() と同じである。
00494   #
00495   # @param self
00496   # @param context bind を開始する NamingContext
00497   # @param name_list オブジェクトに付ける名前の NameComponent
00498   # @param name_cxt 関連付けられる NamingContext
00499   #
00500   # @else
00501   #
00502   # @brief
00503   #
00504   # @endif
00505   def rebindContextRecursive(self, context, name_list, name_cxt):
00506     self.rebindRecursive(context, name_list, name_cxt)
00507     return
00508 
00509 
00510   ##
00511   # @if jp
00512   #
00513   # @brief Object を name から解決する
00514   #
00515   # name に bind されているオブジェクト参照を返す。
00516   # ネームコンポーネント <c_1, c_2, ... c_n> は再帰的に解決される。
00517   # 
00518   # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
00519   # NameComponent に変換される。
00520   # 
00521   # CosNaming::resolve() とほぼ同等の働きをするが、常に与えられた
00522   # ネームサーバのルートコンテキストに対して resolve() が呼び出される点が
00523   # 異なる。
00524   #
00525   # @param self
00526   # @param name 解決すべきオブジェクトの名前のネームコンポーネント
00527   #
00528   # @return 解決されたオブジェクト参照
00529   #
00530   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00531   # @exception CannotProceed 何らかの理由で処理を継続できない。
00532   # @exception InvalidName 引数 name の名前が不正。
00533   #
00534   # @else
00535   #
00536   # @endif
00537   def resolve(self, name):
00538     if isinstance(name, basestring):
00539       name_ = self.toName(name)
00540     else:
00541       name_ = name
00542       
00543     try:
00544       obj = self._rootContext.resolve(name_)
00545       return obj
00546     except CosNaming.NamingContext.NotFound, ex:
00547       return None
00548 
00549 
00550   ##
00551   # @if jp
00552   #
00553   # @brief 指定された名前のオブジェクトの bind を解除する
00554   #
00555   # name に bind されているオブジェクト参照を解除する。
00556   # ネームコンポーネント <c_1, c_2, ... c_n> は再帰的に解決される。
00557   # 
00558   # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
00559   # NameComponent に変換される。
00560   # 
00561   # CosNaming::unbind() とほぼ同等の働きをするが、常に与えられた
00562   # ネームサーバのルートコンテキストに対して unbind() が呼び出される点が
00563   # 異なる。
00564   #
00565   # @param self
00566   # @param name 削除するオブジェクトのネームコンポーネント
00567   #
00568   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00569   # @exception CannotProceed 何らかの理由で処理を継続できない。
00570   # @exception InvalidName 引数 name の名前が不正。
00571   #
00572   # @else
00573   #
00574   # @endif
00575   # void unbind(const CosNaming::Name& name)
00576   #   throw(NotFound, CannotProceed, InvalidName);
00577   def unbind(self, name):
00578     if isinstance(name, basestring):
00579       name_ = self.toName(name)
00580     else:
00581       name_ = name
00582 
00583     self._rootContext.unbind(name_)
00584     return
00585 
00586 
00587   ##
00588   # @if jp
00589   #
00590   # @brief 新しいコンテキストを生成する
00591   #
00592   # 与えられたネームサーバ上で生成された NamingContext を返す。
00593   # 返された NamingContext は bind されていない。
00594   # 
00595   # @param self
00596   # 
00597   # @return 生成された新しい NamingContext
00598   #
00599   # @else
00600   #
00601   # @endif
00602   def newContext(self):
00603     return self._rootContext.new_context()
00604 
00605 
00606   ##
00607   # @if jp
00608   #
00609   # @brief 新しいコンテキストを bind する
00610   #
00611   # 与えられた name に対して新しいコンテキストをバインドする。
00612   # 生成された NamingContext はネームサーバ上で生成されたものである。
00613   # 
00614   # 引数 name に与えられた値が文字列の場合にはまず最初に toName() によって
00615   # NameComponent に変換される。
00616   # 
00617   # @param self
00618   # @param name NamingContextに付ける名前のネームコンポーネント
00619   # @param force trueの場合、途中のコンテキストを強制的にバインドする
00620   #              (デフォルト値:true)
00621   #
00622   # @return 生成された新しい NamingContext
00623   #
00624   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00625   # @exception CannotProceed 何らかの理由で処理を継続できない。
00626   # @exception InvalidName 引数 name の名前が不正。
00627   # @exception AlreadyBound name <n> の Object がすでにバインドされている。
00628   #
00629   # @else
00630   #
00631   # @endif
00632   def bindNewContext(self, name, force=True):
00633     if force is None:
00634       force = True
00635       
00636     if isinstance(name, basestring):
00637       name_ = self.toName(name)
00638     else:
00639       name_ = name
00640 
00641     try:
00642       return self._rootContext.bind_new_context(name_)
00643     except CosNaming.NamingContext.NotFound:
00644       if force:
00645         self.bindRecursive(self._rootContext, name_, self.newContext())
00646       else:
00647         raise
00648     except CosNaming.NamingContext.CannotProceed, err:
00649       if force:
00650         self.bindRecursive(err.cxt, err.rest_of_name, self.newContext())
00651       else:
00652         raise
00653     return None
00654 
00655 
00656   ##
00657   # @if jp
00658   #
00659   # @brief NamingContext を非アクティブ化する
00660   #
00661   # context で指定された NamingContext を非アクティブ化する。
00662   # context に他のコンテキストがバインドされている場合は NotEmpty 例外が
00663   # 発生する。
00664   # 
00665   # @param self
00666   # @param context 非アクティブ化する NamingContext
00667   #
00668   # @exception NotEmpty 対象context に他のコンテキストがバインドされている。
00669   #
00670   # @else
00671   #
00672   # @else
00673   #
00674   # @brief Destroy the naming context
00675   #
00676   # Delete the specified naming context.
00677   # any bindings should be <unbind> in which the given context is bound to
00678   # some names before invoking <destroy> operation on it. 
00679   #
00680   # @param context NamingContext which is destroied.
00681   #     
00682   # @exception NotEmpty 
00683   #
00684   # @else
00685   #
00686   # @endif
00687   def destroy(self, context):
00688     context.destroy()
00689 
00690 
00691   ##
00692   # @if jp
00693   # @brief NamingContext を再帰的に下って非アクティブ化する
00694   #
00695   # context で与えられた NamingContext に対して、name で指定された
00696   # ネームコンポーネント <c_1, ... c_(n-1)> を NamingContext として
00697   # 解決しながら、名前 <c_n> に対して 非アクティブ化を行う。
00698   #
00699   # @param self
00700   # @param context 非アクティブ化する NamingContext
00701   #
00702   # @exception NotEmpty 対象context に他のコンテキストがバインドされている。
00703   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00704   # @exception CannotProceed 何らかの理由で処理を継続できない。
00705   # @exception InvalidName 引数 name の名前が不正。
00706   #
00707   # @else
00708   # @brief Destroy the naming context recursively
00709   # @endif
00710   def destroyRecursive(self, context):
00711     cont = True
00712     bl = []
00713     bi = 0
00714     bl, bi = context.list(self._blLength)
00715     while cont:
00716       for i in range(len(bl)):
00717         if bl[i].binding_type == CosNaming.ncontext:
00718           obj = context.resolve(bl[i].binding_name)
00719           next_context = obj._narrow(CosNaming.NamingContext)
00720 
00721           self.destroyRecursive(next_context)
00722           context.unbind(bl[i].binding_name)
00723           next_context.destroy()
00724         elif bl[i].binding_type == CosNaming.nobject:
00725           context.unbind(bl[i].binding_name)
00726         else:
00727           assert(0)
00728       if CORBA.is_nil(bi):
00729         cont = False
00730       else:
00731         bi.next_n(self._blLength, bl)
00732 
00733     if not (CORBA.is_nil(bi)):
00734       bi.destroy()
00735     return
00736 
00737 
00738   ##
00739   # @if jp
00740   # @brief すべての Binding を削除する
00741   #
00742   # 登録されている全てのBinding を削除する。
00743   #
00744   # @param self
00745   #
00746   # @else
00747   # @brief Destroy all binding
00748   # @endif
00749   def clearAll(self):
00750     self.destroyRecursive(self._rootContext)
00751     return
00752 
00753 
00754   ##
00755   # @if jp
00756   # @brief 与えられた NamingContext の Binding を取得する
00757   #
00758   # 指定された NamingContext の Binding を取得する。
00759   #
00760   # @param self
00761   # @param name_cxt Binding 取得対象 NamingContext
00762   # @param how_many Binding を取得する階層の深さ
00763   # @param rbl 取得した Binding を保持するホルダ
00764   # @param rbi 取得した Binding をたどるためのイテレータ
00765   #
00766   # @else
00767   # @endif
00768   def list(self, name_cxt, how_many, rbl, rbi):
00769     bl, bi = name_cxt.list(how_many)
00770 
00771     for i in bl:
00772       rbl.append(bl)
00773 
00774     rbi.append(bi)
00775   
00776 
00777   #============================================================
00778   # interface of NamingContext
00779   #============================================================
00780 
00781   ##
00782   # @if jp
00783   # @brief 与えられた NameComponent の文字列表現を返す
00784   #
00785   # 指定された NameComponent を文字に変換する。
00786   #
00787   # @param self
00788   # @param name_list 変換対象 NameComponent
00789   #
00790   # @return 文字列変換結果
00791   #
00792   # @exception InvalidName 引数 name_list の名前が不正。
00793   #
00794   # @else
00795   # @brief Get string representation of given NameComponent
00796   # @endif
00797   def toString(self, name_list):
00798     if len(name_list) == 0:
00799       raise CosNaming.NamingContext.InvalidName
00800 
00801     slen = self.getNameLength(name_list)
00802     string_name = [""]
00803     self.nameToString(name_list, string_name, slen)
00804 
00805     return string_name
00806 
00807 
00808   ##
00809   # @if jp
00810   # @brief 与えられた文字列表現を NameComponent に分解する
00811   #
00812   # 指定された文字列を NameComponent に変換する。
00813   #
00814   # @param self
00815   # @param sname 変換対象文字列
00816   #
00817   # @return NameComponent 変換結果
00818   #
00819   # @exception InvalidName 引数 sname が不正。
00820   #
00821   # @else
00822   # @brief Get NameComponent from gien string name representation
00823   # @endif
00824   def toName(self, sname):
00825     if not sname:
00826       raise CosNaming.NamingContext.InvalidName
00827 
00828     string_name = sname
00829     name_comps = []
00830 
00831     nc_length = 0
00832     nc_length = self.split(string_name, "/", name_comps)
00833     if not (nc_length > 0):
00834       raise CosNaming.NamingContext.InvalidName
00835 
00836     name_list = [CosNaming.NameComponent("","") for i in range(nc_length)]
00837 
00838     for i in range(nc_length):
00839       pos = string.rfind(name_comps[i][0:],".")
00840       if pos == -1:
00841         name_list[i].id   = name_comps[i]
00842         name_list[i].kind = ""
00843       else:
00844         name_list[i].id   = name_comps[i][0:pos]
00845         name_list[i].kind = name_comps[i][(pos+1):]
00846 
00847     return name_list
00848 
00849 
00850   ##
00851   # @if jp
00852   # @brief 与えられた addr と string_name から URL表現を取得する
00853   #
00854   # 指定されたアドレスと名称をURLに変換する。
00855   #
00856   # @param self
00857   # @param addr 変換対象アドレス
00858   # @param string_name 変換対象名称
00859   #
00860   # @return URL 変換結果
00861   #
00862   # @exception InvalidAddress 引数 addr が不正。
00863   # @exception InvalidName 引数 string_name が不正。
00864   #
00865   # @else
00866   # @brief Get URL representation from given addr and string_name
00867   # @endif
00868   def toUrl(self, addr, string_name):
00869     return self._rootContext.to_url(addr, string_name)
00870 
00871 
00872   ##
00873   # @if jp
00874   # @brief 与えられた文字列表現を resolve しオブジェクトを返す
00875   #
00876   # 指定された文字列表現をresolveし,オブジェクトを取得する。
00877   #
00878   # @param self
00879   # @param string_name 取得対象オブジェクト文字列表現
00880   #
00881   # @return 解決されたオブジェクト
00882   #
00883   # @exception NotFound 途中の <c_1, c_2, ..., c_(n-1)> が存在しない。
00884   # @exception CannotProceed 何らかの理由で処理を継続できない。
00885   # @exception InvalidName 引数 name の名前が不正。
00886   # @exception AlreadyBound name <n> の Object がすでにバインドされている。
00887   #
00888   # @else
00889   # @brief Resolve from name of string representation and get object 
00890   # @endif
00891   def resolveStr(self, string_name):
00892     return self.resolve(self.toName(string_name))
00893 
00894 
00895   #============================================================
00896   # Find functions
00897   #============================================================
00898 
00899   ##
00900   # @if jp
00901   #
00902   # @brief オブジェクトの名前をバインドまたは解決する
00903   #
00904   # 指定されたコンテキストに対してオブジェクトを NameComponent で指定された
00905   # 位置にバインドする。
00906   # 同一箇所に既に他の要素がバインド済みの場合は、既存のバインド済み要素を
00907   # 取得する。
00908   #
00909   # @param self
00910   # @param context bind もしくは resole 対象コンテキスト
00911   # @param name_list オブジェクトに付ける名前の NameComponent
00912   # @param obj 関連付けられる Object
00913   #
00914   # @return NameComponent で指定された位置にバインドされているオブジェクト
00915   #
00916   # @else
00917   # @brief Bind of resolve the given name component
00918   # @endif
00919   def bindOrResolve(self, context, name_list, obj):
00920     try:
00921       context.bind_context(name_list, obj)
00922       return obj
00923     except CosNaming.NamingContext.AlreadyBound:
00924       obj = context.resolve(name_list)
00925       return obj
00926     return CORBA.Object._nil
00927 
00928 
00929   ##
00930   # @if jp
00931   #
00932   # @brief コンテキストの名前をバインドまたは解決する
00933   #
00934   # 指定されたコンテキストに対して Contextを NameComponent で指定された位置に
00935   # バインドする。
00936   # Context が空の場合は新規コンテキストを生成してバインドする。
00937   # 同一箇所に既に他の要素がバインド済みの場合は、既存のバインド済み要素を
00938   # 取得する。
00939   #
00940   # @param self
00941   # @param context bind もしくは resole 対象コンテキスト
00942   # @param name_list コンテキストに付ける名前の NameComponent
00943   # @param new_context 関連付けられる Context(デフォルト値:None)
00944   #
00945   # @return NameComponent で指定された位置にバインドされているContext
00946   #
00947   # @else
00948   # @brief Bind of resolve the given name component
00949   # @endif
00950   def bindOrResolveContext(self, context, name_list, new_context=None):
00951     if new_context is None:
00952       new_cxt = self.newContext()
00953     else:
00954       new_cxt = new_context
00955 
00956     obj = self.bindOrResolve(context, name_list, new_cxt)
00957     return obj._narrow(CosNaming.NamingContext)
00958 
00959 
00960   ##
00961   # @if jp
00962   # @brief ネームサーバの名前を取得する
00963   #
00964   # 設定したネームサーバの名前を取得する。
00965   #
00966   # @param self
00967   #
00968   # @return ネームサーバの名前
00969   #
00970   # @else
00971   # @brief Get the name of naming server
00972   # @endif
00973   def getNameServer(self):
00974     return self._nameServer
00975 
00976 
00977   ##
00978   # @if jp
00979   # @brief ルートコンテキストを取得する
00980   #
00981   # 設定したネームサーバのルートコンテキストを取得する。
00982   #
00983   # @param self
00984   #
00985   # @return ネームサーバのルートコンテキスト
00986   #
00987   # @else
00988   # @brief Get the root context
00989   # @endif
00990   def getRootContext(self):
00991     return self._rootContext
00992 
00993 
00994   ##
00995   # @if jp
00996   # @brief オブジェクトがネーミングコンテキストか判別する
00997   #
00998   # 指定した要素がネーミングコンテキストか判別する
00999   #
01000   # @param self
01001   # @param obj 判別対象要素
01002   #
01003   # @return 判別結果(ネーミングコンテキスト:true、それ以外:false)
01004   #
01005   # @else
01006   # @brief Whether the object is NamingContext
01007   # @endif
01008   def objIsNamingContext(self, obj):
01009     nc = obj._narrow(CosNaming.NamingContext)
01010     if CORBA.is_nil(nc):
01011       return False
01012     else:
01013       return True
01014 
01015 
01016   ##
01017   # @if jp
01018   # @brief 与えられた名前がネーミングコンテキストかどうか判別する
01019   #
01020   # NameComponent もしくは文字列で指定した要素がネーミングコンテキストか
01021   # 判別する
01022   #
01023   # @param self
01024   # @param name_list 判別対象
01025   #
01026   # @return 判別結果(ネーミングコンテキスト:true、それ以外:false)
01027   #
01028   # @else
01029   # @brief Whether the given name component is NamingContext
01030   # @endif
01031   def nameIsNamingContext(self, name_list):
01032     return self.objIsNamingContext(self.resolve(name_list))
01033 
01034 
01035   ##
01036   # @if jp
01037   # @brief ネームコンポーネントの部分を返す
01038   #
01039   # 指定された範囲のネームコンポーネントを取得する。
01040   # 終了位置が指定されていない場合は、最後の要素を除いたネームコンポーネント
01041   # を返す。
01042   #
01043   # @param self
01044   # @param name_list 検索対象NameComponent
01045   # @param begin 取得範囲開始位置
01046   # @param end 取得範囲終了位置(デフォルト値:None)
01047   #
01048   # @return NameComponent 取得結果
01049   #
01050   # @else
01051   # @brief Get subset of given name component
01052   # @endif
01053   def subName(self, name_list, begin, end = None):
01054     if end is None or end < 0:
01055       end = len(name_list) - 1
01056 
01057     sub_len = end - (begin -1)
01058     objId = ""
01059     kind  = ""
01060     
01061     sub_name = []
01062     for i in range(sub_len):
01063       sub_name.append(name_list[begin + i])
01064 
01065     return sub_name
01066 
01067 
01068   ##
01069   # @if jp
01070   # @brief ネームコンポーネントの文字列表現を取得する
01071   #
01072   # 指定した範囲のネームコンポーネントの文字列表現を取得する。
01073   # 文字列表現は、NameComponentの構成が{Nc[0],Nc[1],Nc[2]・・・}の場合、
01074   #   Nc[0]id.Nc[0].kind/Nc[1]id.Nc[1].kind/Nc[2].id/Nc[2].kind・・・
01075   # という形式で取得できる。
01076   # 取得した文字列の長さが指定した長さ以上の場合は、
01077   # 指定した長さで切り捨てられる。
01078   #
01079   # @param self
01080   # @param name_list 取得対象NameComponent
01081   # @param string_name 取得結果文字列
01082   # @param slen 取得対象文字列最大値
01083   #
01084   # @else
01085   # @brief Get string representation of name component
01086   # @endif
01087   def nameToString(self, name_list, string_name, slen):
01088     for i in range(len(name_list)):
01089       for id_ in name_list[i].id:
01090         if id_ == "/" or id_ == "." or id_ == "\\":
01091           string_name[0] += "\\"
01092         string_name[0] += id_
01093 
01094       if name_list[i].id == "" or name_list[i].kind != "":
01095         string_name[0] += "."
01096 
01097       for kind_ in name_list[i].kind:
01098         if kind_ == "/" or kind_ == "." or kind_ == "\\":
01099           string_name[0] += "\\"
01100         string_name[0] += kind_
01101 
01102       string_name[0] += "/"
01103 
01104 
01105   ##
01106   # @if jp
01107   # @brief ネームコンポーネントの文字列表現時の文字長を取得する
01108   #
01109   # 指定したネームコンポーネントを文字列で表現した場合の長さを取得する。
01110   # 文字列表現は、NameComponentの構成が{Nc[0],Nc[1],Nc[2]・・・}の場合、
01111   #   Nc[0]id.Nc[0].kind/Nc[1]id.Nc[1].kind/Nc[2].id/Nc[2].kind・・・
01112   # という形式で取得できる。
01113   #
01114   # @param self
01115   # @param name_list 取得対象NameComponent
01116   #
01117   # @return 指定したネームコンポーネントの文字列長さ
01118   #
01119   # @else
01120   # @brief Get string length of the name component's string representation
01121   # @endif
01122   def getNameLength(self, name_list):
01123     slen = 0
01124 
01125     for i in range(len(name_list)):
01126       for id_ in name_list[i].id:
01127         if id_ == "/" or id_ == "." or id_ == "\\":
01128           slen += 1
01129         slen += 1
01130       if name_list[i].id == "" or name_list[i].kind == "":
01131         slen += 1
01132 
01133       for kind_ in name_list[i].kind:
01134         if kind_ == "/" or kind_ == "." or kind_ == "\\":
01135           slen += 1
01136         slen += 1
01137 
01138       slen += 1
01139 
01140     return slen
01141 
01142 
01143   ##
01144   # @if jp
01145   # @brief 文字列の分割
01146   #
01147   # 文字列を指定したデリミタで分割する。
01148   #
01149   # @param self
01150   # @param input 分割対象文字列
01151   # @param delimiter 分割用デリミタ
01152   # @param results 分割結果
01153   #
01154   # @return 分割した文字列の要素数
01155   #
01156   # @else
01157   # @brief Split of string
01158   # @endif
01159   def split(self, input, delimiter, results):
01160     delim_size = len(delimiter)
01161     found_pos = begin_pos = pre_pos = substr_size = 0
01162 
01163     if input[0:delim_size] == delimiter:
01164       begin_pos = pre_pos = delim_size
01165 
01166     while 1:
01167       found_pos = string.find(input[begin_pos:],delimiter)
01168       
01169       if found_pos == -1:
01170         results.append(input[pre_pos:])
01171         break
01172 
01173       if found_pos > 0 and input[found_pos - 1] == "\\":
01174         begin_pos += found_pos + delim_size
01175       else:
01176         substr_size = found_pos + (begin_pos - pre_pos)
01177         if substr_size > 0:
01178           results.append(input[pre_pos:(pre_pos+substr_size)])
01179         begin_pos += found_pos + delim_size
01180         pre_pos   = begin_pos
01181 
01182     return len(results)


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Sat Jun 8 2019 18:49:03