初期化処理として以下の処理を行います。
org.omg.CORBA.ORB.init()によりORBオブジェクトを取得します。
RootPOAのオブジェクトリファレンスを取得します。
RootPOAから、Default Servantを使用するポリシで子POAを生成します。
ゲートウェイを実装したServantオブジェクトを生成し、Default Servantとして子POAに登録します。これによりクライアントからの要求に対して、Servant内に記述したinvoke()メソッドが起動されます。
Servantオブジェクトを設定したPOAに関連付けられたPOAManagerのインスタンスに対しactivate()メソッドを発行します。
ゲートウェイでは、以下に示す処理を行います。
メソッドの解析
パラメタの組立て
パラメタの解析
復帰情報の設定
例外情報の設定
ゲートウェイの実装例を以下に示します。
【ゲートウェイ実装例】
class DsiServant
extends org.omg.PortableServer.DynamicImplementation {
public void
invoke(org.omg.CORBA.ServerRequest req)
{
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
String name = req.operation(); //1. メソッド名の取得
if (name.equals("div")) //メソッド名の解析
{
//2. パラメタリストの設定
//パラメタリストの作成
org.omg.CORBA.NVList args = orb.create_list(2);
//パラメタ情報の登録
org.omg.CORBA.Any _a = orb.create_any();
_a.type(orb.get_primitive_tc(
org.omg.CORBA.TCKind.tk_long));
args.add_value("a", _a, org.omg.CORBA.ARG_IN.value);
org.omg.CORBA.Any _b = orb.create_any();
_b.type(orb.get_primitive_tc(
org.omg.CORBA.TCKind.tk_long));
args.add_value("b", _b, org.omg.CORBA.ARG_IN.value);
//3. パラメタの解析
req.arguments(args);
int a = _a.extract_long();
int b = _b.extract_long();
//処理部の起動
org.omg.CORBA.DoubleHolder ret = new org.omg.CORBA.DoubleHolder();
UserMethod um = new UserMethod();
try
{
ret.value = um.method1(a, b);
//4. 復帰情報の設定
org.omg.CORBA.Any _ret = orb.create_any();
_ret.type(orb.get_primitive_tc(
org.omg.CORBA.TCKind.tk_double));
_ret.insert_double(ret.value);
req.set_result(_ret);
}
catch(ZeroDivException e)
{
//5. 例外情報の設定
org.omg.CORBA.Any exp = orb.create_any();
org.omg.CORBA.StructMember[] members = {
new org.omg.CORBA.StructMember("detail",orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_string), null)
};
org.omg.CORBA.TypeCode type =
orb.create_exception_tc("IDL:ODsample/ZeroDivException:1.0","ZeroDivException",members);
exp.type(type);
org.omg.CORBA.portable.OutputStream os = exp.create_output_stream();
//例外のIDの設定
os.write_string("IDL:ODsample/ZeroDivException:1.0");
//例外のメンバの設定
os.write_string(zde.detail);
req.set_exception(exp);
}
return;
}
throw (new org.omg.CORBA.BAD_OPERATION(
0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE));
}
//6. 実装が必要なメソッド
public java.lang.String[] _all_interfaces(
org.omg.PortableServer.POA poa,
byte[] objectId) {
return ids;
}
private static java.lang.String[] ids = {"IDL:ODsample/intf:1.0"};
}
//処理部
class UserMethod
{
public double method1( int a, int b ) throws ZeroDivException{
if(b == 0)
{
throw new ZeroDivException("2nd parameter is 0.");
}
//必要な処理を記述
return( a / b );
}
}ゲートウェイを実装するServantオブジェクトは、org.omg.PortableServer.DynamicImplementationを継承するものとして作成します。また、クライアントからのリクエストに対して起動されるメソッドとしてinvoke()メソッドを実装します。起動の際、invoke()の引数としてServerRequestクラスのオブジェクト(上記例ではreq)が渡されます。
【ゲートウェイServantの必須メソッド(1)】
public void invoke(org.omg.CORBA.ServerRequest req)
(1)メソッドの取得と解析
渡されたServerRequestクラスに登録されているオペレーション名をorg.omg.CORBA.ServerRequest.operation()メソッドにより取得します。
(2)パラメタの組立て
パラメタリストの生成
org.omg.CORBA.ORB.create_list()メソッドにより、アプリケーションに渡すパラメタを格納するための領域を保持するリストオブジェクトを生成します。このとき、引数として何個のパラメタを格納するかを指定します。結果としてorg.omg.CORBA.NVListオブジェクトが返されます(上記例では2)。
パラメタ情報の登録
org.omg.CORBA.add_value()メソッドを使用して、パラメタ情報をNVListオブジェクトに格納します。引数として、パラメタ名、パラメタの値を格納するAny型オブジェクト、パラメタ種別(入出力)を設定します。
(3)パラメタの解析
生成したNVListオブジェクトを引数としてorg.omg.ServerRequest.arguments()メソッドを呼び出します。この結果、アプリケーションに渡すパラメタ値が取得されます。
(4)復帰情報の設定
org.omg.CORBA.ServerRequest.set_result()メソッドを発行して復帰情報の設定を行います。
(5)例外情報の設定
org.omg.CORBA.ServerRequest.set_exception()メソッドを発行して例外情報の設定を行います。
(6)その他実装が必要なメソッド
ゲートウェイを実装するServantはOMG規約上_all_interfaces()メソッドを実装しておく必要があります。上記の例のように、org.omg.PortableServer.POAクラスのオブジェクト、byte配列オブジェクトを引数とし、インタフェースリポジトリID相当の文字列("IDL:xxx:1.0")を最初の要素に持つString配列オブジェクトを戻り値とする形式で実装します。引数の値をメソッド内部で扱う必要は特にありません。
【ゲートウェイServantの必須メソッド(2)】
public java.lang.String[] _all_interfaces(
org.omg.PortableServer.POA poa,
byte[] objectId)