ページの先頭行へ戻る
Interstage Application Server アプリケーション作成ガイド(CORBAサービス編)

4.3.7 サーバアプリケーションのプログラミング例

4.3.7.1 Default Servant使用例(デフォルトインスタンス方式)

(1)IDL定義

  module ODsample{
      interface  intf{
          long  add( in  long  a,  in  long  b ); 
      };
  };

(2)ネーミングサービスの登録

  動的登録


(3)アプリケーション構成概要図



(4)クライアントアプリケーション

  #include <stdlib.h>
  #include <iostream>
  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static  CORBA::Object_var             obj;
  static  CORBA::ORB_var                orb;
  static  CORBA::Environment            env;
  static  CosNaming::NamingContext_var  cos_naming;
  static  CosNaming::Name               name;

  int main( int argc, char *argv[] )
  {

      try {
          // ORBの生成と初期化
          orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env );

          // ネーミングサービスのオブジェクトリファレンスの取得
          obj = orb->resolve_initial_references(
                         CORBA_ORB_ObjectId_NameService, env );
          cos_naming = CosNaming::NamingContext::_narrow( obj );

          // ネーミングサービスのresolveメソッドを発行し、
          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name.length( 1 );
          name[0]->id   = (const CORBA::Char *)"ODsample::POAsample1";
          name[0]->kind = (const CORBA::Char *)"";
          obj = cos_naming->resolve( name, env ); 

          // サーバアプリケーションのオブジェクトリファレンス獲得
          ODsample::intf* obj2 = ODsample::intf::_narrow( obj ); 

          // サーバアプリケーションのメソッド呼出し
          CORBA::Long ret = obj2->add( 1, 2, env ); 

          CORBA::release( obj2 );

      }catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 

      }catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }

      return 0; 
  }

(5)サーバアプリケーション

  #include <iostream>
  #include <stdlib.h>

  #include "orb_cplus.h"
  #include "poa.h"
  #include "CosNaming_cplus.h"

  #include "simple.h"

  using std::cout;
  using std::endl;

  static CORBA::ORB_var                   orb; 
  static CORBA::Object_var                obj; 
  static CORBA::Environment               env; 

  static CosNaming::NamingContext_var     cos_naming; 
  static CosNaming::Name                  name; 

  static PortableServer::POA_var          rootPOA; 
  static PortableServer::POA_var          childPOA; 
  static CORBA::PolicyList                policies( 4 ); 
  static PortableServer::POAManager_var   poa_manager; 

  // ユーザアプリケーション:メイン処理クラス
  int main( int argc, char*argv[] ) 
  {
      int current_argc = argc; 

      try{
          // ORBの生成と初期化
          orb         = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env ); 

          // RootPOAのオブジェクトリファレンスの取得
          obj         = orb->resolve_initial_references( "RootPOA", env ); 
          // RootPOAのPOAオブジェクト獲得
          rootPOA     = PortableServer::POA::_narrow( obj ); 

          // インタフェース用のPOA作成
          // ポリシリスト作成
          policies.length( 4 );
          policies[0] = rootPOA->create_servant_retention_policy(
                                   PortableServer::NON_RETAIN, env );
          policies[1] = rootPOA->create_request_processing_policy(
                                   PortableServer::USE_DEFAULT_SERVANT, env ); 
          policies[2] = rootPOA->create_id_assignment_policy(
                                   PortableServer::SYSTEM_ID, env ); 
          policies[3] = rootPOA->create_id_uniqueness_policy(
                                   PortableServer::MULTIPLE_ID, env ); 

          // Default Servant用のPOAオブジェクトの作成
          childPOA   = rootPOA->create_POA( "childPOA",
                          PortableServer::POAManager::_nil(), policies, env );

          // Servantの生成
          ODsample_intf_impl* svt = new ODsample_intf_impl(); 
          // Default Servantに設定
          childPOA->set_servant( svt, env ); 

          CORBA::Object_var _bind_obj = childPOA->create_reference(
                                          "IDL:ODsample/intf:1.0", env ); 

          // ネーミングサービスのオブジェクトリファレンスの取得
          CORBA::Object_var _tmpObj = orb->resolve_initial_references(
                                          "NameService", env ); 
          cos_naming = CosNaming::NamingContext::_narrow( _tmpObj ); 

          // ネーミングサービスのresolveメソッドを発行し、サーバアプリケーションの
          // オブジェクトリファレンスの獲得
          name.length( 1 ); 
          name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample1"; 
          name[0]->kind = ( const CORBA::Char* )""; 

          try {
              cos_naming->unbind( name, env ); 
          } catch( CORBA::Exception& e ) {
              ; 
          }
          cos_naming->bind( name, _bind_obj, env ); 

          // POAマネージャの獲得
          poa_manager = childPOA->the_POAManager( env ); 

          // POAマネージャのactivate
          poa_manager->activate( env ); 

          orb->run( env ); 

      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }

      return 0; 
  }

  // Servant:メソッド実装
  CORBA::Long ODsample_intf_impl::add(
      CORBA::Long a, 
      CORBA::Long b, 
      CORBA::Environment& env) 
      throw( CORBA::Exception ){

      CORBA::Long    result; 
   
      cout << "ODsample::intf::add()" << endl; 
      cout << "  a     : " << a << endl; 
      cout << "  b     : " << b << endl; 
      result = a + b; 
      cout << "  result: " << result << endl; 
      return result; 
  };

(6)例外情報の獲得

  サーバアプリケーションで例外を獲得する方法の詳細については、“4.2.2 サーバアプリケーションの例外処理”を参照してください。


4.3.7.2 Active Object Map(AOM)使用例 (Factory-1方式)

(1)IDL定義

  module ODsample{
      interface intf{
          readonly  attribute  long  value1; 
          void  add( in  long  a ); 
          void  sub( in  long  b ); 
      }; 
      interface Factory {
          intf   create(); 
          void   destroy( in  intf  obj ); 
      }; 
  };

(2)ネーミングサービスの登録

  OD_or_adm -c IDL:ODsample/Factory:1.0 -a Imple_POAsample3 -n ODsample::POAsample3

(3)アプリケーション構成概要図



(4)クライアントアプリケーション

  #include <stdlib.h>
  #include <iostream>

  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static  CORBA::Object_var             obj; 
  static  CORBA::Environment            env; 
  static  CORBA::ORB_var                orb; 
  static  CosNaming::NamingContext_var  cos_naming; 
  static  CosNaming::Name               name; 

  int main( int argc, char *argv[] ) 
  {
      try {
          // ORBの生成と初期化
          orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env ); 

          // ネーミングサービスのオブジェクトリファレンスの取得
          obj = orb->resolve_initial_references(
                           CORBA_ORB_ObjectId_NameService, env ); 
          cos_naming = CosNaming::NamingContext::_narrow( obj ); 

          // ネーミングサービスのresolveメソッドを発行し、
          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name.length( 1 ); 
          name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample3"; 
          name[0]->kind = ( const CORBA::Char* )""; 

          obj = cos_naming->resolve( name, env ); 

          // Factoryのオブジェクトリファレンス獲得
          ODsample::Factory* target = ODsample::Factory::_narrow( obj ); 

          // Factoryでインタフェース用オブジェクトリファレンス作成
          ODsample::intf* obj2 = target->create( env ); 

          CORBA::Long  a = 10;    // inパラメタ用変数
          CORBA::Long  b = 5; 

          // サーバアプリケーションのメソッド呼出し
          CORBA::Long ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          obj2->add( a, env ); 
          printf( "add( %d )\n", a ); 

          ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          obj2->sub( b, env ); 
          printf( "sub( %d )\n", b ); 

          ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          // インスタンスの解放
          target->destroy( obj2, env ); 

          CORBA::release( target ); 
          CORBA::release( obj2 ); 

      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 

      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

(5)サーバアプリケーション

  #include <stdlib.h>
  #include <iostream>
  #include "orb_cplus.h"
  #include "simple.h"

  #include "poa.h"
  #include "CosNaming_cplus.h"

  using std::cout;
  using std::endl;

  static CORBA::ORB_var                   orb; 
  static CORBA::Object_var                obj; 
  static CORBA::Environment               env; 

  static PortableServer::POA_var          rootPOA; 
  static PortableServer::POA_var          factoryPOA; 
  static CORBA::PolicyList                factory_policies( 4 ); 
  static PortableServer::POAManager_var   poa_manager; 

  static long                             val = 10; 

  // ユーザアプリケーション:メイン処理クラス
  int main( int argc, char*argv[] ) 
  {
      try {
          // ORBの生成と初期化
          orb         = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env ); 

          // RootPOAのオブジェクトリファレンスの取得
          obj         = orb->resolve_initial_references( "RootPOA", env ); 
          // RootPOAのPOAオブジェクト獲得
          rootPOA     = PortableServer::POA::_narrow( obj ); 

          // Factoryインタフェース用のPOA作成
          // ポリシリスト作成
          factory_policies.length( 4 ); 
          factory_policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::NON_RETAIN, env ); 
          factory_policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_DEFAULT_SERVANT, env ); 
          factory_policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::SYSTEM_ID, env ); 
          factory_policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::MULTIPLE_ID, env ); 

          factoryPOA = rootPOA->create_POA( "IDL:ODsample/Factory:1.0", 
               PortableServer::POAManager::_nil(), factory_policies ,env); 

          // FactoryServantの生成
          ODsample_Factory_impl* svt = new ODsample_Factory_impl(); 
          // Factoryインタフェース用POAのDefault Servantに設定
          factoryPOA->set_servant( svt, env ); 

          // POAマネージャの獲得
          poa_manager = rootPOA->the_POAManager( env ); 

          // POAマネージャのactivate
          poa_manager->activate( env ); 

          orb->run( env ); 

      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 
      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

  // Factory_impl::create:Factoryメソッドの実装
  ODsample::intf_ptr ODsample_Factory_impl::create(
            CORBA::Environment&  env ) 
            throw( CORBA::Exception ) 

      try{
          // Servantの生成
          ODsample_intf_impl*  svt = new ODsample_intf_impl(); 

          // Servantからオブジェクトリファレンスの生成
          // IMPLICIT_ACTIVATIONポリシなので、AOMへ自動登録される
          CORBA::Object_var _tmpObj = rootPOA->servant_to_reference( svt, env ); 
          ODsample::intf_ptr ior = ODsample::intf::_narrow( _tmpObj ); 

          return ior; 

      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw e; 
      }
  }; 

  // Factory_impl::destroy:Factoryメソッドの実装
  void ODsample_Factory_impl::destroy(
            ODsample::intf_ptr obj, 
            CORBA::Environment& env ) 
            throw( CORBA::Exception ) 
  {
      try{
          // オブジェクトリファレンスからオブジェクトIDを求める
          PortableServer::ObjectId_var oid = rootPOA->reference_to_id( obj, env ); 

          // Servantオブジェクトの取得
          PortableServer::Servant  svt = id_to_servant( *oid, env ); 

          // Servantをdeactiveにする
          rootPOA->deactivate_object( *oid, env ); 

          // Servantの削除
          svt->servant_delete(); 

      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw e; 
      }
  }; 

  // ODsample::intf:メソッド実装クラス
  void ODsample_intf_impl::add(
              CORBA::Long a, 
              CORBA::Environment& env) 
              throw( CORBA::Exception ){

          cout << "ODsample::intf::add()" << endl; 
          cout << "  val : " << val << endl; 
          cout << "  a     : " << a << endl; 
          val = val + a; 
          cout << "  result: " << val << endl; 
  }; 
  void ODsample_intf_impl::sub(
              CORBA::Long b, 
              CORBA::Environment& env) 
              throw( CORBA::Exception ){

          cout << "ODsample::intf::sub()" << endl; 
          cout << "  val : " << val << endl; 
          cout << "  b     : " << b << endl; 
          val = val - b; 
          cout << "  result: " << val << endl; 
  }; 
  CORBA::Long ODsample_intf_impl::value1(
              CORBA::Environment& env) 
              throw( CORBA::Exception ){
          return val; 
  };

