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

4.3.2 POA概要

4.3.2.1 POAとは

POA (Portable Object Adapter)は、CORBA2.2で新しく標準的なオブジェクトアダプタとして採用された仕様です。POAとしてオブジェクトアダプタの仕様が明確化されたことにより、ORB製品ごとの仕様上の差違が排除されるため、異なるORB製品へのサーバアプリケーションの移植が容易となります。


POAの特徴

インスタンス管理

POAオブジェクト内にAOM(Active Object Map:インスタンスの管理テーブル)を持ち、インスタンス管理を行います。サーバアプリケーションは、以下の2とおりのインスタンス管理を行うことが可能です。

POAポリシ

POAに対してポリシを設定することで、POAごとにインスタンス管理方法、オブジェクトの生存期間、多重動作などのポリシを指定できます。POAポリシとして、以下の種類があります。
詳細については、“4.3.2.3 POAオブジェクト”を参照してください。

4.3.2.2 POAのアーキテクチャ

POAは、以下のような仕組みを提供します。



POAオブジェクト

POAオブジェクトは、オブジェクトID、Servantオブジェクト(ユーザ提供のサーバ実装のインスタンス)の関係をAOM(Active Object Map)上で管理し、クライアントからの要求メッセージに従って、Servantオブジェクトのメソッドを実行します。


POAManagerオブジェクト

POAの要求メッセージ処理の受付けに関する状態を制御します。


Servantオブジェクト

サーバアプリケーションが提供するインタフェースを実装し、リクエストに対する処理を実際に行う、ユーザ作成のオブジェクトを示します。


Default Servantオブジェクト

Default Servantオブジェクトは、RequestProcessingポリシにUSE_DEFAULT_SERVANTが設定されています。さらに、リクエストに対応するServantオブジェクトがPOAのAOM(Active Object Map)に存在しない場合に、POAはDefault Servantオブジェクトのメソッドを実行します。


ServantManagerオブジェクト

ServantManagerオブジェクトはPOAオブジェクトにより呼び出され、Servantオブジェクトの作成および検索を行います。
ServantManagerオブジェクトは、RequestProcessingポリシにUSE_SERVANT_MANAGERが設定されている場合にPOAオブジェクトが呼び出しますが、以下の2種類があります。

詳細については、“4.3.2.10 ServantManagerオブジェクト”を参照してください。


AdapterActivatorオブジェクト

リクエストの受信時、対応するPOAオブジェクトが存在しない場合に、POAオブジェクトを生成します。
このAdapterActivatorオブジェクトは、ユーザが作成する必要があります。


オブジェクトID

オブジェクトIDは、POAオブジェクトが対応するServantオブジェクトを特定するための値です。オブジェクトIDの値は、IdAssignmentポリシによって、POAオブジェクトによって割り当てられる場合と、ユーザアプリケーションにより割り当てられる場合があります。オブジェクトIDは、オブジェクトリファレンス中に含められるため、クライアントから意識する必要はありません。


POA ID

POA IDは、リクエストの受信時にPOAオブジェクトを特定するための値です。POA IDは、オブジェクトリファレンス中に含められるため、クライアントから意識する必要はありません。


4.3.2.3 POAオブジェクト

POAオブジェクト作成時は、まず、POAポリシリストを作成する必要があります。次に、ポリシリストを指定してPOAオブジェクトを作成します。


POAポリシ

POAオブジェクトの作成時に、以下のPOAポリシを設定できます。

POAポリシ

意味

Value

Valueの説明

備考

ServantRetention:
Servant関連付けポリシ

AOMテーブルをPOAオブジェクト内で持つか持たないかを指定します。つまり、POAオブジェクト内でインスタンス管理を行うかどうかを指定できます。

4.3.2.7 リクエスト処理”参照。

RETAIN (注1)

ActiveObjectMapにActiveなServantオブジェクトを憶えます。

  

NON_RETAIN

ActiveObjectMapを使いません。

RequestProcessing:
リクエスト処理ポリシ

リクエスト受信時に対象インスタンスをAOM内に持ってない、もしくはAOM自身を保持しないときの振る舞いを規定するポリシです。

4.3.2.7 リクエスト処理”参照。

USE_ACTIVE_
OBJECT_MAP_
ONLY (注1)

リクエスト処理にActiveObjectMapだけ使用します。

  

USE_DEFAULT_
SERVANT

