From 158b00d895937a411217859d3795af1982a19601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Torres?= Date: Mon, 27 May 2024 21:06:54 +0200 Subject: [PATCH] feature: add GSON module --- jsonschema-generator-parent/pom.xml | 6 ++ jsonschema-module-gson/README.md | 64 +++++++++++++ jsonschema-module-gson/pom.xml | 55 +++++++++++ .../jsonschema/module/gson/GsonModule.java | 54 +++++++++++ .../module/gson/IntegrationTest.java | 93 +++++++++++++++++++ .../module/gson/integration-test-result.json | 17 ++++ .../src/test/resources/logback.xml | 12 +++ pom.xml | 1 + 8 files changed, 302 insertions(+) create mode 100644 jsonschema-module-gson/README.md create mode 100644 jsonschema-module-gson/pom.xml create mode 100644 jsonschema-module-gson/src/main/java/com/github/victools/jsonschema/module/gson/GsonModule.java create mode 100644 jsonschema-module-gson/src/test/java/com/github/victools/jsonschema/module/gson/IntegrationTest.java create mode 100644 jsonschema-module-gson/src/test/resources/com/github/victools/jsonschema/module/gson/integration-test-result.json create mode 100644 jsonschema-module-gson/src/test/resources/logback.xml diff --git a/jsonschema-generator-parent/pom.xml b/jsonschema-generator-parent/pom.xml index cd518f7b..5c6240b9 100644 --- a/jsonschema-generator-parent/pom.xml +++ b/jsonschema-generator-parent/pom.xml @@ -165,6 +165,7 @@ 2.2.5 4.8.149 + 2.11.0 @@ -211,6 +212,11 @@ classgraph ${version.classgraph} + + com.google.code.gson + gson + ${version.gson} + diff --git a/jsonschema-module-gson/README.md b/jsonschema-module-gson/README.md new file mode 100644 index 00000000..89d040db --- /dev/null +++ b/jsonschema-module-gson/README.md @@ -0,0 +1,64 @@ +# Java JSON Schema Generation – Module Gson +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.victools/jsonschema-module-jackson/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.victools/jsonschema-module-jackson) + +Module for the [jsonschema-generator](../jsonschema-generator) – deriving JSON Schema attributes from `gson` annotations. + +## Features +1. Override a field's/method's property name as per `@SerializedName` annotations. +2. Ignore fields/methods that are marked with a `@Expose` annotation. + +---- + +## Documentation +JavaDoc is being used throughout the codebase, offering contextual information in your respective IDE or being available online through services like [javadoc.io](https://www.javadoc.io/doc/com.github.victools/jsonschema-module-jackson). + +Additional documentation can be found in the [Project Wiki](https://github.com/victools/jsonschema-generator/wiki). + +---- + +## Usage +### Dependency (Maven) +```xml + + com.github.victools + jsonschema-module-gson + [4.21.0,5.0.0) + +``` + +Since version `4.7`, the release versions of the main generator library and this module are aligned. +It is recommended to use identical versions for both dependencies to ensure compatibility. + +### Code +#### Passing into SchemaGeneratorConfigBuilder.with(Module) +```java +import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder; +import com.github.victools.jsonschema.generator.SchemaVersion; +import com.github.victools.jsonschema.module.gson.GsonModule; +``` +```java +GsonModule module = new GsonModule(); +SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09) + .with(module); +``` + +#### Complete Example +```java +import com.fasterxml.jackson.databind.JsonNode; +import com.github.victools.jsonschema.generator.OptionPreset; +import com.github.victools.jsonschema.generator.SchemaGenerator; +import com.github.victools.jsonschema.generator.SchemaGeneratorConfig; +import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder; +import com.github.victools.jsonschema.generator.SchemaVersion; +import com.github.victools.jsonschema.module.gson.GsonModule; +``` +```java +GsonModule module = new GsonModule(); +SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09, OptionPreset.PLAIN_JSON) + .with(module); +SchemaGeneratorConfig config = configBuilder.build(); +SchemaGenerator generator = new SchemaGenerator(config); +JsonNode jsonSchema = generator.generateSchema(YourClass.class); + +System.out.println(jsonSchema.toString()); +``` diff --git a/jsonschema-module-gson/pom.xml b/jsonschema-module-gson/pom.xml new file mode 100644 index 00000000..084f15fa --- /dev/null +++ b/jsonschema-module-gson/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + + com.github.victools + jsonschema-generator-parent + 4.35.0 + ../jsonschema-generator-parent/pom.xml + + jsonschema-module-gson + + Java JSON Schema Generator Module – GSON + Module for the jsonschema-generator – deriving JSON Schema attributes from GSON annotations + https://github.com/victools/jsonschema-generator + + + com.github.victools.jsonschema.module.gson + + + + + com.github.victools + jsonschema-generator + provided + + + com.google.code.gson + gson + provided + + + + + + + maven-compiler-plugin + + + maven-checkstyle-plugin + + + maven-source-plugin + + + maven-javadoc-plugin + + + org.moditect + moditect-maven-plugin + + + + + \ No newline at end of file diff --git a/jsonschema-module-gson/src/main/java/com/github/victools/jsonschema/module/gson/GsonModule.java b/jsonschema-module-gson/src/main/java/com/github/victools/jsonschema/module/gson/GsonModule.java new file mode 100644 index 00000000..6e77ebaa --- /dev/null +++ b/jsonschema-module-gson/src/main/java/com/github/victools/jsonschema/module/gson/GsonModule.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019 VicTools. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.victools.jsonschema.module.gson; +import com.github.victools.jsonschema.generator.Module; +import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import java.util.Optional; + +/** + * Module for setting up schema generation aspects based on {@code gson-annotations}. + * + */ +public class GsonModule implements Module { + + /** + * Constructor, without any additional options. + * + * @see GsonModule + */ + public GsonModule() { + } + + @Override + public void applyToConfigBuilder(SchemaGeneratorConfigBuilder builder) { + //if the field should be included yes/no based on GSON Expose declaration + builder.forFields().withIgnoreCheck(field -> { + Expose annotation = field.getAnnotationConsideringFieldAndGetter(Expose.class); + return annotation != null && !annotation.serialize(); + }); + + //Take the property name from the GSON SerializedName declaration + builder.forFields().withPropertyNameOverrideResolver( + field -> Optional.ofNullable(field.getAnnotationConsideringFieldAndGetter(SerializedName.class)) + .map(SerializedName::value).orElse(null)); + } +} diff --git a/jsonschema-module-gson/src/test/java/com/github/victools/jsonschema/module/gson/IntegrationTest.java b/jsonschema-module-gson/src/test/java/com/github/victools/jsonschema/module/gson/IntegrationTest.java new file mode 100644 index 00000000..6273d506 --- /dev/null +++ b/jsonschema-module-gson/src/test/java/com/github/victools/jsonschema/module/gson/IntegrationTest.java @@ -0,0 +1,93 @@ +/* + * Copyright 2020 VicTools. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.victools.jsonschema.module.gson; + +import com.fasterxml.jackson.annotation.JsonClassDescription; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonIdentityReference; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import com.fasterxml.jackson.databind.JsonNode; +import com.github.victools.jsonschema.generator.Option; +import com.github.victools.jsonschema.generator.OptionPreset; +import com.github.victools.jsonschema.generator.SchemaGenerator; +import com.github.victools.jsonschema.generator.SchemaGeneratorConfig; +import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder; +import com.github.victools.jsonschema.generator.SchemaVersion; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Scanner; + +import com.google.gson.annotations.SerializedName; +import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; + +/** + * Integration test of this module being used in a real SchemaGenerator instance. + */ +public class IntegrationTest { + + @Test + public void testIntegration() throws Exception { + GsonModule module = new GsonModule(); + SchemaGeneratorConfig config = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_7, OptionPreset.PLAIN_JSON) + .with(Option.DEFINITIONS_FOR_MEMBER_SUPERTYPES, Option.NULLABLE_ARRAY_ITEMS_ALLOWED) + .with(Option.NONSTATIC_NONVOID_NONGETTER_METHODS, Option.FIELDS_DERIVED_FROM_ARGUMENTFREE_METHODS) + .with(module) + .build(); + SchemaGenerator generator = new SchemaGenerator(config); + JsonNode result = generator.generateSchema(TestClass.class); + + String rawJsonSchema = result.toString(); + System.out.println(rawJsonSchema); + JSONAssert.assertEquals('\n' + rawJsonSchema + '\n', + loadResource("integration-test-result.json"), rawJsonSchema, JSONCompareMode.STRICT); + } + + private static String loadResource(String resourcePath) throws IOException { + StringBuilder stringBuilder = new StringBuilder(); + try (InputStream inputStream = IntegrationTest.class + .getResourceAsStream(resourcePath); + Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name())) { + while (scanner.hasNext()) { + stringBuilder.append(scanner.nextLine()).append('\n'); + } + } + return stringBuilder.toString(); + } + + static class TestClass { + + @SerializedName(value = "field_with_overridden_name") + public boolean originalFieldName; + + public TestEnum enumValueHandledByStandardOption; + + } + + enum TestEnum { + A, B, C + } + +} diff --git a/jsonschema-module-gson/src/test/resources/com/github/victools/jsonschema/module/gson/integration-test-result.json b/jsonschema-module-gson/src/test/resources/com/github/victools/jsonschema/module/gson/integration-test-result.json new file mode 100644 index 00000000..e043f61e --- /dev/null +++ b/jsonschema-module-gson/src/test/resources/com/github/victools/jsonschema/module/gson/integration-test-result.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "enumValueHandledByStandardOption": { + "type": "string", + "enum": [ + "A", + "B", + "C" + ] + }, + "field_with_overridden_name": { + "type": "boolean" + } + } +} \ No newline at end of file diff --git a/jsonschema-module-gson/src/test/resources/logback.xml b/jsonschema-module-gson/src/test/resources/logback.xml new file mode 100644 index 00000000..938180af --- /dev/null +++ b/jsonschema-module-gson/src/test/resources/logback.xml @@ -0,0 +1,12 @@ + + + + + %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n + + + + + + + diff --git a/pom.xml b/pom.xml index 8a8943c0..9c14c553 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ jsonschema-generator-bom jsonschema-generator-parent jsonschema-generator + jsonschema-module-gson jsonschema-module-jackson jsonschema-module-jakarta-validation jsonschema-module-javax-validation