From 4938865785f5ab8f820408a0390aede9d13a70bb Mon Sep 17 00:00:00 2001 From: Carsten Wickner <11309681+CarstenWickner@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:01:18 +0100 Subject: [PATCH] feat: extend support for void methods (#441) --- CHANGELOG.md | 6 ++++ .../impl/SchemaGenerationContextImpl.java | 7 ++++- .../impl/module/FlattenedWrapperModule.java | 2 +- .../impl/module/SimpleTypeModule.java | 5 ++-- .../SchemaGeneratorCustomDefinitionsTest.java | 28 +++++++++++++++++++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3601b9af..7743e5af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### `jsonschema-generator` +#### Added +- check for custom definitions for `void` methods (this may result in exceptions inside custom configuration if a `null` return type is not considered) + +#### Changed +- if present, apply custom definition for `void` methods ## [4.34.0] - 2024-03-14 ### `jsonschema-generator` diff --git a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/SchemaGenerationContextImpl.java b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/SchemaGenerationContextImpl.java index 4c4681c0..a497745b 100644 --- a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/SchemaGenerationContextImpl.java +++ b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/SchemaGenerationContextImpl.java @@ -592,7 +592,12 @@ private JsonNode populateMethodSchema(MethodScope method) { */ private JsonNode createMethodSchema(MemberDetails methodDetails) { if (methodDetails.getScope().isVoid()) { - return BooleanNode.FALSE; + // since 4.35.0: support custom definitions for void methods + CustomDefinition customDefinition = this.generatorConfig.getCustomDefinition(methodDetails.getScope(), this, + methodDetails.getIgnoredDefinitionProvider()); + if (customDefinition == null) { + return BooleanNode.FALSE; + } } ObjectNode subSchema = this.generatorConfig.createObjectNode(); ObjectNode methodAttributes = AttributeCollector.collectMethodAttributes(methodDetails.getScope(), this); diff --git a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/FlattenedWrapperModule.java b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/FlattenedWrapperModule.java index 7db0a59a..716f46a9 100644 --- a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/FlattenedWrapperModule.java +++ b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/FlattenedWrapperModule.java @@ -50,7 +50,7 @@ public FlattenedWrapperModule(Class wrapperType) { * @return whether the given type is deemed to be of the targeted wrapper type in the context of this module */ protected boolean isWrapperType(ResolvedType type) { - return this.wrapperType.isAssignableFrom(type.getErasedType()); + return type != null && this.wrapperType.isAssignableFrom(type.getErasedType()); } /** diff --git a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/SimpleTypeModule.java b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/SimpleTypeModule.java index 4364f132..6d0f6585 100644 --- a/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/SimpleTypeModule.java +++ b/jsonschema-generator/src/main/java/com/github/victools/jsonschema/generator/impl/module/SimpleTypeModule.java @@ -283,13 +283,14 @@ private Map resolvePatternProperties(TypeScope scope) { } private boolean shouldHaveEmptySchema(TypeScope scope) { - return SchemaKeyword.TAG_TYPE_NULL == this.fixedJsonSchemaTypes.get(scope.getType().getErasedType()); + return scope.getType() == null + || SchemaKeyword.TAG_TYPE_NULL == this.fixedJsonSchemaTypes.get(scope.getType().getErasedType()); } /** * Implementation of the {@link CustomDefinitionProviderV2} interface for applying fixed schema definitions for simple java types. */ - private class SimpleTypeDefinitionProvider implements CustomDefinitionProviderV2 { + private final class SimpleTypeDefinitionProvider implements CustomDefinitionProviderV2 { @Override public CustomDefinition provideCustomSchemaDefinition(ResolvedType javaType, SchemaGenerationContext context) { diff --git a/jsonschema-generator/src/test/java/com/github/victools/jsonschema/generator/SchemaGeneratorCustomDefinitionsTest.java b/jsonschema-generator/src/test/java/com/github/victools/jsonschema/generator/SchemaGeneratorCustomDefinitionsTest.java index 39f814a8..21a1c66a 100644 --- a/jsonschema-generator/src/test/java/com/github/victools/jsonschema/generator/SchemaGeneratorCustomDefinitionsTest.java +++ b/jsonschema-generator/src/test/java/com/github/victools/jsonschema/generator/SchemaGeneratorCustomDefinitionsTest.java @@ -26,8 +26,11 @@ import java.util.List; import java.util.Map; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; /** * Test for {@link SchemaGenerator} class. @@ -229,6 +232,25 @@ public void testGenerateSchema_CustomPropertyDefinition(SchemaVersion schemaVers TestUtils.assertGeneratedSchema(result, this.getClass(), "custom-property-definition-" + schemaVersion.name() + ".json"); } + @Test + public void testGenerateSchema_CustomPropertyDefinitionForVoidMethod() throws Exception { + CustomPropertyDefinitionProvider customPropertyDefinitionProvider = (method, context) -> { + if (method.isVoid()) { + return new CustomPropertyDefinition(context.getGeneratorConfig().createObjectNode() + .put(context.getKeyword(SchemaKeyword.TAG_DESCRIPTION), "this method is void")); + } + return null; + }; + SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12, OptionPreset.JAVA_OBJECT); + configBuilder.with(Option.VOID_METHODS); + configBuilder.forMethods() + .withCustomDefinitionProvider(customPropertyDefinitionProvider); + SchemaGenerator generator = new SchemaGenerator(configBuilder.build()); + JsonNode result = generator.generateSchema(TestClassWithVoidMethod.class); + JSONAssert.assertEquals("{\"type\":\"object\",\"properties\":{\"updateSomething()\":{\"description\":\"this method is void\"}}}", + result.toString(), JSONCompareMode.STRICT); + } + private static class TestDirectCircularClass { public int number; @@ -256,4 +278,10 @@ private static class TestCircularClass2 { public List list1; } + + private static class TestClassWithVoidMethod { + public void updateSomething() { + // perform an action + } + } }