リクエストの処理をDefault Servantオブジェクトに任せます。

USE_SERVANT_
MANAGER

ServantManagerオブジェクトによって目的のServantオブジェクトを見つけます。必要であればactivateも行われます。

ImplicitActivation:
暗黙的活性化ポリシ

Servantの活性化のモードを以下のように指定可能です。

  • 自動的にServantがactivateされます。

  • 自動的にServantがactivateされません(アプリケーションが明示的にServantをPOAに登録します)。

4.3.2.8 暗黙的活性化(Implicit Activation)”参照。

IMPLICIT_
ACTIVATION (注1)

自動的にServantオブジェクトがactivateされます。

  

NO_IMPLICIT_
ACTIVATION

自動的にServantオブジェクトがactivateされません(サーバアプリケーションが明示的にServantオブジェクトを生成して、POAオブジェクトに登録します)。

IdAssignment:
ID割り当てポリシ

オブジェクトIDをシステム(POAオブジェクト)が自動設定するか、ユーザが設定するかを指定できます。
USER_IDはアプリケーションで、オブジェクトIDに固有の意味を持たせたいときに有効です。

4.3.2.6 オブジェクトの活性化”参照。

SYSTEM_ID (注1)

POAオブジェクトがオブジェクトIDを付けます。

  

USER_ID

ユーザがオブジェクトIDを付けます。

IdUniqueness:
オブジェクトID一意性ポリシ

ServantにユニークなIDを付けるか、重複したIDを許すかを指定できます。

4.3.2.5 オブジェクトリファレンス、オブジェクトID、Servantオブジェクトの関連”参照。

UNIQUE_ID (注1)

ServantオブジェクトにユニークなIDを付けます。

  

MULTIPLE_ID

Servantオブジェクトに重複したIDを許します。

Lifespan:
生存期間ポリシ

トランジェントタイプのオブジェクトを扱うかパーシステントタイプのオブジェクトを扱うかを指定可能です。

TRANSIENT (注1)

トランジェントタイプのオブジェクトを扱います(サーバlifespan = オブジェクトlifespan)。

PERSISTENTは、指定不可

PERSISTENT

パーシステントタイプのオブジェクトを扱います(サーバlifespan < オブジェクトlifespan)。

Thread:
スレッドポリシ

スレッド処理をORBに任せるかシングルスレッドで動作させるかを指定できます。

ORB_CTRL_MODEL (注1)

スレッド処理をORBに任せます。

このPOAポリシの設定値は、無効(注2)

SINGLE_THREAD_
MODEL

シングルスレッドで動作させます。

注1デフォルト値
注2インプリメンテーションリポジトリ登録時のプロセス最大多重度(proc_conc_max)、スレッド初期多重度(thr_conc_init)の設定内容に依存します。


POAポリシの生成例を以下に示します。


// POAポリシリスト作成
CORBA::PolicyList   policies( 4 );  // POAのポリシリスト
CORBA::Environment  env;            // 例外情報

policies.length( 4 );
policies[0] = Poa->create_servant_retention_policy(
                  PortableServer::NON_RETAIN, env );
policies[1] = Poa->create_request_processing_policy(
                  PortableServer::USE_DEFAULT_SERVANT, env );
policies[2] = Poa->create_id_assignment_policy(
                  PortableServer::SYSTEM_ID, env );
policies[3] = Poa->create_id_uniqueness_policy(
                  PortableServer::MULTIPLE_ID, env );

) ソース内のPoa:POAクラスのインスタンス


POAオブジェクトの生成

RootPOAオブジェクト

POAオブジェクトを使用するためには、まずRootPOAオブジェクトを生成する必要があります。POAオブジェクトは、RootPOAオブジェクトをルートとして、子POAオブジェクトや孫POAオブジェクトを生成することでツリー構成とすることができます。RootPOAオブジェクトは、ORBがサーバの初期化時に生成します。RootPOAオブジェクトのPOAオブジェクトは、以下のように取得できます。


