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: Romain Manni-Bucau <rmannibucau_at_tomitribe.com>
Date: Wed, 11 May 2016 09:42:09 +0200

@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>:

>
>
> On 05/10/2016 10:50 PM, Romain Manni-Bucau wrote:
>
>
> Le 10 mai 2016 21:37, "Dmitry Kornilov" < <dmitry.kornilov_at_oracle.com>
> 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>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>
> 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>rmannibucau_at_tomitribe.com>:
> >>>>
> >>>>
> >>>> 2016-05-10 15:51 GMT+02:00 Roman Grigoriadi <
> 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>:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> 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>:
> >>>>>>>>>
> >>>>>>>>> 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>:
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>>> 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
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>>
> >>
> >
>
>
>