Mapping of Struct Types

From Apache OpenOffice Wiki
Jump to: navigation, search



A plain UNO struct type is mapped to a public Java class with the same name. Only non-null references to such a class are valid. Each member of the UNO struct type is mapped to a public field with the same name and corresponding type. The class provides a default constructor which initializes all members with default values, and a constructor which takes explicit values for all struct members. If a plain struct type inherits from another struct type, the generated class extends the class of the inherited struct type.

  module com { module sun { module star { module chart {
 
  struct ChartDataChangeEvent: com::sun::star::lang::EventObject {
      ChartDataChangeType Type;
      short StartColumn;
      short EndColumn;
      short StartRow;
      short EndRow;
  };
 
  }; }; }; };

is mapped to:

  package com.sun.star.chart;
 
  public class ChartDataChangeEvent extends com.sun.star.lang.EventObject {
      public ChartDataChangeType Type;
      public short StartColumn;
      public short EndColumn;
      public short StartRow;
      public short EndRow;
 
      public ChartDataChangeEvent() {
          Type = ChartDataChangeType.getDefault();
      }
 
      public ChartDataChangeEvent(
          Object Source, ChartDataChangeType Type,
          short StartColumn, short EndColumn, short StartRow, short EndRow)
      {
          super(Source);
          this.Type = Type;
          this.StartColumn = StartColumn;
          this.EndColumn = EndColumn;
          this.StartRow = StartRow;
          this.EndRow = EndRow;
      }
  }

Similar to a plain struct type, a polymorphic UNO struct type template is also mapped to a Java class. The only difference is how struct members with parametric types are handled, and this handling in turn differs between Java 1.5 and older versions.

Take, for example, the polymorphic struct type template:

  module com { module sun { module star { module beans {
 
  struct Optional<T> {
      boolean IsPresent;
      T Value;
  };
 
  }; }; }; };

In Java 1.5, a polymorphic struct type template with a list of type parameters is mapped to a generic Java class with a corresponding list of unbounded type parameters. For com.sun.star.beans.Optional, that means that the corresponding Java 1.5 class looks something like the following example:

  package com.sun.star.beans;
 
  public class Optional<T> {
      public boolean IsPresent;
      public T Value;
 
      public Optional() {}
 
      public Optional(boolean IsPresent, T Value) {
          this.IsPresent = IsPresent;
          this.Value = Value;
      }
  }

Instances of such polymorphic struct type templates map to Java 1.5 in a natural way. For example, UNO Optional<string> maps to Java Optional<String>. However, UNO type arguments that would normally map to primitive Java types map to corresponding Java wrapper types instead:

  • boolean maps to java.lang.Boolean
  • byte maps to java.lang.Byte
  • short and unsigned short map to java.lang.Short
  • long and unsigned long map to java.lang.Integer
  • hyper and unsigned hyper map to java.lang.Long
  • float maps to java.lang.Float
  • double maps to java.lang.Double
  • char maps to java.lang.Character

For example, UNO Optional<long> maps to Java Optional<Integer>. Also note that UNO type arguments of both any and com.sun.star.uno.XInterface map to java.lang.Object, and thus, for example, both Optional<any> and Optional<XInterface> map to Java Optional<Object>.

Still, there are a few problems and pitfalls when dealing with parametric members of default-constructed polymorphic struct type instances:

  • One problem is that such members are initialized to null by the default constructor, but null is generally not a legal value in the context of Java UNO, except for values of any or interface type. For example, new Optional<PropertyValue>().Value is of type com.sun.star.beans.PropertyValue (a struct type), but is a null reference. Similarly, new Optional<Boolean>().Value is also a null reference (instead of a reference to Boolean.FALSE, say). The chosen solution is to generally allow null references as values of Java class fields that correspond to parametric members of polymorphic UNO struct types. However, to avoid any problems, it is a good idea to not rely on the default constructor in such situations, and instead initialize any problematic fields explicitly. (Note that this is not really a problem for Optional, as Optional<T>().IsPresent will always be false for a default-constructed instance and thus, because of the documented conventions for com.sun.star.beans.Optional, the actual contents of Value should be ignored, anyway; in other cases, like with com.sun.star.beans.Ambiguous, this can be a real issue, however.)
  • Another pitfall is that a parametric member of type any of a default-constructed polymorphic struct type instance (think new Optional<Object>().Value in Java 1.5, Optional<Any> o; o.Value in C++) has different values in the Java language binding and the C++ language binding. In Java, it contains a null reference of type XInterface (i.e., the Java value null), whereas in C++ it contains void. Again, to avoid any problems, it is best not to rely on the default constructor in such situations.

In Java versions prior to 1.5, which do not support generics, a polymorphic struct type template is mapped to a plain Java class in such a way that any parametric members are mapped to class fields of type java.lang.Object. This is generally less favorable than using generics, as it reduces type-safety, but it has the advantage that it is compatible with Java 1.5 (actually, a single Java class file is generated for a given UNO struct type template, and that class file works with both Java 1.5 and older versions). In a pre-1.5 Java, the Optional example will look something like the following:

  package com.sun.star.beans;
 
  public class Optional {
      public boolean IsPresent;
      public Object Value;
 
      public Optional() {}
 
      public Optional(boolean IsPresent, Object Value) {
          this.IsPresent = IsPresent;
          this.Value = Value;
      }
  }

How java.lang.Object is used to represent values of arbitrary UNO types is detailed as follows:

  • Values of the UNO types boolean, byte, short, long, hyper, float, double, and char are represented by non-null references to the corresponding Java types java.lang.Boolean, java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Float, java.lang.Double, and java.lang.Character.
  • Values of the UNO types unsigned short, unsigned long, and unsigned hyper are represented by non-null references to the corresponding Java types java.lang.Short, java.lang.Integer, and java.lang.Long. Whether a value of such a Java type corresponds to a signed or unsigned UNO type must be deducible from context.
  • Values of the UNO types string, type, any, and the UNO sequence, enum, struct, and interface types (which all map to Java reference types) are represented by their standard Java mappings.
  • The UNO type void and UNO exception types cannot be used as type arguments of instantiated polymorphic struct types.

This is similar to how java.lang.Object is used to represent values of the UNO any type. The difference is that there is nothing like com.sun.star.uno.Any here, which is used to disambiguate those cases where different UNO types map to the same subclass of java.lang.Object. Instead, here it must always be deducible from context exactly which UNO type a given Java reference represents.

The problems and pitfalls mentioned for Java 1.5, regarding parametric members of default-constructed polymorphic struct type instances, apply for older Java versions as well.

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