(6)例外情報の獲得

  サーバアプリケーションで例外を獲得する方法の詳細については、“4.2.2 サーバアプリケーションの例外処理”を参照してください。


4.3.7.3 Servant Activator使用例 (Factory-2方式)

(1)IDL定義

  module ODsample{
      interface intf{
          readonly  attribute  long  value1; 
          void  add( in  long  a ); 
          void  sub( in  long  b ); 
      }; 
      interface Factory {
          intf   create(); 
          void   destroy( in  intf  obj ); 
      }; 
  };

(2)ネーミングサービスの登録

  OD_or_adm -c IDL:ODsample/Factory:1.0 -a Imple_POAsample3 -n ODsample::POAsample3

(3)アプリケーション構成概要図



(4)クライアントアプリケーション

  #include <stdlib.h>
  #include <iostream>

  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static  CORBA::Object_var             obj; 
  static  CORBA::Environment            env; 
  static  CORBA::ORB_var                orb; 
  static  CosNaming::NamingContext_var  cos_naming; 
  static  CosNaming::Name               name; 

  int main( int argc, char *argv[] ) 
  {
      try {
          // ORBの生成と初期化
          orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env ); 

          // ネーミングサービスのオブジェクトリファレンスの取得
          obj = orb->resolve_initial_references(
                           CORBA_ORB_ObjectId_NameService, env ); 
          cos_naming = CosNaming::NamingContext::_narrow( obj ); 

          // ネーミングサービスのresolveメソッドを発行し、
          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name.length( 1 ); 
          name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample3"; 
          name[0]->kind = ( const CORBA::Char* )""; 
          obj = cos_naming->resolve( name, env ); 

          // Factoryのオブジェクトリファレンス獲得
          ODsample::Factory* target = ODsample::Factory::_narrow( obj ); 

          // Factoryでインタフェース用オブジェクトリファレンスを作成する
          ODsample::intf* obj2 = target->create( env ); 

          CORBA::Long  a = 10;    // inパラメタ用変数
          CORBA::Long  b = 5; 

          // サーバアプリケーションのメソッド呼出し
          CORBA::Long ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          obj2->add( a, env ); 
          printf( "add( %d )\n", a ); 

          ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          obj2->sub( b, env ); 
          printf( "sub( %d )\n", b ); 

          ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          // インスタンスの解放
          target->destroy( obj2, env ); 

          CORBA::release( target ); 
          CORBA::release( obj2 ); 

      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 

      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

(5)サーバアプリケーション

  #include <iostream>
  #include <stdlib.h>

  #include "poa.h"
  #include "CosNaming_cplus.h"
  #include "orb_cplus.h"

  #include "simple.h"

  using std::cout;
  using std::endl;

  static CORBA::ORB_var                   orb; 
  static CORBA::Object_var                obj; 
  static CORBA::Environment               env; 

  static PortableServer::POA_var          rootPOA; 
  static PortableServer::POA_var          factoryPOA; 
  static PortableServer::POA_var          childPOA; 
  static CORBA::PolicyList                factory_policies( 4 ); 
  static CORBA::PolicyList                intf_policies( 4 ); 
  static PortableServer::POAManager_var   poa_manager; 

  static long                             val = 10; 

  // ユーザアプリケーション:メイン処理クラス
  int main( int argc, char*argv[] ) 
  {
      int current_argc = argc; 

      try{
          // ORBの生成と初期化
          orb         = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env ); 

          // RootPOAのオブジェクトリファレンスの取得
          obj         = orb->resolve_initial_references( "RootPOA", env ); 
          // RootPOAのPOAオブジェクト獲得
          rootPOA     = PortableServer::POA::_narrow( obj ); 

          // Factoryインタフェース用のPOA作成
          // ポリシリスト作成
          factory_policies.length( 4 ); 
          factory_policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::NON_RETAIN, env ); 
          factory_policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_DEFAULT_SERVANT, env ); 
          factory_policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::SYSTEM_ID, env ); 
          factory_policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::MULTIPLE_ID, env ); 

          factoryPOA = rootPOA->create_POA( "IDL:ODsample/Factory:1.0", 
                 PortableServer::POAManager::_nil(), factory_policies ,env); 

          // インタフェース用のPOA作成
          // ポリシリスト作成
          intf_policies.length( 4 ); 
          intf_policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::RETAIN, env ); 
          intf_policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_SERVANT_MANAGER, env ); 
          intf_policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::SYSTEM_ID, env ); 
          intf_policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::MULTIPLE_ID, env ); 

          childPOA = rootPOA->create_POA( "childPOA", 
                 PortableServer::POAManager::_nil(), intf_policies ,env ); 

          // FactoryServantの生成
          ODsample_Factory_impl* svt = new ODsample_Factory_impl(); 
          // Factoryインタフェース用POAのDefault Servantに設定
          factoryPOA->set_servant( svt, env ); 

          // ServantActivatorの生成
          PortableServer::ServantActivator_var svtact = new UserServantActivator(); 
          // インタフェース用POAのServantManagerとして登録
          childPOA->set_servant_manager( svtact, env ); 

          // POAマネージャの獲得
          poa_manager = rootPOA->the_POAManager( env ); 

          // POAマネージャのactivate
          poa_manager->activate( env ); 

          orb->run( env ); 

      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 
      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

  // ODsample_Factory_impl::create:Factoryメソッド実装クラス
  ODsample::intf_ptr ODsample_Factory_impl::create(
            CORBA::Environment& env ) 
            throw( CORBA::Exception ) 
  {
      try{
          // オブジェクトリファレンスの生成
          CORBA::Object_var _tmpObj
                = childPOA->create_reference( "IDL:ODsample/intf:1.0", env ); 
          ODsample::intf_ptr ior = ODsample::intf::_narrow( _tmpObj ); 
          return ior; 

      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw( e ); 
      }
  }; 

  // ODsample_Factory_impl::destroy:Factoryメソッド実装クラス
  void ODsample_Factory_impl::destroy(
            ODsample::intf_ptr obj, 
            CORBA::Environment& env ) 
            throw( CORBA::Exception ) 
  {
      try{
          // オブジェクトリファレンスからオブジェクトIDを求める
          PortableServer::ObjectId_var oid = childPOA->reference_to_id( obj, env ); 

          // Servantをdeactiveにする
          childPOA->deactivate_object( *oid, env ); 

      } catch( CORBA::Exception&  e ) {
          cout << "Exception: " << opname << endl; 
          cout << "exception-id: " << e.id() << endl; 
          throw( e ); 
      }
  }; 

  // ServantActivator:Servant生成クラス(ServantActivatorを継承)
  class UserServantActivator: public PortableServer::ServantActivator
  {
  public: 
     UserServantActivator() {};
     ~UserServantActivator() {};

      PortableServer::Servant incarnate(
                    const PortableServer::ObjectId& oid, 
                    PortableServer::POA_ptr adapter, 
                    CORBA::Environment& env ) 
                    throw( CORBA::Exception ) 
      {
          // Servantの生成
          PortableServer::Servant svt = new ODsample_intf_impl(); 
          return( svt ); 
      }; 

      void etherealize( const PortableServer::ObjectId& oid, 
                      PortableServer::POA_ptr adapter, 
                      PortableServer::Servant serv, 
                      CORBA::Boolean cleanup_in_progress, 
                      CORBA::Boolean remaining_activations, 
                      CORBA::Environment& env ) 
                      throw( CORBA::Exception ) 
      {
          // Servantオブジェクトの削除。
          serv->servant_delete(); 
      }
  }; 

  // ODsample_intf_impl:メソッド実装クラス
  void ODsample_intf_impl::add(
            CORBA::Long a, 
            CORBA::Environment& env) 
            throw( CORBA::Exception ){

      cout << "ODsample::intf::add()" << endl; 
      cout << "  val : " << val << endl; 
      cout << "  a     : " << a << endl; 
      val = val + a; 
      cout << "  result: " << val << endl; 
  }; 

  void ODsample_intf_impl::sub(
            CORBA::Long b, 
            CORBA::Environment& env) 
            throw( CORBA::Exception ){

      cout << "ODsample::intf::sub()" << endl; 
      cout << "  val : " << val << endl; 
      cout << "  b     : " << b << endl; 
      val = val - b; 
      cout << "  result: " << val << endl; 
  }; 

  CORBA::Long ODsample_intf_impl::value1(
            CORBA::Environment& env) 
            throw( CORBA::Exception ){
      return val; 
  };

