Skip to content

Commit 52960b8

Browse files
committed
various fixes
1 parent 3dcb59e commit 52960b8

13 files changed

Lines changed: 157 additions & 13 deletions

File tree

bin/configs/java-okhttp-gson.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ parameterNameMappings:
1010
_type: underscoreType
1111
type_: typeWithUnderscore
1212
additionalProperties:
13-
defaultToEmptyContainer: "array?|map?"
13+
defaultToEmptyContainer: "array?|array|map?"
1414
artifactId: petstore-okhttp-gson
1515
hideGenerationTimestamp: true
1616
useOneOfDiscriminatorLookup: true

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ public void processOpts() {
401401

402402
if (additionalProperties.containsKey(DEFAULT_TO_EMPTY_CONTAINER) && additionalProperties.get(DEFAULT_TO_EMPTY_CONTAINER) instanceof String) {
403403
parseDefaultToEmptyContainer((String) additionalProperties.get(DEFAULT_TO_EMPTY_CONTAINER));
404+
defaultToEmptyContainer = true;
404405
}
405406
}
406407

@@ -4328,11 +4329,18 @@ void parseDefaultToEmptyContainer(String input) {
43284329
} else {
43294330
LOGGER.error("Skipped invalid container type `{}` in the rule `{}`.", containerType, input);
43304331
}
4332+
} else { // required
4333+
containerType = rule;
4334+
if ("array".equalsIgnoreCase(containerType)) {
4335+
arrayDefaultToEmpty = true;
4336+
} else if ("map".equalsIgnoreCase(containerType)) {
4337+
mapDefaultToEmpty = true;
4338+
} else {
4339+
LOGGER.error("Skipped invalid container type `{}` in the rule `{}`.", containerType, input);
4340+
}
43314341
}
43324342

4333-
defaultToEmptyContainer = true;
43344343
}
4335-
43364344
}
43374345

43384346
/**

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ public String toArrayDefaultValue(CodegenProperty cp, Schema schema) {
12401240
if (schema.getDefault() instanceof ArrayNode) { // array of default values
12411241
ArrayNode _default = (ArrayNode) schema.getDefault();
12421242
if (_default.isEmpty()) { // e.g. default: []
1243-
return getDefaultCollectionType(schema);
1243+
return getDefaultCollectionType(schema, "");
12441244
}
12451245

12461246
List<String> final_values = _values;
@@ -1253,6 +1253,11 @@ public String toArrayDefaultValue(CodegenProperty cp, Schema schema) {
12531253
_default.forEach((element) -> {
12541254
final_values.add(String.valueOf(element));
12551255
});
1256+
1257+
if (_default != null && _default.isEmpty() && defaultToEmptyContainer) {
1258+
// e.g. [] with the option defaultToEmptyContainer enabled
1259+
return getDefaultCollectionType(schema, "");
1260+
}
12561261
} else { // single value
12571262
_values = java.util.Collections.singletonList(String.valueOf(schema.getDefault()));
12581263
}
@@ -1431,12 +1436,31 @@ private String getDefaultCollectionType(Schema schema) {
14311436

14321437
private String getDefaultCollectionType(Schema schema, String defaultValues) {
14331438
String arrayFormat = "new %s<>(Arrays.asList(%s))";
1439+
1440+
if (defaultToEmptyContainer) {
1441+
// respect the default value in the spec
1442+
if (defaultValues == null) { // default value not provided
1443+
return null;
1444+
} else if (defaultValues.isEmpty()) { // e.g. [] to indicates empty container
1445+
arrayFormat = "new %s<>()";
1446+
return getDefaultCollectionType(arrayFormat, defaultValues, ModelUtils.isSet(schema));
1447+
} else { // default value not empty
1448+
return getDefaultCollectionType(arrayFormat, defaultValues, ModelUtils.isSet(schema));
1449+
}
1450+
}
1451+
14341452
if (defaultValues == null || defaultValues.isEmpty()) {
1453+
// default to empty container even though default value is null
1454+
// to respect default values provided in the spec, set the option `defaultToEmptyContainer` properly
14351455
defaultValues = "";
14361456
arrayFormat = "new %s<>()";
14371457
}
14381458

1439-
if (ModelUtils.isSet(schema)) {
1459+
return getDefaultCollectionType(arrayFormat, defaultValues, ModelUtils.isSet(schema));
1460+
}
1461+
1462+
private String getDefaultCollectionType(String arrayFormat, String defaultValues, boolean isSet) {
1463+
if (isSet) {
14401464
return String.format(Locale.ROOT, arrayFormat,
14411465
instantiationTypes().getOrDefault("set", "LinkedHashSet"), defaultValues);
14421466
}

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5501,4 +5501,35 @@ public void testEnumFieldShouldBeFinal_issue21018() throws IOException {
55015501
JavaFileAssert.assertThat(files.get("SomeObject.java"))
55025502
.fileContains("private final String value");
55035503
}
5504+
5505+
@Test
5506+
public void testCollectionTypesWithDefaults_issue_collection() throws IOException {
5507+
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
5508+
output.deleteOnExit();
5509+
5510+
OpenAPI openAPI = new OpenAPIParser()
5511+
.readLocation("src/test/resources/3_0/java/issue_collection.yaml", null, new ParseOptions()).getOpenAPI();
5512+
SpringCodegen codegen = new SpringCodegen();
5513+
codegen.setLibrary(SPRING_CLOUD_LIBRARY);
5514+
codegen.setOutputDir(output.getAbsolutePath());
5515+
codegen.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "xyz.model");
5516+
codegen.additionalProperties().put(CodegenConstants.API_NAME_SUFFIX, "Controller");
5517+
codegen.additionalProperties().put(CodegenConstants.API_PACKAGE, "xyz.controller");
5518+
codegen.additionalProperties().put(CodegenConstants.MODEL_NAME_SUFFIX, "Dto");
5519+
codegen.additionalProperties().put("defaultToEmptyContainer", "array");
5520+
5521+
ClientOptInput input = new ClientOptInput()
5522+
.openAPI(openAPI)
5523+
.config(codegen);
5524+
5525+
DefaultGenerator generator = new DefaultGenerator();
5526+
Map<String, File> files = generator.opts(input).generate().stream()
5527+
.collect(Collectors.toMap(File::getName, Function.identity()));
5528+
5529+
JavaFileAssert.assertThat(files.get("PetDto.java"))
5530+
.fileContains("private List<@Valid TagDto> tags;")
5531+
.fileContains("private List<@Valid TagDto> tagsRequiredList = new ArrayList<>();")
5532+
.fileContains("private List<String> stringList;")
5533+
.fileContains("private List<String> stringRequiredList = new ArrayList<>();");
5534+
}
55045535
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
openapi: 3.0.0
2+
servers:
3+
- url: 'http://petstore.swagger.io/v2'
4+
info:
5+
description: >-
6+
This is a sample server Petstore server. For this sample, you can use the api key
7+
`special-key` to test the authorization filters.
8+
version: 1.0.0
9+
title: OpenAPI Petstore
10+
license:
11+
name: Apache-2.0
12+
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
13+
paths:
14+
'/pet/{petId}':
15+
get:
16+
tags:
17+
- pet
18+
summary: Find pet by ID
19+
description: Returns a single pet
20+
operationId: getPetById
21+
parameters:
22+
- name: petId
23+
in: path
24+
description: ID of pet to return
25+
required: true
26+
schema:
27+
type: integer
28+
format: int64
29+
responses:
30+
'200':
31+
description: successful operation
32+
content:
33+
application/json:
34+
schema:
35+
$ref: '#/components/schemas/Pet'
36+
'400':
37+
description: Invalid ID supplied
38+
'404':
39+
description: Pet not found
40+
components:
41+
schemas:
42+
Tag:
43+
title: Pet Tag
44+
description: A tag for a pet
45+
type: object
46+
properties:
47+
id:
48+
type: integer
49+
format: int64
50+
name:
51+
type: string
52+
Pet:
53+
title: a Pet
54+
description: A pet for sale in the pet store
55+
type: object
56+
required:
57+
- tagsRequiredList
58+
- stringRequiredList
59+
properties:
60+
tags:
61+
type: array
62+
items:
63+
$ref: '#/components/schemas/Tag'
64+
tagsRequiredList:
65+
type: array
66+
items:
67+
$ref: '#/components/schemas/Tag'
68+
stringList:
69+
type: array
70+
items:
71+
type: string
72+
stringRequiredList:
73+
type: array
74+
items:
75+
type: string

samples/client/petstore/java/okhttp-gson/api/openapi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,7 @@ components:
17571757
example: doggie
17581758
type: string
17591759
photoUrls:
1760+
default: []
17601761
items:
17611762
type: string
17621763
type: array
@@ -2639,13 +2640,15 @@ components:
26392640
example: doggie
26402641
type: string
26412642
photoUrls:
2643+
default: []
26422644
items:
26432645
type: string
26442646
type: array
26452647
xml:
26462648
name: photoUrl
26472649
wrapped: true
26482650
tags:
2651+
default: []
26492652
items:
26502653
$ref: '#/components/schemas/Tag'
26512654
type: array
@@ -2773,6 +2776,7 @@ components:
27732776
example: doggie
27742777
type: string
27752778
photoUrls:
2779+
default: []
27762780
items:
27772781
type: string
27782782
type: array
@@ -2841,6 +2845,7 @@ components:
28412845
example: doggie
28422846
type: string
28432847
photoUrls:
2848+
default: []
28442849
items:
28452850
type: string
28462851
type: array
@@ -3132,6 +3137,7 @@ components:
31323137
AllOfModelArrayAnyOf_allOf_linkListColumn1:
31333138
properties:
31343139
value:
3140+
default: []
31353141
items:
31363142
$ref: '#/components/schemas/AllOfModelArrayAnyOf_allOf_linkListColumn1_value'
31373143
type: array

samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/AllOfModelArrayAnyOfAllOfLinkListColumn1.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class AllOfModelArrayAnyOfAllOfLinkListColumn1 {
5656
public static final String SERIALIZED_NAME_VALUE = "value";
5757
@SerializedName(SERIALIZED_NAME_VALUE)
5858
@javax.annotation.Nonnull
59-
private List<AllOfModelArrayAnyOfAllOfLinkListColumn1Value> value;
59+
private List<AllOfModelArrayAnyOfAllOfLinkListColumn1Value> value = new ArrayList<>();
6060

6161
public AllOfModelArrayAnyOfAllOfLinkListColumn1() {
6262
}

samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/NewPet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public class NewPet {
8888
public static final String SERIALIZED_NAME_PHOTO_URLS = "photoUrls";
8989
@SerializedName(SERIALIZED_NAME_PHOTO_URLS)
9090
@javax.annotation.Nonnull
91-
private List<String> photoUrls;
91+
private List<String> photoUrls = new ArrayList<>();
9292

9393
public static final String SERIALIZED_NAME_TAGS = "tags";
9494
@SerializedName(SERIALIZED_NAME_TAGS)

samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/Pet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public class Pet {
7272
public static final String SERIALIZED_NAME_PHOTO_URLS = "photoUrls";
7373
@SerializedName(SERIALIZED_NAME_PHOTO_URLS)
7474
@javax.annotation.Nonnull
75-
private List<String> photoUrls;
75+
private List<String> photoUrls = new ArrayList<>();
7676

7777
public static final String SERIALIZED_NAME_TAGS = "tags";
7878
@SerializedName(SERIALIZED_NAME_TAGS)

samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/PetComposition.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public class PetComposition {
7272
public static final String SERIALIZED_NAME_PHOTO_URLS = "photoUrls";
7373
@SerializedName(SERIALIZED_NAME_PHOTO_URLS)
7474
@javax.annotation.Nonnull
75-
private List<String> photoUrls;
75+
private List<String> photoUrls = new ArrayList<>();
7676

7777
public static final String SERIALIZED_NAME_TAGS = "tags";
7878
@SerializedName(SERIALIZED_NAME_TAGS)

0 commit comments

Comments
 (0)