main( int argc, char* argv[] )
{
    CORBA::ORB_ptr      orb;          // ORBのオブジェクトリフレンス
    CORBA::Object_ptr   obj;          // オブジェクトリファレンスの格納域
    CORBA::Environment  env;          // 例外情報
    int                 current_argc = argc;

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

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

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

RootPOAオブジェクトには、以下のPOAポリシが設定されています。

ユーザアプリケーションで上記のPOAポリシを使用してインスタンス管理を行う場合は、RootPOAオブジェクトをそのまま使用することが可能です。しかし、新しいPOAオブジェクト(RootPOAオブジェクトの子孫POAオブジェクト)を生成し、固有のPOAポリシを設定することによりRootPOAオブジェクトとは異なるPOAポリシでインスタンス管理を行うことが可能となります。


子孫POAオブジェクト

新しいPOAオブジェクトを生成するには、すでに存在するPOAオブジェクト上でcreate_POA()メソッドを呼び出します。この結果、create_POA()を発行したPOAオブジェクトと新しく生成されたPOAオブジェクトは親子関係となります。アプリケーションで最初に生成するPOAオブジェクトはRootPOAオブジェクトであるため、その他のPOAオブジェクトはすべてRootPOAオブジェクトの子孫POAオブジェクトとなります。
create_POA()の引数としてPOAポリシリスト(Policyクラスの配列)を渡すことで、生成した子POAオブジェクトのポリシを設定することが可能です。


// 子POAオブジェクト(childPOA1)の生成
PortableServer::POA_ptr    childPOA1
        = rootPOA->create_POA( "poa_1", poamanager, policies1 );
// 孫POAオブジェクト(childPOA2)の生成
PortableServer::POA_ptr    childPOA2
        = childPOA1->create_POA("poa_2", poamanager, policies2 );

注)ソース内のpoa_1,poa_2:生成するPOAの名前
    ソース内のpoamanager:POAManagerクラスのインスタンス
    policies1/policies2:Policyクラスのインスタンス


上記のように、POAオブジェクトは階層構造をもたせることが可能です。オブジェクトの生成、オブジェクトと管理するPOAオブジェクトとの関係については、“4.3.3 サーバアプリケーションと環境設定との関連付け”を参照してください。destroy()メソッドによりあるPOAオブジェクトが破棄された場合、その子孫POAオブジェクトはすべて破棄されます。


POAポリシの設定値の組合せ

ポリシリストに設定したPOAポリシの各設定値は、create_POA()メソッド発行時にそれらの組合せが妥当であるかチェックされます。もし、設定値の組合せが妥当でない場合は、例外が発生します。
以下にPOAポリシの設定値の組合せを示します。妥当性欄で“*”の部分はこの値が設定された場合、create_POA()メソッド実行時にPortableServer::POA::InvalidPolicy例外が発生することを示しています。
なお、LifespanPolicyの設定値は、TRANSIENTとしてください。また、ThreadPolicyの設定値は、無視されます。

ポリシ

Servant
Retention

Request
Processing

Implicit
Activation

IdAssignment

IdUniqueness

妥当性

設定値

RETAIN

USE_ACTIVE_
OBJECT_MAP_
ONLY

IMPLICIT_
ACTIVATION

SYSTEM_ID

UNIQUE_ID

  

MULTIPLE_ID

  

USER_ID

*

NO_IMPLICIT_
ACTIVATION

SYSTEM_ID

UNIQUE_ID

  

MULTIPLE_ID

  

USER_ID

UNIQUE_ID

  

MULTIPLE_ID

  

USE_DEFAULT_
SERVANT

IMPLICIT_
ACTIVATION

SYSTEM_ID

UNIQUE_ID

*

MULTIPLE_ID

  

USER_ID

*

NO_IMPLICIT_
ACTIVATION

SYSTEM_ID

UNIQUE_ID

*

MULTIPLE_ID

  

USER_ID

UNIQUE_ID

*

MULTIPLE_ID

  

USE_SERVANT_
MANAGER

IMPLICIT_
ACTIVATION

SYSTEM_ID

UNIQUE_ID

  

MULTIPLE_ID

  

USER_ID

*

NO_IMPLICIT_
ACTIVATION

SYSTEM_ID

UNIQUE_ID

  

MULTIPLE_ID

  

USER_ID

UNIQUE_ID

  

MULTIPLE_ID

  

NON_RETAIN

USE_ACTIVE_
OBJECT_MAP_
ONLY

*

USE_DEFAULT_
SERVANT


()

SYSTEM_ID

UNIQUE_ID

*

MULTIPLE_ID

  

USER_ID

UNIQUE_ID

*

MULTIPLE_ID

  

USE_SERVANT_
MANAGER


