From 251a81551c4a63bf04e0963c6c40cf79fe9e06ae Mon Sep 17 00:00:00 2001 From: Carsten Wickner Date: Mon, 20 Nov 2023 23:21:05 +0100 Subject: [PATCH] chore(example): add example for basic inheritance support --- .../examples/InheritanceRefExample.java | 96 +++++++++++++++++++ .../jsonschema/examples/ExampleTest.java | 1 + .../InheritanceRefExample-result.json | 56 +++++++++++ 3 files changed, 153 insertions(+) create mode 100644 jsonschema-examples/src/main/java/com/github/victools/jsonschema/examples/InheritanceRefExample.java create mode 100644 jsonschema-examples/src/test/resources/com/github/victools/jsonschema/examples/InheritanceRefExample-result.json diff --git a/jsonschema-examples/src/main/java/com/github/victools/jsonschema/examples/InheritanceRefExample.java b/jsonschema-examples/src/main/java/com/github/victools/jsonschema/examples/InheritanceRefExample.java new file mode 100644 index 00000000..395dfab7 --- /dev/null +++ b/jsonschema-examples/src/main/java/com/github/victools/jsonschema/examples/InheritanceRefExample.java @@ -0,0 +1,96 @@ +/* + * Copyright 2023 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.examples; + +import com.fasterxml.classmate.ResolvedType; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.github.victools.jsonschema.generator.CustomDefinition; +import com.github.victools.jsonschema.generator.CustomDefinitionProviderV2; +import com.github.victools.jsonschema.generator.Option; +import com.github.victools.jsonschema.generator.OptionPreset; +import com.github.victools.jsonschema.generator.SchemaGenerationContext; +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.SchemaKeyword; +import com.github.victools.jsonschema.generator.SchemaVersion; +import java.time.LocalDate; + +/** + * Example created in response to #407. + *
+ * Reference separate definitions for common super types. Show-casing capabilities; but not recommended due to risk of infinite loop. + */ +public class InheritanceRefExample implements SchemaGenerationExampleInterface { + + @Override + public ObjectNode generateSchema() { + SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12, OptionPreset.PLAIN_JSON) + .with(Option.DEFINITIONS_FOR_ALL_OBJECTS); + // ignore all fields declared in super types + configBuilder.forFields() + .withIgnoreCheck(field -> !field.getDeclaringType().equals(field.getDeclarationDetails().getSchemaTargetType())); + // reference super types explicitly + configBuilder.forTypesInGeneral() + // including SubtypeResolver would result in a StackOverflowError as the super reference is again replaced with it subtypes + //.withSubtypeResolver(new SubtypeLookUpExample.ClassGraphSubtypeResolver()) + .withCustomDefinitionProvider(new ParentReferenceDefinitionProvider()); + SchemaGeneratorConfig config = configBuilder.build(); + return new SchemaGenerator(config).generateSchema(TestType.class); + } + + static class ParentReferenceDefinitionProvider implements CustomDefinitionProviderV2 { + @Override + public CustomDefinition provideCustomSchemaDefinition(ResolvedType javaType, SchemaGenerationContext context) { + if (javaType.getErasedType().getSuperclass() == null || javaType.getErasedType().getSuperclass() == Object.class) { + return null; + } + ResolvedType superType = context.getTypeContext().resolve(javaType.getErasedType().getSuperclass()); + // two options here: + // 1. providing "null" as second parameter = multiple hierarchy levels are respected + // 2. providing "this" as second parameter = only one hierarchy level is respected + ObjectNode superTypeReference = context.createStandardDefinitionReference(superType, null); + ObjectNode definition = context.createStandardDefinition(javaType, this); + definition.withArray(context.getKeyword(SchemaKeyword.TAG_ALLOF)) + .add(superTypeReference); + return new CustomDefinition(definition, CustomDefinition.DefinitionType.STANDARD, CustomDefinition.AttributeInclusion.YES); + } + } + + static class TestType { + public Book favoriteBook; + public Poster favoritePoster; + } + + static class Book extends PrintPublication { + public int pageCount; + } + + static class Poster extends PrintPublication { + public boolean forMovie; + } + + static class PrintPublication extends Publication { + public String author; + public String publisher; + } + + static class Publication { + public LocalDate published; + public String title; + } +} diff --git a/jsonschema-examples/src/test/java/com/github/victools/jsonschema/examples/ExampleTest.java b/jsonschema-examples/src/test/java/com/github/victools/jsonschema/examples/ExampleTest.java index 92a4782f..ea49a003 100644 --- a/jsonschema-examples/src/test/java/com/github/victools/jsonschema/examples/ExampleTest.java +++ b/jsonschema-examples/src/test/java/com/github/victools/jsonschema/examples/ExampleTest.java @@ -36,6 +36,7 @@ public class ExampleTest { ExternalRefAnnotationExample.class, ExternalRefPackageExample.class, IfThenElseExample.class, + InheritanceRefExample.class, JacksonDescriptionAsTitleExample.class, JacksonSubtypeDefinitionExample.class, StrictTypeInfoExample.class, diff --git a/jsonschema-examples/src/test/resources/com/github/victools/jsonschema/examples/InheritanceRefExample-result.json b/jsonschema-examples/src/test/resources/com/github/victools/jsonschema/examples/InheritanceRefExample-result.json new file mode 100644 index 00000000..7a7dcb1d --- /dev/null +++ b/jsonschema-examples/src/test/resources/com/github/victools/jsonschema/examples/InheritanceRefExample-result.json @@ -0,0 +1,56 @@ +{ + "$schema" : "https://json-schema.org/draft/2020-12/schema", + "$defs" : { + "Book" : { + "type" : "object", + "properties" : { + "pageCount" : { + "type" : "integer" + } + }, + "$ref" : "#/$defs/PrintPublication" + }, + "Poster" : { + "type" : "object", + "properties" : { + "forMovie" : { + "type" : "boolean" + } + }, + "$ref" : "#/$defs/PrintPublication" + }, + "PrintPublication" : { + "type" : "object", + "properties" : { + "author" : { + "type" : "string" + }, + "publisher" : { + "type" : "string" + } + }, + "$ref" : "#/$defs/Publication" + }, + "Publication" : { + "type" : "object", + "properties" : { + "published" : { + "type" : "string", + "format" : "date" + }, + "title" : { + "type" : "string" + } + } + } + }, + "type" : "object", + "properties" : { + "favoriteBook" : { + "$ref" : "#/$defs/Book" + }, + "favoritePoster" : { + "$ref" : "#/$defs/Poster" + } + } +} \ No newline at end of file