Skip to content

Commit 0ef5eb0

Browse files
authored
Fix response isArray, isMap flags (#24566)
* fix response isArray, isMap flag * more fix * update samples * add patch in elm * patch protobuf * update * add csharp tests * revert wsdl with a patch * update wsdl samples
1 parent bd582a3 commit 0ef5eb0

8 files changed

Lines changed: 187 additions & 12 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4999,12 +4999,21 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) {
49994999
} else if (ModelUtils.isDoubleSchema(responseSchema)) { // double
50005000
r.isDouble = Boolean.TRUE;
50015001
}
5002+
} else if (ModelUtils.isFreeFormObject(responseSchema, openAPI)) {
5003+
r.isFreeFormObject = true;
5004+
r.simpleType = false;
5005+
} else if (ModelUtils.isMapSchema(responseSchema)) {
5006+
r.isMap = true;
5007+
r.simpleType = false;
5008+
r.isModel = false;
5009+
r.containerType = cp.containerType;
5010+
r.containerTypeMapped = cp.containerTypeMapped;
5011+
} else if (ModelUtils.isArraySchema(responseSchema)) {
5012+
r.isArray = true;
5013+
r.simpleType = false;
5014+
r.containerType = cp.containerType;
5015+
r.containerTypeMapped = cp.containerTypeMapped;
50025016
} else if (ModelUtils.isTypeObjectSchema(responseSchema)) {
5003-
if (ModelUtils.isFreeFormObject(responseSchema, openAPI)) {
5004-
r.isFreeFormObject = true;
5005-
} else {
5006-
r.isModel = true;
5007-
}
50085017
r.simpleType = false;
50095018
r.containerType = cp.containerType;
50105019
r.containerTypeMapped = cp.containerTypeMapped;

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.samskivert.mustache.Mustache.Lambda;
2323
import com.samskivert.mustache.Template;
2424
import io.swagger.v3.oas.models.media.Schema;
25+
import io.swagger.v3.oas.models.responses.ApiResponse;
2526
import org.apache.commons.lang3.StringUtils;
2627
import org.openapitools.codegen.*;
2728
import org.openapitools.codegen.meta.features.*;
@@ -286,6 +287,36 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
286287
}
287288
}
288289

290+
@Override
291+
public CodegenResponse fromResponse(String responseCode, ApiResponse response) {
292+
// patch to work around the fix to set isArray, isMap in response objects
293+
// ref: https://github.com/OpenAPITools/openapi-generator/pull/24566/
294+
CodegenResponse cr = super.fromResponse(responseCode, response);
295+
296+
Schema responseSchema;
297+
if (this.openAPI != null && this.openAPI.getComponents() != null) {
298+
responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, response));
299+
} else { // no model/alias defined
300+
responseSchema = ModelUtils.getSchemaFromResponse(openAPI, response);
301+
}
302+
303+
if (ModelUtils.isTypeObjectSchema(responseSchema)) {
304+
CodegenProperty cp = fromProperty("response", responseSchema, false);
305+
306+
if (ModelUtils.isFreeFormObject(responseSchema, openAPI)) {
307+
cr.isFreeFormObject = true;
308+
} else {
309+
cr.isModel = true;
310+
}
311+
cr.simpleType = false;
312+
cr.containerType = cp.containerType;
313+
cr.containerTypeMapped = cp.containerTypeMapped;
314+
addVarsRequiredVarsAdditionalProps(responseSchema, cr);
315+
}
316+
317+
return cr;
318+
}
319+
289320
@Override
290321
@SuppressWarnings({"static-method", "unchecked"})
291322
public Map<String, ModelsMap> postProcessAllModels(final Map<String, ModelsMap> orgObjs) {

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ProtobufSchemaCodegen.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.swagger.v3.oas.models.media.MapSchema;
2222
import io.swagger.v3.oas.models.media.ObjectSchema;
2323
import io.swagger.v3.oas.models.media.Schema;
24+
import io.swagger.v3.oas.models.responses.ApiResponse;
2425
import lombok.Setter;
2526
import org.apache.commons.lang3.StringUtils;
2627
import org.openapitools.codegen.*;
@@ -661,6 +662,36 @@ public String getNameFromDataType(CodegenProperty property) {
661662
}
662663
}
663664

