-
Notifications
You must be signed in to change notification settings - Fork 80
Type mapping
This section provides a definition of the mapping between WebIDL and Java types as used by the Java bridge.
The mapping broadly follows WebIDL, although there are a number of specific differences, and a larger number of omissions. The implementation will be expanded over time, although it is not an explicit objective to create a fully comformant implementation of the WebIDL Java binding.
JavaScript code executing in node.js accesses platform functionality via Java implementations of APIs defined in WebIDL. In WebIDL terminology, the bridge exposes platform objects implemented in Java that are instances of WebIDL interfaces.
Similarly, an interface definition will include one or more interfaces that are annotated with the [Callback] extended attribute that are expected to be implemented as user objects in JavaScript and be passed as arguments from JavaScript to Java.
Instances of interfaces are always passed by reference. Therefore, when a platform object is returned from Java to JavaScript, a JS object is created that wraps that Java instance; actions performed on that JS wrapper are mapped to the operations and attributes of the underlying Java platform object instance. Similarly, when a user object is passed from JS to Java, a Java object is created that wraps, and maintains a reference to, the JS object. Actions on that Java wrapper are mapped back to the corresponding JS instance.
WebIDL also allows for the declaration of dictionaries. These are similar to interfaces (containing attributes but no operations) but dictionaries are passed by value. Therefore, if a dictionary is passed from JS as an argument to an operation on a platform object, then a Java object is created containing the values in the dictionary, but no reference is maintained to the JS dictionary object itself. Similarly, dictionary instances can be passed from Java to JS.
The bridge also supports the passing of primitive types, arrays and sequences, nullable types and DOMStrings as defined in WebIDL (with exceptions and incompatibilities as noted below).
The following WebIDL primitive types are supported, with the corresponding Java type.
WebIDL type | Java type |
any | Object |
boolean | boolean |
byte | Not supported (except as sequence, below) |
octet | Not supported (except as sequence, below) |
[unsigned] short | Not supported (use long) |
long | int |
unsigned long | Not supported - use long or long long as appropriate |
long long | long |
unsigned long long | Not supported - use long long |
float | Not supported - use double |
double | double |
DOMString | Not supported - use DOMString? |
Object | Not supported - use Object? |
boolean? | Boolean |
byte? | Not supported (except as sequence, below) |
octet? | Not supported (except as sequence, below) |
[unsigned] short? | Not supported (use long) |
long? | Integer |
unsigned long? | Not supported - use long? or long long? as appropriate |
long long? | Long |
unsigned long long? | Not supported - use long long? |
float? | Not supported - use double? |
double? | Double |
DOMString? | String |
Object? | Object |
In the Anode Java bridge, an explicit distinction is made at declaration time between interfaces that are implemented as platform objects, and interfaces that are implemented as user objects.
An interface to be implemented by a platform object is mapped to a Java abstract class. Interface inheritance is supported. If an interface A inherits from an interface B, then the Java class implementing A must extend (directly or indirectly) the class implementing B.
The Java class has one public static final field for every constant declared in the interface, whose type must be declared according to the type mapping defined here.
Constant names map directly to field names and there is no mangling or escaping of reserved words or illegal identifiers. Thus, constants whose names are reserved words or are otherwise not legal Java identifiers are not supported.
The Java class has one public field for every attribute declared in the interface, whose type must be declared according to the type mapping defined here.
Static attributes are supported, and map to static fields.
Support for readonly attributes is planned.
Attribute names map directly to field names and there is no mangling or escaping of reserved words or illegal identifiers. Thus, attributes whose names are reserved words or are otherwise not legal Java identifiers are not supported.
The Java class has one public method for every operation declared in the interface. The type of each argument in the Java method is the mapped declared type of the corresponding argument of the IDL operation.
Overloaded operations are not supported. An attempt to call an operation with a number of arguments that is different from the declared operation signature is handled as follows:
- superfluous arguments are discarded;
- unsupplied arguments are coerced from
undefined
to the declared IDL argument type.
Variadic operations are not supported.
Static operations are supported, and map to static methods on the Java class corresponding to the IDL interface declaring the operation.
Special operations are not supported but the following are planned:
-
getters and setters for named properties;
Operation names map directly to method names and there is no mangling or escaping of reserved words or illegal identifiers. Thus, operations whose names are reserved words or are otherwise not legal Java identifiers are not supported.
An interface to be implemented by a user object, and which therefore contains the [Callback]
extended attribute is mapped to a Java interface that extends org.meshpoint.anode.idl.Callback
. Interface inheritance is supported. If an interface A inherits from an interface B, then the Java interface implementing A must extend (directly or indirectly) the interface implementing B.
The Java interface has one public static final field for every constant declared in the interface, whose type must be declared according to the type mapping defined here.
Constant names map directly to field names and there is no mangling or escaping of reserved words or illegal identifiers. Thus, constants whose names are reserved words or are otherwise not legal Java identifiers are not supported.
Since Java interfaces do not support (non-static) fields, attributes are mapped to getter and setter methods using the mapping defined in WebIDL, with the following modifications/caveats:
- all such getter and setter methods must be declared
public
; - the algorithm to avoid collisions between getter/setter name and other interface operations is not supported. Therefore, interfaces that give rise to such collisions are not supported.
Similarly, attributes whose getter or setter names are reserved words or are otherwise not legal Java identifiers are not supported.
Support for readonly attributes is planned.
The Java class has one public method for every operation declared in the interface. The type of each argument in the Java method is the mapped declared type of the corresponding argument of the IDL operation.
Overloaded operations are not supported.
Static operations are not supported.
Operation names map directly to method names and there is no mangling or escaping of reserved words or illegal identifiers. Thus, operations whose names are reserved words or are otherwise not legal Java identifiers are not supported.
WebIDL dictionaries map to Java classes that implement the org.meshpoint.anode.idl.Dictionary
interface. The Java class contains a field for each member declared on the dictionary, whose identifier and type are mapped in the same manner as interface attributes for platform objects.
Dictionaries are passed by value.
Note that this mapping diverges from the standardised mapping for dictionaries specified in the WebIDL Java binding. It is believed that the mapping defined here is more natural and a better fit to the language binding as a whole, providing the benefit of strong typing of dictionary members. However, a side-effect is that in practice dictionary members need to be declared as a nullable type in order that the receiver can determine whether or not the member is present.
Nullable types are mapped generally according to the WebIDL Java binding. Nullable number and boolean types are mapped to their Object counterparts in the java.lang
package. All other IDL types map to Java Object types and are therefore intrinsically nullable.
Note that non-primitive non-nullable types - eg DOMString, Object, Date, as well as interface types are strictly not supported (in the sense that they are always processed as being nullable). Thus, an attempt to pass a null value for an argument declared as non-nullable type will not result in a TypeError but will instead result in the null value being passed as the Java value.
In accordance with the WebIDL Java binding, IDL sequences map to Java arrays. Sequences are always passed by value (even if their underlying type is passed by reference).
The IDL types sequence<byte>
and sequence<octet>
are mapped to Java byte[]
. In all other respects, IDL types byte
and octet
are unsupported.
Otherwise, the type sequence<T>
is supported iff the underlying type T
is supported.
Multidimensional sequences are not supported.
In accordance with the WebIDL Java binding, IDL arrays map to Java objects of a specified type in the org.w3c.dom
package. Arrays are always passed by reference (even if their underlying type is passed by value).
For primitive types, the supported array types are as follows.
WebIDL type | Java type |
sequence | org.w3c.dom.ByteArray |
sequence | org.w3c.dom.ByteArray |
sequence | org.w3c.dom.IntegerArray |
sequence | org.w3c.dom.LongArray |
sequence | org.w3c.dom.DoubleArray |
For object types, the type array<T>
is supported iff the underlying type T
is supported, and maps to the Java type org.w3c.dom.ObjectArray<S>
where S
is the mapped Java type of IDL type T
.
Multidimensional arrays are not supported.
IDL Date
maps to java.util.Date
.