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] <javascript:>> 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] 
>> <javascript:>> 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] 
>>> <javascript:>.
>>> 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] 
>> <javascript:>.
>> 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/aaa3bc31-2622-42ce-b9b6-e518638dd4e6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to