(6)例外情報の獲得

  サーバアプリケーションで例外を獲得する方法の詳細については、“4.2.2 サーバアプリケーションの例外処理”を参照してください。


4.3.7.4 Servant Locator使用例 (ユーザインスタンス管理方式)

(1)IDL定義

  module ODsample{
      interface    intf{
          readonly  attribute  long  value1; 
          void add( in  long  a ); 
          void sub( in  long  b ); 
      }; 
      interface Factory{
          intf   create( in  string  userid ); 
          void   destroy( in  intf  obj ); 
      }; 
  };

(2)ネーミングサービスの登録

  OD_or_adm -c IDL:ODsample/Factory:1.0 -a Imple_POAsample4 -n ODsample::POAsample4

(3)アプリケーション構成概要図



(4)クライアントアプリケーション

  #include <iostream>
  #include <stdlib.h>

  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static  CORBA::Object_var             obj; 
  static  CORBA::Environment            env; 
  static  CORBA::ORB_var                orb; 
  static  CosNaming::NamingContext_var  cos_naming; 
  static  CosNaming::Name               name; 

  int main( int argc, char* argv[] ) 
  {
      try {
          // ORBの生成と初期化
          orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env ); 

          // ネーミングサービスのオブジェクトリファレンスの取得
          obj = orb->resolve_initial_references(
                        CORBA_ORB_ObjectId_NameService, env ); 
          cos_naming = CosNaming::NamingContext::_narrow( obj ); 

          // ネーミングサービスのresolveメソッドを発行し、
          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name.length( 1 ); 
          name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample4"; 
          name[0]->kind = ( const CORBA::Char* )""; 

          obj = cos_naming->resolve( name, env ); 

          // サーバアプリケーションのインタフェースクラスの獲得
          ODsample::Factory* target = ODsample::Factory::_narrow( obj ); 

          char userid[1024]; 
          printf( "USERID -> " ); 
          userid[0] = 0; 
          scanf( "%s", userid ); 
          if( strlen( userid ) < 1 ){
              return 255; 
          }

          // FactoryでインタフェースアプリのIORを作成する
          ODsample::intf* obj2 = target->create( userid, env ); 

          CORBA::Long  a = 10; 
          CORBA::Long  b = 5; 

          // サーバアプリケーションのメソッド呼出し
          CORBA::Long ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          obj2->add( a, env ); 
          printf( "add( %d )\n", a ); 

          ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          obj2->sub( b, env ); 
          printf( "sub( %d )\n", b ); 

          ret = obj2->value1( env ); 
          printf( "value = %d\n", ret ); 

          target->destroy( obj2, env ); 

          CORBA::release( target ); 
          CORBA::release( obj2 ); 

      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 
      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

(5)サーバアプリケーション

  #include <iostream>
  #include <stdlib.h>

  #include "orb_cplus.h"
  #include "poa.h"
  #include "CosNaming_cplus.h"

  #include "simple.h"

  using std::cout;
  using std::endl;

  static CORBA::ORB_var                   orb; 
  static CORBA::Object_var                obj; 
  static CORBA::Environment               env; 

  static PortableServer::POA_var          rootPOA; 
  static PortableServer::POA_var          factory_poa; 
  static PortableServer::POA_var          childPOA; 
  static CORBA::PolicyList                policies( 4 ); 
  static CORBA::PolicyList                inf_policies( 4 ); 
  static PortableServer::POAManager_var   poa_manager; 

  static CORBA::Long                      val = 10; 

  // ユーザアプリケーション:メイン処理クラス
  int main( int argc, char*argv[] ) 
  {
      int current_argc = argc; 
      try{
          // ORBの生成と初期化
          orb         = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env ); 

          // RootPOAのオブジェクトリファレンスの取得
          obj         = orb->resolve_initial_references( "RootPOA", env ); 
          // RootPOAのPOAオブジェクト獲得
          rootPOA     = PortableServer::POA::_narrow( obj ); 

          // Factoryインタフェース用のPOA作成
          // ポリシリスト作成
          policies.length( 4 ); 
          policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::NON_RETAIN, env ); 
          policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_DEFAULT_SERVANT, env ); 
          policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::SYSTEM_ID, env ); 
          policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::MULTIPLE_ID, env ); 

          factory_poa = rootPOA->create_POA( "IDL:ODsample/Factory:1.0", 
                          PortableServer::POAManager::_nil(), policies ,env); 

          // インタフェース用のPOA作成
          // ポリシリスト作成
          inf_policies.length( 4 ); 
          inf_policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::NON_RETAIN, env ); 
          inf_policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_SERVANT_MANAGER, env ); 
          inf_policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::USER_ID, env ); 
          inf_policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::UNIQUE_ID, env ); 

          childPOA = rootPOA->create_POA( "childPOA", 
                          PortableServer::POAManager::_nil(), inf_policies ,env); 

          // FactoryServantの生成
          ODsample_Factory_impl* svt = new ODsample_Factory_impl(); 
          // Factoryインタフェース用POAのDefault Servantに設定
          factory_poa->set_servant( svt, env ); 

          // ServantLocatorの生成
          PortableServer::ServantLocator* svtloc = new UserServantLocator(); 
          // インタフェース用POAにServantManagerとして登録
          childPOA->set_servant_manager( svtloc, env ); 

          // POAマネージャの獲得
          poa_manager = rootPOA->the_POAManager( env ); 

          // POAマネージャのactivate
          poa_manager->activate( env ); 

          orb->run( env ); 
      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

  // 管理テーブル
  class ServantList
  {
  public: 
      ServantList() {
          _next = NULL; 
          _svr = NULL; 
          _oid = NULL; 
      }; 
      ~ServantList() {
          if( _svr != NULL ) {
              _svr->servant_delete();
          }
          if( _oid != NULL ) {
              delete _oid; 
          }
      }; 
      PortableServer::ObjectId* getObjectId() {
          return _oid; 
      }; 
      ServantList* getNext() {
          return _next; 
      }; 
      // 管理テーブルから検索
      PortableServer::ServantBase* getServant( const PortableServer::ObjectId* oid ) {
          if( _svr == NULL ) {
              if( _next == NULL ) {
                  return NULL; 
              }
              return _next->getServant( oid ); 
          }
          if( equal( oid ) ) {
              return _svr; 
          }
          if( _next ) {
              return _next->getServant( oid ); 
          }
          return NULL; 
      }; 
      long equal( const PortableServer::ObjectId* oid ) {
          if( _oid == NULL ) {
              return 0; 
          }
          if( oid->length() == oid->length() ) {
              long len = oid->length(); 
              long i; 
              for( i = 0 ; i < len ; i++ ) {
                  if( oid->operator[](i) != _oid->operator[](i) ) {
                      return 0; 
                  }
              }
              return 1; 
          }
          return 0; 
      }; 
      // 管理テーブルから削除
      void remove( PortableServer::ObjectId* oid ) {
          if( _next != NULL ) {
              if( _next->equal( oid ) ) {
                  ServantList* del = _next; 
                  _next = _next->getNext(); 
                   delete del; 
              }
          }
      }; 
      // 管理テーブルへ追加
      void put( const PortableServer::ObjectId* oid, PortableServer::ServantBase* svr ) {
          if( _next != NULL ) {
              _next->put( oid, svr ); 
          } else {
              _next = new ServantList(); 
              _next->_svr = svr; 
              _next->_oid = new PortableServer::ObjectId( *oid ); 
          }
      }; 
  private : 
      PortableServer::ObjectId*      _oid; 
      PortableServer::ServantBase*   _svr; 
      ServantList*                   _next; 
  }; 

  // 管理テーブルのインスタンス
  ServantList servant_list; 

  // ODsample_Factory_impl::create:メソッドの実装
  ODsample::intf_ptr ODsample_Factory_impl::create(
            const CORBA::Char* str, 
            CORBA::Environment& env) 
            throw( CORBA::Exception ){
      try{
          long len = strlen( str );
          CORBA::Octet* buf = PortableServer::ObjectId::allocbuf( len ); 
          memcpy( buf, str, len ); 
          PortableServer::ObjectId_var userid = new PortableServer::ObjectId(
                              len, len, buf, CORBA_TRUE ); 

          // オブジェクトリファレンスの生成
          CORBA::Object_var _tmpObj = childPOA->create_reference_with_id( *userid, 
                                   "IDL:ODsample/intf:1.0",env ); 
          ODsample::intf_ptr ior = ODsample::intf::_narrow( _tmpObj ); 
          return ior; 
      } catch(CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw e; 
      }
  }; 

  // ODsample_Factory_impl::destroy:メソッドの実装
  void ODsample_Factory_impl::destroy(
            ODsample::intf_ptr obj, 
            CORBA::Environment& env) 
            throw( CORBA::Exception ){
      try{
          // オブジェクトリファレンスからオブジェクトIDを求める
          PortableServer::ObjectId_var  oid = childPOA->reference_to_id( obj, env ); 

          // Servantを管理テーブルから削除
          servant_list.remove( oid ); 
      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw e; 
      }
  }; 

  // ServantLocator:Servant生成クラス(ServantLocatorを継承)
  class UserServantLocator: public PortableServer::ServantLocator
  {
  public: 
      UserServantLocator() {};
      ~UserServantLocator() {};

      PortableServer::Servant preinvoke(
                const PortableServer::ObjectId&          oid, 
                PortableServer::POA_ptr                  adapter, 
                const CORBA::Identifier                  operation, 
                PortableServer::ServantLocator::Cookie&  cookie, 
                CORBA::Environment& = CORBA::Environment() ) 
                throw( CORBA::Exception ) 
      {
          // Servantを検索する。みつからなければnewで生成する。
          PortableServer::Servant svt = servant_list.getServant( &oid ); 
          if( svt == NULL ) {
              svt = new ODsample_intf_impl(); 
              servant_list.put( &oid, svt ); 
          }
          // Cookieの作成
          cookie = ( CORBA::ULong )svt; 
          return svt; 
      }; 
      void  postinvoke(
            const PortableServer::ObjectId&         oid, 
            PortableServer::POA_ptr                 adapter, 
            const CORBA::Identifier                 operation, 
            PortableServer::ServantLocator::Cookie  cookie, 
            PortableServer::Servant                 the_servant, 
            CORBA::Environment& = CORBA::Environment() ) 
            throw( CORBA::Exception ) 
      {
      }; 
  }; 

  // ODsample_intf_implクラスのメソッド実装
  void ODsample_intf_impl::add(
            CORBA::Long a, 
            CORBA::Environment& env ) 
            throw( CORBA::Exception ) 
  {
      cout << "ODsample::intf::add()" << endl; 
      cout << "  value : " << val << endl; 
      cout << "  a     : " << a << endl; 
      val = val + a; 
      cout << "  result: " << val << endl; 
  }; 
  void ODsample_intf_impl::sub(
            CORBA::Long b, 
            CORBA::Environment& env ) 
            throw( CORBA::Exception ) 
  {
      cout << "ODsample::intf::sub()" << endl; 
      cout << "  value : " << val << endl; 
      cout << "  b     : " << b << endl; 
      val = val - b; 
      cout << "  result: " << val << endl; 
  }; 
  CORBA::Long ODsample_intf_impl::value1(
            CORBA::Environment& env ) 
            throw( CORBA::Exception ) 
  {
      return val; 
  };

