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

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 サーバアプリケーションの例外処理”を参照してください。