Skip to content

Commit b6db4f7

Browse files
authored
[JAVA] fix: oneOf generates incorrect model for primitive types (#16834)
* generate samples * try fix * add new sample for fixed case * also improve native library Other libraries don't need fixes. * add oneOf_twoPrimitives.yaml * generate samples * resolve comment
1 parent 438bf25 commit b6db4f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+4996
-1
lines changed

.github/workflows/samples-java-client-jdk11.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010
- samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
1111
- samples/openapi3/client/petstore/java/jersey2-java8-swagger2/**
1212
- samples/openapi3/client/petstore/java/native**
13+
- samples/client/others/java/okhttp-gson-oneOf/**
1314
- samples/client/others/java/resttemplate-useAbstractionForFiles/**
1415
- samples/client/others/java/webclient-useAbstractionForFiles/**
1516
pull_request:
@@ -21,6 +22,7 @@ on:
2122
- samples/openapi3/client/petstore/java/jersey2-java8-swagger1/**
2223
- samples/openapi3/client/petstore/java/jersey2-java8-swagger2/**
2324
- samples/openapi3/client/petstore/java/native**
25+
- samples/client/others/java/okhttp-gson-oneOf/**
2426
- samples/client/others/java/resttemplate-useAbstractionForFiles/**
2527
- samples/client/others/java/webclient-useAbstractionForFiles/**
2628
jobs:
@@ -65,6 +67,7 @@ jobs:
6567
- samples/client/petstore/java/okhttp-gson-swagger2/
6668
- samples/client/petstore/java/resttemplate-swagger2/
6769
- samples/openapi3/client/petstore/java/jersey2-java8-swagger2/
70+
- samples/client/others/java/okhttp-gson-oneOf/
6871
- samples/client/others/java/resttemplate-useAbstractionForFiles/
6972
- samples/client/others/java/webclient-useAbstractionForFiles/
7073
steps:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
generatorName: java
2+
outputDir: samples/client/others/java/okhttp-gson-oneOf
3+
library: okhttp-gson
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOf_twoPrimitives.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/Java
6+
additionalProperties:
7+
hideGenerationTimestamp: "true"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7248,7 +7248,7 @@ protected void addBodyModelSchema(CodegenParameter codegenParameter, String name
72487248
codegenParameter.description = codegenModelDescription;
72497249
imports.add(codegenParameter.baseType);
72507250

7251-
if (codegenProperty.complexType != null) {
7251+
if (codegenProperty.complexType != null && codegenProperty.getComposedSchemas() == null) {
72527252
imports.add(codegenProperty.complexType);
72537253
}
72547254
}

modules/openapi-generator/src/main/resources/Java/libraries/native/anyof_model.mustache

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
231231
StringJoiner joiner = new StringJoiner("&");
232232

233233
{{#composedSchemas.oneOf}}
234+
{{^vendorExtensions.x-duplicated-data-type}}
234235
if (getActualInstance() instanceof {{{dataType}}}) {
235236
{{#isArray}}
236237
{{#items.isPrimitiveType}}
@@ -352,6 +353,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
352353
{{/isArray}}
353354
return joiner.toString();
354355
}
356+
{{/vendorExtensions.x-duplicated-data-type}}
355357
{{/composedSchemas.oneOf}}
356358
return null;
357359
}

modules/openapi-generator/src/main/resources/Java/libraries/native/oneof_model.mustache

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
264264
StringJoiner joiner = new StringJoiner("&");
265265

266266
{{#composedSchemas.oneOf}}
267+
{{^vendorExtensions.x-duplicated-data-type}}
267268
if (getActualInstance() instanceof {{{dataType}}}) {
268269
{{#isArray}}
269270
{{#items.isPrimitiveType}}
@@ -385,6 +386,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
385386
{{/isArray}}
386387
return joiner.toString();
387388
}
389+
{{/vendorExtensions.x-duplicated-data-type}}
388390
{{/composedSchemas.oneOf}}
389391
return null;
390392
}

modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/anyof_model.mustache

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
4848
{{#composedSchemas}}
4949
{{#anyOf}}
5050
{{^isArray}}
51+
{{^vendorExtensions.x-duplicated-data-type}}
5152
final TypeAdapter<{{{dataType}}}> adapter{{{dataType}}} = gson.getDelegateAdapter(this, TypeToken.get({{{dataType}}}.class));
53+
{{/vendorExtensions.x-duplicated-data-type}}
5254
{{/isArray}}
5355
{{#isArray}}
5456

@@ -68,6 +70,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
6870

6971
{{#composedSchemas}}
7072
{{#anyOf}}
73+
{{^vendorExtensions.x-duplicated-data-type}}
7174
// check if the actual instance is of the type `{{{dataType}}}`
7275
if (value.getActualInstance() instanceof {{#isArray}}List<?>{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}) {
7376
{{#isPrimitiveType}}
@@ -91,6 +94,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
9194
{{/isPrimitiveType}}
9295
{{/isArray}}
9396
}
97+
{{/vendorExtensions.x-duplicated-data-type}}
9498
{{/anyOf}}
9599
{{/composedSchemas}}
96100
throw new IOException("Failed to serialize as the type doesn't match anyOf schemae: {{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}");
@@ -106,6 +110,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
106110
107111
{{#composedSchemas}}
108112
{{#anyOf}}
113+
{{^vendorExtensions.x-duplicated-data-type}}
109114
{{^hasVars}}
110115
// deserialize {{{dataType}}}
111116
try {
@@ -184,6 +189,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
184189
log.log(Level.FINER, "Input data does not match schema '{{{.}}}'", e);
185190
}
186191
{{/hasVars}}
192+
{{/vendorExtensions.x-duplicated-data-type}}
187193
{{/anyOf}}
188194
{{/composedSchemas}}
189195

@@ -210,7 +216,9 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
210216
static {
211217
{{#composedSchemas}}
212218
{{#anyOf}}
219+
{{^vendorExtensions.x-duplicated-data-type}}
213220
schemas.put("{{{dataType}}}", {{{baseType}}}.class);
221+
{{/vendorExtensions.x-duplicated-data-type}}
214222
{{/anyOf}}
215223
{{/composedSchemas}}
216224
}
@@ -238,6 +246,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
238246
{{/isNullable}}
239247
{{#composedSchemas}}
240248
{{#anyOf}}
249+
{{^vendorExtensions.x-duplicated-data-type}}
241250
if (instance instanceof {{#isArray}}List<?>{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}) {
242251
{{#isArray}}
243252
List<?> list = (List<?>) instance;
@@ -252,6 +261,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
252261
{{/isArray}}
253262
}
254263

264+
{{/vendorExtensions.x-duplicated-data-type}}
255265
{{/anyOf}}
256266
{{/composedSchemas}}
257267
throw new RuntimeException("Invalid instance type. Must be {{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}");
@@ -270,6 +280,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
270280

271281
{{#composedSchemas}}
272282
{{#anyOf}}
283+
{{^vendorExtensions.x-duplicated-data-type}}
273284
/**
274285
* Get the actual instance of `{{{dataType}}}`. If the actual instance is not `{{{dataType}}}`,
275286
* the ClassCastException will be thrown.
@@ -280,6 +291,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
280291
public {{{dataType}}} get{{#isArray}}{{complexType}}List{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}() throws ClassCastException {
281292
return ({{{dataType}}})super.getActualInstance();
282293
}
294+
{{/vendorExtensions.x-duplicated-data-type}}
283295
{{/anyOf}}
284296
{{/composedSchemas}}
285297

@@ -294,6 +306,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
294306
ArrayList<String> errorMessages = new ArrayList<>();
295307
{{#composedSchemas}}
296308
{{#anyOf}}
309+
{{^vendorExtensions.x-duplicated-data-type}}
297310
// validate the json string with {{{dataType}}}
298311
try {
299312
{{^hasVars}}
@@ -350,6 +363,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
350363
errorMessages.add(String.format("Deserialization for {{{dataType}}} failed with `%s`.", e.getMessage()));
351364
// continue to the next one
352365
}
366+
{{/vendorExtensions.x-duplicated-data-type}}
353367
{{/anyOf}}
354368
{{/composedSchemas}}
355369
throw new IOException(String.format("The JSON string is invalid for {{classname}} with anyOf schemas: {{#anyOf}}{{{.}}}{{^-last}}, {{/-last}}{{/anyOf}}. no class match the result, expected at least 1. Detailed failure message for anyOf schemas: %s. JSON: %s", errorMessages, jsonElement.toString()));

modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/oneof_model.mustache

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
4848
{{#composedSchemas}}
4949
{{#oneOf}}
5050
{{^isArray}}
51+
{{^vendorExtensions.x-duplicated-data-type}}
5152
final TypeAdapter<{{{dataType}}}> adapter{{{dataType}}} = gson.getDelegateAdapter(this, TypeToken.get({{{dataType}}}.class));
53+
{{/vendorExtensions.x-duplicated-data-type}}
5254
{{/isArray}}
5355
{{#isArray}}
5456

@@ -68,6 +70,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
6870

6971
{{#composedSchemas}}
7072
{{#oneOf}}
73+
{{^vendorExtensions.x-duplicated-data-type}}
7174
// check if the actual instance is of the type `{{{dataType}}}`
7275
if (value.getActualInstance() instanceof {{#isArray}}List<?>{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}) {
7376
{{#isPrimitiveType}}
@@ -91,6 +94,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
9194
{{/isPrimitiveType}}
9295
{{/isArray}}
9396
}
97+
{{/vendorExtensions.x-duplicated-data-type}}
9498
{{/oneOf}}
9599
{{/composedSchemas}}
96100
throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}");
@@ -131,6 +135,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
131135

132136
{{#composedSchemas}}
133137
{{#oneOf}}
138+
{{^vendorExtensions.x-duplicated-data-type}}
134139
{{^hasVars}}
135140
// deserialize {{{dataType}}}
136141
try {
@@ -206,6 +211,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
206211
log.log(Level.FINER, "Input data does not match schema '{{{.}}}'", e);
207212
}
208213
{{/hasVars}}
214+
{{/vendorExtensions.x-duplicated-data-type}}
209215
{{/oneOf}}
210216
{{/composedSchemas}}
211217

@@ -238,7 +244,9 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
238244
static {
239245
{{#composedSchemas}}
240246
{{#oneOf}}
247+
{{^vendorExtensions.x-duplicated-data-type}}
241248
schemas.put("{{{dataType}}}", {{{baseType}}}.class);
249+
{{/vendorExtensions.x-duplicated-data-type}}
242250
{{/oneOf}}
243251
{{/composedSchemas}}
244252
}
@@ -266,6 +274,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
266274
{{/isNullable}}
267275
{{#composedSchemas}}
268276
{{#oneOf}}
277+
{{^vendorExtensions.x-duplicated-data-type}}
269278
if (instance instanceof {{#isArray}}List<?>{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}) {
270279
{{#isArray}}
271280
List<?> list = (List<?>) instance;
@@ -280,6 +289,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
280289
{{/isArray}}
281290
}
282291

292+
{{/vendorExtensions.x-duplicated-data-type}}
283293
{{/oneOf}}
284294
{{/composedSchemas}}
285295
throw new RuntimeException("Invalid instance type. Must be {{#oneOf}}{{{.}}}{{^-last}}, {{/-last}}{{/oneOf}}");
@@ -298,6 +308,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
298308

299309
{{#composedSchemas}}
300310
{{#oneOf}}
311+
{{^vendorExtensions.x-duplicated-data-type}}
301312
/**
302313
* Get the actual instance of `{{{dataType}}}`. If the actual instance is not `{{{dataType}}}`,
303314
* the ClassCastException will be thrown.
@@ -308,6 +319,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
308319
public {{{dataType}}} get{{#isArray}}{{complexType}}List{{/isArray}}{{^isArray}}{{{dataType}}}{{/isArray}}() throws ClassCastException {
309320
return ({{{dataType}}})super.getActualInstance();
310321
}
322+
{{/vendorExtensions.x-duplicated-data-type}}
311323
{{/oneOf}}
312324
{{/composedSchemas}}
313325

@@ -323,6 +335,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
323335
ArrayList<String> errorMessages = new ArrayList<>();
324336
{{#composedSchemas}}
325337
{{#oneOf}}
338+
{{^vendorExtensions.x-duplicated-data-type}}
326339
// validate the json string with {{{dataType}}}
327340
try {
328341
{{^hasVars}}
@@ -379,6 +392,7 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
379392
errorMessages.add(String.format("Deserialization for {{{dataType}}} failed with `%s`.", e.getMessage()));
380393
// continue to the next one
381394
}
395+
{{/vendorExtensions.x-duplicated-data-type}}
382396
{{/oneOf}}
383397
{{/composedSchemas}}
384398
if (validCount != 1) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
openapi: 3.0.3
2+
info:
3+
title: oneOf two primitives
4+
description: oneOf with two entries of type string, see https://github.com/OpenAPITools/openapi-generator/issues/10450
5+
version: 1.0.0
6+
paths:
7+
/myExample:
8+
post:
9+
requestBody:
10+
content:
11+
application/json:
12+
schema:
13+
oneOf:
14+
- type: string
15+
format: ipv4
16+
- type: string
17+
format: ipv6
18+
responses:
19+
200:
20+
description: OK
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
2+
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3+
#
4+
# This file is auto-generated by OpenAPI Generator (https://openapi-generator.tech)
5+
6+
name: Java CI with Maven
7+
8+
on:
9+
push:
10+
branches: [ main, master ]
11+
pull_request:
12+
branches: [ main, master ]
13+
14+
jobs:
15+
build:
16+
name: Build oneOf two primitives
17+
runs-on: ubuntu-latest
18+
strategy:
19+
matrix:
20+
java: [ '8' ]
21+
steps:
22+
- uses: actions/checkout@v2
23+
- name: Set up JDK
24+
uses: actions/setup-java@v2
25+
with:
26+
java-version: ${{ matrix.java }}
27+
distribution: 'temurin'
28+
cache: maven
29+
- name: Build with Maven
30+
run: mvn -B package --no-transfer-progress --file pom.xml
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
*.class
2+
3+
# Mobile Tools for Java (J2ME)
4+
.mtj.tmp/
5+
6+
# Package Files #
7+
*.jar
8+
*.war
9+
*.ear
10+
11+
# exclude jar for gradle wrapper
12+
!gradle/wrapper/*.jar
13+
14+
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
15+
hs_err_pid*
16+
17+
# build files
18+
**/target
19+
target
20+
.gradle
21+
build

0 commit comments

Comments
 (0)