(6)例外情報の獲得

  サーバアプリケーションで例外を獲得する方法の詳細については、“4.2.2 サーバアプリケーションの例外処理”を参照してください。


4.3.7.5 AdapterActivator使用例 (find_POA時)

(1)IDL定義

  module ODsample{
      interface intf1{
          attribute string value1; 
      }; 
      interface intf2{
          readonly attribute long value1; 
          void add( in long a ); 
          void sub( in long b ); 
      }; 
      interface Factory {
          intf1  create1 (); 
          intf2  create2 (); 
          void   destroy1( in intf1 obj ); 
          void   destroy2( in intf2 obj ); 
      }; 
  };

(2)ネーミングサービスの登録

  OD_or_adm -c IDL:ODsample/Factory:1.0 -a Imple_POAsample9 -n ODsample::POAsample9

(3)アプリケーション構成概要図



(4)クライアントアプリケーション

  #include <stdlib.h>
  #include <iostream>
  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static  CORBA::Object_var             obj; 
  static  CORBA::Environment            env; 
  static  CORBA::ORB_var                orb; 
  static  CosNaming::NamingContext_var  cos_naming; 
  static  CosNaming::Name               name; 

  int main( int argc, char* argv[] ) 
  {
      try {
          // ORBの生成と初期化
          orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env ); 

          // ネーミングサービスのオブジェクトリファレンスの取得
          obj = orb->resolve_initial_references( CORBA_ORB_ObjectId_NameService, env ); 
          cos_naming = CosNaming::NamingContext::_narrow( obj ); 

          // ネーミングサービスのresolveメソッドを発行し、
          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name.length( 1 ); 
          name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample9"; 
          name[0]->kind = ( const CORBA::Char* )""; 

          obj = cos_naming->resolve( name, env ); 

          // Factoryのオブジェクトリファレンス獲得
          ODsample::Factory* target = ODsample::Factory::_narrow( obj ); 

          // Factoryでインタフェース1用オブジェクトリファレンスを作成する
          ODsample::intf1* obj2 = target->create1( env ); 

          printf( "String = " ); 
          char buffer[1024]; 
          buffer[0] = 0; 
          scanf( "%s", buffer ); 

          // サーバアプリケーションのメソッド呼出し
          obj2->value1( buffer, env ); 
          printf( "String = %s\n", obj2->value1( env ) ); 

          // インスタンスの解放
          target->destroy1( obj2, env ); 

          // Factoryでインタフェース2用オブジェクトリファレンスを作成する
          ODsample::intf2* obj3 = target->create2( env ); 

          // サーバアプリケーションのメソッド呼出し
          printf( "value = %d\n", obj3->value1( env ) ); 

          CORBA::Long val; 
          printf( "add =>" ); 
          scanf( "%d", &val ); 
          obj3->add( val, env ); 

          printf( "  value = %d\n", obj3->value1( env ) ); 

          printf( "sub =>"); 
          scanf( "%d", &val ); 
          obj3->sub( val, env ); 

          printf( "  value = %d\n", obj3->value1( env ) ); 

          // インスタンスの解放
          target->destroy2( obj3, env ); 

          CORBA::release( target ); 
          CORBA::release( obj2 ); 
          CORBA::release( obj3 ); 

      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 
      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

(5)サーバアプリケーション

  #include <iostream>
  #include <stdlib.h>
  #include "orb_cplus.h"
  #include "poa.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static CORBA::ORB_var                   orb; 
  static CORBA::Object_var                obj; 
  static CORBA::Environment               env; 
  static PortableServer::POA_var          rootPOA; 
  static PortableServer::POA_var          factoryPOA; 
  static CORBA::PolicyList                policies( 4 ); 
  static PortableServer::POAManager_var   poa_manager; 

  static CORBA::Char*                     Str_value = NULL; 
  static CORBA::Long                      Ln_value = 20; 

  // ユーザアプリケーション:メイン処理クラス
  int main( int argc, char* argv[] ) 
  {
      int current_argc = argc; 
      try{
          // ORBの生成と初期化
          orb         = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env ); 

          // RootPOAのオブジェクトリファレンスの取得
          obj         = orb->resolve_initial_references( "RootPOA", env ); 
          // RootPOAのPOAオブジェクト獲得
          rootPOA     = PortableServer::POA::_narrow( obj ); 

          // Factoryインタフェース用のPOA作成
          // ポリシリスト作成
          policies.length( 4 ); 
          policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::NON_RETAIN, env ); 
          policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_DEFAULT_SERVANT, env ); 
          policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::SYSTEM_ID, env ); 
          policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::MULTIPLE_ID, env ); 
          factoryPOA = rootPOA->create_POA(
                                "IDL:ODsample/Factory:1.0", 
                                PortableServer::POAManager::_nil(), 
                                policies, 
                                env ); 

          // FactoryServantの生成(コンストラクタにインプリ用POAを渡す)
          ODsample_Factory_impl* svt = new ODsample_Factory_impl(); 
          // Factoryインタフェース用POAのDefault Servantに設定
          factoryPOA->set_servant( svt, env ); 

          // AdapterActivatorの生成
          PortableServer::AdapterActivator_var adp = new UserAdapterActivator(); 
          // インプリ用POAのAdapterActivatorに設定
          rootPOA->the_activator( adp, env ); 

          // POAマネージャの獲得
          poa_manager = factoryPOA->the_POAManager( env ); 

          // POAマネージャのactivate
          poa_manager->activate( env ); 

          orb->run( env ); 
      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 
      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

  // ODsample_Factory_impl::create1:メソッドの実装
  ODsample::intf1_ptr ODsample_Factory_impl::create1(
                                                 CORBA::Environment&  env ) 
                                                 throw( CORBA::Exception ) 
  {
      try{
          // インタフェースリポジトリIDに対応するのPOAオブジェクト獲得
          PortableServer::POA_var poa = rootPOA->find_POA( "intf1", CORBA_TRUE, env ); 

          // オブジェクトリファレンスの生成
          CORBA::Object_var _tmpObj = poa->create_reference( "IDL:ODsample/intf1:1.0", env ); 

          ODsample::intf1_ptr ior = ODsample::intf1::_narrow( _tmpObj ); 

          return ior; 
      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw e; 
      }
  }; 

  // ODsample_Factory_impl::create2:メソッドの実装
  ODsample::intf2_ptr ODsample_Factory_impl::create2(
                                                   CORBA::Environment&  env ) 
                                                   throw( CORBA::Exception ) 
  {
      try{
          // インタフェースリポジトリIDに対応するのPOAオブジェクト獲得
          PortableServer::POA_var poa = rootPOA->find_POA( "intf2", CORBA_TRUE, env ); 

          // オブジェクトリファレンスの生成
          CORBA::Object_var _tmpObj = poa->create_reference( "IDL:ODsample/intf2:1.0", env ); 

          ODsample::intf2_ptr ior = ODsample::intf2::_narrow( _tmpObj ); 

          return ior; 
      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw e; 
      }
  }; 

  // ODsample_Factory_impl::destroy1:メソッドの実装
  void ODsample_Factory_impl::destroy1(
                                  ODsample::intf1_ptr  obj, 
                                  CORBA::Environment&  env ) 
                                  throw( CORBA::Exception ) 
  {
      try{
          // インタフェースIDに対応するのPOAオブジェクト獲得
          PortableServer::POA_var poa = rootPOA->find_POA( "intf1", CORBA_TRUE, env ); 

          // オブジェクトリファレンスからオブジェクトIDを求める
          PortableServer::ObjectId_var oid = poa->reference_to_id( obj, env ); 

          // Servantをdeactiveにする
          poa->deactivate_object( *oid, env ); 

      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw e; 
      }
  }; 

  // ODsample_Factory_impl::destroy2:メソッドの実装
  void ODsample_Factory_impl::destroy2(
                                   ODsample::intf2_ptr  obj, 
                                   CORBA::Environment&  env ) 
                                   throw( CORBA::Exception ) 
  {
      try{
          // インタフェースIDに対応するのPOAオブジェクト獲得
          PortableServer::POA_var poa = rootPOA->find_POA( "intf2", CORBA_TRUE, env ); 

          // オブジェクトリファレンスからオブジェクトIDを求める
          PortableServer::ObjectId_var oid = poa->reference_to_id( obj, env ); 

          // Servantをdeactiveにする
          poa->deactivate_object( *oid, env ); 

      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          throw e; 
      }
  }; 

  // AdapterActivator:POA生成クラス(AdapterActivatorを継承)
  class UserAdapterActivator : public PortableServer::AdapterActivator
  {
  public: 
      UserAdapterActivator() {};
      ~UserAdapterActivator() {};

      CORBA::Boolean unknown_adapter(
                              PortableServer::POA_ptr parent, 
                              const CORBA::Char*      name, 
                              CORBA::Environment&     env ) 
                              throw( CORBA::Exception ) 
      {
          // ポリシリスト作成
          CORBA::PolicyList    policies( 4 ); 
          policies.length( 4 ); 
          policies[0] = rootPOA->create_servant_retention_policy(
                                   PortableServer::RETAIN, env ); 
          policies[1] = rootPOA->create_request_processing_policy(
                                   PortableServer::USE_SERVANT_MANAGER, env ); 
          policies[2] = rootPOA->create_id_assignment_policy(
                                   PortableServer::SYSTEM_ID, env ); 
          policies[3] = rootPOA->create_id_uniqueness_policy(
                                   PortableServer:: MULTIPLE_ID, env ); 

          // ServantActivatorの生成
          PortableServer::ServantActivator_ptr svtact = new UserServantActivator(); 

          try {
              if( !strcmp( name, "intf1" ) ) {
                  // intf1用のPOA作成
                  PortableServer::POA_ptr intf1POA
                      = parent->create_POA( name, NULL, policies, env ); 

                  // ServantManager登録
                  intf1POA->set_servant_manager( svtact , env ); 

                  return( CORBA_TRUE ); 
              }
              else if( !strcmp( name, "intf2" ) ) {
                  // intf2用のPOA作成
                  PortableServer::POA_ptr intf2POA
                      = parent->create_POA( name, NULL, policies, env ); 

                  // ServantManager登録
                  intf2POA->set_servant_manager( svtact , env ); 

                  return( CORBA_TRUE ); 
              }
          } catch( CORBA::SystemException&  se ) {
              cout << "exception-id: " << se.id() << endl; 
              return( CORBA_FALSE ); 
          } catch( CORBA::UserException&  ue ) {
              cout << "exception-id: " << ue.id() << endl; 
              return( CORBA_FALSE ); 
          } catch( CORBA::Exception&  e ) {
              cout << "exception-id: " << e.id() << endl; 
              return( CORBA_FALSE ); 
          }
          return CORBA_TRUE; 
      }; 
  }; 

  // ServantActivator:Servant生成クラス(ServantActivatorを継承)
  class UserServantActivator : public PortableServer::ServantActivator
  {
  public: 
      UserServantActivator() {};
      ~UserServantActivator() {};

      PortableServer::Servant incarnate(
                                  const PortableServer::ObjectId& oid, 
                                  PortableServer::POA_ptr         adapter, 
                                  CORBA::Environment&             env ) 
                                  throw( CORBA::Exception ) 
      {
          PortableServer::Servant svt = NULL; 

          CORBA::Char* name = adapter->the_name( env ); 
          if( !strcmp( name, "intf1" ) ) {
              svt = new ODsample_intf1_impl(); 
          } else if( !strcmp( name, "intf2" ) ) {
              svt = new ODsample_intf2_impl(); 
          } else {
              CORBA::StExcep::BAD_PARAM ex; 
              throw ex; 
          }
          CORBA::string_free( name ); 
          return( svt ); 
      }; 

      void etherealize(
                 const PortableServer::ObjectId& oid, 
                 PortableServer::POA_ptr         adapter, 
                 PortableServer::Servant         serv, 
                 CORBA::Boolean                  cleanup_in_progress, 
                 CORBA::Boolean                  remaining_activations, 
                 CORBA::Environment&             env ) 
                 throw( CORBA::Exception ) 
      {
          serv->servant_delete(); 
      }
  }; 

  // メソッドの実装
  void  ODsample_intf1_impl::value1(
                               const CORBA::Char*   a, 
                               CORBA::Environment&  env ) 
                               throw( CORBA::Exception ) 
  {
      cout << "ODsample::intf1::value(Char*)" << endl; 
      cout << "  value : " << a << endl; 
      if( Str_value != NULL ) {
          CORBA::string_free( Str_value ); 
      }
      Str_value = CORBA::string_alloc( strlen( a ) + 1 ); 
      strcpy( Str_value, a ); 
  }; 

  CORBA::Char*  ODsample_intf1_impl::value1(
                                   CORBA::Environment&  env ) 
                                   throw( CORBA::Exception ) 
  {
      if( Str_value == NULL ) {
          Str_value = CORBA::string_alloc( 1 ); 
          Str_value[0] = 0; 
      }
      CORBA::Char* ret = CORBA::string_alloc( strlen( Str_value ) + 1 ); 
      strcpy( ret, Str_value ); 
      return ret; 
  }; 

  CORBA::Long  ODsample_intf2_impl::value1(
                                     CORBA::Environment&  env ) 
                                     throw( CORBA::Exception ) 
  {
      return Ln_value; 
  }; 

  void  ODsample_intf2_impl::add(
                               CORBA::Long          a, 
                               CORBA::Environment&  env ) 
                               throw( CORBA::Exception ) 
  {
      cout << "ODsample::intf2::add()" << endl; 
      cout << "  value : " << Ln_value << endl; 
      cout << "  a     : " << a << endl; 
      Ln_value = Ln_value + a; 
      cout << "  result: " << Ln_value << endl; 
  }; 

  void  ODsample_intf2_impl::sub(
                               CORBA::Long          b, 
                               CORBA::Environment&  env ) 
                               throw( CORBA::Exception ) 
  {
      cout << "ODsample::intf2::sub()" << endl; 
      cout << "  value : " << Ln_value << endl; 
      cout << "  b     : " << b << endl; 
      Ln_value = Ln_value - b; 
      cout << "  result: " << Ln_value << endl; 
  };

