From 754207a636248e8a2384ba78f74ab74ac6006dc6 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Tue, 14 Jan 2025 14:20:18 +0800 Subject: [PATCH] fix schema with just a description --- .../codegen/utils/ModelUtils.java | 149 +++++++++--------- .../codegen/utils/ModelUtilsTest.java | 13 ++ .../test/resources/3_0/null_schema_test.yaml | 15 +- 3 files changed, 101 insertions(+), 76 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index c46de774632..d4059da7d34 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -426,18 +426,18 @@ public class ModelUtils { * A ObjectSchema differs from a MapSchema in the following way: * - An ObjectSchema is not extensible, i.e. it has a fixed number of properties. * - A MapSchema is an object that can be extended with an arbitrary set of properties. - * The payload may include dynamic properties. + * The payload may include dynamic properties. *

* For example, an OpenAPI schema is considered an ObjectSchema in the following scenarios: *

- * - * type: object - * additionalProperties: false - * properties: - * name: - * type: string - * address: - * type: string + *

+ * type: object + * additionalProperties: false + * properties: + * name: + * type: string + * address: + * type: string * * @param schema the OAS schema * @return true if the specified schema is an Object schema. @@ -534,21 +534,21 @@ public class ModelUtils { *

* For example, an OpenAPI schema is considered a MapSchema in the following scenarios: *

- * - * type: object - * additionalProperties: true - * - * type: object - * additionalProperties: - * type: object - * properties: - * code: - * type: integer - * - * allOf: - * - $ref: '#/components/schemas/Class1' - * - $ref: '#/components/schemas/Class2' - * additionalProperties: true + *

+ * type: object + * additionalProperties: true + *

+ * type: object + * additionalProperties: + * type: object + * properties: + * code: + * type: integer + *

+ * allOf: + * - $ref: '#/components/schemas/Class1' + * - $ref: '#/components/schemas/Class2' + * additionalProperties: true * * @param schema the OAS schema * @return true if the specified schema is a Map schema. @@ -840,24 +840,24 @@ public class ModelUtils { * Examples: *

* components: - * schemas: - * arbitraryObject: - * type: object - * description: This is a free-form object. - * The value must be a map of strings to values. The value cannot be 'null'. - * It cannot be array, string, integer, number. - * arbitraryNullableObject: - * type: object - * description: This is a free-form object. - * The value must be a map of strings to values. The value can be 'null', - * It cannot be array, string, integer, number. - * nullable: true - * arbitraryTypeValue: - * description: This is NOT a free-form object. - * The value can be any type except the 'null' value. + * schemas: + * arbitraryObject: + * type: object + * description: This is a free-form object. + * The value must be a map of strings to values. The value cannot be 'null'. + * It cannot be array, string, integer, number. + * arbitraryNullableObject: + * type: object + * description: This is a free-form object. + * The value must be a map of strings to values. The value can be 'null', + * It cannot be array, string, integer, number. + * nullable: true + * arbitraryTypeValue: + * description: This is NOT a free-form object. + * The value can be any type except the 'null' value. * * @param schema potentially containing a '$ref' - * @param openAPI document containing the Schema. + * @param openAPI document containing the Schema. * @return true if it's a free-form object */ public static boolean isFreeFormObject(Schema schema, OpenAPI openAPI) { @@ -999,8 +999,8 @@ public class ModelUtils { /** * Get the schema referenced by $ref to schema's properties, e.g. #/components/schemas/Pet/properties/category. * - * @param openAPI specification being checked - * @param refString schema reference + * @param openAPI specification being checked + * @param refString schema reference * @return schema */ public static Schema getSchemaFromRefToSchemaWithProperties(OpenAPI openAPI, String refString) { @@ -1021,7 +1021,7 @@ public class ModelUtils { /** * Returns true if $ref to a reference to schema's properties, e.g. #/components/schemas/Pet/properties/category. * - * @param refString schema reference + * @param refString schema reference * @return true if $ref to a reference to schema's properties */ public static boolean isRefToSchemaWithProperties(String refString) { @@ -1198,7 +1198,7 @@ public class ModelUtils { /** * Return the first defined Schema for a ApiResponse * - * @param openAPI OpenAPI spec. + * @param openAPI OpenAPI spec. * @param response API response of the operation * @return firstSchema */ @@ -1218,13 +1218,13 @@ public class ModelUtils { * for the 'application/json' content type because it is listed first in the OAS. *

* responses: - * '200': - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/XYZ' - * application/xml: - * ... + * '200': + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/XYZ' + * application/xml: + * ... * * @param content a 'content' section in the OAS specification. * @return the Schema. @@ -1427,7 +1427,7 @@ public class ModelUtils { * any additional properties are allowed. This is equivalent to setting additionalProperties * to the boolean value True or setting additionalProperties: {} * - * @param schema the input schema that may or may not have the additionalProperties keyword. + * @param schema the input schema that may or may not have the additionalProperties keyword. * @return the Schema of the additionalProperties. The null value is returned if no additional * properties are allowed. */ @@ -1540,19 +1540,19 @@ public class ModelUtils { * because 'Animal' specifies a discriminator. *

* animal: - * type: object - * discriminator: - * propertyName: type - * properties: - * type: string + * type: object + * discriminator: + * propertyName: type + * properties: + * type: string * *

* dog: - * allOf: - * - $ref: '#/components/schemas/animal' - * - type: object - * properties: - * breed: string + * allOf: + * - $ref: '#/components/schemas/animal' + * - type: object + * properties: + * breed: string * * @param composedSchema schema (alias or direct reference) * @param allSchemas all schemas @@ -1683,7 +1683,7 @@ public class ModelUtils { * If it's string, return true if it's non-empty. * If the return value is `true`, the schema is a parent. * - * @param schema Schema + * @param schema Schema * @return boolean */ public static boolean isExtensionParent(Schema schema) { @@ -1750,9 +1750,9 @@ public class ModelUtils { * type is one of the elements under 'oneOf'. *

* OptionalOrder: - * oneOf: - * - type: 'null' - * - $ref: '#/components/schemas/Order' + * oneOf: + * - type: 'null' + * - $ref: '#/components/schemas/Order' * * @param schema the OAS composed schema. * @return true if the composed schema is nullable. @@ -1935,7 +1935,7 @@ public class ModelUtils { private static void logWarnMessagesForIneffectiveValidations(Set setValidations, Schema schema, Set effectiveValidations) { setValidations.removeAll(effectiveValidations); setValidations.stream().forEach(validation -> { - LOGGER.warn("Validation '" + validation + "' has no effect on schema '" + getType(schema) +"'. Ignoring!"); + LOGGER.warn("Validation '" + validation + "' has no effect on schema '" + getType(schema) + "'. Ignoring!"); }); } @@ -2214,9 +2214,8 @@ public class ModelUtils { *

* Return true if the schema's type is 'null' or not specified * - * @param schema Schema + * @param schema Schema * @param openAPI OpenAPI - * * @return true if schema is null type */ public static boolean isNullTypeSchema(OpenAPI openAPI, Schema schema) { @@ -2260,11 +2259,14 @@ public class ModelUtils { } // for `type: null` - if (schema.getTypes() == null && schema.get$ref() == null) { + if (schema.getTypes() == null && schema.get$ref() == null + && schema.getDescription() == null) { // ensure it's not schema with just a description return true; } } else { // 3.0.x or 2.x spec - if ((schema.getType() == null || schema.getType().equals("null")) && schema.get$ref() == null) { + if ((schema.getType() == null || schema.getType().equals("null")) + && schema.get$ref() == null + && schema.getDescription() == null) { // ensure it's not schema with just a description return true; } } @@ -2277,9 +2279,8 @@ public class ModelUtils { *

* Return true if the schema can be handled by OpenAPI Generator * - * @param schema Schema + * @param schema Schema * @param openAPI OpenAPIs - * * @return true if schema is null type */ public static boolean isUnsupportedSchema(OpenAPI openAPI, Schema schema) { @@ -2290,7 +2291,7 @@ public class ModelUtils { // dereference the schema schema = ModelUtils.getReferencedSchema(openAPI, schema); - if (schema.getTypes() == null && hasValidation(schema)) { + if (schema.getTypes() == null && hasValidation(schema)) { // just validation without type return true; } else if (schema.getIf() != null && schema.getThen() != null) { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java index 05a3cb48d54..3405a300362 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java @@ -497,9 +497,22 @@ public class ModelUtilsTest { schema = openAPI.getComponents().getSchemas().get("AnyOfTest"); assertFalse(ModelUtils.isNullTypeSchema(openAPI, schema)); + // first element (getAnyOf().get(0)) is a string. no need to test assertTrue(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getAnyOf().get(1))); assertTrue(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getAnyOf().get(2))); assertTrue(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getAnyOf().get(3))); + + schema = openAPI.getComponents().getSchemas().get("OneOfRef"); + assertFalse(ModelUtils.isNullTypeSchema(openAPI, schema)); + assertFalse(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getOneOf().get(0))); + + schema = openAPI.getComponents().getSchemas().get("OneOfMultiRef"); + assertFalse(ModelUtils.isNullTypeSchema(openAPI, schema)); + assertFalse(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getOneOf().get(0))); + assertFalse(ModelUtils.isNullTypeSchema(openAPI, (Schema) schema.getOneOf().get(1))); + + schema = openAPI.getComponents().getSchemas().get("JustDescription"); + assertFalse(ModelUtils.isNullTypeSchema(openAPI, schema)); } @Test diff --git a/modules/openapi-generator/src/test/resources/3_0/null_schema_test.yaml b/modules/openapi-generator/src/test/resources/3_0/null_schema_test.yaml index b7c370080ca..457a3318c09 100644 --- a/modules/openapi-generator/src/test/resources/3_0/null_schema_test.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/null_schema_test.yaml @@ -58,7 +58,7 @@ components: $ref: '#/components/schemas/IntegerRef' number: anyOf: - - $ref: '#/components/schemas/Number' + - $ref: '#/components/schemas/StringRef' AnyOfStringArrayOfString: anyOf: - type: string @@ -85,6 +85,8 @@ components: - $ref: '#/components/schemas/IntegerRef' IntegerRef: type: integer + StringRef: + type: string OneOfAnyType: oneOf: - type: object @@ -93,4 +95,13 @@ components: - type: string - type: integer - type: array - items: {} \ No newline at end of file + items: {} + OneOfRef: + oneOf: + - $ref: '#/components/schemas/IntegerRef' + OneOfMultiRef: + oneOf: + - $ref: '#/components/schemas/IntegerRef' + - $ref: '#/components/schemas/StringRef' + JustDescription: + Description: A schema with just description