()

SYSTEM_ID

UNIQUE_ID

  

MULTIPLE_ID

  

USER_ID

UNIQUE_ID

  

MULTIPLE_ID

  

) ServantRetentionPolicyにNON_RETAINが設定されている場合、ImplicitActivationPolicyの設定値は無視されます。


POAポリシのデフォルト設定値

POAは、デフォルトのポリシ設定値として以下の値を持っています。

ポリシ

デフォルト値

ServantRetention

RETAIN

RequestProcessing

USE_ACTIVE_OBJECT_MAP_ONLY

ImplicitActivation

NO_IMPLICIT_ACTIVATION

IdAssignment

SYSTEM_ID

IdUniqueness

UNIQUE_ID

Lifespan

TRANSIENT

Thread

ORB_CTRL_MODEL

create_POA()メソッドを使用して新しいPOAを生成する際は、デフォルトの設定値から変更したいポリシだけ設定することが可能です。
以下の例では、USE_DEFAULT_SERVANTにRequestProcessingPolicyを、MULTIPLE_IDにIdUniquenessPolicyを設定した子POAを生成しています。この場合、他のポリシの設定値は、上記のデフォルトの設定値のままとなります。


CORBA::Environment  env;    // 例外情報

// POAポリシリスト作成
CORBA::PolicyList   policies( 2 )
policies[0] =  Poa->create_request_processing_policy(
                   PortableServer::USE_DEFAULT_SERVANT, env );
policies[1] =  Poa->create_id_uniqueness_policy(
                   PortableServer::MULTIPLE_ID, env );

// 子POAオブジェクトの生成
PortableServer::POA_ptr  Poa1
    = Poa->create_POA( "poa_1", poamanager, policies );

注)ソース内のPoaは:POAクラスのインスタンス
    ソース内のpoamanager:POAManagerクラスのインスタンス


なお、create_POA()メソッドの第3パラメタにnullを指定した場合は、生成される子POAのポリシはデフォルトの設定値となります。


4.3.2.4 オブジェクトリファレンスの生成

オブジェクトリファレンスは、以下の方法で生成します。


Servantオブジェクトの活性化前に作成する方法(直接作成)

サーバアプリケーションは、直接オブジェクトリファレンスをPOAオブジェクトのcreate_reference()やcreate_reference_with_id()メソッドで作成できます。この操作は、オブジェクトリファレンスだけを作成します。実際のアクティブなServantオブジェクトは、後からServantManagerオブジェクトで生成される場合もあります。


CORBA::Environment  env;   // 例外情報

// オブジェクトリファレンスの生成
CORBA::Object  _bind_obj = 
          Poa->create_reference( "IDL:Intfid11:1.0", env ); 

// ID指定によるオブジェクトリファレンスの生成
long  len = strlen( "USERID" ); 
CORBA::Octet*  buf = PortableServer::ObjectId::allocbuf( len ); 
memcpy( buf, "USERID", len ); 
PortableServer::ObjectId_var  userid =
          new PortableServer::ObjectId( len, len, buf, CORBA_TRUE ); 
CORBA::Object  _bind_obj = 
          Poa->create_reference_with_id( *userid, "IDL:Intfid11:1.0", env ); 

注)ソース内のPoa:POAクラスのインスタンス
    IDL:Intfid11:1.0:インタフェースリポジトリID


Servantオブジェクトの活性化後に作成する方法(間接作成)

サーバアプリケーションは、activate_object()/activate_object_with_id()メソッドよりServantオブジェクトを活性化します。一度Servantオブジェクトが活性化されると、サーバアプリケーションはServantオブジェクト/オブジェクトIDを指定して、servant_to_reference()/id_to_reference()メソッドを発行することにより容易にオブジェクトリファレンスを作成できます。また、POAオブジェクトがIMPLICIT_ACTIVATIONポリシで作成されていれば、servant_to_reference()を使用してオブジェクトリファレンスを生成した場合、自動的にServantオブジェクトがactivateされ、オブジェクトリファレンスが有効となります。


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

// IMPLICIT_ACTIVATIONポリシを指定している場合、自動的にactivateされる
CORBA::Object_ptr obj =  Poa->servant_to_reference( svt, env );

) ソース内のPoaオブジェクト:POAクラスのインスタンス