(6)例外情報の獲得

  サーバアプリケーションで例外を獲得する方法の詳細については、“4.2.2 サーバアプリケーションの例外処理”を参照してください。


4.3.7.6 AdapterActivator使用例 (リクエスト受信時)

(1)IDL定義

  module ODsample{
      interface    intf1{
          long  add( in long a, in long b ); 
      }; 
      interface  intf2{
          long  sub( in long a, in long b ); 
      }; 
  };

(2)ネーミングサービスの登録

  OD_or_adm -c IDL:ODsample/intf1:1.0  -a Imple_POAsample10 -n ODsample::POAsample10-1
  OD_or_adm -c IDL:ODsample/intf2:1.0  -a Imple_POAsample10 -n ODsample::POAsample10-2

(3)アプリケーション構成概要図



(4)クライアントアプリケーション

  #include <stdlib.h>
  #include <iostream>
  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static  CORBA::Object_var             obj; 
  static  CORBA::Environment            env; 
  static  CORBA::ORB_var                orb; 
  static  CosNaming::NamingContext_var  cos_naming; 
  static  CosNaming::Name               name; 
  static  CosNaming::Name               name2; 
   
  int main( int argc, char* argv[] ) 
  {
      CORBA::Long   val1 = 0;      // inパラメタ用変数
      CORBA::Long   val2 = 0;      // inパラメタ用変数

      try {
          // ORBの生成と初期化
          orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env ); 

          // ネーミングサービスのオブジェクトリファレンスの取得
          obj = orb->resolve_initial_references( CORBA_ORB_ObjectId_NameService, env ); 
          cos_naming = CosNaming::NamingContext::_narrow( obj ); 

          // ネーミングサービスのresolveメソッドを発行し、
          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name.length( 1 ); 
          name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample10-1"; 
          name[0]->kind = ( const CORBA::Char* )""; 
          obj = cos_naming->resolve( name, env ); 

          // サーバアプリケーションのオブジェクトリファレンス獲得
          ODsample::intf1* target1 = ODsample::intf1::_narrow( obj ); 

          printf( "val1=>" ); 
          scanf( "%d", &val1 ); 
          printf( "val2=>" ); 
          scanf( "%d", &val2 ); 

          // サーバアプリケーションのメソッド呼出し
          CORBA::Long  ret1 = target1->add( val1, val2, env ); 

          // メソッドの結果表示
          printf( "val1 + val2 = %d\n", ret1 ); 

          CORBA::release( target1 ); 

          // ネーミングサービスのresolveメソッドを発行し、
          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name2.length( 1 ); 
          name2[0]->id   = ( const CORBA::Char* )"ODsample::POAsample10-2"; 
          name2[0]->kind = ( const CORBA::Char* )""; 
          obj = cos_naming->resolve( name2, env ); 

          // サーバアプリケーションのオブジェクトリファレンス獲得
          ODsample::intf2* target2 = ODsample::intf2::_narrow( obj ); 

          printf( "val1=>" ); 
          scanf( "%d", &val1 ); 
          printf( "val2=>" ); 
          scanf( "%d", &val2 ); 

          // サーバアプリケーションのメソッド呼出し
          CORBA::Long  ret2 = target2->sub( val1, val2, env ); 

          // メソッドの結果表示
          printf( "val1 - val2 = %d\n", ret2 ); 

          CORBA::release( target2 ); 
      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 
      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

(5)サーバアプリケーション

  #include <iostream>
  #include <stdlib.h>
  #include "orb_cplus.h"
  #include "poa.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static CORBA::ORB_var                   orb; 
  static CORBA::Object_var                obj; 
  static CORBA::Environment               env; 
  static PortableServer::POA_var          rootPOA; 
  static CORBA::PolicyList                policies( 4 ); 
  static PortableServer::POAManager_var   poa_manager; 

  // ユーザアプリケーション:メイン処理クラス
  int main( int argc, char* argv[] ) 
  {
      int current_argc = argc; 
      try{
          // ORBの生成と初期化
          orb         = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env ); 

          // RootPOAのオブジェクトリファレンスの取得
          obj         = orb->resolve_initial_references( "RootPOA", env ); 
          // RootPOAのPOAオブジェクト獲得
          rootPOA     = PortableServer::POA::_narrow( obj ); 

          // AdapterActivatorの生成
          PortableServer::AdapterActivator_var adp = new UserAdapterActivator(); 
          // インプリ用POAのAdapterActivatorに設定
          rootPOA->the_activator( adp, env ); 

          // POAマネージャの獲得
          poa_manager = rootPOA->the_POAManager( env ); 
          // POAマネージャのactivate
          poa_manager->activate( env ); 

          orb->run( env ); 
      } catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 
      } catch( CORBA::Exception&  e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

  // AdapterActivator:POA生成クラス(AdapterActivatorを継承)
  class UserAdapterActivator : public PortableServer::AdapterActivator
  {
  public: 
      UserAdapterActivator() {};
      ~UserAdapterActivator() {};

      CORBA::Boolean  unknown_adapter(
                                PortableServer::POA_ptr parent, 
                                const CORBA::Char*      name, 
                                CORBA::Environment&     env ) 
                                throw( CORBA::Exception ) 
      {
          // ポリシリスト作成
          CORBA::PolicyList    policies( 4 ); 
          policies.length( 4 ); 
          policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::NON_RETAIN, env ); 
          policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_DEFAULT_SERVANT, env ); 
          policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::SYSTEM_ID, env ); 
          policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::MULTIPLE_ID, env ); 
          try {
              if( !strcmp( name, "IDL:ODsample/intf1:1.0" ) ) {
                  // intf1用のPOA作成
                  PortableServer::POA_ptr intf_POA
                    = parent->create_POA( name, NULL, policies, env ); 

                  // Servantの生成
                  ODsample_intf1_impl* svt = new ODsample_intf1_impl(); 

                  // Default Servantに設定
                  intf_POA->set_servant( svt, env ); 

                  return( CORBA_TRUE ); 
              }
              else if( !strcmp( name, "IDL:ODsample/intf2:1.0" ) ) {
                  // intf2用のPOA作成
                  PortableServer::POA_ptr intf_POA
                      = parent->create_POA( name, NULL, policies, env ); 

                  // Servantの生成
                  ODsample_intf2_impl* svt = new ODsample_intf2_impl(); 

                  // Default Servantに設定
                  intf_POA->set_servant( svt, env ); 

                  return( CORBA_TRUE ); 
              }
          } catch( CORBA::SystemException&  se ) {
              cout << "exception-id: " << se.id() << endl; 
              return( CORBA_FALSE ); 
          } catch( CORBA::UserException&  ue ) {
              cout << "exception-id: " << ue.id() << endl; 
              return( CORBA_FALSE ); 
          } catch( CORBA::Exception&  e ) {
              cout << "exception-id: " << e.id() << endl; 
              return( CORBA_FALSE ); 
          }
          return CORBA_TRUE; 
      }; 
  }; 

  // メソッド実装
  CORBA::Long  ODsample_intf1_impl::add(
                                      CORBA::Long          a, 
                                      CORBA::Long          b, 
                                      CORBA::Environment&  env ) 
                                      throw( CORBA::Exception ) 
  {
      return a + b; 
  }; 

  CORBA::Long  ODsample_intf2_impl::sub(
                                     CORBA::Long  a, 
                                     CORBA::Long  b, 
                                     CORBA::Environment&  env ) 
                                     throw( CORBA::Exception ) 
  {
      return a - b; 
  };

