This is an automated email from the ASF dual-hosted git repository. rmannibucau pushed a commit to branch generated-bindings in repository https://gitbox.apache.org/repos/asf/johnzon.git
The following commit(s) were added to refs/heads/generated-bindings by this push: new 6f59875 trivial flat support of 15869JohnzonJsonb 6f59875 is described below commit 6f59875a18f23f58ac94aa3e2914974c20a77ed8 Author: Romain Manni-Bucau <rmannibu...@gmail.com> AuthorDate: Thu Feb 3 09:58:02 2022 +0100 trivial flat support of 15869JohnzonJsonb --- .../jsonb/generator/GeneratedJohnzonJsonb.java | 23 ++++++ .../jsonb/generator/JsonbMapperGenerator.java | 75 +++++++++++++------ .../jsonb/generator/GeneratedJsonbTest.java | 87 +++++++++++++++++++++- 3 files changed, 160 insertions(+), 25 deletions(-) diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/generator/GeneratedJohnzonJsonb.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/generator/GeneratedJohnzonJsonb.java index df3b42d..305cfc0 100644 --- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/generator/GeneratedJohnzonJsonb.java +++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/generator/GeneratedJohnzonJsonb.java @@ -20,6 +20,9 @@ package org.apache.johnzon.jsonb.generator; import org.apache.johnzon.jsonb.JohnzonJsonb; +import javax.json.JsonNumber; +import javax.json.JsonString; +import javax.json.JsonValue; import java.io.Reader; import java.io.Writer; @@ -33,4 +36,24 @@ public abstract class GeneratedJohnzonJsonb { public abstract <T> T fromJson(Reader reader); public abstract void toJson(Object object, Writer writer); + + protected static String json2String(final JsonValue value) { + switch (value.getValueType()) { + case STRING: + return JsonString.class.cast(value).getString(); + case NULL: + return null; + default: + throw new IllegalArgumentException("expected a string, got " + value.getValueType()); + } + } + + protected static int json2Int(final JsonValue value) { + switch (value.getValueType()) { + case NUMBER: + return JsonNumber.class.cast(value).intValue(); + default: + throw new IllegalArgumentException("expected an int, got " + value.getValueType()); + } + } } diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/generator/JsonbMapperGenerator.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/generator/JsonbMapperGenerator.java index ad0917e..04e51b2 100644 --- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/generator/JsonbMapperGenerator.java +++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/generator/JsonbMapperGenerator.java @@ -29,9 +29,13 @@ import javax.json.bind.JsonbConfig; import java.io.IOException; import java.io.Writer; import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; +import java.util.Map; import java.util.function.Supplier; import java.util.logging.Logger; import java.util.stream.Stream; @@ -95,18 +99,14 @@ public class JsonbMapperGenerator implements Runnable { out.append(" final ").append(clazz.getSimpleName()).append(suffix).append(" instance = new ") .append(clazz.getSimpleName()).append(suffix).append("();\n"); out.append(mapping.setters.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) .map(setter -> toSetter(setter.getValue(), setter.getKey())) .collect(joining("\n", "", "\n"))); - out.append(" return null;\n"); + out.append(" return instance;\n"); out.append(" }\n"); out.append(" case NULL:\n"); - out.append(" case ARRAY:\n"); - out.append(" case STRING:\n"); - out.append(" case NUMBER:\n"); - out.append(" case TRUE:\n"); - out.append(" case FALSE:\n"); + out.append(" return null;\n"); out.append(" default:\n"); - // todo: check if there is an adapter or alike out.append(" throw new IllegalStateException(\"invalid value type: '\" + value.getValueType() + \"'\");\n"); out.append(" }\n"); out.append(" }\n"); @@ -115,8 +115,17 @@ public class JsonbMapperGenerator implements Runnable { out.append("\n"); out.append(" @Override\n"); out.append(" public void toJson(final Object object, final Writer writer) {\n"); - // todo: use mappings.setters and expose with getters jsonb.getMapper().getJsongeneratorFactory() - out.append(" // TBD\n"); + if (mapping.getters.isEmpty()) { // will always be empty + out.append(" writer.write(\"{}\");\n"); + } else { + out.append(" try (final JsonGenerator generator = root.getDelegate().getGeneratorFactory().createGenerator(writer)) {\n"); + out.append(mapping.getters.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .map(setter -> toGetter(setter.getValue(), setter.getKey())) + .collect(joining("\n", "", "\n"))); + out.append(" }\n"); + } + // root.getDelegate().getGeneratorFactory().createGenerator() out.append(" }\n"); out.append("}\n\n"); @@ -152,7 +161,7 @@ public class JsonbMapperGenerator implements Runnable { } } - private String toGetter(final Mappings.Getter value) { + private String toGetter(final Mappings.Getter value, final String name) { try { final Field reader = value.getClass().getDeclaredField("reader"); if (!reader.isAccessible()) { @@ -168,24 +177,35 @@ public class JsonbMapperGenerator implements Runnable { }) .findFirst() .orElseThrow(() -> new IllegalStateException("No finalReader field in " + wrapped)); - return toGetter(AccessMode.Reader.class.cast(finalReader.get(wrapped))); + return toGetter(AccessMode.Reader.class.cast(finalReader.get(wrapped)), name); } catch (final IllegalAccessException | NoSuchFieldException nsfe) { throw new IllegalArgumentException("Unsupported getter: " + value, nsfe); } } - private String toGetter(final MethodAccessMode.MethodReader reader) { - return "instance." + reader.getMethod().getName() + "();"; + private String toGetter(final MethodAccessMode.MethodReader reader, final String name) { + final Type type = reader.getType(); + if (type == String.class || type == int.class || type == long.class || type == boolean.class || type == double.class + || type == BigDecimal.class || type == BigInteger.class) { + return "" + + " {\n" + + " final " + Class.class.cast(type).getSimpleName() + " value = instance." + reader.getMethod().getName() + "();\n" + + " if (value != null) {\n" + + " generator.write(\"" + name + "\", value);\n" + + " }\n" + + " }" + + ""; + } + throw new IllegalArgumentException("Unsupported type: " + type); } - private String toGetter(final AccessMode.Reader reader) { + private String toGetter(final AccessMode.Reader reader, final String name) { if (FieldAndMethodAccessMode.CompositeReader.class.isInstance(reader)) { final MethodAccessMode.MethodReader mr = MethodAccessMode.MethodReader.class.cast( - FieldAndMethodAccessMode.CompositeReader.class.cast(reader).getType2()); - return toGetter(mr); + FieldAndMethodAccessMode.CompositeReader.class.cast(reader).getType1()); + return toGetter(mr, name); } else if (MethodAccessMode.MethodReader.class.isInstance(reader)) { - final MethodAccessMode.MethodReader mr = MethodAccessMode.MethodReader.class.cast(reader); - return toGetter(mr); + return toGetter(MethodAccessMode.MethodReader.class.cast(reader), name); } throw new IllegalArgumentException("Unsupported reader: " + reader); } @@ -194,23 +214,32 @@ public class JsonbMapperGenerator implements Runnable { private String toSetter(final MethodAccessMode.MethodWriter reader, final String name) { return "" + " {\n" + - " final JsonValue value = instance.get(\""+name+"\");\n" + + " final JsonValue value = instance.get(\"" + name + "\");\n" + " if (value != null) {\n" + - " final Object coerced = coerce(value);\n" + - " instance." + reader.getMethod().getName() + "(coerced);\n" + + " instance." + reader.getMethod().getName() + "(" + + coerceFunction(reader.getMethod().getGenericParameterTypes()[0]) + "(value));\n" + " }\n" + " }" + ""; } + private String coerceFunction(final Type type) { + if (type == String.class) { + return "json2String"; + } + if (type == int.class) { + return "json2Int"; + } + throw new IllegalArgumentException("Unsupported type: " + type); + } + private String toSetter(final AccessMode.Writer writer, final String setter) { if (FieldAndMethodAccessMode.CompositeWriter.class.isInstance(writer)) { final MethodAccessMode.MethodWriter mr = MethodAccessMode.MethodWriter.class.cast( FieldAndMethodAccessMode.CompositeWriter.class.cast(writer).getType1()); return toSetter(mr, setter); } else if (MethodAccessMode.MethodWriter.class.isInstance(writer)) { - final MethodAccessMode.MethodWriter mr = MethodAccessMode.MethodWriter.class.cast(writer); - return toSetter(mr, setter); + return toSetter(MethodAccessMode.MethodWriter.class.cast(writer), setter); } throw new IllegalArgumentException("Unsupported writer: " + writer); } diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/generator/GeneratedJsonbTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/generator/GeneratedJsonbTest.java index 05a23b7..a6f18f7 100644 --- a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/generator/GeneratedJsonbTest.java +++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/generator/GeneratedJsonbTest.java @@ -45,7 +45,30 @@ public class GeneratedJsonbTest { final Path result = output.resolve("org/apache/johnzon/jsonb/generator/GeneratedJsonbTest$Empty$$JohnzonJsonb.class"); assertTrue(Files.exists(result)); assertEquals("" + - "" + + "package org.apache.johnzon.jsonb.generator;\n" + + "\n" + + "import org.apache.johnzon.jsonb.generator.GeneratedJohnzonJsonb;\n" + + "import org.apache.johnzon.jsonb.JohnzonJsonb;\n" + + "import javax.json.JsonGenerator;\n" + + "import javax.json.JsonReader;\n" + + "import javax.json.JsonValue;\n" + + "\n" + + "public class Empty$$JohnzonJsonb implements GeneratedJohnzonJsonb {\n" + + " public Empty$$JohnzonJsonb(final JohnzonJsonb root) {\n" + + " super(root);\n" + + " }\n" + + "\n" + + " @Override\n" + + " public <T> T fromJson(final Reader reader) {\n" + + " return JsonValue.EMPTY_JSON_OBJECT;\n" + + " }\n" + + "\n" + + " @Override\n" + + " public void toJson(final Object object, final Writer writer) {\n" + + " writer.write(\"{}\");\n" + + " }\n" + + "}\n" + + "\n" + "", new String(Files.readAllBytes(result), UTF_8)); } @@ -59,7 +82,67 @@ public class GeneratedJsonbTest { final Path result = output.resolve("org/apache/johnzon/jsonb/generator/GeneratedJsonbTest$Simple$$JohnzonJsonb.class"); assertTrue(Files.exists(result)); assertEquals("" + - "" + + "package org.apache.johnzon.jsonb.generator;\n" + + "\n" + + "import org.apache.johnzon.jsonb.generator.GeneratedJohnzonJsonb;\n" + + "import org.apache.johnzon.jsonb.JohnzonJsonb;\n" + + "import javax.json.JsonGenerator;\n" + + "import javax.json.JsonReader;\n" + + "import javax.json.JsonValue;\n" + + "\n" + + "public class Simple$$JohnzonJsonb implements GeneratedJohnzonJsonb {\n" + + " public Simple$$JohnzonJsonb(final JohnzonJsonb root) {\n" + + " super(root);\n" + + " }\n" + + "\n" + + " @Override\n" + + " public <T> T fromJson(final Reader reader) {\n" + + " try (final JsonReader reader = root.getMapper().getReaderFactory().createReader(reader)) {\n" + + " final JsonValue value = reader.readValue();\n" + + " switch (value.getValueType()) {\n" + + " case OBJECT: {\n" + + " final Simple$$JohnzonJsonb instance = new Simple$$JohnzonJsonb();\n" + + " {\n" + + " final JsonValue value = instance.get(\"age\");\n" + + " if (value != null) {\n" + + " instance.setAge(json2Int(value));\n" + + " }\n" + + " }\n" + + " {\n" + + " final JsonValue value = instance.get(\"name\");\n" + + " if (value != null) {\n" + + " instance.setName(json2String(value));\n" + + " }\n" + + " }\n" + + " return instance;\n" + + " }\n" + + " case NULL:\n" + + " return null;\n" + + " default:\n" + + " throw new IllegalStateException(\"invalid value type: '\" + value.getValueType() + \"'\");\n" + + " }\n" + + " }\n" + + " }\n" + + "\n" + + " @Override\n" + + " public void toJson(final Object object, final Writer writer) {\n" + + " try (final JsonGenerator generator = root.getDelegate().getGeneratorFactory().createGenerator(writer)) {\n" + + " {\n" + + " final int value = instance.getAge();\n" + + " if (value != null) {\n" + + " generator.write(\"age\", value);\n" + + " }\n" + + " }\n" + + " {\n" + + " final String value = instance.getName();\n" + + " if (value != null) {\n" + + " generator.write(\"name\", value);\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}\n" + + "\n" + "", new String(Files.readAllBytes(result), UTF_8)); }