Technically we don’t need it. But for the end user it is SOOOO much easier to use. You have an interface with 2 well documented methods. Or ou have an impl with 30 methods. For an end user this makes a HUGE difference!
LieGrue, strub > Am 26.03.2016 um 17:08 schrieb Romain Manni-Bucau <[email protected]>: > > Le 26 mars 2016 13:55, "Mark Struberg" <[email protected]> a écrit : >> >> Yes, the jsonbgenerator et al would be in mapper. >> Johnson misses a clean separation btw api and impl anyway, so binary > compat is moot somehow. >> > > That is not true since Mapper is the API. Not relying on an interface was a > choice cause it doesnt bring anything there - compared to a spec impl which > has other constraints. > > Keeping it simple and avoiding indirections was an assumed design choice, > don't mix thing using expert words ;). > > Side note: please keep these design decisions for now or start a discussion > on them. Splitting mapper doesnt mean we need interface + impl in mapper > module. > >> I'll try to keep the most of mapper APIs stable. I'd still recommend > pushing the minor version. >> >> Lg, >> Strub >> >>> Am 26.03.2016 um 13:32 schrieb Romain Manni-Bucau <[email protected] >> : >>> >>> While it doesnt change any public/protected API and jsonb depends on > mapper >>> and not the opposite feel free to move forward from me. >>> Le 26 mars 2016 12:50, "Mark Struberg" <[email protected]> a écrit : >>> >>>> Hi! >>>> >>>> I’m playing around with making our Mapper more flexible by allowing > more >>>> freedom for writing and parsing JSON from and to arbitrary Objects. >>>> >>>> Currently Mapper contains both the logic of writing and reading > Objects. >>>> As a result our Mapper class became pretty huge already. > 1k LOC is > not >>>> something we like to maintain for a long time. >>>> >>>> I like to split that functionality into 3 different classes >>>> >>>> 1.) MapperConfig. That basically contains all our internal flags. It > gets >>>> constructed in the MapperBuilder and passed to the created Mapper >>>> >>>> 2.) JsonbParserImpl (extends JsonbParser). It will contain all the > Object >>>> reader parts of the Mapper. It will also have a method JsonParser >>>> getJsonParser(); which allows direct access to the JsonParser. >>>> >>>> JsonbParser does _not_ extend JsonParser! I played around with it but > as >>>> JsonParser methods all return a JsonParser and obviously _not_ a >>>> JsonbParser this woud defeat builder-like programming. By having a > separate >>>> method it’s more obvious what happens. >>>> >>>> 3.) JsonbGenerator. See 2, but for writing. It will contain methods to >>>> write full Objects (and Arrays?). >>>> >>>> Mapper will still have the methods for end-users to writeObject, >>>> writeArray + reads with OutputStream, Writer and AsString. But the full >>>> control is done in JsonbParser and JsonbWRiter >>>> >>>> >>>> Why do I need all that? >>>> >>>> The root of this demand was to create a more flexible way to decide > what >>>> gets written and read from Object <-> JSON. I thought about the > following >>>> interface >>>> >>>> public interface ObjectConverter<T> { >>>> void writeJson(T instance, JsonbGenerator jsonbGenerator); >>>> >>>> T fromJson(JsonbParser jsonbParser, Type targetType); >>>> } >>>> >>>> Let’s look at writing JSON from some class: >>>> >>>> public static class Dog { >>>> private String name; >>>> private Dog father; >>>> private Dog mother; >>>> } >>>> >>>> public static class Beagle extends Dog { >>>> } >>>> >>>> public static class Poodle extends Dog { >>>> boolean hairCut = false; >>>> } >>>> >>>> public static class Mutt extends Dog { >>>> } >>>> >>>> and the test code: >>>> >>>> Poodle mum = new Poodle(); >>>> mum.setName("Rosa"); >>>> mum.setHairCut(true); >>>> >>>> Beagle dad = new Beagle(); >>>> dad.setName("Gnarl"); >>>> >>>> Beagle grandPa = new Beagle(); >>>> grandPa.setName("Wuffi"); >>>> dad.setFather(grandPa); >>>> >>>> Mutt snoopie = new Mutt(); >>>> snoopie.setName("Snoopie"); >>>> snoopie.setFather(dad); >>>> snoopie.setMother(mum); >>>> >>>> String json = mapper.writeObjectAsString(snoopie); >>>> >>>> The Mapper will create a JsonbGenerator and hand over snoopy to it. >>>> Whenever the JsonbGenerator hits a type which we have a Object > Converter >>>> for then it will call writeJson(T instance, JsonbGenerator > jsonbGenerator); >>>> In your own Converter you can now e.g. do >>>> jsonbGenerator.getJsonGenerator().write(„//javaType", >>>> instance.getClass().getName()); >>>> jsonbGenerator.writeObject(instance); >>>> >>>> or also probably >>>> jsonbGenerator.getJsonGenerator().write(„//javaType“, >>>> instance.getClass().getName()); >>>> jsonbGenerator.getJsonGenerator().writeStartObject(„dog“); >>>> jsonbGenerator.writeObject(instance); >>>> jsonbGenerator.getJsonGenerator().writeEnd(); >>>> >>>> >>>> How does that look to you? >>>> >>>> LieGrue, >>>> strub >>>> >>>> >>
