0
votes

I have a JSONValue in my Java that may be a JSONArray, a JSONObject, a JSONString, etc. I want to pass it to a JSNI function that can accept any of those types. If I naively write my JSNI as something like:

public final native jsni(Object parameter) /*-{
    doSomething(parameter);
}-*/;

public void useFunction(JSONValue value) {
    jsni(value);  //Throws js exception at runtime :(
}

then I get a javascript exception, because GWT doesn't know how to convert the JSONValue to a JavaScriptObject (or native string / number value).

My current workaround is

public final native jsniForJSO(Object parameter) /*-{
  doSomething(parameter);
}-*/;

public final native jsniForString(String parameter) /*-{
  doSomething(parameter);
}-*/;

public final native jsniForNumber(double parameter) /*-{
  doSomething(parameter);
}-*/;

public actuallyUseFunction(JSONValue value) {
  if (value.isObject()) {
    jsniForJSO(value.isObject().getJavaScriptObject());
  } else if (value.isString()) {
    jsniForString(value.isString().stringValue());
  } else {
    //etc
  }
}

This is a big burden for code maintainability, etc... especially if you have more than one parameter. Is there a way to generate these functions automatically, or get around this issue altogether? I've taken to wrapping everything in a JSONObject first, so I can definitely get a JavaScriptObject to pass to my jsni, but that's another clumsy mechanic.

1

1 Answers

2
votes

JSONObject is wrapping a native Javascript object, so you have to get that wrapped object before passing it to the jsni method.

  jsni(object.getJavaScriptObject());

Then in your jsni code you could handle the appropriate value:

  public final native jsni(JavaScriptObject parameter) /*-{
     doSomething(parameter.myproperty);
  }-*/;

[EDITED] To get the wrapped object of a JSONValue you have to call its getUnwrapper() method, but it is not public, so you have to call it from your jsni code:

private static native void jsni(JSONValue value) /*-{
  if (value) {
    value =  [email protected]::getUnwrapper()()(value);
    alert(value);
  }
}-*/;