IDL と Java のマッピング |
5 |
設計に関する論理的な基礎については、「4. 全体設計の論理的基礎」を参照してください。
多くの場合、マッピングの例が示してあります。ただし、紹介されている例は断片的なコードで、あくまでも説明されている言語構造を例示するためだけのものです。通常、これらのコードを使う場合は、モジュールに埋め込んで Java パッケージにマッピングします。
また、Java 言語の性質上、IDL の単一の構造が Java では異なる名前を持つ複数の構造にマッピングされる場合があります。「追加される」名前は、内容を表す接尾辞を付け加えて作成されます。たとえば、IDL のインタフェース foo は、Java のインタフェース
foo
、および追加される Java クラス fooHelper
と fooHolder
にマッピングされます。「追加される」名前がマッピングされたほかの IDL 名と衝突するような例外的な場合は、上記で説明した衝突解決ルールがほかの IDL 名のマッピングに適用されます。つまり、要求した「追加」名の命名と使用が優先されます。
たとえば、fooHelper または fooHolder という名前のインタフェースは、それぞれ
_fooHelper
または _fooHolder
にマッピングされます。foo という名前のインタフェースが存在するかどうかは関係ありません。インタフェース fooHelper のヘルパークラスとホルダークラスの名前は、_fooHelperHelper
および _fooHelperHolder
になります。通常、IDL の名前は同じ名前で Java の識別子にマッピングされますが、Java の予約語と衝突する場合は、衝突解決のルールが適用されます。
Helper
。<type> は、IDL のユーザ定義型の名前
Holder
。<type> は、IDL の定義型の名前 (typedef 別名など若干の例外あり)
Holder
。<basicJavaType> は、IDL の基本データ型の 1 つで使われる Java プリミティブデータ型の 1 つ (「5.4.1.2 ホルダークラス」を参照)
Package
。<interface> は、IDL インタフェースの名前 (「5.15 入れ子構造の型のマッピング」を参照)
_
) が付きます。
どのモジュールにも囲まれていない IDL 宣言は、(名前のない) Java の大域スコープにマッピングされます。
// IDL
module Example {...}
// generated Java
package Example;
...
Java の型の範囲が IDL の型より「大きい」場合、不一致が発生する可能性があります。実行時に in パラメータとして (または inout に対する input として) 整列化される時点で、値は完全に検査されなければなりません。たとえば、Java の char は、IDL の char のスーパーセットになっています。
図 5-1 基本型のマッピング
5.4.1.1 将来のサポート
将来的には、IDL の「新しい」拡張データ型である fixed と long double が、Java で直接サポートされる予定です。現在、JDK 1.0.2 ではこれらの型はサポートされていないため、実際問題として、ORB ベンダーによって広くサポートされるという状況にもまだ至っていません。これら 2 つの型は、次のようにマッピングされる予定です。
IDL のデータ型 |
Java のデータ型 |
例外 |
long double |
|
|
fixed |
|
CORBA::DATA_CONVERSION |
今後のバージョンの仕様では、このマッピングが標準的にサポートされるようになる予定です。
5.4.1.2 ホルダークラス
out と inout のパラメータ引き渡しモードをサポートするには、特別な「ホルダー」クラス群を使う必要があります。これらのクラスは、org.omg.CORBA
パッケージの IDL の基本データ型のすべてで利用でき、typedef で定義されたものを除くすべての名前が指定されたユーザ定義型に対して生成されます。Holder
が付け加えられたものになります。Holder
が付け加えられたものになります。たとえば、IntHolder
のようになります。ユーザ定義名との衝突の可能性については、「5.2 名前」を参照してください。
個々のホルダークラスには、インスタンスからのコンストラクタ、つまりデフォルトコンストラクタがあります。また、インスタンスの public メンバ
value
があり、これは型指定のある値です。デフォルトコンストラクタは、Java 言語で定義されている型の既定値を値のフィールドに設定します。boolean 型には false
が、数値型と文字型には 0
が、文字列型には null
が、オブジェクト参照には null が、それぞれ設定されます。org.omg.CORBA.portable.Streamable
インタフェースも実装する必要があります。Streamable
インタフェースが実装されていないことに注意してください。これらのインタフェースは、org.omg.CORBA
パッケージの中にあります。// Java
package org.omg.CORBA;
final public class ShortHolder {
public short value;
public ShortHolder() {}
public ShortHolder(short initial) {
value = initial;
}
}
final public class IntHolder {
public int value;
public IntHolder() {}
public IntHolder(int initial) {
value = initial;
}
}
final public class LongHolder {
public long value;
public LongHolder() {}
public LongHolder(long initial) {
value = initial;
}
}
final public class ByteHolder {
public byte value;
public ByteHolder() {}
public ByteHolder(byte initial) {
value = initial;
}
}
final public class FloatHolder {
public float value;
public FloatHolder() {}
public FloatHolder(float initial) {
value = initial;
}
}
final public class DoubleHolder {
public double value;
public DoubleHolder() {}
public DoubleHolder(double initial) {
value = initial;
}
}
final public class CharHolder {
public char value;
public CharHolder() {}
public CharHolder(char initial) {
value = initial;
}
}
final public class BooleanHolder {
public boolean value;
public BooleanHolder() {}
public BooleanHolder(boolean initial) {
value = initial;
}
}
final public class StringHolder {
public java.lang.String value;
public StringHolder() {}
public StringHolder(java.lang.String initial) {
value = initial;
}
}
final public class ObjectHolder {
public org.omg.CORBA.Object value;
public ObjectHolder() {}
public ObjectHolder(org.omg.CORBA.Object initial) {
value = initial;
}
}
final public class AnyHolder {
public Any value;
public AnyHolder() {}
public AnyHolder(Any initial) {
value = initial;
}
}
final public class TypeCodeHolder {
public TypeCode value;
public typeCodeHolder() {}
public TypeCodeHolder(TypeCode initial) {
value = initial;
}
}
final public class PrincipalHolder {
public Principal value;
public PrincipalHolder() {}
public PrincipalHolder(Principal initial) {
value = initial;
}
ユーザ定義型 <foo> に対するホルダークラスを、以下に示します。}
// Java
final public class <foo>Holder
implements org.omg.CORBA.portable.Streamable {
public <foo> value;
public <foo>Holder() {}
public <foo>Holder(<foo> initial) {}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
5.4.1.3 Java の
Java の null
の使用
null
は、「null」オブジェクトの参照を表すためだけに使用できます。たとえば、空の文字列を表すには、null
ではなく、長さが 0 の文字列を使う必要があります。配列についても同様です。 5.4.2 boolean
IDL の boolean 定数 TRUE と FALSE は、Java の対応する boolean リテラル true
と false
にマッピングされます。 5.4.3 文字型
Java の文字型データは符号なし 16 ビット長で Unicode 文字を表していますが、IDL の文字型データは 8 ビット長で文字セットの要素を表しています。型が安全に処理されるようにするため、メソッドの呼び出しでパラメータが整列化された時点で、Java CORBA の実行時環境は、IDL の char 型からマッピングされた Java の char
型のすべてについて、範囲の妥当性を明らかにします。char
が文字セットで定義されている範囲の外にある場合は、例外 CORBA::DATA_CONVERSION がスローされます。char
にマッピングされます。 5.4.4 octet
IDL の octet 型のサイズは 8 ビットで、Java の byte
型にマッピングされます。 5.4.5 文字列型
IDL の string 型は、バウンド形式もアンバウンド形式も、java.lang.String
にマッピングされます。文字列内の個々の文字に対する範囲検査と併せて、文字列のバウンド検査が整列化時に行われます。文字範囲の違反があると、例外 CORBA::DATA_CONVERSION が発生します。バウンドの違反がある場合は、例外 CORBA:: MARSHAL が発生します。java.lang.String
にマッピングされます。文字列のバウンド検査が、整列化時に行われます。バウンドの違反がある場合は、例外 CORBA:: MARSHAL が発生します。 5.4.6 整数型
整数の各型は、図 5-1 に示すようにマッピングされます。
5.4.7 浮動小数点型
IDL の float と double は、図 5-1 に示すようにマッピングされます。
5.4.8 固定小数点型の将来的なサポート
IDL の fixed 型は、Java の java.math.BigDecimal
クラスにマッピングされます。サイズ違反がある場合は、例外 CORBA::DATA_CONVERSION が発生します。 5.4.9 long double 型の将来的なサポート
現在、Java は IDL の long double 型をサポートしていません。現時点では、この型が追加されるかどうか、また追加されるとすればいつか、そしてその場合はプリミティブ型になるのか、あるいは java.math.*
の新しいパッケージ (たとえば java.math.BigFloat
) になるのかなどについては、明らかになっていません。 5.5 ヘルパークラス
IDL のすべてのユーザ定義型には、Java の「ヘルパー」クラスが追加されます。ヘルパークラスの名前は、生成された型の名前に接尾辞 Helper
が付け加えられたものになります。型での処理に必要な static メソッドが、いくつか提供されます。このようなメソッドの機能としては、その型について Any 型の挿入や抽出を行う操作、リポジトリ ID の取得、タイプコードの取得、ストリームからの型の読み出しやストリームへの型の書き込みなどがあります。// generated Java helper
public class <typename>Helper {
public static void
insert(org.omg.CORBA.Any a, <typename> t) {...}
public static <typename> extract(Any a) {...}
public static org.omg.CORBA.TypeCode type() {...}
public static String id() {...}
public static <typename> read(
org.omg.CORBA.portable.InputStream istream)
{...}
public static void write(
org.omg.CORBA.portable.OutputStream ostream,
<typename> value)
{...}
// only for interface helpers
public static
<typename> narrow(org.omg.CORBA.Object obj);
IDL インタフェースに関連付けられたヘルパークラスには、narrow メソッドも含まれています (「5.12 インタフェースのマッピング」を参照)。}
5.5.1 例
// IDL - named type
struct st {long f1; string f2;};
// generated Java
public class stHelper {
public static void insert(org.omg.CORBA.Any any,
st s) {...}
public static st extract(Any a) {...}
public static org.omg.CORBA.TypeCode type() {...}
public static String id() {...}
public static st read(org.omg.CORBA.InputStream is) {...}
public static void write(org.omg.CORBA.OutputStream os,
st s) {...}
}
// IDL - typedef sequence
typedef sequence <long> IntSeq;
// generated Java helper
public class IntSeqHelper {
public static void insert(org.omg.CORBA.Any any,
int[] seq);
public static int[] extract(Any a){...}
public static org.omg.CORBA.TypeCode type(){...}
public static String id(){...}
public static int[] read(
org.omg.CORBA.portable.InputStream is)
{...}
public static void write(
org.omg.CORBA.portable.OutputStream os,
int[] seq)
{...}
}
5.6 定数のマッピング
定数のマッピングは、定数が含まれるスコープによって異なります。 5.6.1 インタフェース内の定数
IDL インタフェースの中で宣言された定数は、IDL インタフェースに対応する Java インタフェースの public static final
フィールドにマッピングされます。 5.6.1.1 例
// IDL
module Example {
interface Face {
const long aLongerOne = -321;
};
};
// generated Java
package Example;
public interface Face {
public static final int aLongerOne = (int) (-321L);
}
5.6.2 インタフェースの内部にない定数
IDL インタフェースの中で宣言されていない定数は、定数と同じ名前の public interface
にマッピングされます。このインタフェースには value
という名前の public static final
フィールドがあり、ここに定数の値が格納されます。Java コンパイラは、通常、クラスがほかの Java コードで使われる時点で値をインラインにします。 5.6.2.1 例
// IDL
module Example {
const long aLongOne = -123;
};
package Example;
public interface aLongOne {
public static final int value = (int) (-123L);
}
5.7 enum 型のマッピング
IDL の enum 型は、同じ名前の Java の final class
にマッピングされます。このクラスでは、value メソッド、ラベルごとに 2 つの static データメンバ、整数値変換メソッド、および private コンストラクタが宣言されています。その例を次に示します。// generated Java
public final class <enum_name> {
// one pair for each label in the enum
public static final int _<label> = <value>;
public static final <enum_name> <label> =
new <enum_name>(_<label>);
public int value() {...}
// get enum with specified value
public static <enum_name> from_int(
int value
);
// constructor
private <enum_name>(
int
) { ... }
メンバの 1 つは }
public static final
で、IDL の enum のラベルと同じ名前が与えられます。もう 1 つのメンバには名前の先頭に下線 (_) が付いており、switch 文で使います。value()
メソッドで衝突は発生しません。equals()
メソッドと hash()
メソッドは、enum の単独オブジェクトに対し、自動的に正しく動作します。from_int()
メソッドが追加されます。このメソッドからは、指定した値に対応する enum の値が返されます。Holder
が付け加えられたものになります。その例を次に示します。public class <enum_name>Holder implements
org.omg.CORBA.portable.Streamable {
public <enum_name> value;
public <enum_name>Holder() {}
public <enum_name>Holder(<enum_name> initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
5.7.1 例
// IDL
enum EnumType {a, b, c};
// generated Java
public final class EnumType {
public static final int _a = 0;
public static final EnumType a = new EnumType(_a);
public static final int _b = 1;
public static final EnumType b = new EnumType(_b);
public static final int _c = 2;
public static final EnumType c = new EnumType(_c);
public int value() {...}
public static EnumType from_int(
int value
) {...};
// constructor
private EnumType(int) {...}
};
5.8 struct 型のマッピング
IDL の struct 型は、同じ名前を持つ Java の final クラスにマッピングされます。このクラスでは、IDL のメンバと同じ順番に宣言されたフィールドのインスタンス変数と、すべての値に対するコンストラクタが提供されます。あとからフィールドを埋められるように、null コンストラクタも用意されています。Holder
が付け加えられたものになります。その例を次に示します。final public class <class>Holder implements
org.omg.CORBA.portable.Streamable {
public <class> value;
public <class>Holder() {}
public <class>Holder(<class> initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
5.8.1 例
// IDL
struct StructType {
long field1;
string field2;
};
// generated Java
final public class StructType {
// instance variables
public int field1;
public String field2;
// constructors
public StructType() {}
public StructType(int field1, String field2)
{...}
}
final public class StructTypeHolder
implements org.omg.CORBA.portable.Streamable {
public StructType value;
public StructTypeHolder() {}
public StructTypeHolder(StructType initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
5.9 union 型のマッピング
IDL の union 型は、同じ名前の Java の final クラスにマッピングされます。次のものが作成されます。
discriminator()
要素のアクセス用メソッドと変更用メソッドはオーバーロードされて、要素名に基づいて名前が付けられます。目的の要素が設定されていない場合は、アクセス用メソッドからシステム例外 CORBA::BAD_OPERATION が発生します。
要素に対応して複数の case ラベルがある場合、その要素に対する単純な変更用メソッドにより、最初の case ラベルの値に判別変数が設定されます。さらに、明示的な判別子パラメータを使用する特別な変更用メソッドが生成されます。
要素が default という case ラベルに対応している場合、変更用メソッドは、ほかのどの case ラベルとも一致しない値を判別変数に設定します。
case ラベルの集合が判別変数として可能性のある値を完全にカバーしている場合、union に default の case ラベルを指定することは誤りです。このような状況を検出し、不当なコードの生成を防ぐのは、Java コードジェネレータ (ILD コンパイラなどのツール) が備える機能です。
デフォルトの変更用メソッドの名前は
default()
(名前が衝突している場合は _default()
) です。default という case ラベルが指定されていなくて、case ラベルの集合が判別変数として考えられる値を完全にカバーしていない場合に、このメソッドが作成されます。このメソッドは、union の値に範囲外の値を設定します。union 型には、ホルダークラスも生成されます。その名前は、union 型がマッピングされた Java のクラス名のあとに
Holder
が付け加えられたものになります。その例を次に示します。
final public class <union_class>Holder
implements org.omg.CORBA.portable.Streamable {
public <union_class> value;
public <union_class>Holder() {}
public <union_class>Holder(<union_class> initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
// IDL
union UnionType switch (EnumType) {
case first: long win;
case second: short place;
case third:
case fourth: octet show;
default: boolean other;
};
// generated Java
final public class UnionType {
// constructor
public UnionType() {....}
// discriminator accessor
public <switch-type> discriminator() {....}
// win
public int win() {....}
public void win(int value) {....}
// place
public short place() {....}
public void place(short value) {....}
// show
public byte show() {....}
public void show(byte value) {....}
public void show(int discriminator, byte value){....}
// other
public boolean other() {....}
public void other(boolean value) {....}
}
final public class UnionTypeHolder
implements org.omg.CORBA.portable.Streamable {
public UnionType value;
public UnionTypeHolder() {}
public UnionTypeHolder(UnionType initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
sequence 型には、ホルダークラスも生成されます。その名前は、sequence 型がマッピングされた Java のクラス名のあとに
Holder
が付け加えられたものになります。その例を次に示します。
final public class <sequence_class>Holder {
public <sequence_element_type>[]
value;
public <sequence_class>Holder() {};
public <sequence_class>Holder(
<sequence_element_type>[]
initial) {...};
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
// IDL
typedef sequence< long > UnboundedData;
typedef sequence< long, 42 > BoundedData;
// generated Java
final public class UnboundedDataHolder
implements org.omg.CORBA.portable.Streamable {
public int[]
value;
public UnboundedDataHolder() {};
public UnboundedDataHolder(int[]
initial) {...};
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
final public class BoundedDataHolder
implements org.omg.CORBA.portable.Streamable {
public int[]
value;
public BoundedDataHolder() {};
public BoundedDataHolder(int[]
initial) {...};
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
配列には、ホルダークラスも生成されます。その名前は、配列がマッピングされた Java のクラス名のあとに
Holder
が付け加えられたものになります。その例を次に示します。
final public class <array_class>Holder
implements org.omg.CORBA.portable.Streamable {
public <array_element_type>[]
value;
public <array_class>Holder() {}
public <array_class>Holder(
<array_element_type>[]
initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
// IDL
const long ArrayBound = 42;
typedef long larray[ArrayBound];
// generated Java
final public class larrayHolder
implements org.omg.CORBA.portable.Streamable {
public int[]
value;
public larrayHolder() {}
public larrayHolder(int[]
initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
Helper
が付け加えられたものになります。Java のインタフェースは、マッピングされた基底インタフェース org.omg.CORBA.Object
を継承したものになります。Java のインタフェースには、マッピングされたオペレーションのシグニチャーが含まれます。このインタフェースに対するオブジェクト参照で、メソッドを呼び出すことができます。
ヘルパークラスには narrow という名前の static メソッドがあり、このメソッドを使うと、
org.omg.CORBA.Object
をより範囲の限定された型のオブジェクト参照にナロー変換できます。ナロー変換に失敗した場合は、例外 CORBA::BAD_PARAM がスローされます。特殊な「nil」オブジェクトの参照はありません。オブジェクト参照が必要な場所であればどこでも、Java の
null
をそのまま渡すことができます。属性は、アクセス用メソッドと変更用メソッドの対にマッピングされます。これらのメソッドは IDL の属性と同じ名前を持ち、オーバーロードされています。IDL の readonly 属性に対しては、変更用メソッドは作成されません。
インタフェースには、ホルダークラスも生成されます。その名前は、インタフェースがマッピングされた Java のクラス名のあとに
Holder
が付け加えられたものになります。その例を次に示します。
final public class <interface_class>Holder
implements org.omg.CORBA.portable.Streamable {
public <interface_class> value;
public <interface_class>Holder() {}
public <interface_class>Holder(
<interface_class> initial) {
value = initial;
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
IDL で規定されているインタフェースの継承は、Java のインタフェース階層に直接反映されます。
// IDL
module Example {
interface Face {
long method (in long arg) raises (e);
attribute long assignable;
readonly attribute long nonassignable;
}
}
// generated Java
package Example;
public interface Face extends org.omg.CORBA.Object {
int method(int arg)
throws Example.e;
int assignable();
void assignable(int i);
int nonassignable();
}
public class FaceHelper {
// ... other standard helper methods
public static Face narrow(org.omg.CORBA.Object obj)
{...}
}
final public class FaceHolder
implements org.omg.CORBA.portable.Streamable {
public Face value;
public FaceHolder() {}
public FaceHolder(Face initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
IDL の out パラメータと inout パラメータは、結果による呼び出し、および値/結果による呼び出しの形式を実装するもので、Java のパラメータ引き渡し機構に直接マッピングすることはできません。このマッピングでは、IDL の基本型とユーザ定義型のすべてに対するホルダークラスが新しく定義されて、このクラスを使って out と inout のパラメータ引き渡しモードが Java に実装されます。クライアントは、Java の適切なホルダークラスのインスタンスを提供し、このインスタンスが IDL の out パラメータまたは inout パラメータに値で渡されます。ホルダークラスのインスタンスの内容 (インスタンス自体ではない) がこの呼び出しで変更されて、クライアントは呼び出しから返されたあとの変更された内容を使用します。
// IDL
module Example {
interface Modes {
long operation( in long inArg,
out long outArg,
inout long inoutArg);
};
};
// Generated Java
package Example;
public interface Modes {
int operation( int inArg,
IntHolder outArg,
IntHolder inoutArg);
}
上の例では、結果は実際の結果として返され、in モードの実パラメータについては実際の値だけが返されます。一方、out パラメータと inout パラメータについては、適切なホルダーが作成される必要があります。典型的な使用例を次に示します。
// user Java code
// select a target object
Example.Modes target = ...;
// get the in actual value
int inArg = 57;
// prepare to receive out
IntHolder outHolder = new IntHolder();
// set up the in side of the inout
IntHolder inoutHolder = new IntHolder(131);
// make the invocation
int result =target.operation(inArg, outHolder, inoutHolder);
// use the value of the outHolder
... outHolder.value ...
// use the value of the inoutHolder
... inoutHolder.value ...
呼び出しの前に、inout パラメータの入力値を、実パラメータとなるホルダーインスタンスに設定する必要があります。値から新しいホルダーを作成するか、あるいは適切な型の既存のホルダーの値に割り当てることで、inout ホルダーに値を設定できます。呼び出しが終了したあと、クライアントは outHolder.value を使って out パラメータの値にアクセスし、inoutHolder.value を使って inout パラメータの出力値にアクセスします。IDL のオペレーションから返される結果は、呼び出しの結果として利用できます。
CORBA のシステム例外は、検査されない例外です。
java.lang.RuntimeException
から間接的に継承します。ユーザ定義の例外は、検査される例外です。
java.lang.Exception
から間接的に継承します。
org.omg.CORBA.UserException
を継承する Java の final クラスにマッピングされます。それを除くと、ヘルパークラスとホルダークラスの作成を含めて、IDL の struct 型と同様にマッピングされます。例外が入れ子の IDL スコープ (特にインタフェース) の中で定義されている場合、Java のクラス名は専用のスコープの中で定義されます。詳細については、「5.15 入れ子構造の型のマッピング」を参照してください。入れ子になっていない場合は、Java のクラス名は、例外を囲む IDL モジュールに対応する Java パッケージのスコープ内で定義されます。
5.13.1.1 例
// IDL
module Example {
exception ex1 { string reason; };
};
// Generated Java
package Example;
final public class ex1 extends org.omg.CORBA.UserException {
public String reason; // instance
public ex1() {...} // default constructor
public ex1(String r) {...} // constructor
}
final public class ex1Holder
implements org.omg.CORBA.portable.Streamable {
public ex1 value;
public ex1Holder() {}
public ex1Holder(ex1 initial) {...}
public void _read(org.omg.CORBA.portable.InputStream i)
{...}
public void _write(org.omg.CORBA.portable.OutputStream o)
{...}
public org.omg.CORBA.TypeCode _type() {...}
}
5.13.2 システム例外
IDL 標準のシステム例外は、org.omg.CORBA.SystemException
を継承する Java の final クラスにマッピングされます。このクラスは、IDL のメジャー例外コードとマイナー例外コード、および例外の理由を示すテキストへのアクセスを提供します。org.omg.CORBA.SystemException
には public コンストラクタはありません。このクラスを継承するクラスに対してだけインスタンスを生成できます。org.omg.CORBA
パッケージの中で宣言されます。デフォルトコンストラクタは、マイナーコードには 0 を、完了コードには COMPLETED_NO を、原因の文字列には "" をそれぞれ設定します。原因を取得し、ほかのフィールドには規定値を設定するコンストラクタ、および 3 つのパラメータすべてに指定を必要とするコンストラクタもあります。IDL の名前と Java のクラス名のマッピングを、次の表に示します。
関連するクラスの定義を次に示します。
// from org.omg.CORBA package
package org.omg.CORBA;
public final class CompletionStatus {
// Completion Status constants
public static final int _COMPLETED_YES = 0,
_COMPLETED_NO = 1,
_COMPLETED_MAYBE = 2;
public static final CompletionStatus COMPLETED_YES =
new CompletionStatus(_COMPLETED_YES);
public static final CompletionStatus COMPLETED_NO =
new CompletionStatus(_COMPLETED_NO);
public static final CompletionStatus COMPLETED_MAYBE =
new CompletionStatus(_COMPLETED_MAYBE);
public int value() {...}
public static final CompletionStatus from_int(int) {...}
private CompletionStatus(int) {...}
}
abstract public class
SystemException extends java.lang.RuntimeException {
public int minor;
public CompletionStatus completed;
// constructor
protected SystemException(String reason,
int minor,
CompletionStatus status) {
super(reason);
this.minor = minor;
this.status = status;
}
}
final public class
UNKNOWN extends org.omg.CORBA.SystemException {
public UNKNOWN() ...
public UNKNOWN(int minor, CompletionStatus completed) ...
public UNKNOWN(String reason) ...
public UNKNOWN(String reason, int minor,
CompletionStatus completed) ...
}
...
// there is a similar definition for each of the standard
// IDL system exceptions listed in the table above
5.14 Any 型のマッピング
IDL の Any 型は、Java の org.omg.CORBA.Any
クラスにマッピングされます。このクラスには、定義済みの型のインスタンスを挿入および取得するために必要なメソッドがすべて備わっています。取得オペレーションで型の不一致が発生した場合は、例外 CORBA::BAD_OPERATION が発生します。type()
を使ってタイプコードを設定すると、値がクリアされます。値が設定される前に値を取得しようとすると、例外 CORBA::BAD_OPERATION が発生します。IDL の out パラメータに適切な値を設定できるように、このオペレーションはあらかじめ提供されています。package org.omg.CORBA;
abstract public class Any {
abstract public boolean equal(org.omg.CORBA.Any a);
// type code accessors
abstract public org.omg.CORBA.TypeCode type();
abstract public void type(org.omg.CORBA.TypeCode t);
// read and write values to/from streams
// throw excep when typecode inconsistent with value
abstract public void read_value(
org.omg.CORBA.portable.InputStream is,
org.omg.CORBA.TypeCode t) throws org.omg.CORBA.MARSHAL;
abstract public void
write_value(org.omg.CORBA.portable.OutputStream os);
abstract public org.omg.CORBA.portable.OutputStream
create_output_stream();
abstract public org.omg.CORBA.portable.InputStream
create_input_stream();
// insert and extract each primitive type
abstract public short extract_short()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_short(short s);
abstract public int extract_long()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_long(int i);
abstract public long extract_longlong()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_longlong(long l);
abstract public short extract_ushort()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_ushort(short s);
abstract public int extract_ulong()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_ulong(int i);
abstract public long extract_ulonglong()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_ulonglong(long l);
abstract public float extract_float()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_float(float f);
abstract public double extract_double()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_double(double d);
abstract public boolean extract_boolean()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_boolean(boolean b);
abstract public char extract_char()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_char(char c)
throws org.omg.CORBA.DATA_CONVERSION;
abstract public char extract_wchar()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_wchar(char c);
abstract public byte extract_octet()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_octet(byte b);
abstract public org.omg.CORBA.Any extract_any()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_any(org.omg.CORBA.Any a);
abstract public org.omg.CORBA.Object extract_Object()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_Object(
org.omg.CORBA.Object o);
// throw excep when typecode inconsistent with value
abstract public void insert_Object(
org.omg.CORBA.Object o,
org.omg.CORBA.TypeCode t)
throws org.omg.CORBA.MARSHAL;
abstract public String extract_string()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_string(String s)
throws org.omg.CORBA.DATA_CONVERSION, org.omg.CORBA.MARSHAL;
abstract public String extract_wstring()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_wstring(String s)
throws org.omg.CORBA.MARSHAL;
// insert and extract typecode
abstract public org.omg.CORBA.TypeCode extract_TypeCode()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_TypeCode(
org.omg.CORBA.TypeCode t);
// insert and extract Principal
abstract public org.omg.CORBA.Principal extract_Principal()
throws org.omg.CORBA.BAD_OPERATION;
abstract public void insert_Principal(
org.omg.CORBA.Principal p);
// insert non-primitive IDL types
abstract public void insert_Streamable(
org.omg.CORBA.portable.Streamable s);
}
5.15 入れ子構造の型のマッピング
IDL では、インタフェース内で入れ子の型宣言が認められています。Java の場合、インタフェース内でクラスを入れ子にすることは認められていません。したがって、Java のクラスにマッピングされる IDL の型で、インタフェースのスコープの中で宣言されているものについては、Java にマッピングされる際に、専用の 「スコープ」パッケージに入れる必要があります。Package
が付け加えられたものになります。 5.15.1 例
// IDL
module Example {
interface Foo {
exception e1 {};
};
};
// generated Java
package Example.FooPackage;
final public class e1 extends org.omg.CORBA.UserException
{...}
5.16 typedef のマッピング
Java には、typedef という構造はありません。 5.16.1 IDL の単純な型
Java の単純な型にマッピングされる IDL の型は、Java の中でサブクラス化されることはありません。したがって、単純な型の型宣言に使われている typedef はすべて、本来マッピングされることになっている型にマッピングされます。
すべての typedef に対して、ヘルパークラスが作成されます。
5.16.2 IDL の複雑な型
配列でもシーケンスでもない typedef は、IDL の単純な型またはユーザ定義型 (typedef 以外の種類) が得られるまで、元の型へと「分解」されます。 5.16.2.1 例
// IDL
struct EmpName {
string firstName;
string lastName;
};
typedef EmpName EmpRec;
// generated Java
// regular struct mapping for EmpName
// regular helper class mapping for EmpRec
final public class EmpName {
...
}
public class EmpRecHelper {
...
}