jsr367-experts@jsonb-spec.java.net

[jsr367-experts] Re: Fwd: Re: [jsonb-spec users] Java polymorphism support

From: Romain Manni-Bucau <rmannibucau_at_tomitribe.com>
Date: Mon, 21 Mar 2016 10:16:53 +0100

The adapter idea was:


@Test
public void notYetPloymorphism() { // we run it since it checked
list/item conversion
    final Bar bar = new Bar();
    bar.value = 11;

    final Bar2 bar2 = new Bar2();
    bar2.value = 21;
    bar2.value2 = 22;

    final Polymorphism foo = new Polymorphism();
    foo.bars = new ArrayList<>(asList(bar, bar2));

    final Jsonb jsonb = JsonbBuilder.create(new
JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL));

    final String toString = jsonb.toJson(foo);
    assertEquals("{\"bars\":[" +
            "{\"type\":\"org.apache.johnzon.jsonb.AdapterTest$Bar\",\"value\":{\"value\":11}},"
+
            "{\"type\":\"org.apache.johnzon.jsonb.AdapterTest$Bar2\",\"value\":{\"value\":21,\"value2\":22}}]}",
toString);

    final Polymorphism read = jsonb.fromJson(toString, Polymorphism.class);
    assertEquals(2, read.bars.size());
    assertEquals(11, read.bars.get(0).value);
    assertTrue(Bar.class == read.bars.get(0).getClass());
    assertEquals(21, read.bars.get(1).value);
    /* SPEC LACK for this solution: THIS NEEDS A "FACTORY" BASED ON
JsonObject: <T> T create(JsonObject currentNode); //
currentNode={type, value}

    assertTrue(Bar2.class == read.bars.get(1).getClass());
    assertEquals(22, Bar2.class.cast(read.bars.get(1)).value2);
    */
}

with the model/adapter:



public static class Polymorphism {
    @JsonbTypeAdapter(PolyBarAdapter.class)
    public List<Bar> bars;
}


public static class TypeInstance {
    public String type;
    private Bar value;

    public Bar getValue() {
        return value;
    }

    public void setValue(final Bar value) {
        this.value = value;
    }
}


public static class Bar2 extends Bar {
    public int value2;
}

public static class Bar {
    public int value;
}

public static class PolyBarAdapter implements JsonbAdapter<Bar, TypeInstance> {
    @Override
    public Bar adaptToJson(final TypeInstance obj) throws Exception {
        return obj.value;
    }

    @Override
    public TypeInstance adaptFromJson(final Bar obj) throws Exception {
        final TypeInstance typeInstance = new TypeInstance();
        typeInstance.type = obj.getClass().getName();
        typeInstance.value = obj;
        return typeInstance;
    }
}



The serializer idea is really the jackson one replacing its JsonSerializer
by a new jsonb API mixing jsonp and jsonb:
http://wiki.fasterxml.com/JacksonHowToCustomDeserializers and
http://wiki.fasterxml.com/JacksonHowToCustomSerializers

let me know if anything is unclear


Romain Manni-Bucau
@rmannibucau
http://www.tomitribe.com
http://rmannibucau.wordpress.com
https://github.com/rmannibucau

2016-03-21 8:32 GMT+01:00 Przemyslaw Bielicki <pbielicki_at_gmail.com>:

> Hi,
>
> I'm not a fan of the original idea (and it's an euphemism). Remember that
> JSONB is used to serialize/deserialize DTOs, not domain objects. You should
> have an additional adapter layer to convert DTOs into application's
> business model/domain objects and back.
> Polymorphism is broken (yeah, it's another topic and more philosophic) and
> I would discourage its application in DTO layer. If you have to, you can
> use an enum to mark what's the target class (check JPA for additional
> inspirations). "//javaType": "x.y.z" is really bad idea IMO - what if you
> use the same JSON to communicate with applications developed in .net,
> python, php, c++ at the same time? (yes, it happens). Would you define a
> type for each platform?
>
> If you use DTOs in business layer, you're doing something wrong :)
>
> @Romain, your idea looks interesting, can you show and example or
> deserialization process where polymorphism is involved?
>
> Cheers,
> Przemyslaw
>
> On Sun, Mar 20, 2016 at 10:52 PM, Romain Manni-Bucau <
> rmannibucau_at_tomitribe.com> wrote:
>
>> Hi guys
>>
>> Why not allowing adapters to wrap and unwrap instances but keep
>> serializer mecanism. For serialization no issue but for deserialization we
>> need to switch the deserialized type and then post process the instance -
>> or do it automatically with an Unwrappable interface?
>>
>> Overall idea for this particular use case would be:
>>
>> X ----TypedWrapper(X)----> JSON
>> JSON----TypedWrapper.class----> TypedWrapped ----unwrap----> X
>>
>> Parts in arrows are adapter/jsonb integration.
>>
>> An alternative is to provide to adapters the stream and jsonp instances
>> to do it themself with probably a mapper reference to re(de)serialise an
>> object directly.
>>
>> Wdyt?
>> ---------- Message transféré ----------
>> De : "Romain Manni-Bucau" <rmannibucau_at_tomitribe.com>
>> Date : 19 mars 2016 21:49
>> Objet : Re: [jsonb-spec users] Java polymorphism support
>> À : <users_at_jsonb-spec.java.net>
>> Cc :
>>
>> Hi Sebastian
>>
>> I am not fan of that - Mark knows ;) - and in particular now I'm sure we
>> shouldnt do it: the 0-day vulnerability is still there and you open the
>> door to the same issue or a complicated config adding this feature in
>> something as generic as jsonb.
>> Le 19 mars 2016 21:28, "Sebastian Daschner" <java_at_sebastian-daschner.de>
>> a écrit :
>>
>>> Hi experts,
>>>
>>> I don't know whether this has been discussed in the mailing list before
>>> but a needed functionality would be to specify the Java type of
>>> properties in the serialized JSON.
>>>
>>> As JSON doesn't standardize comments or other "attributes" (like XML
>>> does) a "magic property" could be added.
>>>
>>> Please see the proposal (explored by Mark Struberg, Reinhard Sandtner
>>> and myself) on my blog:
>>>
>>> https://blog.sebastian-daschner.com/entries/json_mapping_polymorphism_support
>>>
>>> WDYT?
>>>
>>>
>>> Cheers,
>>> Sebastian
>>>
>>>
>