users@jsonb-spec.java.net

[jsonb-spec users] [jsr367-experts] Re: Re: Re: Re: [17-Customizing names]

From: Romain MB <rmannibucau_at_tomitribe.com>
Date: Wed, 13 May 2015 09:15:15 +0200

2015-05-13 8:40 GMT+02:00 Martin Vojtek <voytoo_at_gmail.com>:
> Hi Experts,
>
> we should get some conclusion to this discussion.
>
> I have the following notes:
>
> 1. Nillable, JsonbProperty, JsonbTransient
>
> I don't see any problem adding nillable attribute to JsonbProperty
> annotation. The situation with JsonbTransient is different, because
> transient field is effectively not a JsonbProperty. I think JsonbTransient
> should stay as is.
>

Makes sense +1

> Adding target Property to JsonbProperty makes sense.

+1

>
> 2. Property Naming
>
> I see concept of Mappers equivalent to JsonbAdapter (analogy to XmlAdapter).
> It means that JsonbAdapter should see the context to be able to do complex
> mapping between type and JSON fragment.
>

Makes sense, guess it would use a single generic if designed for
property naming, right?

What would be the context? Class, Type of current "field",
"current"/default name?

> Composition of Mappings looks like an advanced feature and maybe it should
> be postponed to future spec version.
>

if we have JsonbAdapter it is already possible then :).

