[openrtm-users 00098] Re: 一つのRTコンポーネントから複数ネームサーバ登録に関して

Ando Noriaki n-ando @ aist.go.jp
2007年 4月 17日 (火) 16:54:00 JST


江口様

安藤です

お世話になっております。

> 初めて投稿させていただきます、内田洋行 江口と申します。
>
> 私の実行環境のRTMバージョンは、OpenRTM-aist-0.2.0
> OSは、Fedora Core 4です。
>
> 現在、一つのRTコンポーネントから複数のネームサーバに登録を行いたいと考え
> ているのですが、方法をご存知の方がいらっしゃいましたらアドバイスをいただ
> けませんでしょうか?
>
> 具体的には、RTコンポーネントの起動時に一つのネームサーバに登録を行うよう
> にしたときに、同じネットワークに新しいネームサーバがたった場合に、ネーム
> サーバの登録を古いサーバから新しいサーバに変えたいと考えております。

現状のRtcManagerにはそのような機能はありませんので、
ご自分で実装していただくしかありませんが、まもなくリリースする0.4.0では
複数のネームサーバを利用でき、かつrtc.confに記述されているネームサーバが
コンポーネント起動時点で動いていなくても、Managerが定期的にネームサーバが
起動しているかどうか見に行き、起動したら、それまで登録されていたコンポーネント
を全て新しいネームサーバに登録するようになっています。

ご希望の機能は、こういったものでよろしいでしょうか?
他に必要な機能がありましたらお知らせください。
余裕がありましたら実装したいと思います。

