From 3eebe33d8dbd0cd64dfadfd155d87a8fabc0632d Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 12 Dec 2024 18:13:42 +1300 Subject: [PATCH] [json-node] Make avaje-json-node an optional component for JsonB That is, we need to explicitly include avaje-json-node in the classpath/module path. When JsonB starts with avaje-json-node present, it will register with JsonB thus support the JsonNode types in JsonB. --- blackbox-test/pom.xml | 6 ++++ .../example/other/JsonNodeAdaptersTest.java | 33 ++++++++++++++++++ json-node/pom.xml | 9 ++++- .../json/node/adapter/JsonNodeComponent.java | 34 +++++++++++++++++++ json-node/src/main/java/module-info.java | 4 +++ .../io.avaje.jsonb.spi.JsonbExtension | 1 + jsonb/pom.xml | 6 ++++ 7 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 blackbox-test/src/test/java/org/example/other/JsonNodeAdaptersTest.java create mode 100644 json-node/src/main/java/io/avaje/json/node/adapter/JsonNodeComponent.java create mode 100644 json-node/src/main/resources/META-INF/services/io.avaje.jsonb.spi.JsonbExtension diff --git a/blackbox-test/pom.xml b/blackbox-test/pom.xml index 0c479d2c..6a607bdd 100644 --- a/blackbox-test/pom.xml +++ b/blackbox-test/pom.xml @@ -31,6 +31,12 @@ 3.0-RC2 + + io.avaje + avaje-json-node + 3.0-RC2 + + diff --git a/blackbox-test/src/test/java/org/example/other/JsonNodeAdaptersTest.java b/blackbox-test/src/test/java/org/example/other/JsonNodeAdaptersTest.java new file mode 100644 index 00000000..4862567c --- /dev/null +++ b/blackbox-test/src/test/java/org/example/other/JsonNodeAdaptersTest.java @@ -0,0 +1,33 @@ +package org.example.other; + +import io.avaje.json.node.JsonNode; +import io.avaje.json.node.JsonObject; +import io.avaje.jsonb.JsonType; +import io.avaje.jsonb.Jsonb; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class JsonNodeAdaptersTest { + + static final Jsonb jsonb = Jsonb.builder().build(); + static final JsonType nodeType = jsonb.type(JsonNode.class); + + @Test + void test() { + var obj = JsonObject.create().add("name", "foo").add("val", 42); + + String asJson = nodeType.toJson(obj); + assertThat(asJson).isEqualTo("{\"name\":\"foo\",\"val\":42}"); + + String asJson2 = jsonb.toJson(obj); + assertThat(asJson2).isEqualTo(asJson); + + JsonNode fromJson = nodeType.fromJson(asJson); + assertThat(fromJson).isInstanceOf(JsonObject.class); + + JsonObject objFromJson = (JsonObject) fromJson; + assertThat(objFromJson.elements()).containsKeys("name", "val"); + } + +} diff --git a/json-node/pom.xml b/json-node/pom.xml index 6f957c7e..8a08e7b3 100644 --- a/json-node/pom.xml +++ b/json-node/pom.xml @@ -6,7 +6,7 @@ io.avaje avaje-jsonb-parent - 3.0-RC1 + 3.0-RC2 avaje-json-node @@ -29,6 +29,13 @@ 3.0-RC1 + + io.avaje + avaje-jsonb + 3.0-RC1 + true + + io.avaje junit diff --git a/json-node/src/main/java/io/avaje/json/node/adapter/JsonNodeComponent.java b/json-node/src/main/java/io/avaje/json/node/adapter/JsonNodeComponent.java new file mode 100644 index 00000000..70a21373 --- /dev/null +++ b/json-node/src/main/java/io/avaje/json/node/adapter/JsonNodeComponent.java @@ -0,0 +1,34 @@ +package io.avaje.json.node.adapter; + +import io.avaje.json.JsonAdapter; +import io.avaje.json.node.JsonNodeAdapter; +import io.avaje.jsonb.AdapterFactory; +import io.avaje.jsonb.Jsonb; +import io.avaje.jsonb.spi.JsonbComponent; + +import java.lang.reflect.Type; + +/** + * Register with JsonB to support the JsonAdapters for JsonNode types. + */ +public final class JsonNodeComponent implements JsonbComponent { + + @Override + public void register(Jsonb.Builder builder) { + builder.add(new JsonBFactory(JsonNodeAdapter.builder().build())); + } + + private static final class JsonBFactory implements AdapterFactory { + + private final JsonNodeAdapter nodeAdapter; + + JsonBFactory(JsonNodeAdapter nodeAdapter) { + this.nodeAdapter = nodeAdapter; + } + + @Override + public JsonAdapter create(Type type, Jsonb jsonb) { + return nodeAdapter.create(type); + } + } +} diff --git a/json-node/src/main/java/module-info.java b/json-node/src/main/java/module-info.java index 1e7d4bdf..f45db375 100644 --- a/json-node/src/main/java/module-info.java +++ b/json-node/src/main/java/module-info.java @@ -4,4 +4,8 @@ requires transitive org.jspecify; requires transitive io.avaje.json; + + requires static io.avaje.jsonb; + exports io.avaje.json.node.adapter to io.avaje.jsonb; + provides io.avaje.jsonb.spi.JsonbComponent with io.avaje.json.node.adapter.JsonNodeComponent; } diff --git a/json-node/src/main/resources/META-INF/services/io.avaje.jsonb.spi.JsonbExtension b/json-node/src/main/resources/META-INF/services/io.avaje.jsonb.spi.JsonbExtension new file mode 100644 index 00000000..29349b77 --- /dev/null +++ b/json-node/src/main/resources/META-INF/services/io.avaje.jsonb.spi.JsonbExtension @@ -0,0 +1 @@ +io.avaje.json.node.adapter.JsonNodeComponent diff --git a/jsonb/pom.xml b/jsonb/pom.xml index bbfef30f..fcd5593f 100644 --- a/jsonb/pom.xml +++ b/jsonb/pom.xml @@ -19,6 +19,12 @@ ${project.version} + + io.avaje + avaje-json-node + ${project.version} + + io.avaje avaje-jsonb-inject-plugin