How to properly implement JSObject to provide conversion of Gson JsonElement objects?
Daniel Einspanjer
deinspanjer at gmail.com
Tue May 30 16:34:44 UTC 2017
Thank you, yes that is very similar to the approach I went down.
Ultimately I hit another roadblock that forced me to approach the entire
issue differently. The JS library I am interacting with uses Object.keys()
and currently, Nashorn doesn't support Object.keys() calls with custom
JSObjects. I filed an RFE for that, but due to the issue, I'm having to
avoid using JSObject entirely.
Thanks again for your reply.
-Daniel
On Tue, May 30, 2017 at 12:29 PM Jesse Schulman <jesse at dreamtsoft.com>
wrote:
> If you haven't got this working yet, one possible solution is to return
> anonymous inner AbstractJSObject that returns true for isFunction calls:
>
> public Object getMember(String name) {
> if ("map".equals(name)) {
> return new AbstractJSObject() {
> @Override
> public Object call(Object thiz, Object... args) {
> // delegate to your JsonArray.map method from this
> annonymous inner class
> // in your example nashorn should pass you a single
> instance of ScriptObjectMirror for args that returns true for isFunction()
> call
> }
>
> @Override
> public boolean isFunction() {
> return true;
> }
> };
> }
>
> return null;
> }
>
>
> Hope that helps!
> Jesse
>
> On Thu, May 25, 2017 at 1:11 PM Daniel Einspanjer <deinspanjer at gmail.com>
> wrote:
>
>> I have a project that makes extensive use of the Google Gson library.
>>
>> In this particular case, I have a JsonArray object (which implements
>> iterable) containing a collection of objects. In pure JSON it would look
>> like this:
>>
>> [ 1, true, {"a": "b"}, [1,2] ]
>>
>> In Gson JsonElements, it looks like this:
>>
>> arr = new JsonArray();
>> arr.add(1);
>> arr.add(true);
>>
>> obj = new JsonObject();
>> obj.addProperty("a", "b");
>>
>> arr.add(obj);
>>
>> innerArr = new JsonArray();
>> innerArr.add(1);
>> innerArr.add(2);
>>
>> arr.add(innerArr);
>>
>> I am calling a Javascript function in Nashorn that is trying to do a map
>> over this array:
>>
>> nash.eval("function doIt(arr) { print(arr.map(function(item) { return
>> (typeof item); })); }");
>>
>> So, in order for this to work with my own arbitrary object (JsonArray), I
>> believe I need to implement JSObject.
>>
>> I created the wrapper class that implements it, using the underlying
>> JsonArray object as a delegate. things like isArray() and such are
>> trivial, but I'm having trouble with the map.
>> I have a map method that takes a functional interface which is available
>> for the JsonArray object.
>>
>> Nashorn calls getMember("map") when the doIt function is executed. I
>> cannot figure out how to give it an appropriate function reference to my
>> JsonArray.map method.
>> I was able to handle getMember("toString") easily enough, but the problem
>> is that method doesn't take any arguments, so returning a simple
>> Callable<Object> is fine for it, but map is going to take arguments that I
>> don't know about ahead of time.
>>
>> I would really appreciate some assistance here. Thanks.
>>
>> -Daniel
>>
>
More information about the nashorn-dev
mailing list