Type Mappings

From Apache OpenOffice Wiki
Jump to: navigation, search



Mapping of Simple Types

The following table shows the mapping of simple UNO types to the corresponding Java types.

UNO Java
void void
boolean boolean
byte byte
short short
unsigned short short
long int
unsigned long int
hyper long
unsigned hyper long
float float
double double
char char
string java.lang.String
type com.sun.star.uno.Type
any java.lang.Object/com.sun.star.uno.Any

The mapping between the values of the corresponding UNO and Java types is obvious, except for a few cases that are explained in the following sections:

Mapping of Unsigned Integer Types

An unsigned UNO integer type encompasses the range from 0 to 2N − 1, inclusive, while the corresponding signed Java integer type encompasses the range from −2N − 1 to 2N − 1 − 1, inclusive (where N is 16, 32, or 64 for unsigned short, unsigned long, or unsigned hyper, respectively). The mapping is done modulo N, that is: 0 is mapped to 0; 2N − 1 − 1 is mapped to 2N − 1 − 1; 2N − 1 is mapped to −2N − 1; and 2N − 1 is mapped to −1.

Users should be careful when using any of the deprecated UNO unsigned integer types. A user is responsible for correctly interpreting values of signed Java integer types as unsigned integer values in such cases.

Mapping of String

The mapping between the UNO string type and java.lang.String is straightforward, except for three details:

  • Only non-null references to java.lang.String are allowed in the context of UNO.
  • The length of a string that can be represented by a java.lang.String object is limited. It is an error to use a longer UNO string value in the context of the Java language binding.
  • An object of type java.lang.String can represent an arbitrary sequence of UTF-16 code units, whereas a value of the UNO string type is an arbitrary sequence of Unicode scalar values. This only matters in so far as some individual UTF-16 code units (namely the individual high- and low-surrogate code points in the range D800–DFFF) have no corresponding Unicode scalar values, and are thus forbidden in the context of UNO. For example, the Java string "\uD800" is illegal in this context, while the string "\uD800\uDC00" would be legal. See www.unicode.org for more information on the details of Unicode.
Mapping of Type

The Java class com.sun.star.uno.Type is used to represent the UNO type; only non-null references to com.sun.star.uno.Type are valid. (It is a historic mistake that com.sun.star.Type is not final. You should never derive from it in your code.)

In many places in the Java UNO runtime, there are convenience functions that take values of type java.lang.Class where conceptually a value of com.sun.star.uno.Type would be expected. For example, there are two overloaded versions of the method com.sun.star.uno.Uno­Runtime.query­Interface, one with a parameter of type com.sun.star.uno.Type and one with a parameter of type java.lang.Class. See the documentation of com.sun.star.uno.Type for the details of how values of java.lang.Class are interpreted in such a context.

Mapping of Any

There is a dedicated com.sun.star.uno.Any type, but it is not always used. An any in the API reference is represented by a java.lang.Object in Java UNO. An Object reference can be used to refer to all possible Java objects. This does not work with primitive types, but if you need to use them as an any, there are Java wrapper classes available that allow primitive types to be used as objects. Also, a Java Object always brings along its type information by means of an instance of java.lang.Class. Therefore a variable declared as:

  Object ref;

can be used with all objects and its type information is available by calling:

  ref.getClass();

Those qualities of Object are sufficient to replace the Any in most cases. Even Java interfaces generated from IDL interfaces do not contain Anys, instead Object references are used in place of Anys. Cases where an explicit Any is needed to not lose information contain unsigned integer types, all interface types except the basic XInterface, and the void type.

Documentation caution.png However, implementations of those interfaces must be able to deal with real Anys that can also be passed by means of Object references.

To facilitate the handling of the Any type, use the com.sun.star.uno.AnyConverter class. It is documented in the Java UNO reference. The following list sums up its methods:

  static boolean isArray(java.lang.Object object) 
  static boolean isBoolean(java.lang.Object object) 
  static boolean isByte(java.lang.Object object) 
  static boolean isChar(java.lang.Object object) 
  static boolean isDouble(java.lang.Object object) 
  static boolean isFloat(java.lang.Object object) 
  static boolean isInt(java.lang.Object object) 
  static boolean isLong(java.lang.Object object) 
  static boolean isObject(java.lang.Object object) 
  static boolean isShort(java.lang.Object object) 
  static boolean isString(java.lang.Object object) 
  static boolean isType(java.lang.Object object) 
  static boolean isVoid(java.lang.Object object) 
  static java.lang.Object toArray(java.lang.Object object) 
  static boolean toBoolean(java.lang.Object object) 
  static byte toByte(java.lang.Object object) 
  static char toChar(java.lang.Object object) 
  static double toDouble(java.lang.Object object) 
  static float toFloat(java.lang.Object object) 
  static int toInt(java.lang.Object object) 
  static long toLong(java.lang.Object object) 
  static java.lang.Object toObject(Type type, java.lang.Object object) 
  static short toShort(java.lang.Object object) 
  static java.lang.String toString(java.lang.Object object) 
  static Type toType(java.lang.Object object)

The Java com.sun.star.uno.Any is needed in situations when the type needs to be specified explicitly. Assume there is a C++ component with an interface function which is declared in UNOIDL as:

  //UNOIDL
  void foo(any arg);

The corresponding C++ implementation could be:

  void foo(const Any& arg)
  {
      const Type& t = any.getValueType();
      if (t == cppu::UnoType< XReference >::get())
      {
          Reference<XReference> myref = *reinterpret_cast<const Reference<XReference>*>(arg.getValue());
          ...
      }
  }

In the example, the any is checked if it contains the expected interface. If it does, it is assigned accordingly. If the any contained a different interface, a query would be performed for the expected interface. If the function is called from Java, then an interface has to be supplied that is an object. That object could implement several interfaces and the bridge would use the basic XInterface. If this is not the interface that is expected, then the C++ implementation has to call queryInterface to obtain the desired interface. In a remote scenario, those queryInterface() calls could lead to a noticeable performance loss. If you use a Java Any as a parameter for foo(), the intended interface is sent across the bridge.

It is a historic mistake that com.sun.star.uno.Any is not final. You should never derive from it in your code.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages