A few ideas for JsonNode classes:

   1. Helper methods to add Collections of things to ArrayNodes. Right now
   you can only "addAll" other JsonNodes which means you have to loop over
   your collection and call the individual "add" methods. Something like
   "addAll(Iterable <T>, BiConsumer<ArrayNode,T> consumer)" would be lovely
   (e.g. node.putArray("numbers").addAll(listOfInts, ArrayNode::add)).
   2. Helper methods for missing/null node safe conversions. For example,
   getting a string field off of a JsonNode may return an empty string or a
   null value, if this needs to be immediately converted into another type
   (e.g. an enum or an Instant) this adds an extra if statement before the
   conversion can happen. Would be nice to have a method like "Optional<T>
   asValue(Function<JsonNode, T> converter)". The general idea being that
   NullNodes and MissingNodes won't cause the converter to be invoked. I can
   see three main variants of this: return an Optional<T>, accept a default
   value as a parameter and return T, or just return a nullable T—not all of
   which would be needed.  To go even further, since Strings are the most
   likely type to need further mapping, an "asStringValue(Function<String,
   T> converter)" would allow even simpler syntax (e.g. node.path("date").
   asStringValue(Instant::parse)).
   3. Helper method to get a stream from a JsonNode. An ArrayNode would
   return a stream of its children, an ObjectNode or ValueNode would return a
   singleton stream of themselves, and MissingNode would return an empty
   stream.

Also, in general:

   1. Basic reader/writer methods that don't throw checked exceptions for
   easier use within lambdas.


On Thu, May 11, 2017 at 9:30 AM, Jeff Schnitzer <[email protected]> wrote:

