From 3114c101a581a1b361749ab425d38843e0738878 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Thu, 2 Jan 2025 21:39:16 +0100 Subject: [PATCH] code review --- .../converters/PolymorphicModelConverter.java | 49 ++++++----- .../springdoc/api/app13/SpringDocApp13Test.kt | 27 +++---- .../org/springdoc/api/app13/TestController.kt | 1 - .../springdoc/api/app14/SpringDocApp14Test.kt | 30 +++++++ .../org/springdoc/api/app14/TestController.kt | 47 +++++++++++ .../src/test/resources/results/app14.json | 81 +++++++++++++++++++ 6 files changed, 192 insertions(+), 43 deletions(-) create mode 100644 springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app14/SpringDocApp14Test.kt create mode 100644 springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app14/TestController.kt create mode 100644 springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/app14.json diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java index 1673ce8a1..31ece6e16 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java @@ -110,35 +110,32 @@ else if (resolvedSchema.getProperties().containsKey(javaType.getRawClass().getSi @Override public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator chain) { JavaType javaType = springDocObjectMapper.jsonMapper().constructType(type.getType()); - - if (javaType == null || !chain.hasNext()) { - return null; - } - - for (Field field : FieldUtils.getAllFields(javaType.getRawClass())) { - if (field.isAnnotationPresent(JsonUnwrapped.class)) { - PARENT_TYPES_TO_IGNORE.add(javaType.getRawClass().getSimpleName()); + if (javaType != null) { + for (Field field : FieldUtils.getAllFields(javaType.getRawClass())) { + if (field.isAnnotationPresent(JsonUnwrapped.class)) { + PARENT_TYPES_TO_IGNORE.add(javaType.getRawClass().getSimpleName()); + } } - } - - String parentName = type.getParent() == null ? null : type.getParent().getName(); - if (parentName != null && PARENT_TYPES_TO_IGNORE.stream().noneMatch(parentName::startsWith)){ - type.resolveAsRef(true); - } - - Schema resolvedSchema = getResolvedSchema(javaType, chain.next().resolve(type, context, chain)); - if (resolvedSchema == null || resolvedSchema.get$ref() == null) { - return resolvedSchema; - } - - if(resolvedSchema.get$ref().contains(Components.COMPONENTS_SCHEMAS_REF)) { - String schemaName = resolvedSchema.get$ref().substring(Components.COMPONENTS_SCHEMAS_REF.length()); - Schema existingSchema = context.getDefinedModels().get(schemaName); - if (existingSchema != null && (existingSchema.getOneOf() != null || existingSchema.getAllOf() != null || existingSchema.getAnyOf() != null)) { - return resolvedSchema; + if (chain.hasNext()) { + if (!type.isResolveAsRef() && type.getParent() != null + && PARENT_TYPES_TO_IGNORE.stream().noneMatch(ignore -> type.getParent().getName().startsWith(ignore))) + type.resolveAsRef(true); + Schema resolvedSchema = chain.next().resolve(type, context, chain); + resolvedSchema = getResolvedSchema(javaType, resolvedSchema); + if (resolvedSchema == null || resolvedSchema.get$ref() == null) { + return resolvedSchema; + } + if(resolvedSchema.get$ref().contains(Components.COMPONENTS_SCHEMAS_REF)) { + String schemaName = resolvedSchema.get$ref().substring(Components.COMPONENTS_SCHEMAS_REF.length()); + Schema existingSchema = context.getDefinedModels().get(schemaName); + if (existingSchema != null && (existingSchema.getOneOf() != null || existingSchema.getAllOf() != null)) { + return resolvedSchema; + } + } + return composePolymorphicSchema(type, resolvedSchema, context.getDefinedModels().values()); } } - return composePolymorphicSchema(type, resolvedSchema, context.getDefinedModels().values()); + return null; } /** diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app13/SpringDocApp13Test.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app13/SpringDocApp13Test.kt index 1f2f41145..0cf4ba3c5 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app13/SpringDocApp13Test.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app13/SpringDocApp13Test.kt @@ -23,27 +23,22 @@ import org.springdoc.core.properties.SpringDocConfigProperties.ApiDocs.OpenApiVe import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.test.context.SpringBootTest import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration import test.org.springdoc.api.AbstractKotlinSpringDocMVCTest -@SpringBootTest//(classes = [Config::class]) class SpringDocApp13Test : AbstractKotlinSpringDocMVCTest() { - - @Configuration - class Config{ - @Bean - fun springDocConfigProperties():SpringDocConfigProperties{ - val x= SpringDocConfigProperties() - x.apiDocs.version = OpenApiVersion.OPENAPI_3_1 - return x - } - - } - - - @SpringBootApplication - class DemoApplication + @SpringBootApplication + class DemoApplication { + @Bean + fun springDocConfigProperties():SpringDocConfigProperties{ + val x= SpringDocConfigProperties() + x.apiDocs.version = OpenApiVersion.OPENAPI_3_1 + return x + } + } + } diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app13/TestController.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app13/TestController.kt index 7ec21bac8..e13610707 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app13/TestController.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app13/TestController.kt @@ -19,7 +19,6 @@ package test.org.springdoc.api.app13 -import io.swagger.v3.oas.annotations.OpenAPI31 import io.swagger.v3.oas.annotations.media.Schema import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app14/SpringDocApp14Test.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app14/SpringDocApp14Test.kt new file mode 100644 index 000000000..9d7d5e471 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app14/SpringDocApp14Test.kt @@ -0,0 +1,30 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * 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 + * * + * * https://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 test.org.springdoc.api.app14 + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.context.annotation.ComponentScan +import test.org.springdoc.api.AbstractKotlinSpringDocMVCTest + +class SpringDocApp14Test : AbstractKotlinSpringDocMVCTest() { + + @SpringBootApplication + class DemoApplication + +} diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app14/TestController.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app14/TestController.kt new file mode 100644 index 000000000..3f220e658 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/app14/TestController.kt @@ -0,0 +1,47 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * 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 + * * + * * https://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 test.org.springdoc.api.app14 + +import io.swagger.v3.oas.annotations.media.Schema +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@Schema(description = "Generic description") +data class KeyValue( + val key: String, + val value: String, +) + +@Schema +data class SomeDTO( + @Schema(description = "Description A", allOf = [KeyValue::class]) val field_a: KeyValue, + @Schema(description = "Description B", allOf = [KeyValue::class]) val field_b: KeyValue, +) + +@RestController +@RequestMapping("/test") +class TestController { + + @PostMapping("/test") + fun create(@RequestBody some: SomeDTO) { + + } +} \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/app14.json b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/app14.json new file mode 100644 index 000000000..75e6323d4 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/app14.json @@ -0,0 +1,81 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/test/test": { + "post": { + "tags": [ + "test-controller" + ], + "operationId": "create", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SomeDTO" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK" + } + } + } + } + }, + "components": { + "schemas": { + "KeyValue": { + "required": [ + "key", + "value" + ], + "type": "object", + "description": "Generic description", + "allOf": [ + { + "$ref": "#/components/schemas/KeyValue" + }, + { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + } + ] + }, + "SomeDTO": { + "required": [ + "field_a", + "field_b" + ], + "type": "object", + "properties": { + "field_a": { + "$ref": "#/components/schemas/KeyValue" + }, + "field_b": { + "$ref": "#/components/schemas/KeyValue" + } + } + } + } + } +}