(6)例外情報の獲得

  サーバアプリケーションで例外を獲得する方法の詳細については、“4.2.2 サーバアプリケーションの例外処理”を参照してください。


4.3.7.7 代理方式の実装例(デフォルトインスタンス方式の例)

(1)IDL定義

  module ODsample{
      interface  intf{
          long  add( in  long  a,  in  long  b ); 
      }; 
  };

(2)ネーミングサービスの登録

  動的登録


(3)アプリケーション構成概要図



(4)クライアントアプリケーション

  #include <stdlib.h>
  #include <iostream>
  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static  CORBA::Object_var             obj; 
  static  CORBA::ORB_var                orb; 
  static  CORBA::Environment            env; 
  static  CosNaming::NamingContext_var  cos_naming; 
  static  CosNaming::Name               name; 

  int main( int argc, char* argv[] ) 
  {
      try {
          // ORBの生成と初期化
          orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env ); 

          // ネーミングサービスのオブジェクトリファレンスの取得
          obj = orb->resolve_initial_references(
                        CORBA_ORB_ObjectId_NameService, env ); 
          cos_naming = CosNaming::NamingContext::_narrow( obj ); 

          // ネーミングサービスのresolveメソッドを発行し、
          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name.length( 1 ); 
          name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample1"; 
          name[0]->kind = ( const CORBA::Char* )""; 
          obj = cos_naming->resolve( name, env ); 

          // サーバアプリケーションのオブジェクトリファレンス獲得
          ODsample::intf* obj2 = ODsample::intf::_narrow( obj ); 

          CORBA::Long  a;     // inパラメタ用変数
          CORBA::Long  b;     // inパラメタ用変数
          CORBA::Long  ret;   // 復帰値用変数

          printf( "  a => " ); 
          scanf( "%d", &a ); 
          printf( "  b => " ); 
          scanf( "%d", &b ); 

          // サーバアプリケーションのメソッド呼出し
          ret = obj2->add( a, b, env ); 

          // メソッドの結果表示
          printf( "  a + b = %d", ret ); 

          CORBA::release( obj2 ); 
      }catch( CORBA::SystemException&  se ) {
          cout << "exception-id: " << se.id() << endl; 
          exit(1); 
      }catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

