VisiBroker for Java Developer’s Guide : IDL to Java mapping

IDL to Java mapping
This section describes the basics of the VisiBroker for Java current IDL-to-Java language mapping, as implemented by the idl2java compiler. VisiBroker for Java conforms with the OMG IDL/Java Language Mapping Specification.
See the latest version of the OMG IDL/Java Language Mapping Specification for complete information about the following:
Names
In general, IDL names and identifiers are mapped to Java names and identifiers with no change.
If a naming conflict is generated in the mapped Java code, the conflict is resolved by prepending an underscore (_) to the mapped name.
In addition, because of the nature of the Java language, a single IDL construct may be mapped to several (differently named) Java constructs. The “additional” names are constructed by appending a descriptive suffix. For example, the IDL interface AccountManager is mapped to the Java interface AccountManager and additional Java classes AccountManagerOperations, AccountManagerHelper, and AccountManagerHolder.
In the exceptional cases that the “additional” names may conflict with other mapped IDL names, the resolution rule described above is applied to the other mapped IDL names. In other words, the naming and use of required “additional” names takes precedence.
For example, an interface whose name is fooHelper or fooHolder is mapped to _fooHelper or _fooHolder respectively, regardless of whether an interface named foo exists. The helper and holder classes for interface fooHelper are named _fooHelperHelper and _fooHelperHolder.
IDL names that would normally be mapped unchanged to Java identifiers that conflict with Java reserved words will have the collision rule applied.
Reserved names
The mapping reserves the use of several names for its own purposes. The use of any of these names for a user-defined IDL type or interface (assuming it is also a legal IDL name) will result in the mapped name having an underscore (_) prepended. Reserved names are as follows:
The Java class <type>Helper, where <type> is the name of an IDL user-defined type.
The Java class <type>Holder, where <type> is the name of an IDL user-defined type (with certain exceptions such as typedef aliases).
The Java classes <basicJavaType>Holder, where <basicJavaType> is one of the Java primitive data types that is used by one of the IDL basic data types.
The nested scope Java package name <interface>Package, where <interface> is the name of an IDL interface.
The Java classes <interface> Operations, <interfaces> POA, and <interface>POATie, when <interface> is the name of an IDL interface type.
Reserved words
The mapping reserves the use of several words for its own purposes. The use of any of these words for a user-defined IDL type or interface (assuming it is also a legal IDL name) will result in the mapped words having an underscore (_) prepended. The reserved keywords in the Java language are as follows:
Modules
An IDL module is mapped to a Java package with the same name. All IDL type declarations within the module are mapped to corresponding Java class or interface declarations within the generated package.
IDL declarations not enclosed in any modules are mapped into the (unnamed) Java global scope.
The following code sample shows the Java code generated for a type declared within an IDL module.
/* From Example.idl: */
module Example { .... };
// Generated java
package Example;
...
Basic types
The following table shows how the defined IDL types map to basic Java types.
When there is a potential mismatch between an IDL type and its mapped Java type, a standard CORBA exception can be raised. For the most part, exceptions are in two categories,
Additional details are described in the following sections.
IDL type extensions
This section summarizes the VisiBroker for Java support for IDL type extensions. The first table provides a summary for quick look-ups. This is followed by the IDL extensions for new types table summarizing support for new types.
1VisiBroker for Java will support any future release of OMG standard implementation.
2UNICODE is used “on the wire.”
 
 
 
