I am still new to GWT (so this code is probably naive), but I implemented 
this JSON parse wrapper which performs "transparent" conversion of JS 
arrays to java.util.List and using replacer/reviver functions:
https://github.com/bpilot/jclosure/blob/master/src/main/java/ailabs/jclosure/client/encoding/json/JsonParser.java

Could this be made more general?


On Wednesday, May 10, 2017 at 11:40:53 AM UTC-4, Marcin Okraszewski wrote:
>
> I've done something that I think is so far the closest to what I want to 
> achieve - the same object behaving as List in Java and as array in JS. 
> Actually it can be seen in Java as either list or array - both work :-)
>
> First I declare JsArray:
>
> @JsType(isNative=true, name="Array", namespace=JsPackage.GLOBAL)
> public class JsArray<E> {
>   // JS method declarations here, but can be also empty
> }
>
>
> Then extend create a List that extends the JsArray
>
> @JsType
> public class JsArrayList<E> extends JsArray<E> implements List<E> {
>   // List implementation here
> }
>
>
> Now, parse JSON and replace arrays with instances of JsArrayList.
>
> private static native <T> T parse(String json) /*-{
> return JSON.parse(json, function(key, value) {
> if (Array.isArray(value)) {
> var arrayList = new @interop.client.JsArrayList::new();
> Array.prototype.push.apply(arrayList, value);
> value = arrayList;
> }
> return value;
> });
> }-*/;
>
> Now, if the JSON includes any array, you will be able to use in Java as 
> List.
>
> Problems so far:
>
>    1. All elements of the array need to be copied. I was tempted to just 
>    change __proto__ with the one from JsArrayList, but that is said to affect 
>    performance. I could also add methods from JsArrayList to the instance, 
> not 
>    sure if that is better from performance standpoint. 
>    2. The extended array is not recognized as an array in JS (although it 
>    behaves as array). Array.isArray() returns false, same for instanceof 
>    Array. I guess, adding functions to array instance would solve it. 
>    3. While parsing metadata are missing, what actual type should that 
>    be. Switching arrays to list is a decision without context. But when we 
>    want to treat an object as map, then it would need to be known somehow. It 
>    can be naming convention of fields, but it is not perfect; could not 
>    supported nested collections. Some meta provided from the interface that 
> is 
>    being cased, would be great. 
>
> Do you have any thoughts on that maybe?
>
> Thank you,
> Marcin
>
>
> On Wednesday, 10 May 2017 01:19:58 UTC+2, Ray Cromwell wrote:
>>
>> I think it would be better to use a JsArrayListAdapter in order to 
>> prevent making copies all over the place, and also making mutations 
>> write-through on both sides e.g.
>>
>> public class JsArrayListAdapter<T> extends AbstractList<T> {
>>    public JsArrayListAdapter(ArrayLike<T> blah) {
>>       this.array = blah;
>>   }
>>
>>   // implement List methods to delegate to Array methods
>> }
>>
>> To keep referential integrity, you need to use an expando or ES6 Symbol 
>> property to hide a backreference.
>>
>> That is, JsArrayListAdapter.wrap(nativeJsArray) == 
>> JsArrayListAdapter.wrap(nativeJsArray2) IFF nativeJsArray == nativeJsArray2.
>>
>> This technique is less error prone IMHO if you are going to have mutable 
>> objects. If you're using immutables, then making copies is superior.
>>
>>
>>  
>>
>>
>> On Tue, May 9, 2017 at 3:24 PM 'Goktug Gokdogan' via GWT Contributors <
>> [email protected]> wrote:
>>
>>> Yes, theoretically you should be able to use the second parameter on 
>>> Json.parse Json.stringify for conversion back and forth between java 
>>> collections and js primitives. In this model, your javascript code needs to 
>>> use Java collection APIs.
>>>
>>> > java.util.Arrays.asList() should be enough
>>>
>>> keep in mind that Arrays.asList won't let you go out of bounds.
>>>
>>>
>>>
>>> > I believe it was in plans with @JsConvert
>>>
>>>
>>> We are not working on @JsConvert right now. JsConvert is just 
>>> convenience and you can mimic it:
>>>
>>>
>>>   @JsType(isNative=true)
>>>   interface MyType {
>>>      @JsConvert(ListConverter.class)
>>>      List getMyArray()
>>>      void setMyArray(@JsConvert(ListConverter.class) List array)
>>>   }
>>>
>>> is roughly equivalent to:
>>>
>>>   @JsType(isNative=true)
>>>   interface MyType {
>>>      @JsProperty(name="myArray")
>>>      Object[] getMyArrayInternal();
>>>
>>>      @JsOverlay
>>>      default List getMyArray() { return Arrays.asList(getMyArray()); }
>>>
>>>      @JsProperty(name="myArray")
>>>      void setMyArrayInternal(Object[] array);
>>>
>>>      @JsOverlay
>>>      default void setMyArray(List list) {
>>>        setMyArrayInternal(array.toArray());
>>>      }
>>>   }
>>>
>>>
>>> On Tue, May 9, 2017 at 9:32 AM, Thomas Broyer <[email protected]> wrote:
>>>
>>>>
>>>>
>>>> On Tuesday, May 9, 2017 at 4:34:48 PM UTC+2, Marcin Okraszewski wrote:
>>>>>
>>>>> There is indeed something in it. Actually you could have some type of 
>>>>> naming convention, like in TJSON (
>>>>> https://tonyarcieri.com/introducing-tjson-a-stricter-typed-form-of-json) 
>>>>> or TypedJson (https://www.npmjs.com/package/typed-json) to figure out 
>>>>> proper types. But then I would need to create eg. ArrayList with the 
>>>>> Manuel's trick (the asList() from Polymer). I'll test it. 
>>>>>
>>>>
>>>> java.util.Arrays.asList() should be enough actually: 
>>>> https://github.com/gwtproject/gwt/blob/2.8.1/user/super/com/google/gwt/emul/java/util/Arrays.java#L136
>>>>  
>>>> (note that the ArrayList there is not java.util.ArrayList, it's an 
>>>> internal 
>>>> java.util.Arrays.ArrayList class that directly wraps the array with no 
>>>> copy).
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "GWT Contributors" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to 
>>>> [email protected].
>>>> To view this discussion on the web visit 
>>>> https://groups.google.com/d/msgid/google-web-toolkit-contributors/95e1bd43-b4a6-4b2d-bd89-6cc6fb206631%40googlegroups.com
>>>>  
>>>> <https://groups.google.com/d/msgid/google-web-toolkit-contributors/95e1bd43-b4a6-4b2d-bd89-6cc6fb206631%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "GWT Contributors" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected]
>>> .
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/google-web-toolkit-contributors/CAN%3DyUA0Wr0pWKUcqyN2YMkuoZZK7b3e-ipm7jqv2DdDeqk8sMA%40mail.gmail.com
>>>  
>>> <https://groups.google.com/d/msgid/google-web-toolkit-contributors/CAN%3DyUA0Wr0pWKUcqyN2YMkuoZZK7b3e-ipm7jqv2DdDeqk8sMA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-web-toolkit-contributors/651f6423-853c-4c25-9b92-86d8ab711067%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to