(5)サーバアプリケーション

  #include <iostream>
  #include <stdlib.h>
  #include "orb_cplus.h"
  #include "poa.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  using std::cout;
  using std::endl;

  static CORBA::ORB_var                   orb; 
  static CORBA::Object_var                obj; 
  static CORBA::Environment               env; 
  static CosNaming::NamingContext_var     cos_naming; 
  static CosNaming::Name                  name; 
  static PortableServer::POA_var          rootPOA; 
  static PortableServer::POA_var          childPOA; 
  static CORBA::PolicyList                policies( 4 ); 
  static PortableServer::POAManager_var   poa_manager; 

  // ユーザアプリケーション:メイン処理クラス
  int main( int argc, char*argv[] ) 
  {
      int current_argc = argc; 

      try{
          // ORBの生成と初期化
          orb         = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env ); 

          // RootPOAのオブジェクトリファレンスの取得
          obj         = orb->resolve_initial_references( "RootPOA", env ); 

          // RootPOAのPOAオブジェクト獲得
          rootPOA     = PortableServer::POA::_narrow( obj ); 

          // インタフェース用のPOA作成
          // ポリシリスト作成
          policies.length( 4 ); 
          policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::NON_RETAIN, env ); 
          policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_DEFAULT_SERVANT, env ); 
          policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::SYSTEM_ID, env ); 
          policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::MULTIPLE_ID, env ); 

          // Default Servant用のPOAオブジェクトの作成
          childPOA   = rootPOA->create_POA( "childPOA", 
                          PortableServer::POAManager::_nil(), policies, env ); 

          // tieオブジェクト作成とユーザクラスの登録
          PortableServer::Servant svt = _ct_ODsample_intf(); 

          // POAのDefault Servantに設定
          childPOA->set_servant( svt, env ); 

          CORBA::Object_var _bind_obj = childPOA->create_reference( "IDL:ODsample/intf:1.0", env ); 

          // ネーミングサービスのオブジェクトリファレンスの取得
          CORBA::Object_var _tmpObj = orb->resolve_initial_references( "NameService", env ); 
          cos_naming = CosNaming::NamingContext::_narrow( _tmpObj ); 

          // サーバアプリケーションのオブジェクトリファレンスの獲得
          name.length( 1 ); 
          name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample1"; 
          name[0]->kind = ( const CORBA::Char* )""; 
          try{
            cos_naming->unbind( name, env ); 
          } catch( CORBA::Exception& e ) {
              ; 
          }
          cos_naming->bind( name, _bind_obj, env ); 

          // POAマネージャの獲得
          poa_manager = childPOA->the_POAManager( env ); 

          // POAマネージャのactivate
          poa_manager->activate( env ); 

          orb->run( env ); 
      } catch( CORBA::Exception& e ) {
          cout << "exception-id: " << e.id() << endl; 
          exit(1); 
      }
      return 0; 
  }

  //ユーザクラス(インタフェース実装クラス)
  class UserServant
  {
  public: 
      UserServant(){}; 
      ~UserServant(){}; 
      CORBA::Long add(
                   CORBA::Long a, 
                   CORBA::Long b, 
                   CORBA::Environment& env ) 
                   throw( CORBA::Exception ) 
      {

          CORBA::Long    result; 

          cout << "ODsample::intf::add()" << endl; 
          cout << "  a     : " << a << endl; 
          cout << "  b     : " << b << endl; 
          result = a + b; 
          cout << "  result: " << result << endl; 
          return result; 
      }; 
  }; 

  POA_ODsample_intf* _ct_ODsample_intf() 
  {
      // ユーザクラスのインスタンス生成
      UserServant* impl = new UserServant(); 
      // tieオブジェクト作成とユーザクラスの登録
      POA_ODsample_intf_tie<UserServant>* tie = 
          new POA_ODsample_intf_tie<UserServant>( impl ); 
      return tie; 
  };

(6)例外情報の獲得

  サーバアプリケーションで例外を獲得する方法の詳細については、“4.2.2 サーバアプリケーションの例外処理”を参照してください。


4.3.7.8 Active Object Map(AOM)使用例(Factory-1方式+クライアントとのコネクション切断時のインスタンス解放)

(1)IDL定義

  module ODsample{
      interface intf{
          readonly  attribute  long  value1; 
          void  add( in  long  a ); 
          void  sub( in  long  b ); 
      };
      interface Factory {
          intf   create( in string username );
          void   destroy( in  intf  obj ); 
      };
  };

(2)ネーミングサービスの登録

  OD_or_adm -c IDL:ODsample/Factory:1.0 -a Imple_POAsample5 -n ODsample::POAsample5

(3)アプリケーション構成概要図



(4)クライアントアプリケーション

  #include <iostream>
  #include <stdlib.h>
  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"
  #include <string.h>

  using std::cin;
  using std::cout;
  using std::endl;

  int main( int argc, char *argv[] )
  {
    CORBA::Environment env;
    try {
        // ORBの生成と初期化 
        CORBA::ORB_ptr orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env );

        // ネーミングサービスのオブジェクトリファレンスの取得 
        CORBA::Object_ptr obj = orb->resolve_initial_references(
            CORBA_ORB_ObjectId_NameService, env );
        CosNaming::NamingContext_ptr ctx = CosNaming::NamingContext::_narrow( obj );
        CORBA::release( obj );

        // ネーミングサービスのresolveメソッドを発行し、
        // サーバアプリケーションのオブジェクトリファレンスの獲得
        CosNaming::Name name;
        name.length(1);
        name[0]->id   = ( const CORBA::Char* )"ODsample::POAsample5";
        name[0]->kind = ( const CORBA::Char* )"";

        obj = ctx->resolve( name, env );

        // Factoryのオブジェクトリファレンスの獲得
        ODsample::Factory_ptr factory = ODsample::Factory::_narrow( obj );
        CORBA::release( obj );

        // ユーザIDの入力
        char _username[128];
        cout << "input your name  => ";
        cin >> _username;

        // Factoryでインタフェース用オブジェクトリファレンス作成
        ODsample::intf_ptr target = factory->create( _username );

        // サーバアプリケーションのメソッド呼出し
        cout << "value = " << target->value1() << endl;
        cout << "add => ";
        CORBA::Long a;
        cin >> a;

        target->add( a );

        cout << "value = " << target->value1() << endl;
        cout << "sub => ";
        CORBA::Long b;
        cin >> b;

        target->sub( b );

        cout << "value = " << target->value1() << endl;

        CORBA::release( factory );
        CORBA::release( target );

    } catch( CORBA::SystemException&  se ) {
        cout << "exception-id: " << se.id() << endl;
        exit(1);

    } catch( CORBA::Exception&  e ) {
        cout << "exception-id: " << e.id() << endl;
        exit(1);
    }

    return 0;
  }

