Java データ型のバッファから FML および VIEW へのマッピング

型のマッピングが適切に実行されるようにするには、ファイルを編集して、Java 複合データ型のフィールド名を FML/FML32 バッファおよび VIEW/VIEW32 バッファのフィールド名と結び付けるメソッドを定義する必要があります。つまり、コントロールはパラメータ名と Java メンバ名をフィールド化バッファのフィールド名と結び付けます。このフィールドのマッチングにより、コントロールは必要とされる適切な要求バッファと応答バッファを構築できます。このフィールドのマッチングより、コントロールがバッファに配置するデータが定義されます。サービスは、バッファの設定を定義または決定します。言い換えると、サービス タイプによって、要求バッファと応答バッファを決定する通信モデルが定義されます。

通信モデル
サービス タイプ

同期要求/応答 (tpcall)

service

応答なしの要求 (tpacall)

oneway

キューに配置 (tpenqueue)

queue

コントロールのメソッドで定義されたフィールドは、フィールド テーブルまたは VIEW クラスで定義されたフィールドと一致する必要があります。たとえば、コントロールで次のメソッドが定義されているとします。

String anOp (String s1, Float f1, Short s2); 

フィールド化バッファ タイプを使用しているという前提で、実行時に anOp メソッドが呼び出されると、コントロールは「s1」、「f1」、および「s2」という名前のフィールドに対応するフィールド テーブルにアクセスします。見つかったフィールドについて、コントロールはそのフィールドと同じ名前を持つパラメータをバッファに配置します。

Bean や、データ メンバだけを持つ Java クラスなどの Java 複合データ型では、このフィールド マッチング プロセスはより複雑になります。コントロールは前述と同じマッチング アルゴリズムを実行しますが、アルゴリズムはそれぞれの Java 複合データ型に対して再帰的に実行されます。たとえば、次のようなクラスがあるとします。

static public class Name {
	String		First;
	String		Last;
	Character		MI;
}

static public class Person {
	Name		CompleteName;
	Float		Age;
	Integer		Weight;
}

static public class People {
	Person[]		PEOPLE;
} 

オペレーション シグネチャは次のとおりです。

People addPerson(Person aPerson); 

上記の例では、コントロールは実行時に aPerson という名前でフィールド テーブル内のフィールドを検索します。aPerson が見つかり、これが FLD_FML32 のような埋め込みタイプのフィールドである場合、コントロールは埋め込みバッファを作成し、aPerson として渡された値のフィールドで埋め込みバッファを満たします。それ以外の場合は、Person が複合型であるため、コントロールは複合型 Person のメンバと一致するフィールドの検索を開始します。したがって、CompleteName という名前のフィールドが検索されます。この場合も、CompleteName が埋め込みバッファ タイプと一致すると、コントロールは埋め込みバッファを作成し、これを満たします。次に、コントロールは First という名前のフィールドをフィールド テーブルで検索します。一致するものが見つかった場合、コントロールは First という名前に関連付けられたフィールド ID を使用して、Java フィールド aPerson.Name.First をバッファに配置します。次に、Last という名前のフィールドが検索されます。コントロールは、渡されたパラメータの 1 回目のトラバーサルを実行し、フィールド テーブル内で一致するフィールドを検索します。

コントロールは、同様のプロセスを実行して返されるバッファを個別に取得します。前の例では、コントロールはメソッドの戻り値の型を調べます。戻り値の型は複合型の配列であるため、コントロールは PEOPLE という名前のフィールドのオカレンスを検索します。フィールドが見つかった場合、オカレンスの数を確認し、該当サイズの Person の配列を作成します。PEOPLE という名前のフィールドが見つからなかった場合は、CompleteNameAge、および Weight の各フィールドのオカレンスが検索されます。コントロールは、見つかったこれらのフィールドの最少数のオカレンスを保持できるサイズの Person の配列を作成します。その後、コントロールは Person のデータ メンバ名と一致するフィールドをバッファから取り出し、Person のインスタンスを作成して、配列の設定を開始します。

JavaBean スタイルのデータ アクセサの使用

JavaBean は、特定の命名基準に準拠したメソッドの背後に状態を隠す Java クラスです。この Java クラスでは、パブリック アクセサと共にプライベート データ フィールドを使用します。クラスのフィールドを判別するために、コントロールはすべてのパブリック フィールドのリストを作成し、次の形式のメソッドを検索するクラスのパブリック メソッドを調べて、見つかったフィールドを追加します。

public void setFIELD(type val);
public void setFIELD(type[] val);
public type getFIELD();
public type[] getFIELD();
 

上記のコード例では、

JavaBean の命名規約では、フィールド名は小文字で始まる必要があります。デフォルトでは、Tuxedo コントロールは JavaBean の命名規約に従います。たとえば、myField というフィールドが getMyField という名前の getter と setMyField という名前の setter を持っているとします。アクセサ名をフィールド名に変換するために、Tuxedo コントロールは get または set プレフィックスを削除し、プレフィックスを削除したフィールド名の最初の文字を小文字にして myField に変換します。

大文字で始まるフィールド名が含まれた一部の既存の Tuxedo フィールド テーブルでは、この命名規約の変換は問題となります。命名に関するこの問題を解決するには、@TuxedoControl.tuxedo アノテーションで accessor-name-conventions 属性を使用します。

JavaBean のアクセサを使用すると、JavaBean との間でのデータの移動を制御できます。パブリック データ メンバを使用して、コントロールはフィールドに直接アクセスし、データの移動をコントロールの強制変換機能に制限するように制御できます。アクセサにより、ユーザが提供するメソッドで、フィールドのデータを取得または設定する前に、任意のチェックやデータの変更を実行できるようになります。これが役立つと考えられるのは、たとえば、COBOL で生成された VIEW バッファ内と同様に、スペースが埋め込まれているバッファから文字列フィールドを取得する場合です。カスタムで作成した setter によって、文字列を格納する前にフィールドをトリミングできます。

データ型のマッピングと強制変換

同じ名前を持つフィールドのタイプが厳密に一致しない場合、強制変換の指定によってマッピング動作が決まります。プロパティ ビューを使用して、@TuxedoControl.tuxedo アノテーションで mapping-strictness 属性を指定できます。mapping-strictness の指定可能な強制変換値は次のとおりです。

デフォルトは normal です。

Java データ型のバッファから FML および VIEW へのマッピング」の前述の例で、Weight に関連付けられたフィールド テーブル内のフィールドが String フィールドであるとします。この場合、マッピングの厳密性が loose または normal であれば、コントロールはバッファにデータを配置する前に、Person インスタンスの Integer データ メンバを String に変換します。これは、通常実行される妥当な強制変換です。そのため、マッピングの厳密性が strict 以外であるときには、コントロールはこの強制変換を実行します。マッピングの厳密性が normal の場合、コントロールは問題リストに問題点として含め、一部のデータを強制変換しなければならなかったことを示します。マッピングの厳密性が strict の場合、コントロールは例外を発生させます。