Holder classes
Holder classes support OUT and INOUT parameter passing modes and are available for all the basic IDL data types in the org.omg.CORBA package. Holder classes are generated for all named user-defined types except those defined by typedefs. For more information, see the Java API Reference, VisiBroker APIs, org.omg.CORBA package section.
For user-defined IDL types, the holder class name is constructed by appending Holder to the mapped Java name of the type.
For the basic IDL data types, the holder class name is the Java type name (with its initial letter capitalized) to which the data type is mapped with an appended Holder, for example, IntHolder.
Each holder class has a constructor from an instance, a default constructor, and has a public instance member, value, which is the typed value. The default constructor sets the value field to the default value for the type as defined by the Java language:
false for boolean
null for values
0 for numeric and char types
null for strings
null for object references
To support portable stubs and skeletons, Holder classes for user-defined types also implement the org.omg.CORBA.portable.Streamable interface.
The holder classes for the basic types are defined in the following code sample. They are in the org.omg.CORBA package.
// Java
package org.omg.CORBA;
final public class ShortHolder implements Streamable {
public short value;
public ShortHolder() {}
public ShortHolder(short initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class IntHolder implements Streamable {
public int value;
public IntHolder() {}
public IntHolder(int initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class LongHolder implements Streamable {
public long value;
public LongHolder() {}
public LongHolder(long initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class ByteHolder implements Streamable {
public byte value;
public ByteHolder() {}
public ByteHolder(byte initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class FloatHolder implements Streamable {
public float value;
public FloatHolder() {}
public FloatHolder(float initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class DoubleHolder implements Streamable {
public double value;
public DoubleHolder() {}
public DoubleHolder(double initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class CharHolder implements Streamable {
public char value;
public CharHolder() {}
public CharHolder(char initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class BooleanHolder implements Streamable {
public boolean value;
public BooleanHolder() {}
public BooleanHolder(boolean initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class StringHolder implements Streamable {
public java.lang.String value;
public StringHolder() {}
public StringHolder(java.lang.String initial) {
value = initial;
}
...//implementation of the streamable interface
}

final public class ObjectHolder implements Streamable {
public org.omg.CORBA.Object value;
public ObjectHolder() {}
public ObjectHolder(org.omg.CORBA.Object initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class ValueBaseHolder implements Streamable {
public java.io.Serializable value;
public ValueBaseHolder() {}
public ValueBaseHolder(java.io.Serializable initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class AnyHolder implements Streamable {
public Any value;
public AnyHolder() {}
public AnyHolder(Any initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class TypeCodeHolder implements Streamable {
public TypeCode value;
public typeCodeHolder() {}
public TypeCodeHolder(TypeCode initial) {
value = initial;
}
...//implementation of the streamable interface
}
final public class PrincipalHolder implements Streamable {
public Principal value;
public PrincipalHolder() {}
public PrincipalHolder(Principal initial) {
value = initial;
}
...//implementation of the streamable interface
}
The follwing code sample shows the Holder class for a user-defined type <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() {...}
}
Java null
The Java null may only be used to represent null CORBA object references and valuetypes (including recursive valuetypes). For example, a zero length string, rather than null must be used to represent the empty string. This is also true for arrays and any constructed type, except for valuetypes. If you attempt to pass a null for a structure, it will raise a NullPointerException.
Boolean
The IDL type boolean is mapped to the Java type boolean. The IDL constants TRUE and FALSE are mapped to the Java constants true and false.
Char
IDL characters are 8-bit quantities representing elements of a character set while Java characters are 16-bit unsigned quantities representing Unicode characters. To enforce type-safety, the Java CORBA run-time asserts range validity of all Java chars mapped from IDL chars when parameters are marshaled during method invocation. If the char falls outside the range defined by the character set, a CORBA::DATA_CONVERSION exception is thrown.
The IDL wchar maps to the Java char type.
Octet
The IDL type octet, an 8-bit quantity, is mapped to the Java type byte.
String
The IDL type string, both bounded and unbounded variants, is mapped to the Java typejava.lang.String. Range checking for characters in the string as well as bounds checking of the string are done at marshal time.
WString
The IDL type wstring, used to represent Unicode strings, is mapped to the Java typejava.lang.String. Bounds checking of the string is done at marshal time.
Integer types
IDL short and unsigned short map to Java type short. IDL long and unsigned long map to Java type int.
Note
Because there is no support in Java for unsigned types, the developer is responsible for ensuring that negative integers in Java are handled correctly as large unsigned values.
Floating point types
The IDL floating point types float and double map to a Java class containing the corresponding data type.
Helper classes
All user-defined IDL types have an additional “helper” Java class with the suffix Helper appended to the type name generated. Several static methods needed to manipulate the type are supplied:
Any insert and extract operations for the type
For any user-defined IDL type <typename>, the following code sample is the Java code generated for the type. The helper class for a mapped IDL interface has a narrow operation defined for it.
// generated Java helper
public class
<typename>Helper {
public static void insert(org.omg.CORBA.Any a, <typename> t);
public static <typename> extract(org.omg.CORBA.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);
The following code sample shows the mapping of a named type to Java helper class.
// 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(org.omg.CORBA.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) {...}
}
The following code sample shows mapping of a typedef sequence to Java helper class.
// 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(org.omg.CORBA.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)
{...}
}
Constants
Constants are mapped depending upon the scope in which they appear.
Constants within an interface
Constants declared within an IDL interface are mapped to public static final fields in the Java interface Operations class corresponding to the IDL interface.
The following code sample shows the mapping of an IDL constant within a module to a Java class.
/* From Example.idl: */
module Example {
interface Foo {
const long aLongerOne = -321;
};
};
// Foo.java
package Example;
public interface Foo extends com.inprise.vbroker.CORBA.Object,
Example.FooOperations,
org.omg.CORBA.portable.IDLEntity {
}
// FooOperations.java
package Example;
public interface FooOperations {
public final static int aLongerOne = (int)-321;
}
Constants NOT within an interface
Constants declared within an IDL module are mapped to a public interface with the same name as the constant and containing a public static final field named value. This field holds the constant's value.
Note
The Java compiler normally inlines the value when the class is used in other Java code.
The following code sample shows the mapping of an IDL constant within a module to a Java class.
/* From Example.idl: */
module Example {
const long aLongOne = -123;
};
// Generated java
package Example;
public interface aLongOne {
public final static int value = (int) -123;
}
Constructed types
IDL constructed types include enum, struct, union, sequence, and array. The types sequence and array are both mapped to the Java array type. The IDL constructed types enum, struct, and union are mapped to a Java class that implements the semantics of the IDL type. The Java class generated will have the same name as the original IDL type.
Enum
An IDL enum is mapped to a Java final class with the same name as the enum type which declares a value method, two static data members per label, an integer conversion method, and a private constructor. The following code sample is an example of an IDL enum mapped to a Java final class:
// 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
protected <enum_name>(int) {...}
}
One of the members is a public static final , which has the same name as the IDL enum label. The other has an underscore (_) prepended and is used in switch statements.
The value method returns the integer value. Values are assigned sequentially starting with 0. If the enum has a label named value, there is no conflict with the value() method in Java.
There will be only one instance of an enum. Since there is only one instance, pointer equality tests will work correctly; that is, the default java.lang.Object implementation of equals() and hash() will automatically work correctly for an enumeration's singleton object.
The Java class for the enum has an additional method, from_int(), which returns the enum with the specified value.
The holder class for the enum is also generated. Its name is the enumeration's mapped Java classname with Holder appended to it as follows:
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() {...}
}
The following code sample shows the IDL mapped to Java for enum.
// IDL
module Example {
enum EnumType { first, second, third };
};
// generated Java
public final class EnumType
implements org.omg.CORBA.portable.IDLEntity {
public static final int _first = 0;
public static final int _second = 1;
public static final int _third = 2;
public static final EnumType first = new EnumType(_first);
public static final EnumType second = new EnumType(_second);
public static final EnumType third = new EnumType(_third);
protected EnumType (final int _vis_value) { ... }
public int value () { ... }
public static EnumType from_int (final int _vis_value) { ... }
public java.lang.String toString() { ... }
}
public final class EnumTypeHolder
implements org.omg.CORBA.portable.Streamable {
public OtherExample.EnumType value;
public EnumTypeHolder () { ... }
public EnumTypeHolder (final OtherExample.EnumType _vis_value) { ... }
public void _read (final org.omg.CORBA.portable.InputStream input) { ... }
public void _write (final org.omg.CORBA.portable.OutputStream output) { ... }
public org.omg.CORBA.TypeCode _type () { ... }
public boolean equals (java.lang.Object o) {...}
}
Struct
An IDL struct is mapped to a final Java class with the same name that provides instance variables for the fields in IDL member ordering and a constructor for all values. A null constructor is also provided which allows the structure's fields to be initialized later. The Holder class for the struct is also generated. Its name is the struct's mapped Java classname with Holder appended to it as follows:
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() {...}
}
The following code sample shows the mapping of an IDL struct to Java.
/* From Example.idl: */
module Example {
struct StructType {
long field1;
string field2;
};
};
// generated Java
public final class StructType
implements org.omg.CORBA.portable.IDLEntity {
public int field1;
public java.lang.String field2;
public StructType () { ... }
public StructType (final int field1,
final java.lang.String field2) { ... }
public java.lang.String toString() { ... }
public boolean equals (java.lang.Object o) {...}
public final class StructTypeHolder implements
org.omg.CORBA.portable.Streamable {
public Example.StructType value;
public StructTypeHolder () { ... }
public StructTypeHolder (final Example.StructType _vis_value)
{ ... }
public void _read (final org.omg.CORBA.portable.InputStream input)
{ ... }
public void _write (final org.omg.CORBA.portable.OutputStream output)
{ ... }
public org.omg.CORBA.TypeCode _type () { ... }
}
Union
An IDL union is given the same name as the final Java class, and mapped to it. It provides the following:
If there is a name clash with the mapped union type name or any of the field names, the normal name conflict resolution rule is used: prepend an underscore for the discriminator.
The branch accessor and modifier methods are overloaded and named after the branch. Accessor methods shall raise the CORBA::BAD_OPERATION system exception if the expected branch has not been set.
If there is more than one case label corresponding to a branch, the simple modifier method for that branch sets the discriminant to the value of the first case label. In addition, an extra modifier method which takes an explicit discriminator parameter is generated.
If the branch corresponds to the default case label, then the modifier method sets the discriminant to a value that does not match any other case labels.
It is illegal to specify a union with a default case label if the set of case labels completely covers the possible values for the discriminant. It is the responsibility of the Java code generator (for example, the IDL compiler, or other tool) to detect this situation and refuse to generate illegal code.
A default method _default() is created if there is no explicit default case label, and the set of case labels does not completely cover the possible values of the discriminant. It will set the value of the union to be an out-of-range value.
The holder class for the union is also generated. Its name is the union's mapped Java classname with Holder appended to it as follows:
This code sample shows the Holder class for a union.
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() {...}
}
The following code sample shows the mapping of an IDL union to Java.
/* From Example.idl: */
module Example {
enum EnumType { first, second, third, fourth, fifth, sixth };
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 int 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) { ... }
public java.lang.String to String () { ...}
public boolean equals (java.lang.Object o) { ...}
}
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
An IDL sequence is mapped to a Java array with the same name. In the mapping, anywhere the sequence type is needed, an array of the mapped type of the sequence element is used.
The holder class for the sequence is also generated. Its name is the sequence's mapped Java classname with Holder appended to it as follows:
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() {...}
}
The following code sample shows the mapping of an IDL sequence to Java.
// 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(final 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(final 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() { ... }
}
Array
An IDL array is mapped the same way as an IDL bounded sequence. In the mapping, anywhere the array type is needed, an array of the mapped type of array element is used. In Java, the natural Java subscripting operator is applied to the mapped array. The length of the array can be made available in Java, by bounding the array with an IDL constant, which will be mapped as per the rules for constants.
The holder class for the array is also generated. Its name is the array's mapped Java classname with Holder appended to it as follows:
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() {...}
}
The following code sample shows the mapping for an array.
// 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() {...}
}
Interfaces
IDL interfaces are mapped to the two following public Java interfaces:
An additional “helper” Java class with the suffix Helper is appended to the interface name. The Java interface extends the mapped, base org.omg.CORBA.Object interface.
The Java interface contains the mapped operation signatures. Methods can be invoked on an object reference to this interface.
The helper class declares a static narrow method that allows an instance of org.omg.CORBA.Object to be narrowed to the object reference of a more specific type. The IDL exception CORBA::BAD_PARAM is thrown if the narrow fails because the object reference doesn't support the request type. A different system exception is raised to indicate other kinds of errors. Trying to narrow a null will always succeed with a return value of null.
There are no special “nil” object references. Java null can be passed freely wherever an object reference is expected.
Attributes are mapped to a pair of Java accessor and modifier methods. These methods have the same name as the IDL attribute and are overloaded. There is no modifier method for IDL “readonly” attributes.
The holder class for the interface is also generated. Its name is the interface's mapped Java classname with Holder appended to it as follows:
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() {...}
}
The following code sample shows the mapping of an IDL interface to Java.
/* From Example.idl: */

module Example {
interface Foo {
long method(in long arg) raises(AnException);
attribute long assignable;
readonly attribute long nonassignable;
};
};
// Generated java
package Example;
public interface Foo extends com.inprise.vbroker.CORBA.Object,
Example.FooOperations, org.omg.CORBA.portable.IDLEntity {
}
public interface FooOperations {
public int method (int arg) throws Example.AnException;
public int assignable ();
public void assignable (int assignable);
public int nonassignable ();
}
public final class FooHelper {
// ... other standard helper methods
public static Foo narrow(org.omg.CORBA.Object obj)
{ ... }
public static Example.Foo bind (org.omg.CORBA.ORB orb,
java.lang.String name,
java.lang.String host,
com.inprise.vbroker.CORBA.BindOptions _options) { ... }
public static Example.Foo bind (org.omg.CORBA.ORB orb,
java.lang.String fullPoaName, byte[] oid) { ... }
public static Example.Foo bind (org.omg.CORBA.ORB orb,
java.lang.String fullPoaName, byte[] oid,
java.lang.String host,
com.inprise.vbroker.CORBA.BindOptions _options) { ... }
public Foo read (org.omg.CORBA.portable.InputStream in) { ... }
public void write (org.omg.CORBA.portable.OutputStream out, Foo foo) { ... }
public Foo extract (org.omg.CORBA.Any any) { ... }
public void insert (org.omg.CORBA.Any any, Foo foo) { ... }
}
public final class FooHolder
implements org.omg.CORBA.portable.Streamable {
public Foo value;
public FooHolder() {}
public FooHolder(final 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() { ... }
}
Abstract interfaces
An IDL abstract interface is mapped into a single public Java interface with the same name as the IDL interface. The mapping rules are similar to the rules for generating the Java operations interface for a non-abstract IDL interface. However, this interface also serves as the signature interface, and hence extends org.omg.CORBA.protable.IDLEntity. The mapped Java interface has the same name as the IDL interface and is also used as the signature type in method declarations when interfaces of the specified types are used in other interfaces. It contains the methods which are the mapped operations signatures.
A holder class is generated as for non-abstract interfaces. See “Holder classes” for more information.
A helper class is also generated according to the normal rules. See “Helper classes” for more information.
Local interfaces
An IDL local interface is mapped similarly to that of a non-local interface except that a local interface is marked by org.omg.CORBA.LocalInterface. A local interface may not be marshaled and its implementation must extend a special base org.omg.CORBA.LocalObject and implement the generated signature interface. In Java mapping, the LocalObject class is used as a base class of implementations of a local interface. Creating an instance of local interface implementation is the same as creating normal Java object; that is using the new Java operator.
A holder class is generated as for non-local interfaces. See “Holder classes” for more information.
A helper class is also generated according to the normal rules. See “Helper classes” for more information.
The VisiBroker ORB implementation will detect any attempt to marshal local objects and throw a CORBA::MARSHAL exception.
Passing parameters
IDL in parameters are mapped to normal Java actual parameters. The results of IDL operations are returned as the result of the corresponding Java method.
IDL out and inout parameters cannot be mapped directly into the Java parameter passing mechanism. This mapping defines additional holder classes for all the IDL basic and user-defined types which are used to implement these parameter modes in Java. The client supplies an instance of the appropriate holder Java class that is passed (by value) for each IDL out or inout parameter. The contents of the holder instance (but not the instance itself) are modified by the invocation, and the client uses the (possibly) changed contents after the invocation returns.
This code sample shows the IN parameter mapping to Java actual parameters.
/* From Example.idl: */
module Example {
interface Modes {
long operation(in long inArg, out long outArg, inout long inoutArg);
};
};
// Generated Java:
package Example;
public interface Modes extends com.inprise.vbroker.CORBA.Object,
Example.ModesOperations,
org.omg.CORBA.portable.IDLEntity {
}
public interface ModesOperations {
public int operation (int inArg,
org.omg.CORBA.IntHolder outArg,
org.omg.CORBA.IntHolder inoutArg);
}
In the above, the result comes back as an ordinary result and the actual in parameters only an ordinary value. But for the out and inout parameters, an appropriate holder must be constructed. A typical use case might look as follows:
// 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 ...
Before the invocation, the input value of the inout parameter must be set in the holder instance that will be the actual parameter. The inout holder can be filled in either by constructing a new holder from a value, or by assigning it to the value of an existing holder of the appropriate type. After the invocation, the client uses the outHolder.value to access the value of the out parameter, and the inoutHolder.value to access the output value of the inout parameter. The return result of the IDL operation is available as the result of the invocation.
Server implementation with inheritance
Using inheritance is the simplest way to implement a server because server objects and object references look the same, behave the same, and can be used in exactly the same contexts. If a server object happens to be in the same process as its client, method invocations are an ordinary Java function call with no transport, indirection, or delegation of any kind.
Each IDL interface is mapped to a Java POA abstract class that implements the Java version of the IDL interface.
Note
The POA class does not “truly” extend the IDL interface, meaning that POA is not a CORBA object. It is a CORBA servant and it can be used to create a “true” CORBA object. For more information on the POA class, go to the Java API Reference, VisiBroker APIs, org.omg.PortableServer package section. For more information about POAs, see “Using POAs”.
 
User-defined server classes are then linked to the VisiBroker ORB by extending the <interface>POA class, as shown in the following code sample.
Note
The POA class itself is abstract and cannot be instantiated. To instantiate it, your implementation must implement its declared IDL interface operations.
 
The following code sample shows the Server implementation in Java using inheritance.
/* From Bank.idl: */
module
Bank {
interface Account {
};
};
// Generated java
package Bank;
public abstract class AccountPOA extends org.omg.PortableServer.Servant implements
org.omg.CORBA.portable.InvokeHandler,
Bank.AccountOperations { ... }
// Linking an implementation to the ORB :
public class AccountImpl extends Bank.AccountPOA { ... }
Server implementation with delegation
The use of inheritance to implement a server has one drawback: since the server class extends the POA skeleton class, it cannot use implementation inheritance for other purposes because Java only supports single inheritance. If the server class needs to use the sole inheritance link available for another purpose, the delegation approach must be used.
When server classes are implemented using delegation some extra code is generated.
Each interface is mapped to a Tie class that extends the POA skeleton and provides the delegation code.
Each interface is also mapped to an Operations interface that is used to defined the type of object the Tie class is delegating.
The delegated implementation must implement the Operation interface and has to be stored in a Tie class instance. Storing the instance of the Operation interface in the Tie object is done through a constructor provided by the Tie class. The code sample below shows an example of how delegation is used.
/* From Bank.idl: */
module
Bank {
interface AccountManager {
Account open(in string name);
};
};
// Generated java
package Bank;
public interface AccountManagerOperations {
public Example.Account open(java.lang.String name);
}
// Generated java
package Bank;
public class AccountManagerPOATie extends AccountManagerPOA {
public AccountManagerPOATie (final Bank.AccountManagerOperations _delegate)
{ ... }
public AccountManagerPOATie (final Bank.AccountManagerOperations _delegate,
final org.omg.PortableServer.POA _poa) { ... }
public Bank.AccountManagerOperations _delegate () { ... }
public void _delegate (final Bank.AccountManagerOperations delegate) { ... }
public org.omg.PortableServer.POA _default_POA () { ... }
public float open () { ... }
}
// Linking an implementation to the ORB :
classAccountImpl implements AccountManager Operations
public class Server {
public static main(String args) {
// ...
AccountManagerPOAtie managerServant = new AccountManagerPOATie(new AccountManagerImpl());
// ...
}
Interface scope
OMG IDL to Java mapping specification does not allow declarations to be nested within an interface scope, nor does it allow packages and interfaces to have the same name. Accordingly, interface scope is mapped to a package with the same name with a “Package” suffix.
Mapping for exceptions
IDL exceptions are mapped very similarly to structs. They are mapped to a Java class that provides instance variables for the fields of the exception and constructors.
CORBA system exceptions are unchecked exceptions. They inherit (indirectly) from java.lang.RuntimeException.
User defined exceptions are checked exceptions. They inherit (indirectly) from java.lang.Exception.
User-defined exceptions
User-defined exceptions are mapped to final Java classes that extend org.omg.CORBA.UserException and are otherwise mapped just like the IDL struct type, including the generation of Helper and Holder classes.
If the exception is defined within a nested IDL scope (essentially within an interface) then its Java class name is defined within a special scope. Otherwise its Java class name is defined within the scope of the Java package that corresponds to the exception's enclosing IDL module.
The following code sample shows the mapping of user-defined exceptions.
// IDL
module Example {
exception AnException {
string reason;
};
};
// Generated Java
package Example;
public final class AnException extends org.omg.CORBA.UserException {
public java.lang.String extra;
public AnException () { ... }
public AnException (java.lang.String extra) { ... }
public AnException (java.lang.String _reason, java.lang.String extra) { ... }
public java.lang.String to String () { ... }
public boolean equals (java.lang.Object o) { ... }
}
public final class AnExceptionHolder implements
org.omg.CORBA.portable.Streamable {
public Example.AnException value;
public AnExceptionHolder () { }
public AnExceptionHolder (final Example.AnException _vis_value) { ... }
public void _read (final org.omg.CORBA.portable.InputStream input) { ... }
public void _write (final org.omg.CORBA.portable.OutputStream output) { ... }
public org.omg.CORBA.TypeCode _type () { ... }
}
System exceptions
The standard IDL system exceptions are mapped to final Java classes that extend org.omg.CORBA.SystemException and provide access to the IDL major and minor exception code, as well as a string describing the reason for the exception. There are no public constructors for org.omg.CORBA.SystemException; only classes that extend it can be instantiated.
The Java class name for each standard IDL exception is the same as its IDL name and is declared to be in the org.omg.CORBA package. The default constructor supplies 0 for the minor code, COMPLETED_NO for the completion code, and the empty string (““) for the reason string. There is also a constructor which takes the reason and uses defaults for the other fields, as well as one which requires all three parameters to be specified.
Mapping for the Any type
The IDL type Any maps to the Java class org.omg.CORBA.Any. This class has all the necessary methods to insert and extract instances of predefined types. If the extraction operations have a mismatched type, the CORBA::BAD_OPERATION exception is thrown.
In addition, insert and extract methods which take a holder class are defined to provide a high speed interface for use by portable stubs and skeletons. There is an insert and extract method defined for each primitive IDL type as well as a pair for a generic streamable to handle the case of non-primitive IDL types.
The insert operations set the specified value and reset the Any's type if necessary.
Setting the typecode via the type() accessor wipes out the value. An attempt to extract before the value is set will result in a CORBA::BAD_OPERATION exception being raised. This operation is provided primarily so that the type may be set properly for IDL out parameters.
Mapping for certain nested types
IDL allows type declarations nested within interfaces. Java does not allow classes to be nested within interfaces. Hence those IDL types that map to Java classes and that are declared within the scope of an interface must appear in a special “scope” package when mapped to Java.
IDL interfaces that contain these type declarations generate a scope package to contain the mapped Java class declarations. The scope package name is constructed by appending Package to the IDL type name.
This code sample shows the mapping for certain nested types.
// IDL
module Example {
interface Foo {
exception e1 {};
};
}
// generated Java
package Example.FooPackage;
final public class e1 extends org.omg.CORBA.UserException {...}
Mapping for Typedef
Java does not have a typedef construct.
Simple IDL types
IDL types that are mapped to simple Java types may not be subclassed in Java. Therefore, any typedefs that are type declarations for simple types are mapped to the original (mapped type) any where the typedef type appears. For simple types, Helper classes are generated for all typedefs.
Complex IDL types
Typedefs for non arrays and sequences are “unwound” to their original type until a simple IDL type or user-defined IDL type (of the non typedef variety) is encountered.
Holder classes are generated for sequence and array typedefs.
The following code sample shows the mapping of a complex idl typedef.
// 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 {
...
}