一度オブジェクトリファレンスがクライアントに通知されると、クライアントの側から見るとそのオブジェクトリファレンスはオブジェクトの身元を持っていることになります。クライアントプログラムがそのオブジェクトリファレンスを使う限り、そのオブジェクトリファレンスで作られるリクエストは同一のオブジェクトのインスタンスに送信されます。


4.3.2.5 オブジェクトリファレンス、オブジェクトID、Servantオブジェクトの関連



オブジェクトリファレンス、オブジェクトID(oid)、Servantオブジェクトの関係は、IdUniquenessPolicyによって決まります。オブジェクトリファレンスは、oidを包含しているため、referenceとoidは、1対1の関係となります。oidとServantオブジェクトの関係は、UNIQUE_IDの場合では、Servantオブジェクトごとに一意のoidが割り当てられます。MULTIPLE_IDの場合は、同じServantオブジェクトへの複数のoidが割り当て可能です。このことは、具体的にはoidを生成するservant_to_id()/servant_to_reference()の動作に影響を与えます。



4.3.2.6 オブジェクトの活性化

オブジェクトが活性状態とは、POAオブジェクトの管理するAOM(Active Object Map)に、あるServantオブジェクトがオブジェクトIDと関連付けられて登録されている状態のことを指します。
Servantオブジェクトは、インスタンスとして生成されただけでは、POAオブジェクトに認識されないため、activate_object()/activate_object_with_id()メソッドを使用して、オブジェクトIDとの関連付けをPOAオブジェクトに登録する必要があります。Servantオブジェクトを活性化する方法を以下に示します。


明示的にServantオブジェクトを活性化する方法

Servantオブジェクトの作成(new)後に、activate_object()/activate_object_with_id()メソッドでAOMに登録できます。


CORBA::Environment  env;  // 例外情報

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

// Servantの活性化
Poa->activate_object ( svt, env ); 

// ID指定によるServantの活性化
long  len = strlen( "USERID" ); 
CORBA::Octet*  buf = PortableServer::ObjectId::allocbuf( len ); 
memcpy( buf, "USERID", len ); 
PortableServer::ObjectId_var  userid =
          new PortableServer::ObjectId( len, len, buf, CORBA_TRUE ); 
Poa->activate_object_with_id( *userid, svt, env ); 

) ソース内のPoaオブジェクト:POAクラスのインスタンス


なお、活性化の際にはオブジェクトIDが必要となりますが、オブジェクトIDの割付けは、IdAssignmentPolicyに従って処理されます。

暗黙的にServantオブジェクトを活性化する方法

POAオブジェクトがIMPLICIT_ACTIVATIONポリシを持っている場合、servant_to_reference()メソッドを使用してリファレンスを生成すると、自動的にServantオブジェクトが活性化されて、オブジェクトリファレンスが通知されます。暗黙的活性化については、“4.3.2.8 暗黙的活性化(Implicit Activation)”を参照してください。


CORBA::Environment  env;  // 例外情報

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

// IMPLICIT_ACTIVATIONポリシを指定している場合、自動的にactivateされる
CORBA::Object Obj =  Poa->servant_to_reference( svt, env ); 

) ソース内のPoaオブジェクト:POAクラスのインスタンス


なお、暗黙的活性化の場合、オブジェクトIDはPOAオブジェクトにより自動的に割り付けます。このため、IdAssignmentPolicyは、SYSTEM_IDに設定しておく必要があります。


4.3.2.7 リクエスト処理

POAオブジェクトの検索

クライアントからのリクエスト受信時に、インタフェースリポジトリIDに対応するPOAオブジェクトがサーバプロセス上に存在しなければ、親のPOAオブジェクトはAdapterActivatorオブジェクトを呼び出します。AdapterActivatorオブジェクトでは、要求されたPOAオブジェクトを作成します。
AdapterActivatorオブジェクトは、ユーザが作成する必要があります。また、事前にPOAオブジェクトに登録しておく必要があります。もし、AdapterActivatorオブジェクトが登録されていない場合、クライアントはOBJECT_NOT_EXIST例外を受け取ります。


Servantオブジェクトの検索

クライアントからのリクエスト受信時に、POAオブジェクトはAOMに登録されているServantオブジェクトを検索します。なお、AOMを使用するかどうかは、対象のPOAオブジェクトがRETAINポリシ(使用する)とNON_RETAINポリシ(使用しない)のどちらが指定されているかによります。
RETAINポリシが指定され、目的のServantオブジェクトがAOM内にみつかった場合、検索処理はそこで終了してServantオブジェクトのメソッドを実行します。Servantオブジェクトがみつからなかった場合や、NON_RETAINの場合は、以下のRequestProcessingポリシに従って処理を行います。

