[Previous] [Contents] [Next] [IONA Technologies]


Chapter 5
IDL to Java Mapping


Contents

5.1 Overview of the Mapping
5.1.1 Terminology
5.2 Mapping for Identifiers
5.3 Scoped Names
5.4 The CORBA Module
5.5 Mapping for Basic Data Types
5.6 Mapping for Interfaces
5.6.1 Client Mapping
5.6.2 Server Implementation Mapping
5.7 Mapping for Attributes and Operations
5.8 Object References
5.9 Inheritance
5.9.1 Narrowing Object References
5.10 Mapping for Constants
5.11 Mapping for Enums
5.12 Mapping for Strings
5.13 Mapping for Typedefs
5.14 Mapping for Structs
5.15 Mapping for Unions
5.16 Mapping for Arrays
5.17 Mapping for Sequence Types
5.18 Mapping for Exception Types
5.19 Context Arguments
5.20 Common Mapping for Pseudo Types
5.20.1 Creating Pseudo-Objects
5.21 Mapping for Parameters and Return Values
5.21.1 Holder Classes
5.21.2 Details of Parameter Type Mappings
5.21.3 Memory Allocation Issues



This chapter describes the OrbixWeb mapping from the CORBA Interface Definition Language (IDL) to Java. The purpose of the chapter is to explain the rules by which OrbixWeb converts IDL definitions into Java source code and how to use the generated Java constructs. The mapping described here is specific to OrbixWeb.

5.1 Overview of the Mapping

major elements of the mapping are:

5.1.1 Terminology

In the text following, the term "OrbixWeb" is used to denote services provided by OrbixWeb, without distinguishing between Java code generated by the IDL compiler and the core of OrbixWeb itself.

Ellipses (...) are used in examples to stand for declarations and code which are not relevant to the current discussion.

5.2 Mapping for Identifiers