参考までに、その部分の0.4.0のソースをお送りいたします。
ただ、これを0.2.0のマネージャに組み込むのは少し面倒かもしれません。
もし組み込む場合は、NamingManagerクラスのupdate()を定期的に呼んでください。
なお、すでに存在しているネームサーバがなくなったときの処理はまだ書いていない
ので、その場合に新たに名前を登録しようとするとおそらく落ちます(笑

処理の概要は以下のとおりです。
CorbaNaming クラスはCORBA::ORB::resolve_initial_referenceではなく、
CORBA::ORB::string_to_objectを使用してネームサーバのオブジェクト参照を
取得し、参照やコンテキストのバインド・アンバインドを行います。
(なので、複数のNSを使用することができます。)
NamingManagerはCorbaNamingのインスタンスを複数作成・管理しており、
NamingManager::bindObjectで管理下にあるCorbaNamingを通して、
コンポーネントのバインドを行うと同時に、コンポーネントの名前とポインタを保存します。
update()を呼び出すと、未接続のCorbaNamingに対し、再度接続を試みて
接続できれば、NamingManagerに保存されているコンポーネントを
登録しに行くという流れです。

なお、OpenRTM-aist-0.4.0は4月中にはリリースしたいと考えております。
リリース時にはこのメーリングリストでも改めてお知らせいたします。

また、4月末か5月初めに産総研で、また5月の秋田のROBOMECで、
0.4.0を対象とした講習会も行う予定です。(まだ予定ですが。)
講習会についても日程等が決まりましたらこのMLでお知らせいたします。

どうぞよろしくお願いいたします。
-- 
安藤慶昭@独立行政法人産業技術総合研究所 研究員
                   知能システム研究部門 タスクインテリジェンス研究グループ
                   〒305-8568 茨城県つくば市梅園1-1-1 中央第2
                   TEL: 029-861-5981 FAX: 029-861-5971
                   n-ando @ aist.go.jp, n-ando @ ieee.org
-------------- next part --------------
// -*- C++ -*-
/*!
 * @file CorbaNaming.h
 * @brief CORBA naming service helper class
 * @date $Date: 2007/04/13 15:35:21 $
 * @author Noriaki Ando <n-ando @ aist.go.jp>
 *
 * Copyright (C) 2006
 *     Noriaki Ando
 *     Task-intelligence Research Group,
 *     Intelligent Systems Research Institute,
 *     National Institute of
 *         Advanced Industrial Science and Technology (AIST), Japan
 *     All rights reserved.
 *
 * $Id: CorbaNaming.h,v 1.2 2007/04/13 15:35:21 n-ando Exp $
 *
 */

/*
 * $Log: CorbaNaming.h,v $
 * Revision 1.2  2007/04/13 15:35:21  n-ando
 * Error handing processing in case NameServer does not exist was added.
 * Some bug fixes.
 *
 * Revision 1.1  2006/11/04 19:43:01  n-ando
 * CORBA Naming service helper class has rewritten and renamed.
 *
 */


#ifndef CorbaNaming_h
#define CorbaNaming_h

#include <rtm/RTC.h>
#ifdef ORB_IS_OMNIORB
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include <omniORB4/CORBA.h>
#endif

// STL includes
#include <map>
#include <string>
#include <vector>

namespace RTC
{
  /*!
   * @if jp
   * @class CorbaNaming
   * @brief CORBA Naming Service ??????????????
   *
   * ??????????????CosNaming::NamingContext ??????????????????????????????
   * CosNaming::NamingContext ????????????????????????????????????
   * ?????????????????????????????????????????????????????? CosNaming::Name
   * ????????????????????????????????????????????????????????????????????
   *
   * ???????????????????????????????????????? CORBA ????????????????????
   * ??????????????????????????????????????????????????????????????????????
   * ????????????
   * ????????????????????????????????????????????????????????????????????????
   * ??????????????????????????????????????????????????????????????????????
   * ????????????????????????????????????????????????????????????????
   *
   * @else
   * @class CorbaNaming
   * @brief CORBA Naming Service helper class
   *
   * This class is a wrapper class of CosNaming::NamingContext.
   * Almost the same operations which CosNaming::NamingContext has are
   * provided, and some operation allows string naming representation of
   * context and object instead of CosNaming::Name.
   *
   * The object of the class would connect to a CORBA naming server at
   * the instantiation or immediately after instantiation.
   * After that the object invokes operations to the root context of it.
   * This class realizes forced binding to deep NamingContext, without binding
   * intermediate NamingContexts explicitly.
   *
   * @endif
   */
  class CorbaNaming
  {
  public:
    CorbaNaming(CORBA::ORB_ptr orb);
    CorbaNaming(CORBA::ORB_ptr orb, const char* name_server);
    virtual ~CorbaNaming(){};
    void init(const char* name_server);

    typedef CosNaming::NamingContext::NotFound      NotFound;
    typedef CosNaming::NamingContext::CannotProceed CannotProceed;
    typedef CosNaming::NamingContext::InvalidName   InvalidName;
    typedef CosNaming::NamingContext::AlreadyBound  AlreadyBound;
    typedef CosNaming::NamingContext::NotEmpty      NotEmpty;
    typedef CosNaming::NamingContextExt::InvalidAddress InvalidAddress;
    typedef std::vector<CORBA::Object_ptr> ObjectList;


    /*!
     * @if jp
     *
     * @brief Object ?? bind ????
     *
     * CosNaming::bind() ??????????????????????????????????????????????????????
     * ??????????????????????????bind()??????????????????????????
     *
     * Name <name> ?? Object <obj> ?????? NamingContext ??????????????????
     * c_n ?? n ?????? NameComponent ????????????????????
     * name ?? n ???? NameComponent ????????????????????????????????????
     *
     * cxt->bind(<c_1, c_2, ... c_n>, obj) ??????????????????????????
     * cxt->resolve(<c_1, ... c_(n-1)>)->bind(<c_n>, obj)
     *
     * ??????????1????????n-1????????????????????????????n-1??????????????????
     * ???? name <n> ????????obj ?? bind ??????
     * ?????????????????? <c_1, ... c_(n-1)> ?? NemingContext ????
     * bindContext() ?? rebindContext() ??????????????????????????????????????
     * ???? <c_1, ... c_(n-1)> ?? NamingContext ??????????????????????
     * NotFound ????????????????
     *
     * ?????????????????????????? force ?? true ????????<c_1, ... c_(n-1)>
     * ??????????????????????????????????????????????????????????????
     * ???????? obj ?????? name <c_n> ????????????????
     *
     * ??????????????????n-1?????????????????????? name<n> ??????????????
     * (Object ???????? ????????????) ??????????????????????
     * AlreadyBound ????????????????
     *
     * @param name ?????????????????????????? NameComponent
     * @param obj ?????????????? Object
     * @param force true????????????????????????????????????????????????
     *
     * @exception NotFound ?????? <c_1, c_2, ..., c_(n-1)> ??????????????
     * @exception CannotProceed ??????????????????????????????????
     * @exception InvalidName ???? name ??????????????
     * @exception AlreadyBound name <c_n> ?? Object ????????????????????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void bind(const CosNaming::Name& name, CORBA::Object_ptr obj,
	      const bool force = 1)
      throw(NotFound, CannotProceed, InvalidName, AlreadyBound);


    /*!
     * @if jp
     *
     * @brief Object ?? bind ????
     *
     * Object ?? bind ????????????????????????????????????????????????bind()
     * ??????????????bind(toName(string_name), obj) ????????
     *
     * @param string_name ????????????????????????????????????
     * @param obj ??????????????????????????
     * @param force true????????????????????????????????????????????????
     *
     * @exception NotFound ?????? <c_1, c_2, ..., c_(n-1)> ??????????????
     * @exception CannotProceed ??????????????????????????????????
     * @exception InvalidName ???? name ??????????????
     * @exception AlreadyBound name <n> ?? Object ????????????????????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void bindByString(const char* string_name, CORBA::Object_ptr obj,
		      const bool force = 1)
      throw(NotFound, CannotProceed, InvalidName, AlreadyBound);

    /*!
     * @if jp
     *
     * @brief ???????????????????? bind ???????? Object ?? bind ????
     *
     * context ???????????? NamingContext ??????????name ????????????
     * ???????????????????? <c_1, ... c_(n-1)> ?? NamingContext ??????
     * ?????????????????? <c_n> ???????? obj ?? bind ??????
     * ??????<c_1, ... c_(n-1)> ?????????? NamingContext ??????????????
     * ?????? NamingContext ????????????????
     *
     * ???????? <c_1, c_2, ..., c_(n-1)> ?????????? NamingContext ??????
     * ??????????????????????CosNaming::bind(<c_n>, object) ????????????????
     * ?????????????????????????????????????????? AlreadyBound????????????????
     *
     * ??????????????????????????????????????????????????????????????????
     * ?????????? NamingContext ???????? Binding ????????????????
     * CannotProceed ????????????????????????????
     *
     * @param context bind ????????????NamingContext
     * @param name ??????????????????????????????????????????????
     * @param obj ??????????????????????????
     *
     * @exception CannotProceed <c_1, ..., c_(n-1)> ?????????? NamingContext 
     *            ?????????????????????? NamingContext ?????? object ??????????
     *            ????????????????????????????????
     * @exception InvalidName ???? name ??????
     * @exception AlreadyBound name <c_n> ???????????????? object ??????????
     *            ????????????
     * @else
     *
     * @brief
     *
     * @endif
     */
    void bindRecursive(CosNaming::NamingContext_ptr context,
		       const CosNaming::Name& name,
		       CORBA::Object_ptr obj)
      throw(CannotProceed, InvalidName, AlreadyBound);



    /*!
     * @if jp
     *
     * @brief Object ?? rebind ????
     *
     * name ???????????? Binding ???????????????????????????? bind() ??????
     * ??????????????????????????????????????????????????????????????????????
     * ????????????????
     *
     * @param name ?????????????????????????? NameComponent
     * @param obj ??????????????????????????
     * @param force true????????????????????????????????????????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void rebind(const CosNaming::Name& name, CORBA::Object_ptr obj,
		const bool force = 1)
      throw(NotFound, CannotProceed, InvalidName);


    /*!
     * @if jp
     *
     * @brief Object ?? rebind ????
     *
     * Object ?? rebind ?????????????????????????????????????????????? rebind()
     * ??????????????rebind(toName(string_name), obj) ????????
     *
     * @param string_name ????????????????????????????????????
     * @param obj ??????????????????????????
     * @param force true????????????????????????????????????????????????
     *
     * @exception NotFound ?????? <c_1, c_2, ..., c_(n-1)> ??????????????
     * @exception CannotProceed ??????????????????????????????????
     * @exception InvalidName ???? name ??????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void rebindByString(const char* string_name, CORBA::Object_ptr obj,
			const bool force = 1)
      throw(NotFound, CannotProceed, InvalidName);

    
    /*!
     * @if jp
     *
     * @brief ???????????????????? bind ???????? Object ?? rebind ????
     *
     * name <c_n> ???????????? NamingContext ???????? Object ????????????????
     * ???????????? bindRecursive() ??????????????
     *
     * name <c_n> ????????????????????????????????????????????????????
     * ??????????????????????????????????????
     *
     * @param name ????????????????????????????????????
     * @param obj ??????????????????????????
     * @param force true????????????????????????????????????????????????
     *
     * @exception CannotProceed ??????????????????????????????????
     * @exception InvalidName ?????????? name ????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void rebindRecursive(CosNaming::NamingContext_ptr context,
			 const CosNaming::Name& name,
			 CORBA::Object_ptr obj)
      throw(CannotProceed, InvalidName);

    /*!
     * @if jp
     *
     * @brief NamingContext ?? bind ????
     *
     * bind ???????????????????? NamingContext ?????????????????? bind() 
     * ??????????????
     *
     * @param name ??????????????????????????????????????????????
     * @param name_cxt ?????????????? NamingContext
     * @param force true????????????????????????????????????????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void bindContext(const CosNaming::Name& name,
		     CosNaming::NamingContext_ptr name_cxt,
		     const bool force = 1)
      throw(NotFound, CannotProceed, InvalidName, AlreadyBound);

    /*!
     * @if jp
     *
     * @brief NamingContext ?? bind ????
     *
     * bind ???????????????????? NamingContext ?????????????????? bind() 
     * ??????????????
     *
     * @param name ????????????????????????????????????
     * @param name_cxt ?????????????? NamingContext
     * @param force true????????????????????????????????????????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void bindContext(const char* string_name,
		     CosNaming::NamingContext_ptr name_cxt,
		     const bool force = 1)
      throw(NotFound, CannotProceed, InvalidName, AlreadyBound);

    /*!
     * @if jp
     *
     * @brief NamingContext ?? bind ????
     *
     * bind ???????????????????? NamingContext ??????????????????
     * bindRecursive() ??????????????
     *
     * @param context bind ????????????NamingContext
     * @param name ??????????????????????????????????????????????
     * @param name_cxt ?????????????? NamingContext
     * @param force true????????????????????????????????????????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void bindContextRecursive(CosNaming::NamingContext_ptr context,
			      const CosNaming::Name& name,
			      CosNaming::NamingContext_ptr name_cxt);
    /*!
     * @if jp
     *
     * @brief NamingContext ?? rebind ????
     *
     * name ???????????????????????????????????????????????????? bindContext() 
     * ??????????????
     * ??????????????????????????????????????????????????????????????
     * ????????????????
     *
     * @param name ??????????????????????????????????????????????
     * @param name_cxt ?????????????? NamingContext
     * @param force true????????????????????????????????????????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void rebindContext(const CosNaming::Name& name,
		       CosNaming::NamingContext_ptr name_cxt,
		       const bool force = 1)
      throw(NotFound, CannotProceed, InvalidName);

    /*!
     * @if jp
     *
     * @brief NamingContext ?? rebind ????
     *
     * name ???????????????????????????????????????????????????? bindContext() 
     * ??????????????
     * ??????????????????????????????????????????????????????????????
     * ????????????????
     *
     * @param name ????????????????????????????????????
     * @param name_cxt ?????????????? NamingContext
     * @param force true????????????????????????????????????????????????
     *
     * @else
     *
     * @brief
     *
     * @endif
     */
    void rebindContext(const char* string_name,
		       CosNaming::NamingContext_ptr name_cxt,
		       const bool force = 1)
      throw(NotFound, CannotProceed, InvalidName);


    void rebindContextRecursive(CosNaming::NamingContext_ptr context,
				const CosNaming::Name& name,
				CosNaming::NamingContext_ptr name_cxt);

    /*!
     * @if jp
     *
     * @brief Object ?? name ????????????
     *
     * name ?? bind ??????????????????????????????????
     * ???????????????????? <c_1, c_2, ... c_n> ??????????????????????
     * 
     * CosNaming::resolve() ????????????????????????????????????????
     * ???????????????????????????????????????? resolve() ??????????????????
     * ????????
     *
     * @param name ??????????????????????????????????????????????????
     * @return ??????????????????????????
     *
     * @else
     *
     * @endif
     */
    CORBA::Object_ptr resolve(const CosNaming::Name& name)
      throw(NotFound, CannotProceed, InvalidName);

    /*!
     * @if jp
     *
     * @brief Object ?? name ????????????
     *
     * name ?? bind ??????????????????????????????????
     * ???????????????????? <c_1, c_2, ... c_n> ??????????????????????
     * 
     * CosNaming::resolve() ????????????????????????????????????????
     * ???????????????????????????????????????? resolve() ??????????????????
     * ????????
     *
     * @param name ????????????????????????????????????????
     * @return ??????????????????????????
     *
     * @else
     *
     * @endif
     */
    CORBA::Object_ptr resolve(const char* string_name)
      throw(NotFound, CannotProceed, InvalidName);

    /*!
     * @if jp
     *
     * @brief ?????????????????????????????? bind ??????????
     *
     * name ?? bind ??????????????????????????????????
     * ???????????????????? <c_1, c_2, ... c_n> ??????????????????????
     * 
     * CosNaming::unbind() ????????????????????????????????????????
     * ???????????????????????????????????????? unbind() ??????????????????
     * ????????
     *
     * @param name ??????????????????????????????????????????????????
     * @return ??????????????????????????
     *
     * @else
     *
     * @endif
     */
    void unbind(const CosNaming::Name& name)
      throw(NotFound, CannotProceed, InvalidName);

    /*!
     * @if jp
     *
     * @brief ?????????????????????????????? bind ??????????
     *
     * name ?? bind ??????????????????????????????????
     * ???????????????????? <c_1, c_2, ... c_n> ??????????????????????
     * 
     * CosNaming::unbind() ????????????????????????????????????????
     * ???????????????????????????????????????? unbind() ??????????????????
     * ????????
     *
     * @param name ????????????????????????????????????????
     * @return ??????????????????????????
     *
     * @else
     *
     * @endif
     */
    void unbind(const char* string_name)
      throw(NotFound, CannotProceed, InvalidName);

    /*!
     * @if jp
     *
     * @brief ????????????????????????????
     *
     * ???????????????????????????????????? NamingContext ????????
     * ???????? NamingContext ?? bind ??????????????
     * 
     * @return ???????????????? NamingContext
     *
     * @else
     *
     * @endif
     */
    CosNaming::NamingContext_ptr newContext();

    /*!
     * @if jp
     *
     * @brief ???????????????????? bind ????
     *
     * ?????????? name ??????????????????????????????????????????
     * ????????????NamingContext ????????????????????????????????????????
     * 
     * @param name NamingContext??????????????????????????????????
     * @return ???????????????? NamingContext
     *
     * @else
     *
     * @endif
     */
    CosNaming::NamingContext_ptr
    bindNewContext(const CosNaming::Name& name, bool force = true)
      throw(NotFound, CannotProceed, InvalidName, AlreadyBound);

    /*!
     * @if jp
     *
     * @brief ???????????????????? bind ????
     *
     * ?????????? name ??????????????????????????????????????????
     * ????????????NamingContext ????????????????????????????????????????
     * 
     * @param name NamingContext????????????????????????
     * @return ???????????????? NamingContext
     *
     * @else
     *
     * @endif
     */
    CosNaming::NamingContext_ptr
    bindNewContext(const char* string_name, bool force = true)
      throw(NotFound, CannotProceed, InvalidName, AlreadyBound);

    /*!
     * @if jp
     *
     * @brief NamingContext ????????????????????
     *
     * context ???????????? NamingContext ??????????????????????
     * context ???????????????????????????????????????????? NotEmpty ??????
     * ??????????
     * 
     * @param context ?????????????????? NamingContext
     *
     * @else
     *
     * @brief Destroy the naming context
     *
     * Delete the specified naming context.
     * any bindings should be <unbind> in which the given context is bound to
     * some names before invoking <destroy> operation on it. 
     *
     * @param context NamingContext which is destroied.
     *     
     * @endif
     */
    void destroy(CosNaming::NamingContext_ptr context)
      throw(NotEmpty);


    /*!
     * @if jp
     * @brief NamingContext ??????????????????????????????????
     * @else
     * @brief Destroy the naming context recursively
     * @endif
     */
    void destroyRecursive(CosNaming::NamingContext_ptr context)
      throw(NotEmpty, NotFound, CannotProceed, InvalidName);


    /*!
     * @if jp
     * @brief ???????? Binding ??????????
     * @else
     * @brief Destroy all binding
     * @endif
     */
    void clearAll();


    /*!
     * @if jp
     * @brief ?????????? NamingContext ?? Binding ??????????
     * @else
     * @brief Get Binding on the NamingContextDestroy all binding
     * @endif
     */
    void list(CosNaming::NamingContext_ptr name_cxt,
	      unsigned long how_many,
	      CosNaming::BindingList_var& bl,
	      CosNaming::BindingIterator_var& bi);


    //============================================================
    // interface of NamingContextExt
    //============================================================
    /*!
     * @if jp
     * @brief ?????????? NameComponent ??????????????????
     * @else
     * @brief Get string representation of given NameComponent
     * @endif
     */
    char* toString(const CosNaming::Name& name)
      throw(InvalidName);
    

    /*!
     * @if jp
     * @brief ?????????????????????? NameComponent ??????????
     * @else
     * @brief Get NameComponent from gien string name representation
     * @endif
     */
    CosNaming::Name toName(const char* string_name)
      throw(InvalidName);


    /*!
     * @if jp
     * @brief ?????????? addre ?? string_name ???? URL??????????????
     * @else
     * @brief Get URL representation from given addr and string_name
     * @endif
     */
    char* toUrl(char* addr, char* string_name)
      throw(InvalidAddress, InvalidName);


    /*!
     * @if jp
     * @brief ?????????????????????? resolve ????????????????????
     * @else
     * @brief Resolve from name of string representation and get object 
     * @endif
     */
    CORBA::Object_ptr resolveStr(const char* string_name)
      throw(NotFound, CannotProceed, InvalidName, AlreadyBound);


    //============================================================
    // Find functions
    //============================================================

    //    ObjectList find(const char* name, const char* kind);
    //    ObjectList findById(const char* name, const char* kind);
    //    ObjectList findByKind(const char* name, const char* kind);

    /*!
     * @if jp
     * @brief ????????????????????????????
     * @else
     * @brief Bind of resolve the given name component
     * @endif
     */
    CORBA::Object_ptr bindOrResolve(CosNaming::NamingContext_ptr context,
				    const CosNaming::Name& name,
				    CORBA::Object_ptr obj);
    
    /*!
     * @if jp
     * @brief ????????????????????????????
     * @else
     * @brief Bind of resolve the given name component
     * @endif
     */
    CosNaming::NamingContext_ptr
    bindOrResolveContext(CosNaming::NamingContext_ptr context,
			 const CosNaming::Name& name,
			 CosNaming::NamingContext_ptr new_context);

    
    /*!
     * @if jp
     * @brief ????????????????????????????
     * @else
     * @brief Bind of resolve the given name component
     * @endif
     */
    CosNaming::NamingContext_ptr
    bindOrResolveContext(CosNaming::NamingContext_ptr context,
			 const CosNaming::Name& name);


    /*!
     * @if jp
     * @brief ????????????????????????????
     * @else
     * @brief Get the name of naming server
     * @endif
     */
    const char* getNameServer();
    
    /*!
     * @if jp
     * @brief ????????????????????????????
     * @else
     * @brief Get the root context
     * @endif
     */
    CosNaming::NamingContext_ptr getRootContext();

    
    /*!
     * @if jp
     * @brief ??????????????????????????????????????????????
     * @else
     * @brief Whether the object is NamingContext
     * @endif
     */
    bool isNamingContext(CORBA::Object_ptr obj);
    
    /*!
     * @if jp
     * @brief ??????????????????????????????????????????????
     * @else
     * @brief Whether the given name component is NamingContext
     * @endif
     */
    bool isNamingContext(const CosNaming::Name& name);
    
    /*!
     * @if jp
     * @brief ??????????????????????????????????????????????
     * @else
     * @brief Whether the given string name is NamingContext
     * @endif
     */
    bool isNamingContext(const char* string_name);
    
    /*!
     * @if jp
     * @brief ????????????????????????????????
     * @else
     * @brief Get subset of given name component
     * @endif
     */
    CosNaming::Name subName(const CosNaming::Name& name,
			    long begin,
			    long end = -1);


  protected:
    /*!
     * @if jp
     * @brief ??????????????????????????????????????????
     * @else
     * @brief Get string representation of name component
     * @endif
     */
    void nameToString(const CosNaming::Name& name, char* string_name,
		      unsigned long slen);
    /*!
     * @if jp
     * @brief ????????????????????????????????????????????????????
     * @else
     * @brief Get string length of the name component's string representation
     * @endif
     */
    CORBA::ULong getNameLength(const CosNaming::Name& name);

    /*!
     * @if jp
     * @brief ????????????
     * @else
     * @brief Split of string
     * @endif
     */
    unsigned int split(const std::string& input,
		       const std::string& delimiter,
		       std::vector<std::string>& results);


    
    CORBA::ORB_var m_varORB;
    std::string m_nameServer;
    CosNaming::NamingContextExt_var m_rootContext;

  private:
    CORBA::ULong m_blLength;
    
  }; // class CorbaNaming

}; // namespace RTC

#endif // end of __Naming_h__
-------------- next part --------------
// -*- C++ -*-
/*!
 * @file CorbaNaming.cpp
 * @brief CORBA naming service helper class
 * @date $Date: 2007/04/13 15:35:16 $
 * @author Noriaki Ando <n-ando @ aist.go.jp>
 *
 * Copyright (C) 2006
 *     Noriaki Ando
 *     Task-intelligence Research Group,
 *     Intelligent Systems Research Institute,
 *     National Institute of
 *         Advanced Industrial Science and Technology (AIST), Japan
 *     All rights reserved.
 *
 * $Id: CorbaNaming.cpp,v 1.3 2007/04/13 15:35:16 n-ando Exp $
 *
 */

/*
 * $Log: CorbaNaming.cpp,v $
 * Revision 1.3  2007/04/13 15:35:16  n-ando
 * Error handing processing in case NameServer does not exist was added.
 * Some bug fixes.
 *
 * Revision 1.2  2007/01/21 09:05:47  n-ando
 * "assert.h" is included.
 *
 * Revision 1.1  2006/11/04 19:42:55  n-ando
 * CORBA Naming service helper class has rewritten and renamed.
 *
 */

#ifdef WIN32
#define ACE_HAS_WINSOCK2 0
#endif //WIN32

#include <assert.h>
#include <rtm/CorbaNaming.h>
#include <iostream>

namespace RTC
{
  CorbaNaming::CorbaNaming(CORBA::ORB_ptr orb)
    : m_varORB(orb), m_nameServer(""),
      m_rootContext(CosNaming::NamingContextExt::_nil()),
      m_blLength(100)
  {
  }


  CorbaNaming::CorbaNaming(CORBA::ORB_ptr orb,
				 const char* name_server)
    : m_varORB(CORBA::ORB::_duplicate(orb)), m_nameServer(name_server),
      m_rootContext(CosNaming::NamingContextExt::_nil()),
      m_blLength(100)
  {
    CORBA::Object_var obj;
    m_nameServer = "corbaloc::" + m_nameServer + "/NameService";
    try
      {
	obj = m_varORB->string_to_object(m_nameServer.c_str());
	std::cout << m_varORB->object_to_string(obj) << std::endl;
	m_rootContext = CosNaming::NamingContextExt::_narrow(obj);
	if (CORBA::is_nil(m_rootContext)) throw std::bad_alloc();
      }
    catch(...)
      {
	throw std::bad_alloc();
      }
  }
  

  void CorbaNaming::init(const char* name_server)
  {
    m_nameServer = name_server;
    m_nameServer = "corbaloc::" + m_nameServer + "/NameService";
    CORBA::Object_var obj;
    obj = m_varORB->string_to_object(m_nameServer.c_str());
    m_rootContext = CosNaming::NamingContextExt::_narrow(obj);
    if (CORBA::is_nil(m_rootContext)) throw std::bad_alloc();
  }


  /*!
   * @if jp
   * @brief Object ?? bind ????
   * @else
   * @brief Bind object on specified name component position
   * @endif
   */
  void CorbaNaming::bind(const CosNaming::Name& name, CORBA::Object_ptr obj,
			    const bool force)
    throw(NotFound, CannotProceed, InvalidName, AlreadyBound)
  {
    try
      {
	m_rootContext->bind(name, obj);
      }
    catch (NotFound& e)
      {
	force ? bindRecursive(m_rootContext, name, obj) : throw e;
      }
    catch (CannotProceed& e)
      {
	force ? bindRecursive(e.cxt, e.rest_of_name, obj) : throw e;
      }
  }
  
  
  /*!
   * @if jp
   * @brief Object ?? bind ????
   * @else
   * @brief Bind object on specified string name position
   * @endif
   */
  void CorbaNaming::bindByString(const char* string_name, CORBA::Object_ptr obj,
			    const bool force)
    throw(NotFound, CannotProceed, InvalidName, AlreadyBound)
  {
    this->bind(toName(string_name), obj, force);
  }
  
  
  /*!
   * @if jp
   * @brief ???????????????????????????? bind ???????? Object ?? bind ????
   * @else
   * @brief Bind intermediate context recursively and bind object
   * @endif
   */
  void CorbaNaming::bindRecursive(CosNaming::NamingContext_ptr context,
				     const CosNaming::Name& name,
				     CORBA::Object_ptr obj)
    throw(CannotProceed, InvalidName, AlreadyBound)
  {
    CORBA::ULong len(name.length());
    CosNaming::NamingContext_var cxt;
    cxt = CosNaming::NamingContext::_duplicate(context);
    
    for (CORBA::ULong i = 0; i < len; ++i)
      {
	if (i == (len - 1))
	  { // this operation may throw AlreadyBound, 
	    cxt->bind(subName(name, i, i), obj);
	    return;
	  }
	else
	  { // If the context is not a NamingContext, CannotProceed is thrown
	    if (isNamingContext(cxt))
	      cxt = bindOrResolveContext(cxt, subName(name, i, i));
	    else
	      throw CannotProceed(cxt, subName(name, i));
	  }
      }
    return;
  }
  
  
  /*!
   * @if jp
   * @brief Object ?? rebind ????
   * @else
   * @brief Rebind object
   * @endif
   */
  void CorbaNaming::rebind(const CosNaming::Name& name,
			      CORBA::Object_ptr obj,
			      const bool force)
    throw(NotFound, CannotProceed, InvalidName)
  {
    try
      {
	m_rootContext->rebind(name, obj);
      }
    catch (NotFound& e)
      {
	force ? rebindRecursive(m_rootContext, name, obj) : throw e;
      }
    catch (CannotProceed& e)
      {
	force ? rebindRecursive(e.cxt, e.rest_of_name, obj) : throw e;
      }
  }
  
  
  /*!
   * @if jp
   * @brief Object ?? rebind ????
   * @else
   * @brief Rebind object
   * @endif
   */
  void CorbaNaming::rebindByString(const char* string_name,
				      CORBA::Object_ptr obj,
				      const bool force)
    throw(NotFound, CannotProceed, InvalidName)
  {
    rebind(toName(string_name), obj, force);
  }
  
  
  /*!
   * @if jp
   * @brief Object ?? rebind ????
   * @else
   * @brief Rebind object
   * @endif
   */
  void CorbaNaming::rebindRecursive(CosNaming::NamingContext_ptr context,
				       const CosNaming::Name& name,
				       CORBA::Object_ptr obj)
    throw(CannotProceed, InvalidName)
  {
    CORBA::ULong len(name.length());
    CosNaming::NamingContext_var cxt;
    cxt = CosNaming::NamingContext::_duplicate(context);
    
    for (CORBA::ULong i = 0; i < len; ++i)
      {
	if (i == (len - 1))
	  {
	    cxt->rebind(subName(name, i, i), obj);
	    return;
	  }
	else
	  { // If the context is not a NamingContext, CannotProceed is thrown
	    if (isNamingContext(cxt))
	      {
		try
		  {
		    cxt = cxt->bind_new_context(subName(name, i, i));
		  }
		catch (AlreadyBound& e)
		  {
		    cxt = CosNaming::
		      NamingContextExt::
		      _narrow(cxt->resolve(subName(name, i, i)));
		  }
	      }
	    else
	      throw CannotProceed(cxt, subName(name, i));
	  }
      }
    return;
  }
  
  
  /*!
   * @if jp
   * @brief NamingContext ?? bind ????
   * @else
   * @brief Bind NamingContext
   * @endif
   */
  void CorbaNaming::bindContext(const CosNaming::Name& name,
				   CosNaming::NamingContext_ptr name_cxt,
				   const bool force)
    throw(NotFound, CannotProceed, InvalidName, AlreadyBound)
  {
    bind(name, name_cxt, force);
  }
  
  
  /*!
   * @if jp
   * @brief NamingContext ?? bind ????
   * @else
   * @brief Bind NamingContext
   * @endif
   */
  void CorbaNaming::bindContext(const char* string_name,
				   CosNaming::NamingContext_ptr name_cxt,
				   const bool force)
    throw(NotFound, CannotProceed, InvalidName, AlreadyBound)
  {
    bindContext(toName(string_name), name_cxt, force);
  }
  
  
  /*!
   * @if jp
   * @brief ???????????????????????????? bind ?? NamingContext ?? bind ????
   * @else
   * @brief Rebind object
   * @endif
   */
  void
  CorbaNaming::bindContextRecursive(CosNaming::NamingContext_ptr context,
				       const CosNaming::Name& name,
				       CosNaming::NamingContext_ptr name_cxt)
  {
    bindRecursive(context, name, name_cxt);
    return;
  }
  
  
  /*!
   * @if jp
   * @brief NamingContext ?? rebind ????
   * @else
   * @brief Rebind NamingContext
   * @endif
   */
  void CorbaNaming::rebindContext(const CosNaming::Name& name,
				     CosNaming::NamingContext_ptr name_cxt,
				     const bool force)
    throw(NotFound, CannotProceed, InvalidName)
  {
    rebind(name, name_cxt, force);
    return;
  }
  
  
  /*!
   * @if jp
   * @brief NamingContext ?? rebind ????
   * @else
   * @brief Rebind NamingContext
   * @endif
   */
  void CorbaNaming::rebindContext(const char* string_name,
				     CosNaming::NamingContext_ptr name_cxt,
				     const bool force)
    throw(NotFound, CannotProceed, InvalidName)
  {
    rebindContext(toName(string_name), name_cxt, force);
  }
  
  
  /*!
   * @if jp
   * @brief ???????????????????????????? rebind ?? NamingContext ?? rebind ????
   * @else
   * @brief Create or resolve intermediate context and rebind NamingContext 
   * @endif
   */
  void
  CorbaNaming::rebindContextRecursive(CosNaming::NamingContext_ptr context,
					 const CosNaming::Name& name,
					 CosNaming::NamingContext_ptr name_cxt)
  {
    rebindRecursive(context, name, name_cxt);
    return;
  }
  
  
  /*!
   * @if jp
   * @brief ?????????? NameComponent ???????????????????? Object ??????
   * @else
   * @brief Return object bound on the specified NameComponent
   * @endif
   */
  CORBA::Object_ptr CorbaNaming::resolve(const CosNaming::Name& name)
    throw(NotFound, CannotProceed, InvalidName)
  { 
    return m_rootContext->resolve(name);
  }
  
  
  /*!
   * @if jp
   * @brief ?????????? NameComponent ???????????????????? Object ??????
   * @else
   * @brief Return object bound on the specified NameComponent
   * @endif
   */
  CORBA::Object_ptr CorbaNaming::resolve(const char* string_name)
    throw(NotFound, CannotProceed, InvalidName)
  { 
    return resolve(toName(string_name));
  }
  
  
  /*!
   * @if jp
   * @brief ?????????? NameComponent ??????????????????????????
   * @else
   * @brief Unbind a binding specified by NameComponent
   * @endif
   */   
  void CorbaNaming::unbind(const CosNaming::Name& name)
    throw(NotFound, CannotProceed, InvalidName)
  {
    m_rootContext->unbind(name);
  }
  
  
  /*!
   * @if jp
   * @brief ?????????? NameComponent ??????????????????????????
   * @else
   * @brief Unbind a binding specified by NameComponent
   * @endif
   */
  void CorbaNaming::unbind(const char* string_name)
    throw(NotFound, CannotProceed, InvalidName)
  {
    unbind(toName(string_name));
  }
  
  
  /*!
   * @if jp
   * @brief ????????????????????????????
   * @else
   * @brief Create new NamingContext
   * @endif
   */
  CosNaming::NamingContext_ptr CorbaNaming::newContext()
  {
    return m_rootContext->new_context();
  }
  
  
  /*!
   * @if jp
   * @brief ???????????????????? bind ????
   * @else
   * pbrief Bind new namingContext
   * @endif
   */
  CosNaming::NamingContext_ptr
  CorbaNaming::bindNewContext(const CosNaming::Name& name, bool force)
    throw(NotFound, CannotProceed, InvalidName, AlreadyBound)
  {
    try
      {
	return m_rootContext->bind_new_context(name);
      }
    catch (NotFound& e)
      {
	force ? bindRecursive(m_rootContext, name, newContext()) : throw e;
      }
    catch (CannotProceed& e)
      {
	force ? bindRecursive(e.cxt, e.rest_of_name, newContext()) : throw e;
      }
    return CosNaming::NamingContext::_nil();
  }
  
  
  /*!
   * @if jp
   * @brief ???????????????????? bind ????
   * @else
   * pbrief Bind new namingContext
   * @endif
   */
  CosNaming::NamingContext_ptr
  CorbaNaming::bindNewContext(const char* string_name, bool force)
    throw(NotFound, CannotProceed, InvalidName, AlreadyBound)
  {
    return bindNewContext(toName(string_name));
  }
  
  
  /*!
   * @if jp
   * @brief NamingContext ????????????????????
   * @else
   * @brief Destroy the naming context
   * @endif
   */
  void CorbaNaming::destroy(CosNaming::NamingContext_ptr context)
    throw(NotEmpty)
  {
    context->destroy();
  }
  
  
  /*!
   * @if jp
   * @brief NamingContext ??????????????????????????????????
   * @else
   * @brief Destroy the naming context recursively
   * @endif
   */
  void CorbaNaming::destroyRecursive(CosNaming::NamingContext_ptr context)
    throw(NotEmpty, NotFound, CannotProceed, InvalidName)
  {
    CosNaming::BindingList_var     bl;
    CosNaming::BindingIterator_var bi;
    CORBA::Boolean cont(true);
    
    context->list(m_blLength, bl, bi);
    
    while (cont)
      {
	CORBA::ULong len(bl->length());
	
	for (CORBA::ULong i = 0; i < len; ++i)
	  {
	    if (bl[i].binding_type == CosNaming::ncontext)
	      {	// If Object is context, destroy recursive.
		CosNaming::NamingContext_var next_context;
		next_context = CosNaming::NamingContext::
		  _narrow(context->resolve(bl[i].binding_name));
		
		// Recursive function call
		destroyRecursive(next_context); // +++ Recursive call +++
		context->unbind(bl[i].binding_name);
		next_context->destroy();
	      }
	    else if (bl[i].binding_type == CosNaming::nobject)
	      {	// If Object is object, unbind it.
		context->unbind(bl[i].binding_name);
	      }
	    else assert(0); // never comes here
	  }
	
	// no more binding -> do-while loop will be finished
	if (CORBA::is_nil(bi)) cont = false;
	else bi->next_n(m_blLength, bl);
      }
    
    if (!CORBA::is_nil(bi)) bi->destroy();
    return;
  }
  
  
  /*!
   * @if jp
   * @brief ???????? Binding ??????????
   * @else
   * @brief Destroy all binding
   * @endif
   */
  void CorbaNaming::clearAll()
  {
    destroyRecursive(m_rootContext);
  }
  
  
  /*!
   * @if jp
   * @brief ?????????? NamingContext ?? Binding ??????????
   * @else
   * @brief Get Binding on the NamingContextDestroy all binding
   * @endif
   */
  void CorbaNaming::list(CosNaming::NamingContext_ptr name_cxt,
			    unsigned long how_many,
			    CosNaming::BindingList_var& bl,
			    CosNaming::BindingIterator_var& bi)
  {
    name_cxt->list(how_many, bl, bi);
  }
  
  
  /*!
   * @if jp
   * @brief ?????????? NameComponent ??????????????????
   * @else
   * @brief Get string representation of given NameComponent
   * @endif
   */
  char* CorbaNaming::toString(const CosNaming::Name& name)
    throw(InvalidName)
  {
    if (name.length() == 0)
      throw InvalidName();
    
    CORBA::ULong slen = 0;
    slen = getNameLength(name);
    
    char* string_name = CORBA::string_alloc(slen);
    nameToString(name, string_name, slen);
    
    return string_name;
  }
  
  
  /*!
   * @if jp
   * @brief ?????????????????????? NameComponent ??????????
   * @else
   * @brief Get NameComponent from gien string name representation
   * @endif
   */
  CosNaming::Name CorbaNaming::toName(const char* sname)
    throw(InvalidName)
  {
    if (!sname)         throw InvalidName();
    if (*sname == '\0') throw InvalidName();
    
    std::string string_name(sname);
    std::vector<std::string> name_comps;
    
    // String name should include 1 or more names
    CORBA::ULong nc_length = 0;
    nc_length = split(string_name, std::string("/"), name_comps);
    if (!(nc_length > 0)) throw InvalidName();
    
    // Name components are allocated
    CosNaming::Name*    namep = new CosNaming::Name;
    CosNaming::Name_var name(namep);
    name->length(nc_length);
    
    // Insert id and kind to name components
    for (CORBA::ULong i = 0; i < nc_length; ++i)
      {
	std::string::size_type pos;
	pos = name_comps[i].find_last_of(".");
	if (pos != 0)
	  {
	    name[i].id   = 
	      CORBA::string_dup(name_comps[i].substr(0, pos).c_str());
	    name[i].kind = 
	      CORBA::string_dup(name_comps[i].substr(pos + 1).c_str());
	  }
	else
	  {
	    name[i].id   = CORBA::string_dup(name_comps[i].c_str());
	    name[i].kind = "";
	  }
      }
    return name;
  }
  
  
  /*!
   * @if jp
   * @brief ?????????? addre ?? string_name ???? URL??????????????
   * @else
   * @brief Get URL representation from given addr and string_name
   * @endif
   */
  char* CorbaNaming::toUrl(char* addr, char* string_name)
    throw(InvalidAddress, InvalidName)
  {
    return m_rootContext->to_url(addr, string_name);
  }
  
  
  /*!
   * @if jp
   * @brief ?????????????????????? resolve ????????????????????
   * @else
   * @brief Resolve from name of string representation and get object 
   * @endif
   */
  CORBA::Object_ptr CorbaNaming::resolveStr(const char* string_name)
    throw(NotFound, CannotProceed, InvalidName, AlreadyBound)
  {
    return resolve(string_name);
  }
  
  
  
  //======================================================================
  // Util functions
  //======================================================================
  /*!
   * @if jp
   * @brief ????????????????????????????
   * @else
   * @brief Bind of resolve the given name component
   * @endif
   */
  CORBA::Object_ptr
  CorbaNaming::bindOrResolve(CosNaming::NamingContext_ptr context,
				const CosNaming::Name& name,
				CORBA::Object_ptr obj)
  {
    try
      {
	context->bind(name, obj);
	return obj;
      }
    catch (AlreadyBound& e)
      {
	return context->resolve(name);
      }
    return CORBA::Object::_nil();
  }
  
  
  /*!
   * @if jp
   * @brief ????????????????????????????
   * @else
   * @brief Bind of resolve the given name component
   * @endif
   */
  CosNaming::NamingContext_ptr
  CorbaNaming::bindOrResolveContext(CosNaming::NamingContext_ptr context,
				       const CosNaming::Name& name,
				       CosNaming::NamingContext_ptr new_context)
  {
    return CosNaming::NamingContext::_narrow(bindOrResolve(context, name, new_context));
  }
  
  
  /*!
   * @if jp
   * @brief ????????????????????????????
   * @else
   * @brief Bind of resolve the given name component
   * @endif
   */
  CosNaming::NamingContext_ptr
  CorbaNaming::bindOrResolveContext(CosNaming::NamingContext_ptr context,
				       const CosNaming::Name& name)
  {
    return bindOrResolveContext(context, name, newContext());
  }
  
  
  
  /*!
   * @if jp
   * @brief ????????????????????????????
   * @else
   * @brief Get the name of naming server
   * @endif
   */
  const char* CorbaNaming::getNameServer()
  {
    return m_nameServer.c_str();
  }
  
  
  /*!
   * @if jp
   * @brief ????????????????????????????
   * @else
   * @brief Get the root context
   * @endif
   */
  CosNaming::NamingContext_ptr CorbaNaming::getRootContext()
  {
    return m_rootContext;
  }
  
  
  /*!
   * @if jp
   * @brief ??????????????????????????????????????????????
   * @else
   * @brief Whether the object is NamingContext
   * @endif
   */
  bool CorbaNaming::isNamingContext(CORBA::Object_ptr obj)
  {
    CosNaming::NamingContext_var nc;
    nc = CosNaming::NamingContext::_narrow(obj);
    return CORBA::is_nil(nc) ? false : true;
  }
  
  
  /*!
   * @if jp
   * @brief ??????????????????????????????????????????????
   * @else
   * @brief Whether the given name component is NamingContext
   * @endif
   */
  bool CorbaNaming::isNamingContext(const CosNaming::Name& name)
  {
    return isNamingContext(resolve(name));
  }
  
  
  /*!
   * @if jp
   * @brief ??????????????????????????????????????????????
   * @else
   * @brief Whether the given string name is NamingContext
   * @endif
   */
  bool CorbaNaming::isNamingContext(const char* string_name)
  {
    return isNamingContext(resolve(string_name));
  }
  
  
  /*!
   * @if jp
   * @brief ????????????????????????????????
   * @else
   * @brief Get subset of given name component
   * @endif
   */
  CosNaming::Name CorbaNaming::subName(const CosNaming::Name& name,
				       long begin,
				       long end)
  {
    if (end < 0) end = name.length() - 1;
    
    CosNaming::Name sub_name;
    CORBA::ULong sub_len(end - (begin - 1));
    if (sub_len > 0)
      {
	sub_name.length(sub_len);
      }
    else
      {
	sub_name.length(0);
	return sub_name;
      }
    
    for (CORBA::ULong i = 0; i < sub_len; ++i)
      {
	sub_name[i] = name[begin + i];
      }
    return sub_name;
  }
  
  
  //------------------------------------------------------------
  // Protected member functions
  //------------------------------------------------------------
  /*!
   * @if jp
   * @brief ??????????????????????????????????????????
   * @else
   * @brief Get string representation of name component
   * @endif
   */
  void CorbaNaming::nameToString(const CosNaming::Name& name,
				    char* string_name,
				    unsigned long slen)
  {
    char* s = string_name;
    for (CORBA::ULong i = 0; i < name.length(); ++i)
      {
	// Copy id to string_name
	for (const char* id = name[i].id; *id != '\0'; ++id)
	  {
	    if (*id == '/' || *id == '.' || *id == '\\') *s++ = '\\';
	    *s++ = *id;
	  }
	// '.' if there is a kind, or no id
	if (((const char*)(name[i].id  ))[0] == '\0' || 
	    ((const char*)(name[i].kind))[0] != '\0')
	  *s++ = '.';
	// Copy kind to string_name
	for (const char* kind = name[i].kind; *kind != '\0'; ++kind)
	  {
	    if (*kind == '/' || *kind == '.' || *kind == '\\')
	      *s++ = '\\';
	    *s++ = *kind;
	  }
	// The end of string_name will be overwritten by '\0'
	*s++ = '/';
      }
    string_name[slen-1] = '\0';
  }
  
  
  /*!
   * @if jp
   * @brief ????????????????????????????????????????????????????
   * @else
   * @brief Get string length of the name component's string representation
   * @endif
   */
  CORBA::ULong CorbaNaming::getNameLength(const CosNaming::Name& name)
  {
    CORBA::ULong slen = 0;
    
    for (CORBA::ULong i = 0; i < name.length(); ++i)
      {
	// Count string length of id(s)
	for (const char* id = name[i].id; *id; ++id)
	  {
	    // Escape character '/', '.', '\' will convert to "\/", "\.", "\\".
	    if (*id == '/' || *id == '.' || *id == '\\') slen++;
	    slen++;
	  }
	// If kind exists, space for '.' is counted
	if (((const char*)(name[i].id  ))[0] == '\0' || 
	    ((const char*)(name[i].kind))[0] != '\0')
	  {
	    slen++;
	  }
	// Count string length of kind(s)
	for (const char* kind = name[i].kind; *kind; kind++)
	  {
	    if (*kind == '/' || *kind == '.' || *kind == '\\') slen++;
	    slen++;
	  }
	// Space for '/' or '\0'
	slen++;
      }
    return slen;
  }
  
  
  /*!
   * @if jp
   * @brief ????????????
   * @else
   * @brief Split of string
   * @endif
   */
  unsigned int CorbaNaming::split(const std::string& input,
				     const std::string& delimiter,
				     std::vector<std::string>& results)
  {
    typedef std::string::size_type size;
    size delim_size = delimiter.size();
    size found_pos(0), begin_pos(0), pre_pos(0), substr_size(0);
    
    if (input.substr(0, delim_size) == delimiter)
      begin_pos = pre_pos = delim_size;
    
    while (1)
      {
      REFIND:
	found_pos = input.find(delimiter, begin_pos);
	if (found_pos == std::string::npos) 
	  {
	    results.push_back(input.substr(pre_pos));
	    break;
	  }
	if ('\\' == input.at(found_pos - 1))
	  {
	    begin_pos = found_pos + delim_size;
	    goto REFIND;
	  }
	
	substr_size = found_pos - pre_pos;
	
	if (substr_size > 0)
	  {
	    results.push_back(input.substr(pre_pos, substr_size));
	  }
	begin_pos = found_pos + delim_size;
	pre_pos   = found_pos + delim_size;
      }
    return results.size();
  }
}; // namespace RTC
-------------- next part --------------
// -*- C++ -*-
/*!
 * @file NamingManager.h
 * @brief naming Service helper class
 * @date $Date: 2007/04/13 18:08:42 $
 * @author Noriaki Ando <n-ando @ aist.go.jp>
 *
 * Copyright (C) 2006
 *     Task-intelligence Research Group,
 *     Intelligent Systems Research Institute,
 *     National Institute of
 *         Advanced Industrial Science and Technology (AIST), Japan
 *     All rights reserved.
 *
 * $Id: NamingManager.h,v 1.2 2007/04/13 18:08:42 n-ando Exp $
 *
 */

/*
 * $Log: NamingManager.h,v $
 * Revision 1.2  2007/04/13 18:08:42  n-ando
 * Some changes for NameServers rebinding and objects rebinding.
 *
 * Revision 1.1  2006/11/04 21:11:44  n-ando
 * NamingManager was introduced to support multiple name server.
 *
 */
#ifndef NamingManager_h
#define NamingManager_h

#include <ace/Task.h>
#include <rtm/CorbaNaming.h>
#include <rtm/RTObject.h>
#include <rtm/SystemLogger.h>


namespace RTC
{
  class Manager;
  class NamingBase
  {
  public:
    NamingBase() {};
    virtual ~NamingBase() {};
    virtual void bindObject(const char* name, const RTObject_impl* rtobj) = 0;
    virtual void unbindObject(const char* name) = 0;
  };


 
  class NamingOnCorba
    : public virtual NamingBase
  {
  public:
    NamingOnCorba(CORBA::ORB_ptr orb, const char* names)
      : m_cosnaming(orb, names)
    {};
    virtual ~NamingOnCorba(){};

    virtual void bindObject(const char* name, const RTObject_impl* rtobj);

    virtual void unbindObject(const char* name);



  private:
    CorbaNaming m_cosnaming;
    std::map<std::string, RTObject_impl*> m_names;
  };




  class NamingManager
  {
  public:
    NamingManager(Manager* manager);
    virtual ~NamingManager();

    void registerNameServer(const char* method, const char* name_server);
    void bindObject(const char* name, const RTObject_impl* rtobj);
    void update();
    void unbindObject(const char* name);
    void unbindAll();

  protected:
    NamingBase* createNamingObj(const char* method, const char* name_server);
    void bindCompsTo(NamingBase* ns);
    void registerCompName(const char* name, const RTObject_impl* rtobj);
    void unregisterCompName(const char* name);


  protected:
    // Name Servers' method/name and object
    struct Names
    {
      Names(const char* meth, const char* name, NamingBase* naming)
	: method(meth), nsname(name), ns(naming)
      {
      }
      std::string method;
      std::string nsname;
      NamingBase* ns;
    };
    std::vector<Names*> m_names;
    ACE_Thread_Mutex m_namesMutex;

    // Components' name and object
    struct Comps
    {
      Comps(const char* n, const RTObject_impl* obj)
	: name(n), rtobj(obj)
      {}
      std::string name;
      const RTObject_impl* rtobj;
    };
    std::vector<Comps*> m_compNames;

    Manager* m_manager;
    MedLogbuf m_MedLogbuf;
    LogStream rtcout;
  }; // class NamingManager


}; // namespace RTC

#endif // NamingManager_h
-------------- next part --------------
// -*- C++ -*-
/*!
 * @file NamingManager.h
 * @brief naming Service helper class
 * @date $Date: 2007/04/13 18:08:38 $
 * @author Noriaki Ando <n-ando @ aist.go.jp>
 *
 * Copyright (C) 2006
 *     Task-intelligence Research Group,
 *     Intelligent Systems Research Institute,
 *     National Institute of
 *         Advanced Industrial Science and Technology (AIST), Japan
 *     All rights reserved.
 *
 * $Id: NamingManager.cpp,v 1.3 2007/04/13 18:08:38 n-ando Exp $
 *
 */

/*
 * $Log: NamingManager.cpp,v $
 * Revision 1.3  2007/04/13 18:08:38  n-ando
 * Some changes for NameServers rebinding and objects rebinding.
 *
 * Revision 1.2  2007/01/14 19:43:28  n-ando
 * Debugging messages to stdout were deleted.
 *
 * Revision 1.1  2006/11/04 21:11:36  n-ando
 * NamingManager was introduced to support multiple name server.
 *
 */

#include <rtm/NamingManager.h>
#include <rtm/Manager.h>
#include <rtm/StringUtil.h>
#include <functional>
#include <algorithm>
#include <iostream>

namespace RTC
{
  void NamingOnCorba::bindObject(const char* name,
				 const RTObject_impl* rtobj)
  {
    try
      {
	m_cosnaming.rebindByString(name, rtobj->getObjRef(), true);
      }
    catch (...)
      {
	;
      }
  }

  void NamingOnCorba::unbindObject(const char* name)
  {
    try
      {
	m_cosnaming.unbind(name);
      }
    catch (...)
      {
	;
      }
  }

  //============================================================
  // NamingManager
  //============================================================
  NamingManager::NamingManager(Manager* manager)
    :m_manager(manager), 
     m_MedLogbuf(manager->getLogbuf()), rtcout(m_MedLogbuf)
  {
    m_MedLogbuf.setSuffix("naming_svc");
    m_MedLogbuf.setDateFmt(manager->getConfig()["logger.date_format"]);
    rtcout.setLogLevel(manager->getConfig()["logger.log_level"]);
    rtcout.setLogLock(toBool(manager->getConfig()["logger.stream_lock"],
			     "enable", "disable", false));
  }


  NamingManager::~NamingManager()
  {
    
  }


  void NamingManager::registerNameServer(const char* method,
					 const char* name_server)
  {
    RTC_TRACE(("NamingManager::registerNameServer(%s, %s)", \
	       method, name_server));
    NamingBase* name;
    name = createNamingObj(method, name_server);
    m_names.push_back(new Names(method, name_server, name));
  }
  

  void NamingManager::bindObject(const char* name, 
			       const RTObject_impl* rtobj)
  {
    RTC_TRACE(("NamingManager::bindObject(%s)", name));

    ACE_Guard<ACE_Thread_Mutex> guard(m_namesMutex);
    for (int i(0), len(m_names.size()); i < len; ++i)
      {
	if (m_names[i]->ns != NULL)
	  m_names[i]->ns->bindObject(name, rtobj);
      }
    registerCompName(name, rtobj);
  }

  
  void NamingManager::update()
  {
    RTC_TRACE(("NamingManager::update()"));

    ACE_Guard<ACE_Thread_Mutex> guard(m_namesMutex);
    
    for (int i(0), len(m_names.size()); i < len; ++i)
      {
	if (m_names[i]->ns == NULL) // if ns==NULL
	  { // recreate NamingObj
	    NamingBase* nsobj;
	    nsobj = createNamingObj(m_names[i]->method.c_str(),
				    m_names[i]->nsname.c_str());
	    if (nsobj != NULL) // if succeed
	      {
		RTC_INFO(("New name server found: %s/%s", \
			  m_names[i]->method.c_str(), \
			  m_names[i]->nsname.c_str()));
		m_names[i]->ns = nsobj;
		bindCompsTo(nsobj); // rebind all comps to new NS
	      }
	  }
      }
  }


  void NamingManager::unbindObject(const char* name)
  {
    RTC_TRACE(("NamingManager::unbindObject(%s)", name));

    ACE_Guard<ACE_Thread_Mutex> guard(m_namesMutex);
    for (int i(0), len(m_names.size()); i < len; ++i)
      {
	if (m_names[i]->ns != NULL)
	  m_names[i]->ns->unbindObject(name);
      }
    unregisterCompName(name);
  }


  void NamingManager::unbindAll()
  {
    RTC_TRACE(("NamingManager::unbindAll(): %d names.", m_compNames.size()));
    ACE_Guard<ACE_Thread_Mutex> guard(m_namesMutex);
    for (int i(0), len(m_compNames.size()); i < len; ++i)
      {
	unbindObject(m_compNames[i]->name.c_str());
      }
  }


  //============================================================
  // Protected
  //============================================================
  NamingBase* NamingManager::createNamingObj(const char* method,
					     const char* name_server)
  {
    std::string m(method);
    if (m == "corba")
      {
	try
	  {
	    NamingBase* name;
	    name = new NamingOnCorba(m_manager->getORB(), name_server);
	    if (name == NULL) return NULL;
	    RTC_INFO(("NameServer connection succeeded: %s/%s", \
		       method, name_server));
	    return name;
	  }
	catch (...)
	  {
	    RTC_INFO(("NameServer connection failed: %s/%s", \
		      method, name_server));
	    return NULL;
	  }
      }
    return NULL;
  }
  
  
  void NamingManager::bindCompsTo(NamingBase* ns)
  {
    for (int i(0), len(m_compNames.size()); i < len; ++i)
      {
	ns->bindObject(m_compNames[i]->name.c_str(), m_compNames[i]->rtobj);
      }
  }


  void NamingManager::registerCompName(const char* name,
				       const RTObject_impl* rtobj)
  {
    for (int i(0), len(m_compNames.size()); i < len; ++i)
      {
	if (m_compNames[i]->name == name)
	  {
	    m_compNames[i]->rtobj = rtobj;
	    return;
	  }
      }
    m_compNames.push_back(new Comps(name, rtobj));
    return;
  }
  

  void NamingManager::unregisterCompName(const char* name)
  {
    std::vector<Comps*>::iterator it(m_compNames.begin());
    for (int i(0), len(m_compNames.size()); i < len; ++i, ++it)
      {
	if (m_compNames[i]->name == name)
	  {
	    m_compNames.erase(it);
	    return;
	  }
      }
    return;
  }

}; // namespace RTC


openrtm-users メーリングリストの案内