4.3.2.8 暗黙的活性化(Implicit Activation)

Servantオブジェクトの活性化方法には、アプリケーションが明示的にServantオブジェクトを活性化させる方法に加え、POAオブジェクトにより暗黙的(Implicit)にServantオブジェクトを活性化させるIMPLICIT_ACTIVATIONポリシがあります。
IMPLICIT_ACTIVATIONポリシを使用するためには、SYSTEM_IDポリシおよびRETAINポリシを指定する必要があります。IMPLICIT_ACTIVATIONポリシを指定することにより、servant_to_reference()/servant_to_id()などのServantオブジェクトからオブジェクトリファレンスやオブジェクトIDに変換するメソッドを使用した際に、POAオブジェクトがAOMにServantオブジェクトおよびオブジェクトIDを登録し、Servantオブジェクトを活性化できます。このときにUNIQUE_IDポリシが指定されていた場合、再度、servant_to_reference()/servant_to_id()を使用した場合、前回と同じリファレンスやオブジェクトIDが返されます。MULTIPLE_IDポリシが指定されていた場合、毎回、異なったオブジェクトリファレンスやオブジェクトIDが返されます。これは、同じServantオブジェクトに複数のオブジェクトリファレンスやオブジェクトIDが割り付けられることを意味します。


4.3.2.9 POAManagerオブジェクト

POAManagerオブジェクトは、POAオブジェクトの生成時、create_POA()メソッドの引数として渡すことにより、POAオブジェクトと関連付けられます。POAManagerは、以下の4つの状態を持っています。POAオブジェクトは、POAManagerの状態に従って処理を決定します。この状態は、activate()、hold_requests()、discard_requests()、deactivate()などのメソッドで変更できます。


holding状態

受け取ったメッセージをキューイングします。

active状態

受け取ったメッセージを処理します。

discarding状態

受け取ったメッセージを捨てます。この場合、クライアントへはエラーが通知されます。

inactive状態

shutdown直前の状態。


POAオブジェクトの状態遷移を以下に示します。



4.3.2.10 ServantManagerオブジェクト

ServantManagerオブジェクトは、リクエスト受信時に、Servantオブジェクトの生成/削除/検索を可能にする機能です。ServantManagerオブジェクトの各メソッドの実装は、ユーザ自身で作成します。作成したServantManagerオブジェクトは、POAオブジェクトに登録しておきます。
POAオブジェクトがリクエストを受信した際、AOMにオブジェクトIDが一致するServantオブジェクトが登録されていない場合、POAオブジェクトはServantManagerオブジェクトのメソッドを呼び出し、Servantオブジェクトの生成/削除/検索を依頼します。
ServantManagerオブジェクトは、以下のの2種類が存在します。

POAオブジェクトは、以下のオブジェクトを呼び出します。

(1)ServantActivatorオブジェクト

作成するServantActivatorクラスは、以下のようにPortableServer::ServantActivatorクラスを継承させる必要があります。また、メソッドとしてincarnate()/etherealize()を実装している必要があります。

【ServantActivatorクラスの実装形式】

class UserServantActivator : public PortableServer::ServantActivator
{ public : PortableServer::Servant incarnate(...) {...} void etherealize(...) {...} };

POAオブジェクトは、以下のメソッドを呼び出します。

POAオブジェクトから渡されるパラメタは、必要に応じて各メソッドの実装部で使用できます。

ServantActivatorオブジェクトの具体的な処理の流れを以下に示します。



  1. FactoryにServantのオブジェクトリファレンスの生成を依頼します。()

  2. Factoryで生成したオブジェクトリファレンスをクライアントに返します。

  3. Servantに、オペレーションop()を要求します。

  4. POAでは、AOMに未登録の要求であるため、ServantActivatorを呼び出します。

  5. ServantActivatorでは、該当するServantを検索して返します。

  6. ServantActivatorからServantを受け取り、AOMに登録します。

  7. Servantに対してオペレーションop()の実行を依頼します。

  8. クライアントに、オペレーションop()の結果を通知します。

) Factoryは、リクエストごとにオブジェクトリファレンスやインスタンスを作成するオブジェクトです。インスタンス管理を行う場合に必要となるオブジェクトです。


