Interstage Application Server アプリケーション作成ガイド (CORBAサービス編)
目次 索引 前ページ次ページ

第5章 アプリケーションの開発(C++言語)> 5.3 サーバアプリケーションのプログラミング(Portable Object Adapter:POA)> 5.3.7 サーバアプリケーションのプログラミング例

5.3.7.5 AdapterActivator使用例 (find_POA時)

(1)IDL定義

  module ODsample{
      interface intf1{
          attribute string value; 
      }; 
      interface intf2{
          readonly attribute long value; 
          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.h>
  #include "orb_cplus.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  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->value( buffer, env ); 
          printf( "String = %s\n", obj2->value( env ) ); 

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

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

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

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

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

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

          printf( "  value = %d\n", obj3->value( 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.h>
  #include <stdlib.h>
  #include "orb_cplus.h"
  #include "poa.h"
  #include "CosNaming_cplus.h"
  #include "simple.h"

  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::value(
                               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::value(
                                   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::value(
                                     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)例外情報の獲得

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


目次 索引 前ページ次ページ

All Rights Reserved, Copyright(C) 富士通株式会社 2005