(5)サーバアプリケーション

  #include <iostream>
  #include <stdlib.h>

  #include "orb_cplus.h"
  #include "simple.h"
  #include "poa.h"
  #include "CosNaming_cplus.h"

  using std::cout;
  using std::endl;

  static CORBA::ORB_var                   orb;
  static CORBA::Object_var                obj;
  static CORBA::Environment               env;

  static PortableServer::POA_var          rootPOA;
  static PortableServer::POA_var          factoryPOA;
  static CORBA::PolicyList                factory_policies;
  static PortableServer::POAManager_var   poa_manager;

  // ユーザアプリケーション:メイン処理クラス
  int main( int argc, char*argv[] )
  {
    int current_argc = argc;

    try{
        // ORBの生成と初期化
        orb         = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env );

        // RootPOAのオブジェクトリファレンスの取得
        obj         = orb->resolve_initial_references( "RootPOA", env );

        // RootPOAのPOAオブジェクト獲得
        rootPOA     = PortableServer::POA::_narrow( obj );

        // Factoryインタフェース用のPOA作成
        // ポリシリスト作成
        factory_policies.length( 4 );
        factory_policies[0] = rootPOA->create_servant_retention_policy(
                                 PortableServer::NON_RETAIN, env );
        factory_policies[1] = rootPOA->create_request_processing_policy(
                                 PortableServer::USE_DEFAULT_SERVANT, env );
        factory_policies[2] = rootPOA->create_id_assignment_policy(
                                 PortableServer::SYSTEM_ID, env );
        factory_policies[3] = rootPOA->create_id_uniqueness_policy(
                                 PortableServer::MULTIPLE_ID, env );

        factoryPOA = rootPOA->create_POA( "IDL:ODsample/Factory:1.0",
                 PortableServer::POAManager::_nil(), factory_policies ,env);

        // FactoryServantの生成
        PortableServer::Servant  svt = _ct_ODsample_Factory( rootPOA );

        // Factoryインタフェース用POAをDefault Servantに設定
        factoryPOA->set_servant( svt, env );

        // POAマネージャの獲得
        poa_manager = rootPOA->the_POAManager( env );

        // インスタンス解放処理の登録
        PortableServer::POAdiconnect::setDisconnect(new instrelease());

        // POAマネージャのactivate
        poa_manager->activate( env );

        orb->run( env );

    } catch( CORBA::SystemException&  se ) {
        cout << "exception-id: " << se.id() << endl;
        exit(1);
    } catch( CORBA::Exception&  e ) {
        cout << "exception-id: " << e.id() << endl;
        exit(1);
    }

    return 0;
  }

  // FactoryServant:Factoryメソッド実装クラス
  class FactoryServant
  {
  public :
    // コンストラクタ
    FactoryServant(
        PortableServer::POA_ptr  poa )
    {
        _poa = poa;
    }

    ~FactoryServant()
    {
        CORBA::release( _poa );
    }

    ODsample::intf_ptr create(
        const CORBA::Char *username,
        CORBA::Environment&  env )
        throw( CORBA::Exception )
    {
        if( !_poa ) return NULL;
        ODsample::intf_ptr _ior = NULL;
        try{
            if( servant_list == NULL ){
                servant_list = new ServantList();
            }

            // Servantの検索
            PortableServer::ServantBase *_svt = servant_list->get( username );

            // みつからない場合、Servantを作成(guestは毎回作成)
            if( !_svt ){
                _svt = _ct_ODsample_intf( username );
                servant_list->put( username, _svt );
                if( 100 < servant_list->length()){
                  PortableServer::POAdisconnect::setDisconnect(new ALLinstrelease());
                }
            }

            // Servantからオブジェクトリファレンスの生成
            // IMPLICIT_ACTIVATIONポリシを指定しているので、AOMへ自動登録される
            CORBA::Object_ptr _obj = _poa->servant_to_reference( _svt, env );
            _ior = ODsample::intf::_narrow( _obj );

            CORBA::release( _obj );
        } catch( CORBA::Exception &e ) {
            cout << "exception-id: " << e.id() << endl;
            throw e;
        }
        return _ior;
    };


    void destroy(
        ODsample::intf_ptr obj,
        CORBA::Environment& env )
        throw( CORBA::Exception )
    {
        if( !_poa ) return;
        try{
            // オブジェクトリファレンスからオブジェクトIDを求める
            PortableServer::ObjectId_var _oid = _poa->reference_to_id( obj, env );

            // オブジェクトIDからServantを求める
            PortableServer::Servant _svt = _poa->id_to_servant( *_oid, env );

            // Servantをdeactiveにする
            _poa->deactivate_object( *_oid, env );

            // Servantの削除
            _svt->servant_delete();
        } catch( CORBA::Exception& e ) {
            cout << "exception-id: " << e.id() << endl;
            throw e;
        }
    };
  private :
    FactoryServant() {}
    PortableServer::POA_ptr    _poa;
  };

  // FactoryServantをtieオブジェクトに関連付けるためのメソッド(delegate方式の場合)
  POA_ODsample_Factory*  _ct_ODsample_Factory(
    PortableServer::POA_ptr poa )
  {
    FactoryServant*  impl = new FactoryServant( poa );
    POA_ODsample_Factory_tie< FactoryServant >*  tie
        = new POA_ODsample_Factory_tie< FactoryServant >( impl );
    return tie;
  }

  // Servant:メソッド実装クラス(スケルトンを継承)
  class UserServant
  {
  public :
    UserServant(
        const CORBA::Char *username )
    {
        _username = new char[ strlen(username) + 1 ];
        strcpy( _username, username );
        _val = 10;
    }
    ~UserServant()
    {
        if( _username )
            delete [] _username;
    }

    void add(
        CORBA::Long a,
        CORBA::Environment& env)
        throw( CORBA::Exception )
    {
        cout << "ODsample::intf::add()" << endl;
        cout << "  val : " << _val << endl;
        cout << "  a     : " << a << endl;
        _val = _val + a;
        cout << "  result: " << _val << endl;
    }

    void sub(
        CORBA::Long b,
        CORBA::Environment& env)
        throw( CORBA::Exception )
    {
        cout << "ODsample::intf::sub()" << endl;
        cout << "  val : " << _val << endl;
        cout << "  b     : " << b << endl;
        _val = _val - b;
        cout << "  result: " << _val << endl;
    }

    CORBA::Long value1(
        CORBA::Environment& env)
        throw( CORBA::Exception )
    {
        return _val;
    }

    const char *name()
    {
        return _username;
    }

  private :
    UserServant() {}
    char *_username;
    long _val;
  };

  // UserServantをtieオブジェクトに関連付けるためのメソッド(delegate方式の場合)
  POA_ODsample_intf *_ct_ODsample_intf(
      const CORBA::Char *username )
  {
      UserServant*  impl = new UserServant( username );
      POA_ODsample_intf_tie< UserServant >*  tie
          = new POA_ODsample_intf_tie< UserServant >( impl );
      return tie;
  }

  // 条件付きインスタンス解放クラス(POAdisconnectを継承)
  class instrelease : public virtual PortableServer::POAdisconnect
  {
  public :
    instrelease() {}
    ~instrelease() {}

    CORBA::Boolean release_instance(
        PortableServer::POA_ptr poa,
        PortableServer::ServantBase *svt,
        PortableServer::ObjectId&  oid,
        CORBA::Environment&  env  )
    {
        cout << "instrelease::release_instance called..." << endl;
        POA_ODsample_intf_tie< UserServant >*  _tie
                        = dynamic_cast< POA_ODsample_intf_tie< UserServant >* >( svt );
        UserServant*  _svt = _tie->_tied_object();
        cout << "    servant->name : " << _svt->name() << endl;
        if( !strcmp( _svt->name(), "guest" )){
            ServantList::remove( servant_list, "guest" );
            return true;
        }
        return false;
    }
  };

  // 無条件インスタンス解放クラス(POAdisconnectを継承)
  class ALLinstrelease : public virtual PortableServer::POAdisconnect
  {
  public :
    ALLinstrelease() {}
    ~ALLinstrelease() {}

    CORBA::Boolean release_instance(
        PortableServer::POA_ptr poa,
        PortableServer::ServantBase *svt,
        PortableServer::ObjectId&  oid,
        CORBA::Environment&  env  )
    {
        cout << "ALLinstrelease::release_instance called..." << endl;
        POA_ODsample_intf_tie< UserServant >*  _tie
                        = dynamic_cast< POA_ODsample_intf_tie< UserServant >* >( svt );
        UserServant*  _svt = _tie->_tied_object();
        cout << "    servant->name : " << _svt->name() << endl;
        ServantList::remove( servant_list, _svt->name());
        return true;
    }
  };

  // Servant管理テーブル
  class ServantList
  {
  public:
    ServantList()
    {
        _svt = NULL;
        _username = NULL;
        _next = NULL;
    };
    ServantList(
        const CORBA::Char *username,
        PortableServer::ServantBase *svt )
    {
        _username = new char[ strlen(username) + 1];
        strcpy( _username, username );
        _svt = svt;
        _next = NULL;
    };
    ~ServantList()
    {
        if( _username )
            delete [] _username;
        if( _next )
            delete _next;
    };

    PortableServer::ServantBase *get(
        const CORBA::Char *username )
    {
        if( !username || !_username )
            return NULL;
        if( !strcmp( username, _username )){
            return _svt;
        }
        if( _next )
            return _next->get(username);
        return NULL;
    }

    void put(
        const CORBA::Char *username,
        PortableServer::ServantBase *svt )
    {
        if( _next != NULL ){
            _next->put( username, svt );
        }
        else{
            if( _svt == NULL ){
                _svt = svt;
                _username = new char[ strlen(username) + 1];
                strcpy( _username, username );
            }
            else{
                _next = new ServantList( username, svt );
            }
        }
    }

    static void remove(
        ServantList *&list,
        const CORBA::Char *username )
    {
        ServantList *_back = NULL;
        for( ServantList *_list = list; _list; _list = _list->_next ){
            if( !strcmp( _list->_username, username )){
                if( _back ){
                    _back->_next = _list->_next;
                }
                else{
                    list = _list->_next;
                }
                _list->_next = NULL;
                delete _list;
                break;
            }
            _back = _list;
        }
        return;
    }

    int length()
    {
        ServantList *_p = _next;
        int _count = 1;
        while( _p ){
            _p = _p->_next;
            ++_count;
        }
        return _count;
    }

  private :
    PortableServer::ServantBase *_svt;
    char *_username;
    ServantList *_next;
  };

  // 管理テーブルのインスタンス
  ServantList *servant_list = NULL;

(6)例外情報の獲得

  サーバアプリケーションで例外を獲得する方法の詳細については、“4.2.2 サーバアプリケーションの例外処理”を参照してください。