(2)ServantLocatorオブジェクト

作成するServantLocatorクラスは、以下のようにPortableServer::ServantLocatorクラスを継承させる必要があります。また、メソッドとしてpreinvoke()/postinvoke()を実装している必要があります。


【ServantLocatorクラスの実装形式】

class UserServantLocator : public PortableServer::ServantLocator
{ public : PortableServer::Servant preinvoke(...) {...} void postinvoke(...) {...} };

POAオブジェクトはクライアントからの要求を処理するため、毎回ServantLocatorオブジェクトのpreinvoke()メソッドを呼び出し、処理対象のServantオブジェクトを獲得します。POAオブジェクトはそのServantオブジェクトに処理を要求し、その処理が終わったら、ServantLocatorオブジェクトのpostinvoke()メソッドを呼び出し、ServantLocatorオブジェクトに後処理を依頼します。
POAオブジェクトから渡されるパラメタは、必要に応じて各メソッドの実装部で使用できます。

ServantLocatorの具体的な処理の流れを以下に示します。



  1. Factoryに、Servantのオブジェクトリファレンスの生成を依頼します。

  2. Factoryで生成したオブジェクトリファレンスをクライアントに返します。

  3. Servantに、オペレーションop()を要求します。

  4. POAでは、ServantLocatorを呼び出します。

  5. ServantLocatorのpreinvoke()でServantを検索します。

  6. Servantを受け取ります。

  7. Servantに対してオペレーションop()の実行を依頼します。

  8. クライアントに、オペレーションop()の結果を通知します。

  9. ServantLocatorのpostinvoke()を呼び出します。

  10. クライアントへオペレーションを復帰します。


4.3.2.11 AdapterActivatorオブジェクト

AdapterActivatorオブジェクトは、リクエストを受信時にPOAオブジェクトを生成するために使用します。POAオブジェクトが生成したオブジェクトリファレンスには、オブジェクトIDに加え、生成元POAオブジェクトを示すPOAidが埋め込まれています。クライアントからのリクエストが送られてきた際、POA idに対応するPOAオブジェクトが検索され、そのPOAオブジェクトがリクエストに対する処理を行います。もし、みつからない場合、検索対象のPOAの親POAオブジェクトにAdapterActivatorオブジェクトが設定されているならば、そのAdapterActivatorオブジェクトに子POAオブジェクトの生成を依頼します。親POAにAdapterActivatorオブジェクトが設定されていない場合は、CORBA::StExcep::OBJ_ADAPTER例外がクライアントに通知されます。
AdapterActivatorオブジェクトは、ユーザが作成し、POAに登録する必要があります。
作成するAdapterActivatorクラスは、PortableServer::AdapterActivatorクラスを継承させる必要があります。また、メソッドとしてunknown_adapter()を実装している必要があります。


【AdapterActivatorクラスの実装形式】

class UserAdapterActivator : public PortableServer::AdapterActivator {
public :
    CORBA::Boolean unknown_adapter(...){...}
}

AdapterActivatorオブジェクトのunknown_adapterメソッドは、PortableServer::POA::find_POAメソッド発行時に呼び出すことも可能です。


AdapterActivatorの処理の流れを以下に示します。



  1. クライアントからのリクエストを受信します。リクエストの対象となるオブジェクトリファレンスは、POAidを内包しています。

  2. POAidに対応するPOAオブジェクトを検索します。存在しない場合は、既存のPOAから対象のPOAの親POAを検索します。

  3. 親POAオブジェクトに設定されているAdapterActivatorクラスのインスタンスに対して、unknown_adapeter()メソッドが発行されます。

  4. unknown_adapeter()の実装部では、パラメタで渡されたPOA(親POA)の子POAオブジェクトを生成します。以降、同じオブジェクトリファレンスに対するリクエストの処理は、このPOAが行います。

  5. 生成した子POAに対する設定などを行います。ここでは、直接Servantを生成して子POAに登録することも可能であり、ServantManagerを生成し登録しておくことも可能です。

  6. 子POAの生成に成功した場合は、trueを返します。

  7. Servantの生成/登録を行います(ServantManager使用時)。

  8. Servantのオペレーションを起動します。

  9. オペレーションの実行結果を返します。