From Java interfaces to a JavaScript API using JIDL and WebVM
JIDL is a tool of the WebVM SDK which generates native module stub code out of Java interfaces in order to expose similiar API into JavaScript by using the WebVM browser plugin. It also generates OpenAjax Metadata Specification files, though it doesn’t process them as input format yet.
Java interface
Imagine the following two Java interfaces:
public interface TestInterface {
public int getInt();
public int[] getIntArray();
public TestInterface2 getTestInterface2();
public void setTestInterface2(TestInterface2 test2);
public int add(int x, int y);
}
import java.util.Hashtable;
public interface TestInterface2 {
public String getString();
public void setMap(Hashtable table);
}
JavaScript representation
The above interfaces describe the following JavaScript API:
var ob = webvm.load("TestInterface");
var i = ob.getInt();
var arr[] = ob.getIntArray();
var ob2 = ob.getTestInterface2();
var ob3 = { getString: function() { return "JS String" }, setMap: function(x) { } };
ob.setTestInterface2(ob3);
var str = ob2.getString();
Generating native module stubs from Java interfaces
In order to generate native WebVM module stubs, the JIDL tool from the WebVM SDK should be used. It can be found in the directory
webvm-sdk-dir/tools
To generate native module implementation stubs for given Java interfaces, it is assumed that the class files of these interfaces are relative to the current directory. The first step is compiling class files from Java interface descriptions:
javac TestInterface.java
javac TestInterface2.java
Then JIDL can be used to generate the native module stubs:
mkdir result
java -jar jidl.jar result TestInterface TestInterface2
Afterwards there will be
result/TestInterface_decl.h
result/TestInterface_decl.c
result/TestInterface_impl.c
result/TestInterface2_decl.h
result/TestInterface2_decl.c
result/TestInterface2_impl.c
All files need to be included into your native module project, and only the _impl.c postfixed file needs to be edited in order to implement the interface.
A native module will also need an implementation of the entry points as follows:
#include "result/TestInterface_decl.h"
#include "result/TestInterface2_decl.h"
typedef struct {
WVMCallbackFuncs *wvcf;
WVMObjectReference scriptableObjectRef;
} Instance;
static WVMClassSpec *classes[] = { &TestInterfaceClass, &TestInterface2Class };
static WVMStatus init(WVM /* [in] */ *instance,
UInt16 /* [out] */ *classSpecCount,
WVMClassSpec /* [out] */ ***classSpecs)
{
*classSpecCount = 2;
*classSpecs = classes;
return OK;
}
static void deinit(WVM /* [in] */ *instance) {
}
static WVMStatus start(WVM /* [in] */ *instance) {
WVMStatus result;
Instance *inst = (Instance *)instance->mData;
result = inst->wvcf->createObjectRef(instance, classes[0], NULL, &inst->scriptableObjectRef);
if(result == OK) {
result = inst->wvcf->setScriptableObject(instance, inst->scriptableObjectRef);
}
return result;
}
static WVMStatus stop(WVM /* [in] */ *instance) {
Instance *inst = (Instance *)instance->mData;
return inst->wvcf->destroyObjectRef(instance, inst->scriptableObjectRef);
}
/****************************************************************************
* Module entry/exit functions
****************************************************************************/
WVMStatus WVMAttach(WVM /* [in] */ *instance,
WVMCallbackFuncs /* [in] */ *wvcFuncs,
WVMModuleFuncs /* [out] */ **wvmFuncs)
{
static WVMModuleFuncs wvmf = {
sizeof(WVMModuleFuncs),
{ WEBVM_VERSION_MAJOR, WEBVM_VERSION_MINOR },
init,
deinit,
start,
stop,
};
Instance *inst = NULL;
if(wvcFuncs->version.major < WEBVM_VERSION_MAJOR
|| (wvcFuncs->version.major == WEBVM_VERSION_MAJOR
&& wvcFuncs->version.minor < WEBVM_VERSION_MINOR))
{
return Error_Unsupported;
}
if(!(inst = (Instance *)malloc(sizeof(Instance)))) {
return Error_Mem;
}
inst->wvcf = wvcFuncs;
*wvmFuncs = &wvmf;
instance->mData = inst;
return OK;
}
void WVMDetach(WVM /* [in] */ *instance) {
Instance *inst = (Instance *)instance->mData;
free(inst);
instance->mData = NULL;
}
const char *WVMGetProperty(const char /* [in] */ *key) {
if(!strcmp(key, "vendor")) {
return "YOUR COMPANY";
}
else if(!strcmp(key, "copyright")) {
return "YOUR COPYRIGHT";
}
else if(!strcmp(key, "version")) {
return "YOUR VERSION";
}
else if(!strcmp(key, "description")) {
return "YOUR DESCRIPTION";
}
return NULL;
}