users@jsonb-spec.java.net

[jsonb-spec users] [jsr367-experts] Re: Re: Re: Polymorphic deserializer

From: Romain Manni-Bucau <rmannibucau_at_tomitribe.com>
Date: Tue, 10 May 2016 16:48:58 +0200

it shouldn't loop since it is not working on the same instance so at some
point you will stop (or you have a cycle which is something else but not
possible in plain JSON on deserialization - without references I mean).



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

2016-05-10 16:47 GMT+02:00 Roman Grigoriadi <roman.grigoriadi_at_oracle.com>:

> But what if root is a part of deserialized subpart of the tree?
>
> class Part {
> ...
> List<Subpart>
> }
>
> class Subpart {
> ...
> Part child;
> }
>
> now in PartDeserializer you call ctx.deserialize( new
> TokenImpl<List<Subpart>>() {}.getRuntimeType()) ?
>
> On 05/10/2016 04:29 PM, Romain Manni-Bucau wrote:
>
> case I had in mind was when you only deserialize a subpart of the tree and
> not the root directly. At each level you can prevent to re-enter in the
> same deserializer but you can need it later in the tree.
>
>
> Romain Manni-Bucau
> @rmannibucau
> http://www.tomitribe.com
> http://rmannibucau.wordpress.com
> https://github.com/rmannibucau
>
> 2016-05-10 16:02 GMT+02:00 Roman Grigoriadi <roman.grigoriadi_at_oracle.com>:
>
>> Is there a usecase where you actually may need reentrant deserialize()
>> calls, with recursive models?
>>
>> When you call context.deserialize() inside deserializer, even for other
>> type than deserializer return type, you may still encounter deserialization
>> into return type of deserializer inside.
>>
>> Roman
>>
>>
>> On 05/10/2016 03:49 PM, Romain Manni-Bucau wrote:
>>
>> Hi Roman,
>>
>> We encountered it in johnzon when Mark implemented it. We chose to just
>> prevent these loops since they can easily be detected at framework level
>> but not expose it to the end user.
>>
>> typically in your code it would be:
>>
>> ctx.deserialize(clazz, parser) { // pseudo code
>>
>> return this.deserialize(clazz, parser, <ignore PolymorphicDeserializer for root level *only*>);
>>
>> }
>>
>> Note: in this snippet it would be great to not require the hasNext to be called (ie if called ok but if not then deserialize can do it).
>>
>>
>>
>>
>> Romain Manni-Bucau
>> @rmannibucau
>> http://www.tomitribe.com
>> http://rmannibucau.wordpress.com
>> https://github.com/rmannibucau
>>
>> 2016-05-10 15:42 GMT+02:00 Roman Grigoriadi <
>> <roman.grigoriadi_at_oracle.com>roman.grigoriadi_at_oracle.com>:
>>
>>> According to polymorphic deserialization, which was one of the usecases
>>> for deserializers, I encountered the fact, that if context.deserialize() is
>>> called inside the deserializer for the type that is the return type for
>>> that deserializer, jsonb runtime will try to use such deserializer again
>>> inside. Example:
>>>
>>> public class PolymorphicDeserializer implements JsonbDeserializer<Animal> {
>>> @Override public Animal deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
>>> Class<? extends Animal> clazz = null;
>>>
>>> while (parser.hasNext()) { //some code to get class, which will result to subclass of an Animal //... //following will cause adding PolymorphicDeserializer instance to call stack again, calling deserialize on it
>>> return ctx.deserialize(clazz, parser); //--- REENTRANT CALL---
>>> }
>>> throw new IllegalStateException("animal not found!");
>>> }
>>> }
>>>
>>> Looks like this is correct behaviour, JSONB runtime has deserializer
>>> registered for it. Without some kind of parameter flag it has no clue not
>>> to use it. How about adding default to true method "boolean isReentrant()"
>>> to JsonbDeserializer interface?
>>>
>>> Thanks,
>>> Roman
>>>
>>
>>
>>
>
>