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 <k...@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 <rmannibu...@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 <k...@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 <rmannibu...@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 <k...@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 > > > > > > > > > > > >