jsr367-experts@jsonb-spec.java.net

[jsr367-experts] Re: [jsonb-spec users] Re: Re: Re: Re: Re: Re: Re: Re: JSONB De/Serializers proposal

From: Roman Grigoriadi <roman.grigoriadi_at_oracle.com>
Date: Wed, 11 May 2016 09:59:13 +0200

Sorry Romain, didn't catch, can you be more specific please? What I was
thinking about is:

class OuterPojo {
   InnerPojo inner;
}

class InnerPojo {
   Date defaultDate;
   @DateFormat("xxxxx")
   Date customDate;
}

Now when user call ctx.deserialzie(Date.class) inside
OuterPojoDeserializer, how would mapper know that processed date field
is inside InnerPojo and it has an annotation provided? Even if I cache
last json key name somewhere during calls to parser.next(), I don't know
the context (a wrapper class).

Roman
On 05/11/2016 09:42 AM, Romain Manni-Bucau wrote:
> @Roman: why wouldn't adapter/(de)serializer active there as requested
> by the user? Only issue is loop which can occur but it is easy to fix
> (you wrap the serializer and if current node == the one you process
> then you ignore it the second time for this node). This means all
> @JsonbXXX are respected for the whole tree.
>
> Does it make sense?
>
>
> Romain Manni-Bucau
> @rmannibucau
> http://www.tomitribe.com
> http://rmannibucau.wordpress.com
> https://github.com/rmannibucau
>
> 2016-05-11 9:31 GMT+02:00 Roman Grigoriadi
> <roman.grigoriadi_at_oracle.com <mailto:roman.grigoriadi_at_oracle.com>>:
>
>
>
> On 05/10/2016 10:50 PM, Romain Manni-Bucau wrote:
>>
>>
>> Le 10 mai 2016 21:37, "Dmitry Kornilov"
>> <dmitry.kornilov_at_oracle.com <mailto:dmitry.kornilov_at_oracle.com>>
>> a écrit :
>> >
>> > Here are my two cents:
>> >
>> > We don’t need any wrappers. It just adds complications to the API.
>>
>> Ok for 1.0. Any way to track it as a backlog in case it comes
>> back later?
>>
>> > I agree to add default JsonbSerializer::isReentrant() method indicating that serializer
>> can be called the recursive way.
>> >
>>
>> This is not needed as mentionned. ConvertDefault is suspicious
>> too IMO and could be removed from both sides (deser/ser).
>>
> Well, maybe convertDefault is not such a good idea. Reason for it
> was separation of mapper serialization/deserialization which
> honors annotation customization and conversion to/from string
> value which doesn't. For example when Date is serialized with
> custom DateFormat, it will fail to be deserialized with
> context.deserialize(Date.class). Why it fails may not be obvious
> to user. ctx.deserialize behaves like deserializing root and have
> no info about level/context of given object inside its wrapper.
> ConvertDefault explicitly says it will convert json value to
> object using default configuration.
>
>> > If it’s OK I’ll consider it as finished. I will commit a
>> modified spec and be ready to submit a public draft at the end of
>> this week.
>> >
>> > Dmitry
>> >
>> >> On 10 May 2016, at 20:05, Romain Manni-Bucau
>> <rmannibucau_at_tomitribe.com <mailto:rmannibucau_at_tomitribe.com>> wrote:
>> >>
>> >> we kind of ack - me being alone ;) - we'll go with jsonp as
>> first class citizen so I guess you are right Eugen. My hope was
>> to wrap jsonp to ensure to the user a unified jsonb view.
>> >>
>> >> Side note on that: anyone knowning from memory if we can
>> access the streamer in jaxb? I don't think so, maybe why I was
>> not shocked to not expose it in jsonb.
>> >>
>> >>
>> >> Romain Manni-Bucau
>> >> @rmannibucau
>> >> http://www.tomitribe.com
>> >> http://rmannibucau.wordpress.com
>> >> https://github.com/rmannibucau
>> >>
>> >> 2016-05-10 19:55 GMT+02:00 Eugen Cepoi <cepoi.eugen_at_gmail.com
>> <mailto:cepoi.eugen_at_gmail.com>>:
>> >>>
>> >>> About using writeName followed by writeXXX: it is prevented
>> by the api. For example the writeValueXXX without the name as
>> parameter can be called only once in the root context or in an
>> array,
>> https://github.com/json-processing-inofficial/jsonp/blob/master/api/src/main/java/javax/json/stream/JsonGenerator.java#L185
>> >>>
>> >>> Indeed we could have a wrapper that does this logic and then
>> does the respective calls to the backed JsonGenerator, but I am
>> not a big fan of this option. It adds another api and feels like
>> a disagreement with what has been done in jsonp (be it good or
>> bad), which I really see as the low level streaming pendent of jsonb.
>> >>>
>> >>>
>> >>>
>> >>>
>> >>> 2016-05-10 7:30 GMT-07:00 Romain Manni-Bucau
>> <rmannibucau_at_tomitribe.com <mailto:rmannibucau_at_tomitribe.com>>:
>> >>>>
>> >>>>
>> >>>> 2016-05-10 15:51 GMT+02:00 Roman Grigoriadi
>> <roman.grigoriadi_at_oracle.com <mailto:roman.grigoriadi_at_oracle.com>>:
>> >>>>>
>> >>>>>
>> >>>>>
>> >>>>> On 05/10/2016 03:37 PM, Romain Manni-Bucau wrote:
>> >>>>>>
>> >>>>>>
>> >>>>>> 2016-05-10 15:26 GMT+02:00 Roman Grigoriadi
>> <roman.grigoriadi_at_oracle.com <mailto:roman.grigoriadi_at_oracle.com>>:
>> >>>>>>>
>> >>>>>>>
>> >>>>>>>
>> >>>>>>> On 05/10/2016 08:14 AM, Romain Manni-Bucau wrote:
>> >>>>>>>>
>> >>>>>>>> Ok, let step back. Before all *technically* I fully
>> agree with you. Why I defend a different position is from my
>> experience a lot of people will not be able to use such an API so
>> i'm trying to ensure our API is adopted whatever use case we support.
>> >>>>>>>
>> >>>>>>> Whats wrong with JsonParser API from user perspective? If
>> JsonStructure is needed instead of event driven api, it can be
>> provided by mapper API (as Eugene mentioned). JsonParser will be
>> at START_OBJECT position when passed to deserializer, so user can
>> get JsonStructure for whole deserializer root/return type.
>> Furthermore, according to JSONP master branch, looks like there
>> will be methods for getting JsonArray/JsonObject directly on
>> JsonParser since JSONP 1.1 release.
>> >>>>>>>>
>> >>>>>>>>
>> >>>>>>
>> >>>>>> Proposal is just to add an abstract child already
>> doing context.deserialize(JsonObject.class, parser) and giving as
>> parameter the JsonObject instead of the parser. Making it direct
>> and not requiring users to look for this or to know they have to
>> pass JsonObject.class as parameter is good enough.
>> >>>>>
>> >>>>> But wouldn't it be redundant after JSONP 1.1, which has
>> those already in JsonParser?
>> >>>>>>
>> >>>>>>
>> >>>>
>> >>>>
>> >>>> Maybe but it doesn't cost much and makes it an easier entry
>> point for several users so I think it does worth it.
>> >>>>
>> >>>>>>>>
>> >>>>>>>> Secondly the fact jsonp doesnt support
>> writeKey()writeValue() doesnt prevent us to do it (we actually do
>> since we have the key before the value in the mapper model ;)).
>> >>>>>>>
>> >>>>>>> Didn't get this one, we do writeStartObject(String key),
>> and writeEndObject() in the mapper.
>> >>>>>>>
>> >>>>>>
>> >>>>>> In the API or the impl? Globally point is we can support a
>> single serialize method as mentionned by Eugen.
>> >>>>>
>> >>>>> Ok, I missed the point.
>> >>>>>
>> >>>>>>
>> >>>>>>>>
>> >>>>>>>>
>> >>>>>>>> It means I think we can go for Eugen proposal BUT to
>> support my case too we would need a subclass/abstract impl giving
>> the JsonReader (read(parser, Object) doesn't work, see
>> polymorphism thread).
>> >>>>>>>>
>> >>>>>>>> Would it be a good compromise?
>> >>>>>>>>
>> >>>>>>>>
>> >>>>>>>>
>> >>>>>>>> Romain Manni-Bucau
>> >>>>>>>> @rmannibucau
>> >>>>>>>> http://www.tomitribe.com
>> >>>>>>>> http://rmannibucau.wordpress.com
>> >>>>>>>> https://github.com/rmannibucau
>> >>>>>>>>
>> >>>>>>>> 2016-05-10 0:46 GMT+02:00 Eugen Cepoi
>> <cepoi.eugen_at_gmail.com <mailto:cepoi.eugen_at_gmail.com>>:
>> >>>>>>>>>
>> >>>>>>>>> Ahh damn I remember now... in jsonp we have a separate
>> methods to be used inside objects which takes the key and others
>> without the key, but you can't first write the key and then write
>> the value...which sucks. I should have insisted more on that :p
>> >>>>>>>>>
>> >>>>>>>>> So in short my comment is irrelevant as I was assuming
>> that we have writeName+writeValue methods in JsonGenerator...so
>> yeah in this case there is no choice, we need serialize methods
>> that take a key and another that doesn't... :(
>> >>>>>>>>>
>> >>>>>>>>> 2016-05-09 15:22 GMT-07:00 Dmitry Kornilov
>> <dmitry.kornilov_at_oracle.com <mailto:dmitry.kornilov_at_oracle.com>>:
>> >>>>>>>>>>
>> >>>>>>>>>>
>> >>>>>>>>>>>> I also think that passing jsonp parser/generator as
>> an argument is OK. The question here is that we are forcing
>> implementations to use parser/generator. What if (as Romain
>> mentioned somewhere in this thread) some implementations will use
>> reader/writer as a parsing mechanism? Shall we consider this
>> option? Folks, I need you opinion here.
>> >>>>>>>>>>>>
>> >>>>>>>>>>>
>> >>>>>>>>>>> JsonReader/writer just deal with the full dom
>> structures, to get a dom structure one could simply do
>> ctx.deserialize(JsonObject.class, stream).
>> >>>>>>>>>>> So I think it is just fine and is the right thing to
>> do: use the low level jsonp api.
>> >>>>>>>>>>
>> >>>>>>>>>>
>> >>>>>>>>>> Agree.
>> >>>>>>>>>>
>> >>>>>>>>>>>> But there is another use case. What if we have a
>> list inside an object we are serializing.
>> >>>>>>>>>>>>
>> >>>>>>>>>>>> public class Create {
>> >>>>>>>>>>>> public List items;
>> >>>>>>>>>>>> }
>> >>>>>>>>>>>>
>> >>>>>>>>>>>> For some reason we don’t want to serialize items
>> list using context.serialize(“items”, crate.items, generator).
>> >>>>>>>>>>>> We want to serialize each item manually in a cycle.
>> >>>>>>>>>>>>
>> >>>>>>>>>>>> generator.writeStartArray();
>> >>>>>>>>>>>> for (Object item in crate.items) {
>> >>>>>>>>>>>> // Ooops! We don’t have a method to write an object
>> without a key in SerializationContext
>> >>>>>>>>>>>> // It should be something like this
>> >>>>>>>>>>>> context.serialize(item, generator); // This is a new
>> method to add I was talking about
>> >>>>>>>>>>>> }
>> >>>>>>>>>>>> generator.writeEnd();
>> >>>>>>>>>>>>
>> >>>>>>>>>>>
>> >>>>>>>>>>> Not sure if I followed everything (I have been busy
>> with other things lately), but IMO the context should not provide
>> different methods for arrays, objects etc. Only one that takes an
>> object, a generator and eventually a type (if we want to allow a
>> user to say serialize object of type B but using his super type
>> A). One could pass to it arrays, lists, pojos, primitives,
>> whatever he wants and it will get serialized/deser using the
>> registered serializers for that type.
>> >>>>>>>>>>> I hope I am not adding more confusion here…if you
>> want some code examples let me know.
>> >>>>>>>>>>
>> >>>>>>>>>>
>> >>>>>>>>>> Yes, I think we have some misunderstanding here. Below
>> I copied our latest version of SerializationContext interface to
>> make it clear. As you see there are no methods for arrays, lists,
>> etc. The method I was talking about above is marked bold.
>> >>>>>>>>>>
>> >>>>>>>>>> public interface SerializationContext {
>> >>>>>>>>>>
>> >>>>>>>>>> /**
>> >>>>>>>>>> * Serializes arbitrary object to JSON, using
>> current {_at_link javax.json.stream.JsonGenerator} instance.
>> >>>>>>>>>> *
>> >>>>>>>>>> * @param key JSON key name
>> >>>>>>>>>> * @param object object to serialize
>> >>>>>>>>>> * @param generator JSONP generator to serialize with
>> >>>>>>>>>> * @param <T> Type of serialized object
>> >>>>>>>>>> */
>> >>>>>>>>>> <T> void serialize(String key, T object, JsonGenerator
>> generator);
>> >>>>>>>>>>
>> >>>>>>>>>> /**
>> >>>>>>>>>> * Serializes arbitrary object to JSON, using
>> current {_at_link javax.json.stream.JsonGenerator} instance.
>> >>>>>>>>>> *
>> >>>>>>>>>> * @param object object to serialize
>> >>>>>>>>>> * @param generator JSONP generator to serialize with
>> >>>>>>>>>> * @param <T> Type of serialized object
>> >>>>>>>>>> */
>> >>>>>>>>>> <T> void serialize(T object, JsonGenerator generator);
>> >>>>>>>>>>
>> >>>>>>>>>> /**
>> >>>>>>>>>> * Converts string value into provided type.
>> String value has to be single JSON value, not a part
>> >>>>>>>>>> * of a JSON document representing JSON object.
>> >>>>>>>>>> *
>> >>>>>>>>>> * @param obj object to convert to string
>> >>>>>>>>>> * @param generator JSONP generator to serialize with
>> >>>>>>>>>> * @param <T> type of object
>> >>>>>>>>>> *
>> >>>>>>>>>> * @return converted string value
>> >>>>>>>>>> * @throws javax.json.bind.JsonbException if
>> conversion of given type is not supported
>> >>>>>>>>>> */
>> >>>>>>>>>> <T> String convertDefault(T obj, JsonGenerator generator);
>> >>>>>>>>>> }
>> >>>>>>>>>>
>> >>>>>>>>>> Thanks,
>> >>>>>>>>>> Dmitry
>> >>>>>>>>>>
>> >>>>>>>>>
>> >>>>>>>>
>> >>>>>>>
>> >>>>>>
>> >>>>>
>> >>>>
>> >>>
>> >>
>> >
>>
>
>