OK in this case we can replace Java FQCN with an enum which would be more
elegant.
Is there a specific need for using PropertyOrderStrategy.LEXICOGRAPHICAL?
Anyway, I'm not convinced this is necessary - it's a very simple example,
yet quite complex solution.
On Mon, Mar 21, 2016 at 10:16 AM, Romain Manni-Bucau <
rmannibucau_at_tomitribe.com> wrote:
> 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
>>>>
>>>>
>>
>