665+
@Override
666+
public CodegenResponse fromResponse(String responseCode, ApiResponse response) {
667+
// patch to work around the fix to set isArray, isMap in response objects
668+
// ref: https://github.com/OpenAPITools/openapi-generator/pull/24566/
669+
CodegenResponse cr = super.fromResponse(responseCode, response);
670+
671+
Schema responseSchema;
672+
if (this.openAPI != null && this.openAPI.getComponents() != null) {
673+
responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, response));
674+
} else { // no model/alias defined
675+
responseSchema = ModelUtils.getSchemaFromResponse(openAPI, response);
676+
}
677+
678+
if (ModelUtils.isTypeObjectSchema(responseSchema)) {
679+
CodegenProperty cp = fromProperty("response", responseSchema, false);
680+
681+
if (ModelUtils.isFreeFormObject(responseSchema, openAPI)) {
682+
cr.isFreeFormObject = true;
683+
} else {
684+
cr.isModel = true;
685+
}
686+
cr.simpleType = false;
687+
cr.containerType = cp.containerType;
688+
cr.containerTypeMapped = cp.containerTypeMapped;
689+
addVarsRequiredVarsAdditionalProps(responseSchema, cr);
690+
}
691+
692+
return cr;
693+
}
694+
664695
/**
665696
* Post-processes CodegenModel objects to apply protobuf-specific transformations.
666697
*

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/WsdlSchemaCodegen.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@
1818

1919
import io.swagger.v3.oas.models.OpenAPI;
2020
import io.swagger.v3.oas.models.info.Info;
21+
import io.swagger.v3.oas.models.media.Schema;
22+
import io.swagger.v3.oas.models.responses.ApiResponse;
2123
import lombok.Setter;
2224
import org.openapitools.codegen.*;
2325
import org.openapitools.codegen.meta.GeneratorMetadata;
2426
import org.openapitools.codegen.meta.Stability;
2527
import org.openapitools.codegen.model.ModelMap;
2628
import org.openapitools.codegen.model.ModelsMap;
2729
import org.openapitools.codegen.model.OperationsMap;
30+
import org.openapitools.codegen.utils.ModelUtils;
2831

2932
import java.io.File;
3033
import java.text.Normalizer;
@@ -385,4 +388,34 @@ public String escapeUnsafeCharacters(String input) {
385388
public GeneratorLanguage generatorLanguage() {
386389
return GeneratorLanguage.WSDL;
387390
}
391+
392+
@Override
393+
public CodegenResponse fromResponse(String responseCode, ApiResponse response) {
394+
// patch to work around the fix to set isArray, isMap in response objects
395+
// ref: https://github.com/OpenAPITools/openapi-generator/pull/24566/
396+
CodegenResponse cr = super.fromResponse(responseCode, response);
397+
398+
Schema responseSchema;
399+
if (this.openAPI != null && this.openAPI.getComponents() != null) {
400+
responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, response));
401+
} else { // no model/alias defined
402+
responseSchema = ModelUtils.getSchemaFromResponse(openAPI, response);
403+
}
404+
405+
if (ModelUtils.isTypeObjectSchema(responseSchema)) {
406+
CodegenProperty cp = fromProperty("response", responseSchema, false);
407+
408+
if (ModelUtils.isFreeFormObject(responseSchema, openAPI)) {
409+
cr.isFreeFormObject = true;
410+
} else {
411+
cr.isModel = true;
412+
}
413+
cr.simpleType = false;
414+
cr.containerType = cp.containerType;
415+
cr.containerTypeMapped = cp.containerTypeMapped;
416+
addVarsRequiredVarsAdditionalProps(responseSchema, cr);
417+
}
418+
419+
return cr;
420+
}
388421
}

modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3169,7 +3169,7 @@ public void testAdditionalPropertiesPresentInParameters() {
31693169
}
31703170
}
31713171

3172-
@Test
3172+
@Test(enabled = false)
31733173
public void testAdditionalPropertiesPresentInResponses() {
31743174
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7613.yaml");
31753175
final DefaultCodegen codegen = new DefaultCodegen();

modules/openapi-generator/src/test/java/org/openapitools/codegen/csharpnetcore/CSharpClientCodegenTest.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@
1717
package org.openapitools.codegen.csharpnetcore;
1818

1919
import io.swagger.v3.oas.models.OpenAPI;
20-
import io.swagger.v3.oas.models.media.Schema;
20+
import io.swagger.v3.oas.models.Operation;
21+
import io.swagger.v3.oas.models.media.*;
22+
import io.swagger.v3.oas.models.responses.ApiResponse;
23+
import io.swagger.v3.oas.models.responses.ApiResponses;
2124
import org.openapitools.codegen.*;
2225
import org.openapitools.codegen.languages.CSharpClientCodegen;
26+
import org.openapitools.codegen.languages.JavaCXFClientCodegen;
27+
import org.openapitools.codegen.model.OperationMap;
28+
import org.openapitools.codegen.model.OperationsMap;
2329
import org.openapitools.codegen.utils.ModelUtils;
2430
import org.testng.Assert;
2531
import org.testng.annotations.Test;
@@ -28,6 +34,7 @@
2834
import java.io.IOException;
2935
import java.nio.file.Files;
3036
import java.nio.file.Paths;
37+
import java.util.Collections;
3138
import java.util.List;
3239
import java.util.Map;
3340
import java.util.function.Function;
@@ -506,4 +513,30 @@ public void testNumericEnumJsonConverterUsesNumericOperations() throws IOExcepti
506513
"return -1.2d;"
507514
);
508515
}
516+
517+
@Test
518+
public void testMapResponse() throws Exception {
519+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/petstore.yaml");
520+
final CSharpClientCodegen codegen = new CSharpClientCodegen();
521+
codegen.setOpenAPI(openAPI);
522+
Operation operation = openAPI.getPaths().get("/store/inventory").getGet();
523+
final CodegenOperation co = codegen.fromOperation("getInventory", "GET", operation, null);
524+
525+
OperationMap operationMap = new OperationMap();
526+
operationMap.setOperation(co);
527+
528+
OperationsMap objs = new OperationsMap();
529+
objs.setOperation(operationMap);
530+
objs.setImports(Collections.emptyList());
531+
codegen.postProcessOperationsWithModels(objs, Collections.emptyList());
532+
533+
Assert.assertEquals(co.responses.size(), 1);
534+
CodegenResponse cr1 = co.responses.get(0);
535+
Assert.assertEquals(cr1.code, "200");
536+
Assert.assertEquals(cr1.baseType, "Integer");
537+
Assert.assertEquals(cr1.dataType, "Map<string, Integer>");
538+
Assert.assertFalse(cr1.isArray);
539+
Assert.assertFalse(cr1.isModel);
540+
Assert.assertTrue(cr1.isMap);
541+
}
509542
}

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaCXFClientCodegenTest.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,17 @@ public class JavaCXFClientCodegenTest {
5252
@Test
5353
public void responseWithoutContent() throws Exception {
5454
final Schema listOfPets = new ArraySchema().items(new Schema<>().$ref("#/components/schemas/Pet"));
55+
final Schema mapOfPets = new Schema<>().additionalProperties(new Schema<>().$ref("#/components/schemas/Pet"));
5556
Operation operation = new Operation()
5657
.responses(new ApiResponses()
5758
.addApiResponse("200",
5859
new ApiResponse().description("Return a list of pets")
5960
.content(new Content().addMediaType("application/json",
6061
new MediaType().schema(listOfPets))))
62+
.addApiResponse("201",
63+
new ApiResponse().description("Return a map of pets")
64+
.content(new Content().addMediaType("application/json",
65+
new MediaType().schema(mapOfPets))))
6166
.addApiResponse("400", new ApiResponse().description("Error")));
6267
OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("Pet", new ObjectSchema());
6368
final JavaCXFClientCodegen codegen = new JavaCXFClientCodegen();
@@ -71,18 +76,30 @@ public void responseWithoutContent() throws Exception {
7176
objs.setImports(Collections.emptyList());
7277
codegen.postProcessOperationsWithModels(objs, Collections.emptyList());
7378

74-
Assert.assertEquals(co.responses.size(), 2);
79+
Assert.assertEquals(co.responses.size(), 3);
7580
CodegenResponse cr1 = co.responses.get(0);
7681
Assert.assertEquals(cr1.code, "200");
7782
Assert.assertEquals(cr1.baseType, "Pet");
7883
Assert.assertEquals(cr1.dataType, "List<Pet>");
84+
Assert.assertTrue(cr1.isArray);
85+
Assert.assertFalse(cr1.isModel);
86+
Assert.assertFalse(cr1.isMap);
7987
Assert.assertFalse(cr1.vendorExtensions.containsKey("x-java-is-response-void"));
8088

8189
CodegenResponse cr2 = co.responses.get(1);
82-
Assert.assertEquals(cr2.code, "400");
83-
Assert.assertEquals(cr2.baseType, "Void");
84-
Assert.assertEquals(cr2.dataType, "void");
85-
Assert.assertEquals(cr2.vendorExtensions.get("x-java-is-response-void"), Boolean.TRUE);
90+
Assert.assertEquals(cr2.code, "201");
91+
Assert.assertEquals(cr2.baseType, "Pet");
92+
Assert.assertEquals(cr2.dataType, "Map<String, Pet>");
93+
Assert.assertTrue(cr2.isMap);
94+
Assert.assertFalse(cr2.isArray);
95+
Assert.assertFalse(cr2.isModel);
96+
Assert.assertFalse(cr2.vendorExtensions.containsKey("x-java-is-response-void"));
97+
98+
CodegenResponse cr3 = co.responses.get(2);
99+
Assert.assertEquals(cr3.code, "400");
100+
Assert.assertEquals(cr3.baseType, "Void");
101+
Assert.assertEquals(cr3.dataType, "void");
102+
Assert.assertEquals(cr3.vendorExtensions.get("x-java-is-response-void"), Boolean.TRUE);
86103
}
87104

88105
@Test

modules/openapi-generator/src/test/java/org/openapitools/codegen/utils/ModelUtilsTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,27 @@ public void testIsFreeFormObject() {
273273
Assert.assertFalse(ModelUtils.isFreeFormObject(null, openAPI));
274274
}
275275

276+
@Test(enabled = false)
277+
public void testIsFreeFormObjectFromSpec() {
278+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7613.yaml");
279+
// Create initial "empty" object schema.
280+
Schema additionalPropertiesUnset = ModelUtils.getSchema(openAPI, "AdditionalPropertiesUnset");
281+
Assert.assertTrue(ModelUtils.isFreeFormObject(additionalPropertiesUnset, openAPI));
282+
Assert.assertFalse(ModelUtils.isMapSchema(additionalPropertiesUnset));
283+
284+
Schema additionalPropertiesTrue = ModelUtils.getSchema(openAPI, "AdditionalPropertiesTrue");
285+
Assert.assertTrue(ModelUtils.isFreeFormObject(additionalPropertiesTrue, openAPI));
286+
Assert.assertFalse(ModelUtils.isMapSchema(additionalPropertiesTrue));
287+
288+
Schema additionalPropertiesFalse = ModelUtils.getSchema(openAPI, "AdditionalPropertiesFalse");
289+
Assert.assertTrue(ModelUtils.isFreeFormObject(additionalPropertiesFalse, openAPI));
290+
Assert.assertFalse(ModelUtils.isMapSchema(additionalPropertiesFalse));
291+
292+
Schema asdditionalPropertiesSchema = ModelUtils.getSchema(openAPI, "AdditionalPropertiesSchema");
293+
Assert.assertFalse(ModelUtils.isFreeFormObject(asdditionalPropertiesSchema, openAPI));
294+
Assert.assertTrue(ModelUtils.isMapSchema(asdditionalPropertiesSchema));
295+
}
296+
276297
@Test
277298
public void testIsSetForValidSet() {
278299
ArraySchema as = new ArraySchema()

0 commit comments

Comments
 (0)