johnzon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Romain Manni-Bucau <rmannibu...@gmail.com>
Subject Re: User Question: Complex Adapters
Date Tue, 01 Oct 2019 16:23:56 GMT
Assuming last spec is JSON-B ;)

A few points to maybe be more accurate in the sample:

1. You can map root level object but Arne fixed some cases in 1.2.1, not
1.2.0
2. If you dont have a valid constructor it is undefined if it must be
supported - I am assuming it is not and think it is not doable in johnzon
currently



Le mar. 1 oct. 2019 à 17:39, Markus Karg <karg@quipsy.de> a écrit :

> Romain,
>
> thank you for this interesting analysis! In fact I think the cause is
> actually more simple and has nothing to do with cardinality, Map or
> Map.Entry etc.: It is impossible to use Adapters on the top level OR
> adapters must not adapt upon custom types (even when they are mappable)!
>
> Proof see below. Question: Is that wanted by JSON-B spec or is that a bug
> in Johnzon?
>
>  public static void main(String[] a) {
>       // Should parse JSON to Foo, then map Foo to Bar, but actually tries
> to parse JSON to Bar directly, IGNORING the mapper!
>       JsonbConfig jsonbConfig = new JsonbConfig().withAdapters(new
> FooBarMapper());
>       Jsonb jsonb = JsonbBuilder.create(jsonbConfig);
>       System.out.println(jsonb.fromJson("{ }", Foo.class)); // works well
> :-)
>       System.out.println(jsonb.fromJson("{ }", Bar.class)); //
> FooBarMapper is NOT invoked -> Johnzon tries to create Bar instance :-(
> }
>
> public static class Foo { }
>
> @JsonbTypeAdapter(FooBarMapper.class) private static class Bar {
>     Bar(int jsonCannotCallThis) { }
> }
>
> public static class FooBarMapper implements JsonbAdapter<Bar, Foo> {
>         @Override public Foo adaptToJson(Bar obj) throws Exception {
> return new Foo(); }
>         @Override public Bar adaptFromJson(Foo obj) throws Exception
> {return new Bar(1); }
>     }
>
> I know, I can solve with a Deserializer. What I like to reach is to
> clarify whether this is a bug in Johnzon (so we need to fix it) or whether
> this is as wanted by JSON-P spec, so we should improve the JavaDocs there.
> :-)
>
> -Markus
>
>
> -----Ursprüngliche Nachricht-----
> Von: Romain Manni-Bucau <rmannibucau@gmail.com>
> Gesendet: Dienstag, 1. Oktober 2019 16:50
> An: dev@johnzon.apache.org
> Betreff: Re: User Question: Complex Adapters
>
> Le mar. 1 oct. 2019 à 16:36, Markus Karg <karg@quipsy.de> a écrit :
>
> > Romain,
> >
> > thanks for your ideas. As always, they are very valueable. 😊
> >
> > I assume that a Deserializer would actually work and *workaround* the
> > current problem (which is fine for now). But my question really is:
> > Isn't the word "cardinality" missing in the Spec then? And what if I
> > actually want to map a collection to an int by let's say return the
> > count of ist entries... (yes, hypothethical, just to make you
> > understand my point: this is nowhere forbidden by the spec)?
> >
>
> Well spec explains how  a map is mapped not how a nested object of an
> object is automatically mapped so it sounds explicitly not handled to me.
>
>
>
> > The container level actually is there, but not visible to Johnzon: The
> > adapter actually does the cardinality change in its *implementation*
> > (not in its *declaration*), as it simply picks the first entry in the
> > map. In fact I do not find anything in JSON-B spec nor JavaDocs that
> > both sides of the adapter MUST have the same cardinality, as the spec
> > and JavaDocs for adapters *just* say that any umappable class has to
> > be adapted to "just some" mappable class (without a word about
> > cardinality) -- and Map apparently *is* "just some" mappable class.
> >
>
> It is not needed but your Entry has no link with the json so it would fail
> anyway.
>
> Note that the underlying is not cardinality but object mapping (and 100%
> relies on the signatures in jsonb - johnzon has a programmatic alternative
> but it is not needed here).
>
> I suspect here the map type is the issue since it is handled ad-hoc and
> bypasses adapters.
>
> We could add a toggle to disable that since spec does not say anything on
> that but we would keep current behavior until the johnzon toggle is enabled
> for compatibility reasons (we just did a 1.2, i prefer to avoid a 1.3 less
> than a month after ;)).
>
>
> > Wdyt?
> >
> > -Markus
> >
> >
> > -----Ursprüngliche Nachricht-----
> > Von: Romain Manni-Bucau <rmannibucau@gmail.com>
> > Gesendet: Dienstag, 1. Oktober 2019 16:24
> > An: dev@johnzon.apache.org
> > Betreff: Re: User Question: Complex Adapters
> >
> > Hi Markus,
> >
> > Map does not match Map.Entry so it does not work ;)
> >
> > Semantically you miss a level of "container" (a map is a kind of
> > List<Map.Entry> even if structurally it does not match).
> > Also note that Map.Entry is modelized per its signatures as a
> > {key:...,
> > value: ....} and not as {key:value} as in a map.
> >
> > I guess a Deserializer can be closer than an adapter of what you are
> > trying to do.
> >
> > Romain Manni-Bucau
> > @rmannibucau <https://twitter.com/rmannibucau> |  Blog <
> > https://rmannibucau.metawerx.net/> | Old Blog <
> > http://rmannibucau.wordpress.com> | Github
> > <https://github.com/rmannibucau>
> > | LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book <
> > https://www.packtpub.com/application-development/java-ee-8-high-perfor
> > mance
> > >
> >
> >
> > Le mar. 1 oct. 2019 à 16:17, Markus Karg <karg@quipsy.de> a écrit :
> >
> > > I’d be very very glad if you could answer a short user question I’m
> > > completely stuck with. 😊
> > >
> > > Johnzon is able to parse JSON object into Java Map while respecting
> > > custom
> > > adapters:
> > >
> > > // Works well: Uses custom Adapter<UUID, String> Map<UUID, Foo>
map
> > > = jsonb.fromJson("{ \"" + uuid + "\": { \"name\":
> > > \"Lala\" } }", new JohnzonParameterizedType(Map.class, UUID.class,
> > > Foo.class));
> > >
> > > Now let’s assume we do not want to get a complete Map but just a
> > > single Map.Entry, as we know for sure the JSON string only contains
> > > exactly just one single key-value-pair:
> > >
> > > JsonbConfig jsonbConfig = new JsonbConfig().withAdapters(new
> > > UuidAdapter(), new MapEntryAdapter<UUID, Foo>());
> > >
> > > // Fails with "Can't map Entry<UUID, Foo>"
> > > Map.Entry<UUID, Foo> entry = jsonb.fromJson("{ \"" + uuid + "\": {
> > > \"name\": \"Lala\" } }", new
> > > JohnzonParameterizedType(Map.Entry.class,
> > > UUID.class, Foo.class));
> > >
> > > public class MapEntryAdapter<K, V> implements
> > > JsonbAdapter<Map.Entry<K,
> > > V>, Map<K, V>> {
> > >     @Override public Map<K, V> adaptToJson(Entry<K, V> obj) throws
> > > Exception { … }
> > >     @Override public Entry<K, V> adaptFromJson(Map<K, V> obj) throws
> > > Exception { … } }
> > >
> > > Strange but true, this does not work but complains it cannot map
> > > Entry<UUID, Foo> -- it seems it cannot „see“ the correctly
> > > registered adapter (not even if I replace <K, V> by <UUID, String>
> > > manually in the code).
> > >
> > > So the question is: Where is the fault? Did I try something (what?)
> > > which is forbidden in JSON-B? Is this a bug in Johnzon?
> > >
> > > Actually I assume it is my personal fault (as so often), but I just
> > > cannot see where… 😉
> > >
> > > Thanks a lot for your kind help!
> > > -Markus
> > >
> > >
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message