> WDYT?
>
> 3. Property Order
>
> Case insensitive mapping is special, because it is not 1:1 mapping. To make
> PropertyOrderStrategy simple, it should support only 1:1 mapping. In that
> case PropertyOrderPolicy should not implement PropertyOrderStrategy. I am
> not sure if there is a need to introduce Accessor class. In this case simple
> String -> String mapping (accessor name -> JSON key) should work.
> Implementations could provide some internal mechanism to call this function
> only once per property.
>
> +1 for changing getPropertiesOrder to something immutable like
> Collection/Iterable parameter.
>
> 4. JsonPointer support
>
> @JsonbProperty({"foo", "bar"}) vs @JsonbProperty("/foo/bar")
>
> This should be discussed in separate thread.
>
> 5. Null serialization policy
>
> Replacing enum with JsonbConfig options makes sense. User should be able to
> implement custom null serialization policy for given type with the use of
> JsonbAdapter (not proposed yet).
>
> MartinV
>
> On Wed, Apr 29, 2015 at 10:35 PM, Eugen Cepoi <cepoi.eugen_at_gmail.com> wrote:
>>
>>
>>
>> 2015-04-29 22:18 GMT+02:00 Romain MB <rmannibucau_at_tomitribe.com>:
>>>
>>> 2015-04-29 21:54 GMT+02:00 Eugen Cepoi <cepoi.eugen_at_gmail.com>:
>>> > I think JsonbProperty should accept Parameter as target. This would
>>> > allow to
>>> > use it on constructor parameters (and factory methods).
>>> >
>>> > About all the naming policy, I agre with Romain. We should have an
>>> > interface
>>> > that defines the naming strategy api (convert from one string to
>>> > another or
>>> > from a Method/Field/Param to a String) and provide impls as an enum for
>>> > the
>>> > actual policies.
>>> >
>>> > I don't think NullSerPolicy is useful. IMO it should be an option at
>>> > the
>>> > builder or jsonbconfig level and provide some way to the user to
>>> > implement a
>>> > custom strategy (so a kind of Adapter/Converter/Whatever where he has
>>> > enough
>>> > information to decide how he should ser/de).
>>> >
>>> > In PropertyOrderStrategy we give to the user control to a mutable
>>> > structure
>>> > the array of strings, perhaps we should provide just a
>>> > collection/iterable
>>> > or document that the user can or not modify the original structure.
>>> > Also I
>>> > am not sure there is enough information to sort things properly. For
>>> > example
>>> > the user doesn't know from which class the property comes (ex: A
>>> > extends B,
>>> > does it come from A or B).
>>> >
>>>
>>> That is why a mapping API (class -> Map<String /* json key */,
>>> Accessor> map(Class)) is nice but I agree it is less user friendly
>>> since it mixed 3 concerns (naming, merging and accessibility). We can
>>> of course provide helpers but not sure it is a good idea for a v1.0 of
>>> the API.
>>
>>
>> Mhh I don't like mixing so much things :)
>>
>> I don't know if its "the best" way, but in Genson I have one mechanism for
>> selecting if a property (method/field/param) should be used in ser/de and
>> another one that resolves the name (this is a bit different than a naming
>> strategy where one would translate a string into another one). This allows
>> one to choose what the name should be based on infos like annotations,
>> declaring class, type etc. This is done per "property".
>>
>> Something similar doesn't prevent then having a "renaming" strategy that
>> would take a string (without any other infos) and transform it to another
>> string.
>>
>> The merging stuff is a bit more buried in the internal api as I didn't
>> think people would need easy control over this.
>>
>>>
>>>
>>> > About Nillable, I don't care :) But following the same logic, what
>>> > about
>>> > JsonTransient?
>>> >
>>>
>>> +1 for transient (as annotation or field of property one depending
>>> what we decide here) is important to fully ignore a field.
>>>
>>> > For JsonPointer, Path & cie, jsonp will come with an impl of
>>> > jsonpointer
>>> > over the DOM model. This could make things easier... Also what's the
>>> > advantage of @JsonbProperty({"foo", "bar"}) vs
>>> > @JsonbProperty("/foo/bar") ?
>>> > The sad thing is that I think we can't express something like:
>>> >
>>>
>>> or even foo.bar? just the fact you can use all "single string" naming
>>> as key and not path:
>>
>>
>> Oh I didn't think about this. Naturally I would feel more comfortable to
>> define a path "foo/bar" vs {"foo", "bar"}, but I don't have enough insight
>> into this kind of usage to have a solid opinion :)
>>
>> Side note: I have been hesitant to add something similar in genson for
>> some time, but initially I wanted to provide stuff that worked over streams
>> and not DOM. In practice this gets tricky to implement (even more if you
>> want to support immutable objects) and not flexible (once the stream has
>> been consumed you can't extract properties from it anymore). So in the end
>> relying on what has been done in jsonp could be more pragmatic...
>>
>>>
>>>
>>> { // Map
>>> "/home/rmannibucau/Desktop": "5MB",
>>> "/home/rmannibucau/dev": "65MB"
>>> }
>>>
>>> which is valid to map to:
>>>
>>> public class MyFiles {
>>> @JsonbProperty("/home/rmannibucau/Desktop")
>>> private String desktop;
>>>
>>> @JsonbProperty("/home/rmannibucau/dev")
>>> private String dev;
>>> }
>>>
>>>
>>> > @JsonProperty("/person/childrens/name")
>>> > List<String> childrenNames;
>>> >
>>> > where the json would be
>>> > {
>>> > person {
>>> > childrens: [ {...name: foo}, {...name: bar} ]
>>> > }
>>> > }
>>> >
>>> >
>>> > I agree with Romain about the composition part. This can be pretty
>>> > neat, not
>>> > only for naming but also for property resolution.
>>> >
>>> >
>>> > 2015-04-29 21:08 GMT+02:00 Romain MB <rmannibucau_at_tomitribe.com>:
>>> >>
>>> >>
>>> >> Le 29 avr. 2015 19:18, "Martin Vojtek" <voytoo_at_gmail.com> a écrit :
>>> >> >
>>> >> >
>>> >> >
>>> >> > On Wed, Apr 29, 2015 at 6:56 PM, Romain MB
>>> >> > <rmannibucau_at_tomitribe.com>
>>> >> > wrote:
>>> >> >>
>>> >> >> 2015-04-29 18:30 GMT+02:00 Martin Vojtek <voytoo_at_gmail.com>:
>>> >> >> > Hi,
>>> >> >> >
>>> >> >> > ad 1) interface for PropertyNamingPolicy?
>>> >> >> >
>>> >> >> > I was experimenting with the idea of interface, but there is an
>>> >> >> > open
>>> >> >> > question how to design API to provide support also for the
>>> >> >> > reverse
>>> >> >> > mapping.
>>> >> >> >
>>> >> >> > For example, if I have case insensitive mapping, I need to know
>>> >> >> > how
>>> >> >> > to map
>>> >> >> > from JSON key to field name (in efficient way). I have removed
>>> >> >> > such
>>> >> >> > an
>>> >> >> > interface to see if there is a need for such customization
>>> >> >> > (obviously
>>> >> >> > there
>>> >> >> > is :)).
>>> >> >> >
>>> >> >> > The alternative is to provide mechanism analogical to JAXBAdapter
>>> >> >> > mechanism
>>> >> >> > (or general mapper for given type).
>>> >> >> >
>>> >> >>
>>> >> >> think we can do better than something called each time here. Why
>>> >> >> not
>>> >> >> just a Mapper? String map(Accessor)?
>>> >> >>
>>> >> >
>>> >> > this is mapping from Accessor to JSON. This works in many cases
>>> >> > (like
>>> >> > 1:1), but what about other cases like case insensitive special case?
>>> >> >
>>> >>
>>> >> I would expect to be able to compose them in my code:
>>> >>
>>> >> new MyMapping(DefaultMappings.LEXICOGRAPHIC,
>>> >> DefaultMappings.CASE_INSENSITIVE);
>>> >>
>>> >> The impl being just a chain in this case but could also managed an
>>> >> exclude
>>> >> list to skip JPA state fields for instance - these fields are not in
>>> >> user
>>> >> code so cant be ignored by static code (annotations).
>>> >>
>>> >> > If we agree that this is enough and the special case will be handled
>>> >> > by
>>> >> > JsonbAdapter, that it is ok.
>>> >> >
>>> >> >
>>> >> >>
>>> >> >> > ad 2)
>>> >> >> >
>>> >> >> > The difference between JsonbNillable and JsonbProperty is also in
>>> >> >> > scope. It
>>> >> >> > makes sense to make JsonbNillable property to be available for
>>> >> >> > Type/Package
>>> >> >> > target.
>>> >> >> >
>>> >> >>
>>> >> >> Makes sense but i would still add it in property and keep @Nillable
>>> >> >> for type and packages only.
>>> >> >>
>>> >> >
>>> >> > Don't have strong opinion about this. What others think?
>>> >> >
>>> >> >
>>> >> >>
>>> >> >> > ad 3)
>>> >> >> >
>>> >> >> > Maybe it makes sense to make it more general. What about JSON
>>> >> >> > Pointer?
>>> >> >> >
>>> >> >>
>>> >> >> can make sense but should stay simple/fluent cause it is super
>>> >> >> common
>>> >> >> (github/confluence/...). If you have some pseudo code we can
>>> >> >> discuss
>>> >> >> around I would be more than happy to dig into it.
>>> >> >>
>>> >> >
>>> >> > I was thinking about similar functionality as MOXy XPath provides.
>>> >> >
>>> >> > https://wiki.eclipse.org/EclipseLink/Examples/MOXy/XPath
>>> >> >
>>> >> > JSON-B could support reasonable subset of JSON Pointer to map field
>>> >> > (JavaBean property) to given node.
>>> >> >
>>> >>
>>> >> Let s try it. Maybe needs its own thread then.
>>> >>
>>> >> >>
>>> >> >> > ad ProertyOrderStrategy with enum)
>>> >> >> >
>>> >> >> > no problem to introduce enum. In that case I would also add
>>> >> >> > LEXICOGRAPHICAL,
>>> >> >> > which is default (and slightly different than ALPHABETICAL).
>>> >> >> >
>>> >> >> > MartinV
>>> >> >> >
>>> >> >> >
>>> >> >> > On Wed, Apr 29, 2015 at 6:09 PM, Romain MB
>>> >> >> > <rmannibucau_at_tomitribe.com>
>>> >> >> > wrote:
>>> >> >> >>
>>> >> >> >> Hi
>>> >> >> >>
>>> >> >> >> @JsonbProperty is good to rename a property.
>>> >> >> >>
>>> >> >> >> However I don't like much PropertyNamingPolicy being an enum.
>>> >> >> >> How do
>>> >> >> >> I
>>> >> >> >> do if I want to prefix everything with "mysuperapp_"? I would
>>> >> >> >> use an
>>> >> >> >> interface instead with default implementations (as constants in
>>> >> >> >> Jsonb
>>> >> >> >> or in a DefaultPropertyNamingPolicies enum if you want). This
>>> >> >> >> would
>>> >> >> >> also be consistent with PropertyOrderStrategy (why not having an
>>> >> >> >> enum
>>> >> >> >> with ALPHABETICAL, REFLECTION, REVERSE...)
>>> >> >> >>
>>> >> >> >> I think having nillable as an attribute of @JsonProperty is
>>> >> >> >> maybe
>>> >> >> >> better.
>>> >> >> >>
>>> >> >> >> Now the harder question. Suppose I have this json:
>>> >> >> >>
>>> >> >> >> {
>>> >> >> >> "foo": {
>>> >> >> >> "bar": "dummy"
>>> >> >> >> }
>>> >> >> >> }
>>> >> >> >>
>>> >> >> >> Can I map foo/bar to a field directly? I'm super tempted to
>>> >> >> >> support
>>> >> >> >> it. It means @JsonbProperty needs an array of string instead a
>>> >> >> >> simple
>>> >> >> >> String:
>>> >> >> >>
>>> >> >> >> public class MyBinding {
>>> >> >> >> @JsonbProperty({ "foo", "bar" })
>>> >> >> >> private String bar;
>>> >> >> >> }
>>> >> >> >>
>>> >> >> >> Side note: of course this doesn't prevent simple renaming with
>>> >> >> >> the
>>> >> >> >> same user API as today (speaking about the "look") thanks to
>>> >> >> >> annotations properties:
>>> >> >> >>
>>> >> >> >> public class MyBinding {
>>> >> >> >> @JsonbProperty("foo")
>>> >> >> >> private Foo _foo;
>>> >> >> >> }
>>> >> >> >>
>>> >> >> >> trying to summarize my feedback, here are the points I'd like to
>>> >> >> >> discuss:
>>> >> >> >>
>>> >> >> >> 1) interface for PropertyNamingPolicy?
>>> >> >> >> 2) nillable in @JsonbProperty (means value() would have an empty
>>> >> >> >> default to keep a nice API in all cases)
>>> >> >> >> 3) nested attribute support?
>>> >> >> >>
>>> >> >> >>
>>> >> >> >> Romain Manni-Bucau
>>> >> >> >> @rmannibucau
>>> >> >> >> http://www.tomitribe.com
>>> >> >> >> http://rmannibucau.wordpress.com
>>> >> >> >> https://github.com/rmannibucau
>>> >> >> >>
>>> >> >> >>
>>> >> >> >> 2015-04-29 17:36 GMT+02:00 Martin Vojtek <voytoo_at_gmail.com>:
>>> >> >> >> > Hi Experts,
>>> >> >> >> >
>>> >> >> >> > I have pushed proposal regarding Customizing names.
>>> >> >> >> >
>>> >> >> >> > Short summary:
>>> >> >> >> >
>>> >> >> >> > introduce annotation and enum with most common naming
>>> >> >> >> > policies.
>>> >> >> >> >
>>> >> >> >> > 1. use of javax.json.bind.annotation.JsonbProperty
>>> >> >> >> > 2. using javax.json.bind.config.PropertyNamingPolicy
>>> >> >> >> >
>>> >> >> >> > JsonbProperty annotation is applicable to Field, getter or
>>> >> >> >> > setter.
>>> >> >> >> >
>>> >> >> >> > PropertyNamingPolicy enum contains several different policies
>>> >> >> >> > like
>>> >> >> >> > IDENTITY,
>>> >> >> >> > CASE_INSENSITIVE, LOWER_CASE_WITH_UNDERSCORE ...
>>> >> >> >> >
>>> >> >> >> > Details could be found in specification and in code (api +
>>> >> >> >> > examples).
>>> >> >> >> >
>>> >> >> >> > MartinV
>>> >> >> >> >
>>> >> >> >> >
>>> >> >> >
>>> >> >> >
>>> >> >
>>> >> >
>>> >
>>> >
>>
>>
>