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

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を生成する際は、デフォルトの設定値から変更したいポリシの設定だけを行うことが可能です。
  以下の例ではRequestProcessingPolicyをUSE_DEFAULT_SERVANTに、IdUniquenessPolicyをMULTIPLE_IDに設定した子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オブジェクトの活性化後に作成する方法(間接作成)

  サーバアプリケーションはServantオブジェクトを、activate_object()またはactivate_object_with_id()メソッドより活性化します。一度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オブジェクトは、Servantオブジェクトの生成/削除を行うServantActivatorオブジェクトと、Servantオブジェクトを検索するServantLocatorオブジェクトの2種類が存在します。POAオブジェクトは、ServerRetentionポリシがRETAINの場合はServantActivatorオブジェクトを呼び出し、NON_RETAINの場合はServantLocatorオブジェクトを呼び出します。


(1)ServantActivatorオブジェクト

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

【ServantActivatorクラスの実装形式】
  class UserServantActivator : public PortableServer::ServantActivator
{ public : PortableServer::Servant incarnate(...) {...} void etherealize(...) {...} };

  POAオブジェクトは、Servantオブジェクトの生成を依頼する場合、ServantActivatorオブジェクトのincarnate()メソッドを呼び出し、Servantオブジェクトの削除を依頼する場合は、etherealize()メソッドを呼び出します。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. オペレーションの実行結果を返します。