D-Bus supports a number of types in its messages, some which Java supports natively, and some which it doesn’t. This library provides a way of modelling the extra D-Bus Types in Java. The full list of types and what D-Bus type they map to is in table 1.
All of Java’s basic types are supported as parameters and return types to methods, and as parameters to signals. These can be used in either their primitive or wrapper types.
D-Bus, like C and similar languages, has a notion of unsigned numeric types. The library supplies UInt1614 , UInt32 and UInt64 classes to represent these new basic types.
D-Bus also supports sending Strings. When mentioned below, Strings count as a basic type.
There may be some problems with comparing strings received over D-Bus with strings generated locally when using the String.equals method. This is due to how the Strings are generated from a UTF8 encoding. The recommended way to compare strings which have been sent over D-Bus is with the java.text.Collator class. Figure 10 demonstrates its use.
You can send arrays of any valid D-Bus Type over D-Bus. These can either be declared in Java as arrays (e.g. Integer[] or int[]) or as Lists (e.g. List<String>). All lists must be parameterised with their type in the source (reflection on this is used by the library to determine their type). Also note that arrays cannot be used as part of more complex type, only Lists (for example List<List<String>>).
D-Bus supports a dictionary type analogous to the Java Map type. This has the additional restriction that only basic types can be used as the key (including String). Any valid D-Bus type can be the value. As with lists, maps must be fully parameterised. (e.g. Map<Integer, String>).
D-Bus has support for a Variant type. This is similar to declaring that a method takes a parameter of type Object, in that a Variant may contain any other type. Variants can either be declared using the Variant15 class, or as a Type Variable. In the latter case the value is automatically unwrapped and passed to the function. Variants in compound types (Arrays, Maps, etc) must be declared using the Variant class with the full type passed to the Variant constructor and manually unwrapped.
Both these methods use variants:
D-Bus has a struct type, which is a collection of other types. Java does not have an analogue of this other than fields in classes, and due to the limitation of Java reflection this is not sufficient. The library declares a Struct16 class which can be used to create structs. To define a struct you extend the Struct class and define fields for each member of the struct. These fields then need to be annotated in the order which they appear in the struct (class fields do not have a defined order). You must also define a single constructor which takes the contents of he struct in order. This is best demonstrated by an example. Figure 11 shows a Struct definition, and figure 12 shows this being used as a parameter to a method.
package org.freedesktop.dbus.test;
import org.freedesktop.dbus.DBusException; import org.freedesktop.dbus.Position; import org.freedesktop.dbus.Struct; public final class TestStruct extends Struct { @Position(0) public final String a; @Position(1) public final int b; @Position(2) public final String c; public Struct3(String a, int b, String c) { this.a = a; this.b = b; this.c = c; } }
|
Section 10 describes how these can be automatically generated from D-Bus introspection data.
You can pass references to exportable objects round using their object paths. To do this in Java you declare a type of DBusInterface. When the library receive- an object path it will automatically convert it into the object you are exporting with that object path. You can pass remote objects back to their processes in a similar fashion.
Using a parameter of type DBusInterface can cause the automatic creation of a proxy object using introspection. If the remote app does not support introspection, or the object does not exist at the time you receive the message then this will fail. In that case the parameter can be declared to be of type Path. In this case no automatic creation will be performed and you can get the path as a string with either the getPath or toString methods on the Path object.
D-Bus also allows functions to return multiple values, a concept not supported by Java. This has been solved in a fashion similar to the struct, using a Tuple17 class. Tuples are defined as generic tuples which can be parameterised for different types and just need to be defined of the appropriate length. This can be seen in figure 13 and a call in figure 14. Again, these can be automatically generated from introspection data.
import org.freedesktop.dbus.Tuple;
public final class TestTuple<A, B, C> extends Tuple { public final A a; public final B b; public final C c; public TestTuple(A a, B b, C c) { this.a = a; this.b = b; this.c = c; } }
|
public ThreeTuple<String, Integer, Boolean> status(int item);
|
Table 1 contains a full list of all the Java types and their corresponding D-Bus types.
|
Currently the D-Bus reference implementation does not support a native single-precision floating point type. Along with the C# implementation of the protocol, the Java implementation supports this extension to the protocol. By default, however, the library operates in compatibility mode and converts all floats to the double type. To disable compatibility mode export the environment variable DBUS_JAVA_FLOATS=true.