IDL identifiers are mapped to an identifier of the same name in Java. However, if an IDL definition contains an identifier that exactly matches a Java keyword, the identifier is mapped to the name of the identifier preceded by `_' as follows:

(for example, new would map to _new). An IDL identifier cannot begin with an underscore.

5.3 Scoped Names

All types defined inside an IDL module are placed within a Java package that has the same name as the module. For example, if an interface named Bank is defined inside the module IDLDemo, then the Java Ref interface for Bank is scoped as IDLDemo._BankRef.

Similarly, anything defined inside an interface is scoped first by the module name (if any), and then by a package named _<type>, where <type> is the interface name. Therefore, if Bank in the above example defines a structure called Details, then the corresponding class is scoped as IDLDemo._Bank.Details.

Anything that is not defined inside either a module or an interface goes into the default (global) package. The only exception to this is the case of globally defined constants, which are discussed in section 5.10. This mapping creates the potential for name collisions with other globally defined Java types, so it is advisable to avoid the generation of global Java definitions whenever possible.

To help alleviate this problem, the -jP option was added to the IDL compiler. The -jP option specifies a package prefix that is added to generated types. This makes it possible to use globally defined IDL types within a package scope.

5.4 The CORBA Module

The objects and data types pre-defined in CORBA are logically defined within an IDL module called CORBA. Therefore, in IDL the type Object, for example, is scoped as CORBA::Object. OrbixWeb maps the CORBA module to Java in order to provide a corresponding scoping for Java types.

The Java mapping for the CORBA module is defined within the package IE.Iona.Orbix2. Within this scope, the CORBA module is defined in two sections:

In this mapping, all constants and member variables defined directly in the CORBA namespace are referenced within the IE.Iona.Orbix2._CORBA scope; all other elements of the CORBA module are referenced within the IE.Iona.Orbix2.CORBA scope.

For full details of the contents of the IE.Iona.Orbix2 package, see Part II, "Class and Interface Reference" of the OrbixWeb Reference Guide.

5.5 Mapping for Basic Data Types

The IDL basic data types have the mappings shown in Table 5.1.

IDL

JAVA

     short
    
     short
    
     long
    
     int
    
     unsigned short
    
     int
    
     unsigned long
    
     int
    
     float
    
     float
    
     double
    
     double
    
     char
    
     char
    
     boolean
    
     boolean
    
     octet
    
     byte
    
     any
    
     IE.Iona.Orbix2.CORBA.Any
    

Table 5.1: Mapping for basic types

Java does not support unsigned data types, therefore all unsigned IDL types are simply mapped to signed Java types. Note that the IDL unsigned short type maps to Java int, in order to avoid value wrapping. Consequently, when transmitting unsigned short values, it is the responsibility of the application programmer not to transmit Java int values greater than the upper limit on the IDL unsigned short type (216-1).

A Java int is a 32 bit quantity whereas a long is a 64 bit quantity. Therefore the IDL long type, which is specified as a 32 bit integer, is mapped to the Java int type, rather than the Java long type.

The mapping of the IDL char type to the Java char type requires special consideration. IDL chars come from the ISO 8859.1 character set, having at most 255 different values. Java chars come from the UNICODE character set, having at most 65536 different values. Therefore, IDL chars can only represent a small subset of Java chars.

OrbixWeb programmers can form Java chars which are outside the range of IDL chars. However, when a Java char is passed as a parameter to an IDL operation, only the low order 8 bits are preserved during transmission.

The mapping for type any is described in full in Chapter 18, "Type any".

5.6 Mapping for Interfaces

OrbixWeb maps IDL interfaces to a set of Java types which support client development and a set of types which support server implementation. We will examine each of these mappings in turn.

5.6.1 Client Mapping

IDL supports multiple inheritance of interfaces. Java also supports multiple inheritance of interfaces, but does not support multiple inheritance of classes. For this reason, IDL interfaces are mapped to Java interfaces, from the point of view of client applications.

Unfortunately, this mapping is not sufficient to provide an OrbixWeb client with proxy functionality for the IDL interface type. Consequently, the IDL compiler generates two Java types for each IDL interface definition:

Consider the following example of an IDL interface to describe a bank account:

This produces the following Java interface definition:

and the following Java class definition:

The Java interface derives from interface IE.Iona.Orbix2.CORBA._ObjectRef which defines the developer's view of functionality common to all OrbixWeb objects; the Java class derives from class IE.Iona.Orbix2.CORBA.BaseObject, which implements the _ObjectRef interface.

The generated class also has static class methods for _narrow() and _bind(). The _narrow() method takes an _ObjectRef type as an argument, and returns an object reference of the same type as the class. The _bind() method may be used to create a proxy for an object which implements the IDL interface.

A client wishing to use the IDL interface should bind an object of the Java class type to the target implementation object in the server, assigning the result to the Java interface type. For example, a client could bind to an Account implementation object by calling the _bind() static method on the Java Account class as follows:

This returns a proxy object which can be accessed via the methods defined in the _AccountRef interface.

The IDL compiler also generates a Holder class for each IDL interface type, within a package (where the package name is that of the IDL interface). For example, the above IDL definition results in the generation of the following Holder class:

This Java class is required for passing the IDL interface type as an inout or out parameter to IDL operations. section 5.21 provides full details of the mapping for operation parameter values.

5.6.2 Server Implementation Mapping

OrbixWeb supports two approaches to the implementation of IDL interfaces in Java applications: the BOAImpl approach and the TIE approach. In this section we will discuss the Java types generated to enable each implementation method.

Both approaches to interface implementation share the common requirement that the application programmer must create a Java implementation class. This class must fully implement methods corresponding to the attributes and operations of the IDL interface.

The IDL compiler generates a Java interface which defines the minimum set of methods which must by supplied in order to implement an IDL interface. The name of this Java interface has the following format:

For example, given the IDL definition of type Account, the IDL compiler generates the Java interface _AccountOperations as follows:

The relationship of this Java interface to a programmer's implementation class is dependent on the implementation approach.

The BOAImpl Approach

To support the BOAImpl approach, the IDL compiler generates an abstract Java class from each IDL interface definition. This abstract class is named by appending the IDL interface name to the string _boaimpl_. For example, the compiler generates class _boaimpl_Account from the definition of interface Account.

The generated BOAImpl-class implements the IDL generated Operations interface. The implementation methods defined by this interface are redefined as abstract methods of the BOAImpl-class. To implement an IDL interface using the BOAImpl approach, the programmer must create a Java class which extends the corresponding BOAImpl-class and implements the abstract methods.

For example, given the IDL definition for interface Account, the compiler generates the abstract class _boaimpl_Account as follows:

A sample class which implements the IDL interface Account could be outlined as follows:

Note that the BOAImpl-class constructor can throw OrbixWeb system exceptions, so the implementation class constructor must include a Java throws clause for such exceptions.

Once the IDL interface has been implemented using the BOAImpl approach, the server application should simply instantiate one or more objects of the implementation class. These objects will then be capable of handling client requests through the IDL interface in question.

The TIE Approach

To support the TIE approach to implementation, the IDL compiler generates an additional, non-abstract Java class from each IDL interface definition. This class is named by appending the IDL interface name to the string _tie_. For example, the compiler generates class _tie_Account from the definition of interface Account:

The TIE-class does not implement the Java Operations interface generated by the IDL compiler. When implementing an IDL interface using the TIE method, the programmer's Java implementation class must directly implement the Operations interface. However, the implementation class is not required to inherit from any other Java class.

For example, the class AccountImplementation could be outlined using the TIE approach as follows:

When the programmer has created an implementation class which implements the required Operations interface, the server application should instantiate one or more objects of this type. For each implementation object, the server should also instantiate an object of the corresponding TIE-class, passing the implementation object as a parameter to the TIE constructor.

Each TIE object stores a reference to a single implementation object. Client operation invocations through the IDL interface are routed to the appropriate TIE object which then delegates the call to the appropriate method in its implementation object.

5.7 Mapping for Attributes and Operations

Operations within an IDL interface are mapped to methods of the corresponding Java interface; these methods have the same name as their corresponding IDL operation.

The mapping for each read-write attribute produces two methods: one to get the attribute's value and the other to set it. The name of the get method is formed by appending the string get_ with the attribute name; the set method by appending the string set_ with the attribute name. A readonly attribute is mapped to a single method, which gets the value.

Consider the following IDL interface:

The following code illustrates the mapping:

Operation return values and in parameters following the general mapping rules for the appropriate IDL type. However, as Java does not support the passing of method parameters by reference, inout and out parameter passing modes often require a more complex mapping.

To return simple types by reference, a Java class instance must be passed instead of the primitive type itself. OrbixWeb provides Holder classes for the following Java basic types: short, int, char, boolean, byte, double and float. These Holder classes are defined in the IE.Iona.Orbix2.CORBA package and are named ShortHolder, IntHolder, CharHolder, and so on.

For example, if we add the following operation to the interface Account:

the following code would be generated for this operation:

where the class FloatHolder is defined as follows:

Holder classes are also required when passing Strings or object references as inout or out parameters. The mapping for operation parameters is described in full in section 5.21.

The mapping to Java for oneway operations is the same as it is for normal operations; however, the IDL compiler will ensure that these operations do not have any inout or out parameters, that they have a void return type and that they do not raise user-defined exceptions (oneway operations may however raise system exceptions). This is in accordance with the restrictions on oneway operations prescribed in the CORBA specification.

A raises clause on an operation maps directly to a throws clause on the equivalent Java method. The mapping for user defined exceptions is described in section 5.18.

The mapping for IDL context clauses is described in section 5.19.

5.8 Object References

When an interface type is used in IDL, this denotes an object reference. For example, consider the IDL operation newAccount(), defined as follows:

The return type of newAccount() is an object reference. An object reference maps to an interface named _<type>Ref, where <type> is the name of the IDL interface type. The Ref interface allows IDL operations to be invoked on the object reference with normal Java method invocation syntax. For example, the newAccount() operation could be invoked as follows:

The server implementation of operation newAccount() will create an Account implementation object, store a reference to this object, and return the object reference to the client. For example, using the BOAImpl approach and an implementation class named AccountImplementation, this could be done as follows:

Similarly, the TIE approach could be used as follows:

If the operation newAccount() returned the Account object reference as an inout or out parameter value, then the generated class _AccountHolder would need to be passed to the newAccount() Java method. _AccountHolder is a class which can contain an _AccountRef object reference value. The use of Holder classes is documented in full in section 5.21.1.

5.9 Inheritance

This section describes the mapping for interfaces that inherit from other interfaces. Additional details of this mapping are provided in Chapter 13, "Inheritance".

IDL interfaces support both single and multiple inheritance. On the client side, the OrbixWeb IDL compiler maps IDL interfaces to Java interfaces, which also support single and multiple inheritance, and generates Java classes which implement proxy functionality for these interfaces. Inherited interfaces in IDL are mapped to extended interfaces in Java; the inheritance hierarchy of the Java interfaces matches that of the original IDL interfaces.

Consider the following example:

The corresponding Java interface for type CheckingAccount is:

The corresponding Java class implements all methods for both Account and CheckingAccount. The generated class looks like this:

As expected, code written in Java to use the CheckingAccount interface can call the inherited makeDeposit() function:

Naturally, assignments from a derived to a base class object reference are allowed, for example:

Normal or cast assignments in the opposite direction–from a base class object reference to a derived class object reference–are not generally allowed. The _narrow() method can be used to bypass this restriction where it is safe to do so, as described in section 5.9.1.

On the server side, the IDL compiler generates a Java Operations interface for each IDL interface. The generated Java interface defines the minimum set of implementation methods required for the IDL interface. The inheritance hierarchy of generated Operations interfaces matches that of the original IDL interfaces.

To support the BOAImpl approach to interface implementation, the compiler generates a Java BOAImpl class for each IDL interface. This class implements the Operations interface for its corresponding IDL type and redefines each of the interface methods as abstract methods–including all methods defined in interfaces from which the Operations interface inherits.

To implement an IDL interface which derives from another, the programmer must define an implementation class which extends the BOAImpl class for the required interface and implements all the methods defined in the BOAImpl class. For example, given the IDL definition of Account and CheckingAccount, a CheckingAccount implementation class will appear as follows:

Using the TIE approach, the implementation class should implement the generated Operations interface for the relevant IDL type. The implementation class must implement each method defined in the Operations interface and all interfaces from which it inherits. However, this may be achieved using an inheritance hierarchy of implementation classes, as the TIE approach, unlike the BOAImpl approach, imposes no implicit inheritance requirements on such classes.

For example, if the IDL type Account is implemented by class AccountImplementation, using the TIE approach, then IDL interface CheckingAccount might be implemented by type CheckingAccountImplementation as follows:

5.9.1 Narrowing Object References

In the CheckingAccount example above, if the programmer knows that a reference of type _AccountRef actually references an object which implements interface CheckingAccount, then it is legal to narrow the object reference to a CheckingAccount reference. To narrow an object reference, the _narrow() method (which is defined as a static method in each IDL generated Java class) should be used:

It can be called as follows:

If the parameter passed to T._narrow() is not of class T or one of its derived classes, T._narrow() raises the IE.Iona.Orbix2.CORBA.BAD_PARAM exception and returns null.

5.10 Mapping for Constants

IDL constants are mapped differently depending on whether they are defined globally, within a module or within an interface.

For a global, file level IDL constant such as:

OrbixWeb generates a Java class in which an equivalent Java constant is defined. The class name is generated using the following convention:

The constant is then mapped to a public static final member of this class. For example, MaxLen in the above IDL definition maps to:

A Java class is also generated when an IDL constant is defined within a module. In this case, the class name is generated using the convention:

The constant is then mapped to a public static final member of this class.

Consider the following example:

This maps to:

An IDL constant defined in an interface simply maps to a public static final member of the generated Java class for the IDL interface. For example, the following IDL:

maps to the following Java class:

Programmers can then access the constant by scoping with the Java class name, for example:

5.11 Mapping for Enums

An IDL enum maps to a Java class containing static class variables for each element in the enumeration. These variables are initialised to sequential values, starting at zero.

Individual enumeration values map to Java type int. Therefore, to use an IDL enum in Java, a developer could declare an int and initialise it using one of the values from the generated enumeration class. Legal values for an enum operation parameter are enforced when an operation is invoked.

Consider the following IDL definition:

This maps to:

5.12 Mapping for Strings

IDL bounded and unbounded strings map to the Java type String. As Java Strings are fundamentally unbounded, OrbixWeb checks the range of String parameter values passed as bounded strings to IDL operations. If the actual string length is greater than the bound value, then the string is truncated during marshalling to the maximum allowable length. This truncation has no effect on the sender's copy of the string.

IDL string parameters defined as inout or out map to Java method parameters of type StringHolder. This Holder class contains a Java String value, which can be updated during the operation invocation:

Consider the following IDL definition:

This maps to the following Java interface:

A client application could invoke the IDL operations as follows:

The server programmer receives the StringHolder variable as a parameter to the implementation method and simply assigns the required string to the value field.

OrbixWeb programmers who wish to use IDL strings should be aware of the difference between IDL chars and Java chars as outlined in section 5.5.

5.13 Mapping for Typedefs

Java has no language construct that is equivalent to the IDL typedef statement. However, the same effect as typedef can be achieved by declaring a new Java type as a subclass of the original type. Of course, this works only if the original type can be subclassed.

Basic types cannot be subclassed, therefore typedefs for simple types do not map directly to Java. Instead, the original type is substituted for the new type everywhere the new type is encountered. In this particular case, IDL string counts as a simple type (since the Java type String is a final class), while IDL any does not.

Complex types can be subclassed. A typedef for a complex type generates a class that extends the class of the original type. It contains no methods or variables of its own.

For example, consider a typedef on an IDL interface:

The CustomerDetails structure maps to a Java class as described in section 5.14. The typedef statement results in an additional Java class as follows:

5.14 Mapping for Structs

An IDL struct maps to a Java class containing one instance variable for each field in the structure. There are two constructors for each structure class: the first takes no arguments and initialises all fields in the structure to null or zero; the other takes the fields in the structure as arguments, and initialises the structure.

All IDL parameters (in, out and inout) and return values of a given struct type map to the Java class for that structure.

For example, the structure Time in the following example:

maps to:

while the Time operation parameters map directly as follows:

5.15 Mapping for Unions

IDL supports discriminated unions. A discriminated union consists of a discriminator and a value: the discriminator indicates what type the value holds. For example:

IDL discriminated unions map to a Java class. The class provides modifier methods which allow the discriminator and value to be set simultaneously. It also provides accessor methods which allow the discriminator to be queried and the value to be retrieved.

The above IDL definition maps to:

The discriminator and value member variables of the Java class are labelled private in order to prevent either being modified independently of the other. In order to set the union to a given value, the programmer must invoke one of the three generated set methods: curAcc(), depAcc(), or genAcc().

For example, the following code sample assigns a DepositAccount value:

The accessor methods can then be used to retrieve the union value. This is illustrated below:

IDL parameters of a discriminated union type map directly to the corresponding Java class.

5.16 Mapping for Arrays

IDL arrays map directly to Java arrays. However, Java arrays are not bounded, therefore OrbixWeb explicitly checks the bound of an array when an operation is called with the array as an argument.

The actual length of the Java array used as a parameter should be at least as long as the length specified in the IDL file. If it is shorter, then the values of elements for which space has not been allocated will be undefined. If it is longer, then the extra elements will be ignored.

As a simple example, the following IDL definition:

maps to:

5.17 Mapping for Sequence Types

In OrbixWeb, the basic mappings for bounded and unbounded IDL sequences are identical. A type declaration for an IDL sequence maps to a Java class, using the following naming convention for the class:

This generated class contains two instance variables (buffer and length) and an ensureCapacity() method. If the sequence has been the source of an IDL typedef statement, the new type defined in the typedef is mapped to a derived class of the sequence class, as described in section 5.13.

The member variable buffer is a Java array of elements which are of the same type as the IDL sequence elements. The default constructor assigns this array to null. An alternative constructor is provided which allows the programmer to specify a size to which the array is initialised.

The member variable length can be assigned by the programmer to indicate the current length of the array stored in buffer (which may be less than the actual size of the allocated array). If length is set to any value less than zero or greater than the actual size of the buffer array, then OrbixWeb will assume the length to be equal to the actual size of the array.

The ensureCapacity() method takes an int parameter value, which indicates the minimum array size required by the programmer. If the actual buffer size is less than the required minimum, ensureCapacity() reallocates the buffer array appropriately and copies any existing elements into the new array. The new buffer is guaranteed to be at least as long as the requested size, but for efficiency reasons the buffer will often be made larger than the requested size.

When ensureCapacity() resizes a buffer array, the length field is not set. Therefore it is necessary to set the length field explicitly if that is the desired behaviour.

The following IDL definition provides an example of declaring IDL sequences:

Given this example, the IDL compiler produces a Java class which maps all sequence of CustomerDetails declarations (bounded or unbounded):

Derived classes of this sequence class are generated for the UnboundedSeq and BoundedSeq types in accordance with the IDL to Java mapping for typedefs, as described in section 5.13.

Bounded IDL sequence types map to Java classes which contain implicitly unbounded array buffers. When a Java sequence class is passed to an operation which takes a bounded sequence as a parameter, OrbixWeb explicitly checks the length of the sequence. If the length is greater than the bound specified in the IDL definition, the transmitted sequence will be truncated to the maximum legal length for that sequence type. However, this truncation does not affect the sender's copy of the sequence.

5.18 Mapping for Exception Types

An IDL exception type is mapped to a Java class that derives from the OrbixWeb class UserException, which in turn derives from the class CORBAException (where both these classes are defined in the IE.Iona.Orbix2.CORBA package). The class CORBAException derives from java.lang.Exception, which allows classes for IDL exceptions to be thrown as normal Java exceptions.

The Java class includes the IDL exception data. For example, the exception definition:

is mapped to:

This mapping defines a default constructor and a constructor with one parameter for each exception member; this second constructor initialises each exception member to the given value. In this example, this constructor has two parameters, one for each of the fields reason and s defined in the exception. The default constructor performs no explicit member initialisation.

Now consider an interface with an operation that can raise a Reject IDL exception:

An OrbixWeb server can raise a Bank::Reject exception by passing the Java type Bank.Reject to a Java throw() statement:

An OrbixWeb client can test for such an exception when invoking the newAccount() operation as follows:

OrbixWeb exception handling is described in detail in Chapter 12, "Exception Handling".

5.19 Context Arguments

An IDL operation can specify that it is to be provided with the client's mapping for particular identifiers (properties): it does this by listing these identifiers following the operation declaration in a context clause. An IDL operation that specifies a context clause is mapped to a Java method which takes an extra input parameter of type Context (scoped within package IE.Iona.Orbix2.CORBA), at the end of the parameter list. For example:

maps to:

A client can optionally maintain one or more Context objects, which provide a mapping from identifiers (string names) to string values. A Context object contains a list of properties; each property consists of a name and a string value associated with that name and can be passed to a method that takes a Context parameter.

Contexts can be arranged in a hierarchy by specifying parent-child relationships among them. Then, a child passed to an operation also includes the identifiers of its parent(s). The called operation can decide whether to use just the context actually passed, or the hierarchy above it.

The manipulation of Context objects is illustrated in full in Chapter 15, "Contexts", while the definition of the API to class Context can be found in Appendix A, "IDL Reference" in the OrbixWeb Reference Guide.

5.20 Common Mapping for Pseudo Types

As described in Chapter 4, the CORBA standard defines a number of so-called pseudo interfaces–that is, interfaces defined (for convenience) in IDL but whose implementations do not strictly follow the normal mapping for interfaces. An instance of a pseudo interface is termed a pseudo-object. In OrbixWeb, a pseudo-object is a serverless object, which does not inherit from class BaseObject and is not registered with an OrbixWeb server. OrbixWeb does not create proxies for pseudo-objects.

The following CORBA pseudo interfaces are implemented in OrbixWeb: NamedValue, NVList, Request, Context, TypeCode and ORB.

Note that pseudo IDL interfaces do not have equivalent Ref types. Also, the mapping to Holder types for pseudo IDL interfaces does not match that for other IDL interfaces: a Holder type for a pseudo IDL interface is named <type>Holder where <type> is the interface name. The following pseudo types have no equivalent Holder type: NamedValue, TypeCode and ORB.

5.20.1 Creating Pseudo-Objects

For most pseudo object types, the CORBA specification defines an operation to create a pseudo-object. For example, the pseudo interface ORB defines the operations create_list() and create_operation_list() to create an NVList (an NVList describes the arguments of an IDL operation).

For each pseudo interface, OrbixWeb provides static IT_create() methods in the corresponding Java class. These methods provide an OrbixWeb specific means to create and obtain a pseudo-object reference. An overloaded version of IT_create() is provided which corresponds to each constructor defined on the class. It is recommended that IT_create() should be used in preference to Java operator new but only where there is no (suitable) alternative way to obtain a pseudo-object reference.

5.21 Mapping for Parameters and Return Values

When writing OrbixWeb applications, it is necessary to be aware of the IDL to Java mapping for IDL types and the corresponding mapping for parameters and return values of those types. In particular, the mapping for an operation argument may depend on whether it is an in parameter, an out parameter, an inout parameter, or a return value. This section provides a description of the mappings for IDL parameters and return values.

In summary, IDL in parameters always map directly to the corresponding Java type. This mapping is possible because these parameters are always passed by value, and Java supports by value passing of all types. Similarly, IDL return values always map directly to the corresponding Java type.

IDL inout and out parameters need to be passed by reference, as they may be modified during an operation invocation. This poses no problem for the IDL to Java mapping in cases where Java supports by reference parameter passing for the Java type and the actual parameter type is guaranteed not to change during the operation. However, these criteria do not hold for all types generated by the OrbixWeb IDL to Java mapping. In cases where either requirement is not satisfied, OrbixWeb defines an additional Holder type which facilitates the passing of inout and out parameters.

In particular, Java supports by reference passing of class instances and arrays. The IDL struct, union, sequence, any and array types map to Java classes or arrays and these types never implicitly change (at the parameter type level) during IDL operation invocations. Consequently, inout and out parameters for these types follow the direct IDL to Java mapping rules.

IDL basic types (other than type any) and the IDL string type map to Java types which cannot be passed by reference. For this reason, inout and out parameters of these types require Holder classes.

Finally, inout and out object reference parameters also require Holder classes. This requirement is due to the fact that, although object references map to Java interfaces, the actual type of an object reference parameter may change (to a subtype) during an operation invocation.

We will now discuss the implementation of Holder classes in detail.

5.21.1 Holder Classes

To allow IDL basic types (except type any), IDL strings and IDL object reference types to be passed as inout and out parameters to IDL operations, OrbixWeb implements Holder classes for these types.

Each basic IDL type maps to a basic Java type, which has an associated Holder class as shown in Table 5.2.


JAVA Type

HOLDER CLASS

     short
    
     ShortHolder
    
     int
    
     IntHolder
    
     float
    
     FloatHolder
    
     double
    
     DoubleHolder
    
     char
    
     CharHolder
    
     boolean
    
     BooleanHolder
    
     byte
    
     ByteHolder
    

Table 5.2: Holder classes for basic types

The Holder class for the Java String type is named StringHolder. The basic type Holder classes and the StringHolder class are defined within the IE.Iona.Orbix2.CORBA package. The class IntHolder provides and example implementation:

The Holder class simply stores an int value as a member variable, which can be initialised by the constructor and accessed directly. The Holder class is passed by reference to method invocations and so facilitates the modification of an int, which would not be possible if the int were passed directly.

Holder classes for IDL object reference types are generated during compilation of the IDL definition. These classes are required to allow the actual type of an object reference inout or out parameter to change (to a subtype) during an operation call. A Holder class for an IDL interface type is named _<type>Holder where <type> is the name of the IDL interface. For example, given an IDL interface Account, the following Holder class will be generated:

In order to invoke an operation which requires a Holder class as a parameter, a client programmer simply creates a variable of the Holder type, passes this variable as an operation parameter, and retrieves the value member variable to obtain the required operation result.

For example, the following IDL definition:

maps to:

A programmer who wishes to retrieve a string from the getCustomerName() operation should pass a StringHolder as an operation parameter as follows:

Of course, the retrieved value can be copied or manipulated as required.

A server programmer simply receives the instantiated Holder type and manipulates the value field as required. For example, the implementation of operation getCustomerName() might return a String value as follows:

5.21.2 Details of Parameter Type Mappings

Table 5.3 shows the mapping for the IDL parameter passing modes and return types.

IDL Type

In

Inout

Out

Return

short

short

ShortHolder

ShortHolder

short

long

int

IntHolder

IntHolder

int

unsigned short

int

IntHolder

IntHolder

int

unsigned long

int

IntHolder

IntHolder

int

float

float

FloatHolder

FloatHolder

float

double

double

DoubleHolder

DoubleHolder

double

boolean

boolean

BooleanHolder

BooleanHolder

boolean

char

char

CharHolder

CharHolder

char

octet

byte

ByteHolder

ByteHolder

byte

any

Any

Any

Any

Any

enum

int

IntHolder

IntHolder

int

object reference

_ObjectRef

_<type>Holder

_<type>Holder

_ObjectRef

struct

class

class

class

class

union

class

class

class

class

string

String

StringHolder

StringHolder

String

sequence

class

class

class

class

array

array

array

array

array

Table 5.3: Mapping for parameters and return values

5.21.3 Memory Allocation Issues

Java provides automatic garbage collection, which greatly simplifies the memory management issues associated with the OrbixWeb IDL to Java mapping in comparison with, for example, the Orbix IDL to C++ mapping. However, an OrbixWeb programmer should understand where memory needs to be allocated for IDL operation parameters.

For all IDL basic types (except type any) and the IDL type string, in parameters and return values are passed by value. inout and out parameters of these types are passed as Holder classes. An instantiation of the Holder type must be passed to the operation, which may then modify the value member.

For IDL structs, unions, sequences, arrays, and type any, in parameters are passed by reference and not modified. Return values need not be pre-allocated. Return types are automatically allocated and are then given to the caller to manage. out and inout parameters require the caller to pre-allocate the value and this is modified in place.

IDL object reference in parameters and return values obey similar rules to IDL struct in parameters and return values. However, object reference inout and out parameters are passed as Holder types. An instantiation of the Holder type must be passed to the operation, which may then modify the value member.



[Roadmap] [Introduction] [GS: Applications] [GS: Applets]
[IDL] [Mapping] [Programming OrbixWeb] [Publishing Objects] [Retrieving Objects] [IIOP]
[Running Clients] [Running Servers] [Exceptions] [Inheritance] [Callbacks] [Contexts]
[API Configuration] [TypeCode] [Any] [DII] [IR] [Filters] [Smart Proxies] [Loaders] [Locators]
[Index]