Apologies for slow response. I think things looks like something potentially useful, as sort of Builder for JsonNode-trees. I don't know if it would fit within `jackson-databind`, so best way would probably be to package it as an extension. It is not quite a module (so should not be named such), but would have dependency to `jackson-databind`.
It might make sense to separate Lens class from whatever creates it, however (JsonLensFactory or -Builder?), and doing that would probably allow adding convenience methods that would start by parsing Json into JsonNode, then feeding that and JsonNodeFactory into lens instance. In fact, Lens instance probably should keep a reference to mapper, as that would also allow convenient serialization (JsonNode.toString() is NOT guaranteed to produce valid json, at least not with 2.9 and prior versions). -+ Tatu +- On Tue, Nov 6, 2018 at 7:27 PM George Campbell <[email protected]> wrote: > I have come up with a library for doing haskell like lens operations on a > JsonNode. My need was from wanting to do complex edits on the JsonNode in a > fluent way. Currently they only way (I've found) to edit a tree is to do a > lot of casts with intermediate variables. With the JsonLens wrapper the > edits almost look like you are working directly with JsonNode tree but with > edit support. Here is an example of what it would look like. > > Given the input: > > { > "name": "Homer Simpson", > "address": { > "street": "742 Evergreen Ter.", > "city": "Springfield" > } > } > > > With the JsonLens adding a state would look like > > JsonNode output = new JsonLens(input).path("address").set("state", > "Ohio").result(); > > > this would return (there are options to edit in-place or do an > non-mutating copy on write). The main thing I want you to notice is that > returned value is not the address object but the whole tree with the > address changed. > > { > "name": "Homer Simpson", > "address": { > "street": "742 Evergreen Ter.", > "city": "Springfield", > "state": "Ohio" > } > } > > > This just barely scratches the surface. I'll paste a full method list at > the end. > > My question to the list are: > > 1) Would anyone else like to use this? > > 2) If #1 is yes. What are best practices for packaging this up to be > compatible with jackson? > The only dependency is on the JsonNodeFactory and JsonNode classes. > > Appendix: Full API > > class JsonLens { > class Options { > JsonNodeFactory factory // the class used for generating empty > ObjectNode and ArrayNode as needed. > boolean immutable // copy on write > boolean throwClassCast // if the user steps out of bounds throw a > ClassCastException otherwise just make JsonNodes to make whatever they > write work. > } > JsonLens() > JsonLens(JsonNode) > JsonLens(JsonNode, Options) > JsonLens(Options) > > JsonNode result() // when done with the edits this returns the result. > > JsonLens append(boolean) > JsonLens append(byte) > JsonLens append(double) > JsonLens append(float) > JsonLens append(Function<JsonLens, JsonLens>) // function input is > always a lens to a MissingNode. > JsonLens append(int) > JsonLens append(JsonLens) > JsonLens append(JsonNode) > JsonLens append(long) > JsonLens append(short) > JsonLens append(String) > JsonLens appendAll(JsonLens) // recursive object and array merge > JsonLens appendAll(JsonNode) // recursive object and array merge > JsonLens insert(int, boolean) > JsonLens insert(int, byte) > JsonLens insert(int, double) > JsonLens insert(int, float) > JsonLens insert(int, Function<JsonLens, JsonLens>) // the methods that > take a function let the user do multiple edits all at once. > JsonLens insert(int, int) > JsonLens insert(int, JsonLens) > JsonLens insert(int, JsonNode) > JsonLens insert(int, long) > JsonLens insert(int, short) > JsonLens insert(int, String) > JsonLens path(int) > JsonLens path(String) > JsonLens remove(int) > JsonLens remove(String) > JsonLens set(boolean) > JsonLens set(double) > JsonLens set(Function<JsonLens, JsonLens>) > JsonLens set(int) > JsonLens set(int, boolean) > JsonLens set(int, double) > JsonLens set(int, Function<JsonLens, JsonLens>) > JsonLens set(int, int) > JsonLens set(int, JsonLens) > JsonLens set(int, JsonNode) > JsonLens set(int, String) > JsonLens set(JsonLens) > JsonLens set(JsonNode) > JsonLens set(long) > JsonLens set(String) > JsonLens set(String, boolean) > JsonLens set(String, double) > JsonLens set(String, Function<JsonLens, JsonLens>) > JsonLens set(String, int) > JsonLens set(String, JsonLens) > JsonLens set(String, JsonNode) > JsonLens set(String, long) > JsonLens set(String, String) > } > > -- > You received this message because you are subscribed to the Google Groups > "jackson-user" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send 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-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