> This is just one programmer’s opinion:
>
>  * ObjectReader and ObjectWriter are not great as the “master” object; I
> need both of them, which means I would need to pass around two variables
> everywhere. It would be better to have an ObjectReaderWriter.
>
>  * The performance of creating new ObjectMappers can be pretty easily
> understood as “it’s best to re-use objectmappers”. I think people
> understand that and making a more convenient configuration API wouldn’t
> hurt. I believe from observation that it’s pretty common for people to new
> ObjectMapper().readValue(…) so it’s probably the case that performance of
> creating new OMs is fine for most users.
>
>  * Immutable ObjectMappers would make it _easier_ to re-use existing
> objectmappers, because you don’t need to worry that somebody is going to
> change the config of your OM.
>
> Jeff
>
> On Thu, May 11, 2017 at 8:20 AM, Tatu Saloranta <[email protected]>
> wrote:
>
>> On Wed, May 10, 2017 at 12:35 AM, Jeff Schnitzer <[email protected]>
>> wrote:
>> > I guess what I’m hoping for is something like:
>> >
>> > final ObjectMapper mapper1 = new
>> > ObjectMapper().writeDatesAsTimestamps(false);
>> > mapper1.writeValue(stream, thing);
>> > final ObjectMapper mapper2 = mapper1.writeDatesAsTimestamps(true);
>> > mapper2.writeValue(stream, thing);
>> >
>> > Of course, if ObjectMapper is immutable then there’s never any need to
>> ’new’
>> > an ObjectMapper. A singleton suffices.
>>
>> This is how ObjectReader and ObjectWriter work. I think that purely
>> from user perspective this approach would makes sense. But from
>> implementation perspective there is a reason to keep mapper (or
>> whatever you call the factory) separate: it has configurability that
>> can not be (easily, cheaply) change on per-call basis (like adding a
>> mix-in, or changing aspects of how (de)serializers are constructed).
>> This is largely how MapperFeature differs from
>> Serialization-/DeserializationFeature: former basically clears all
>> cached state and can be incredibly expensive to change.
>>
>> In addition, unless Builder of some kind is added, number of
>> permutations that comes from all configuration aspects gets quite
>> unwieldy (for implementing all various "mutant factory" methods).
>> Adding a builder could help, but some users would consider this
>> further complexity.
>>
>> -+ Tatu +-
>>
>>
>> >
>> > Jeff
>> >
>> >
>> > On Tue, May 9, 2017 at 5:41 PM, Tatu Saloranta <[email protected]>
>> wrote:
>> >>
>> >> On Mon, May 8, 2017 at 5:00 PM, Jeff Schnitzer <[email protected]>
>> >> wrote:
>> >> > Is there anything about making ObjectMapper immutable in the works?
>> The
>> >> > api
>> >> > is a bit messy for making new objectmappers derived from old
>> >> > objectmappers.
>> >> >
>> >> > (sorry if this question has already been asked/answered, I’m
>> >> > intermittent)
>> >>
>> >> No, although it would make sense to do one of two things:
>> >>
>> >> 1. Remove all readValue()/writeValue() calls from ObjectMapper, and
>> >> consider it strictly as factory for ObjectReaders and ObjectWriters
>> >> 2. Create ObjectMapper builder/factory, which is configurable, but
>> >> require construction of immutable mapper for actual use (if so, it'd
>> >> be redundant with ObjectReader/ObjectWriter)
>> >>
>> >> I agree in that at this point ObjectMapper is bit stuck between two
>> >> worlds: one where it is to be used directly (original state), and one
>> >> where it's merely a factory.
>> >>
>> >> Division (or not) of reading/writing side is also tricky:
>> >>
>> >> - On plus side, separating the two simplifies respective APIs and
>> >> allows easier identification of which features matter where
>> >> - On down side it is more difficult to pass 2 things through
>> >> frameworks like JAX-RS or Spring, and they much prefer getting
>> >> ObjectMapper
>> >>
>> >> One thing I have no interest in doing, but that has been proposed, is
>> >> adding some kind of flag to indicate that ObjectMapper can not be
>> >> configured again: I don't think that approach works well either from
>> >> user or implementation perspective.
>> >>
>> >> -+ Tatu +-
>> >>
>> >> >
>> >> > Jeff
>> >> >
>> >> >
>> >> >
>> >> > On Mon, May 8, 2017 at 11:58 AM, Jeff Maxwell <
>> [email protected]>
>> >> > wrote:
>> >> >>
>> >> >> Streamify ObjectMapper and ObjectReader
>> >> >>
>> >> >> ObjectMapper and Object Reader methods that return Iterators should
>> >> >> have
>> >> >> associated *AsStream methods.
>> >> >>
>> >> >> Note that users will have to close the returned Streams to avoid
>> >> >> leaking
>> >> >> resources.
>> >> >>
>> >> >> Below are potential methods to add:
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(byte[])
>> >> >> DoubleStream readValuesAsDoubleStream(byte[])
>> >> >> IntStream readValuesAsIntStream(byte[])
>> >> >> LongStream readValuesAsLongStream(byte[])
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(byte[], int, int)
>> >> >> DoubleStream readValuesAsDoubleStream(byte[], int, int)
>> >> >> IntStream readValuesAsIntStream(byte[], int, int)
>> >> >> LongStream readValuesAsLongStream(byte[], int, int)
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(DataInput)
>> >> >> DoubleStream readValuesAsDoubleStream(DataInput)
>> >> >> IntStream readValuesAsIntStream(DataInput)
>> >> >> LongStream readValuesAsLongStream(DataInput)
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(File)
>> >> >> DoubleStream readValuesAsDoubleStream(File)
>> >> >> IntStream readValuesAsIntStream(File)
>> >> >> LongStream readValuesAsLongStream(File)
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(InputStream)
>> >> >> DoubleStream readValuesAsDoubleStream(InputStream)
>> >> >> IntStream readValuesAsIntStream(InputStream)
>> >> >> LongStream readValuesAsLongStream(InputStream)
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(JsonParser)
>> >> >> DoubleStream readValuesAsDoubleStream(JsonParser)
>> >> >> IntStream readValuesAsIntStream(JsonParser)
>> >> >> LongStream readValuesAsLongStream(JsonParser)
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(JsonParser, Class)
>> >> >> <T> Stream<T> readValuesAsStream(JsonParser, Class<T>)
>> >> >> <T> Stream<T> readValuesAsStream(JsonParser, JavaType)
>> >> >> <T> Stream<T> readValuesAsStream(JsonParser, ResolvedType)
>> >> >> <T> Stream<T> readValuesAsStream(JsonParser, TypeReference)
>> >> >> <T> Stream<T> readValuesAsStream(JsonParser, TypeReference<?>)
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(Reader)
>> >> >> DoubleStream readValuesAsDoubleStream(Reader)
>> >> >> IntStream readValuesAsIntStream(Reader)
>> >> >> LongStream readValuesAsLongStream(Reader)
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(String)
>> >> >> DoubleStream readValuesAsDoubleStream(String)
>> >> >> IntStream readValuesAsIntStream(String)
>> >> >> LongStream readValuesAsLongStream(String)
>> >> >>
>> >> >> <T> Stream<T> readValuesAsStream(URL)
>> >> >> DoubleStream readValuesAsDoubleStream(URL)
>> >> >> IntStream readValuesAsIntStream(URL)
>> >> >> LongStream readValuesAsLongStream(URL)
>> >> >>
>> >> >>
>> >> >>
>> >> >> On Tuesday, February 21, 2017 at 8:53:03 PM UTC-6, Tatu Saloranta
>> >> >> wrote:
>> >> >>>
>> >> >>> Quick note: I collected existing ideas on my notes to a single wiki
>> >> >>> page:
>> >> >>>
>> >> >>>
>> >> >>> https://github.com/FasterXML/jackson-future-ideas/wiki/Jacks
>> on3-Changes
>> >> >>>
>> >> >>> and intend to evolve that on short term, possibly dividing into
>> more
>> >> >>> granular pages.
>> >> >>> Eventually should split those into issues, but before that a lot
>> more
>> >> >>> needs to happen; including question of whether there should be new
>> >> >>> repo for Jackson 3 core components.
>> >> >>> But I thought it's better to start collecting ideas.
>> >> >>>
>> >> >>> Another related wiki page is this:
>> >> >>>
>> >> >>>
>> >> >>>
>> >> >>> https://github.com/FasterXML/jackson-future-ideas/wiki/Major
>> -Design-Issues
>> >> >>>
>> >> >>> and it contains (an incomplete) list of major unsolved issue
>> regarding
>> >> >>> Jackson core design, especially in areas that we have had to
>> postpone
>> >> >>> from 2.9.
>> >> >>>
>> >> >>> -+ Tatu +-
>> >> >>
>> >> >> --
>> >> >> You received this message because you are subscribed to the Google
>> >> >> Groups
>> >> >> "jackson-dev" group.
>> >> >> To unsubscribe from this group and stop receiving emails from it,
>> send
>> >> >> an
>> >> >> email to [email protected].
>> >> >> For more options, visit https://groups.google.com/d/optout.
>> >> >
>> >> >
>> >> > --
>> >> > You received this message because you are subscribed to the Google
>> >> > Groups
>> >> > "jackson-dev" group.
>> >> > To unsubscribe from this group and stop receiving emails from it,
>> send
>> >> > an
>> >> > email to [email protected].
>> >> > For more options, visit https://groups.google.com/d/optout.
>> >>
>> >> --
>> >> You received this message because you are subscribed to the Google
>> Groups
>> >> "jackson-dev" group.
>> >> To unsubscribe from this group and stop receiving emails from it, send
>> an
>> >> email to [email protected].
>> >> For more options, visit https://groups.google.com/d/optout.
>> >
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> Groups
>> > "jackson-dev" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> an
>> > email to [email protected].
>> > For more options, visit https://groups.google.com/d/optout.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "jackson-dev" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "jackson-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to