diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index bbf9a3004ac..abc2d1eed96 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -809,6 +809,13 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code return String.format(Locale.ROOT, pattern, typeDeclaration); } else if (ModelUtils.isMapSchema(schema) && !(schema instanceof ComposedSchema)) { + if (schema.getProperties() != null && schema.getProperties().size() > 0) { + // object is complex object with free-form additional properties + if (schema.getDefault() != null) { + return super.toDefaultValue(schema); + } + return null; + } final String pattern; if (fullJavaUtil) { pattern = "new java.util.HashMap<%s>()"; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java index 0a694cffd6b..4e2c6014193 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java @@ -26,6 +26,7 @@ import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenType; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.languages.AbstractJavaCodegen; @@ -524,6 +525,55 @@ public class AbstractJavaCodegenTest { Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SNAPSHOT_VERSION)); } + @Test + public void nullDefaultValueForModelWithDynamicProperties() { + final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/mapSchemas.yaml"); + codegen.additionalProperties().put(CodegenConstants.GENERATE_ALIAS_AS_MODEL, true); + codegen.setOpenAPI(openAPI); + + Schema schema = openAPI.getComponents().getSchemas().get("ModelWithAdditionalProperties"); + CodegenModel cm = codegen.fromModel("ModelWithAdditionalProperties", schema); + Assert.assertEquals(cm.vars.size(), 1, "Expected single declared var"); + Assert.assertEquals(cm.vars.get(0).name, "id"); + Assert.assertNull(cm.defaultValue, "Expected no defined default value in spec"); + + String defaultValue = codegen.toDefaultValue(schema); + Assert.assertNull(defaultValue); + } + + @Test + public void maplikeDefaultValueForModelWithStringToStringMapping() { + final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/mapSchemas.yaml"); + codegen.additionalProperties().put(CodegenConstants.GENERATE_ALIAS_AS_MODEL, true); + codegen.setOpenAPI(openAPI); + + Schema schema = openAPI.getComponents().getSchemas().get("ModelWithStringToStringMapping"); + CodegenModel cm = codegen.fromModel("ModelWithAdditionalProperties", schema); + Assert.assertEquals(cm.vars.size(), 0, "Expected no declared vars"); + Assert.assertNull(cm.defaultValue, "Expected no defined default value in spec"); + + String defaultValue = codegen.toDefaultValue(schema); + Assert.assertEquals(defaultValue, "new HashMap()", "Expected string-string map aliased model to default to new HashMap()"); + } + + @Test + public void maplikeDefaultValueForModelWithStringToModelMapping() { + final P_AbstractJavaCodegen codegen = new P_AbstractJavaCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/mapSchemas.yaml"); + codegen.additionalProperties().put(CodegenConstants.GENERATE_ALIAS_AS_MODEL, true); + codegen.setOpenAPI(openAPI); + + Schema schema = openAPI.getComponents().getSchemas().get("ModelWithStringToModelMapping"); + CodegenModel cm = codegen.fromModel("ModelWithStringToModelMapping", schema); + Assert.assertEquals(cm.vars.size(), 0, "Expected no declared vars"); + Assert.assertNull(cm.defaultValue, "Expected no defined default value in spec"); + + String defaultValue = codegen.toDefaultValue(schema); + Assert.assertEquals(defaultValue, "new HashMap()", "Expected string-ref map aliased model to default to new HashMap()"); + } + private static Schema createObjectSchemaWithMinItems() { return new ObjectSchema() .addProperties("id", new IntegerSchema().format("int32")) diff --git a/modules/openapi-generator/src/test/resources/3_0/mapSchemas.yaml b/modules/openapi-generator/src/test/resources/3_0/mapSchemas.yaml new file mode 100644 index 00000000000..b57ee87455d --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/mapSchemas.yaml @@ -0,0 +1,71 @@ +openapi: "3.0.0" +info: + title: Example API + version: "3.0.0" +paths: + /: + get: + summary: Empty Route + responses: + "200": + description: Good Request. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/FreeformObjectTypes' + "400": + description: Bad Request. + "403": + description: Forbidden. Access denied. + +components: + schemas: + ExampleModel: + type: object + properties: + id: + type: string + withAdditinalProperties: + $ref: '#/components/schemas/ModelWithAdditionalProperties' + ModelWithAdditionalProperties: + type: object + properties: + id: + type: string + additionalProperties: {} + ModelWithStringToStringMapping: + type: object + additionalProperties: + type: string + ModelWithStringToModelMapping: + type: object + additionalProperties: + $ref: '#/components/schemas/ComplexModel' + ComplexModel: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + required: + - name + example: + name: Puma + id: 1 + FreeformObjectTypes: + type: object + properties: + ExampleModel: + $ref: '#/components/schemas/ExampleModel' + ModelWithAdditionalProperties: + $ref: '#/components/schemas/ModelWithAdditionalProperties' + ModelWithStringToStringMapping: + $ref: '#/components/schemas/ModelWithStringToStringMapping' + ModelWithStringToModelMapping: + $ref: '#/components/schemas/ModelWithStringToModelMapping' + ComplexModel: + $ref: '#/components/schemas/ComplexModel'