Skip to content

Commit 67957b2

Browse files
committed
fix (JAVA): example in README for useOneOfInterfaces (#17419)
1 parent d55388b commit 67957b2

File tree

5 files changed

+78
-2
lines changed

5 files changed

+78
-2
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ apiTemplateFiles are for API outputs only (controllers/handlers).
291291
// whether or not the oneOf imports machinery should add oneOf interfaces as imports in implementing classes
292292
protected boolean addOneOfInterfaceImports = false;
293293
protected List<CodegenModel> addOneOfInterfaces = new ArrayList<>();
294+
// set of all classnames that are oneOf interfaces (both synthetic property-level and component-level)
295+
// populated during preprocessOpenAPI(), used by setParameterExampleValue() to avoid "new InterfaceType()"
296+
protected Set<String> oneOfInterfaceNames = new HashSet<>();
294297

295298
// flag to indicate whether to only update files whose contents have changed
296299
protected boolean enableMinimalUpdate = false;
@@ -1084,6 +1087,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
10841087
} else {
10851088
// else this is a component schema, so we will just use that as the oneOf interface model
10861089
addOneOfNameExtension(s, n);
1090+
oneOfInterfaceNames.add(n);
10871091
}
10881092
} else if (ModelUtils.isArraySchema(s)) {
10891093
Schema items = ModelUtils.getSchemaItems(s);
@@ -8491,6 +8495,7 @@ public void addOneOfInterfaceModel(Schema cs, String type) {
84918495
cm.interfaceModels = new ArrayList<>();
84928496

84938497
addOneOfInterfaces.add(cm);
8498+
oneOfInterfaceNames.add(type);
84948499
}
84958500

84968501
public void addImportsToOneOfInterface(List<Map<String, String>> imports) {

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1728,7 +1728,13 @@ public void setParameterExampleValue(CodegenParameter p) {
17281728
example = type + ".fromValue(\"" + example + "\")";
17291729
} else if (!languageSpecificPrimitives.contains(type)) {
17301730
// type is a model class, e.g. User
1731-
example = "new " + type + "()";
1731+
// if useOneOfInterfaces is enabled and the type is a generated oneOf interface,
1732+
// we cannot instantiate it with 'new', so we use null instead
1733+
if (useOneOfInterfaces && oneOfInterfaceNames.contains(type)) {
1734+
example = "null";
1735+
} else {
1736+
example = "new " + type + "()";
1737+
}
17321738
}
17331739

17341740
if (example == null) {

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3897,4 +3897,33 @@ public void testOkHttpGsonClientWithUseOneOfInterfaceShouldntRegisterInterfaceAs
38973897
);
38983898
}
38993899

3900+
@Test(dataProvider = "allJavaClients")
3901+
public void testClientWithUseOneOfInterfaceShouldntInstantiateInterfaceInApiDoc_issue_17419(String client) {
3902+
// given
3903+
final Path output = newTempFolder();
3904+
final CodegenConfigurator configurator = new CodegenConfigurator()
3905+
.setGeneratorName("java")
3906+
.setLibrary(client)
3907+
.setAdditionalProperties(Map.of("useOneOfInterfaces", "true"))
3908+
.setInputSpec("src/test/resources/bugs/issue_17419_readme.yaml")
3909+
.setOutputDir(output.toString().replace("\\", "/"));
3910+
3911+
final ClientOptInput input = configurator.toClientOptInput();
3912+
3913+
// when
3914+
List<File> files = new DefaultGenerator().opts(input).generate();
3915+
3916+
// then
3917+
validateJavaSourceFiles(files);
3918+
3919+
// In every generated Markdown file (README.md, api_doc, etc.) the example for a
3920+
// oneOf interface parameter must not contain "new MyOperationRequest()" since
3921+
// interfaces cannot be instantiated with 'new'.
3922+
files.stream()
3923+
.filter(f -> f.getName().endsWith(".md"))
3924+
.forEach(f -> TestUtils.assertFileNotContains(f.toPath(),
3925+
"new MyOperationRequest()"
3926+
));
3927+
}
3928+
39003929
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
openapi: 3.0.0
2+
info:
3+
title: OneOf interface README bug
4+
version: '1.0'
5+
servers:
6+
- url: 'http://localhost:8080'
7+
paths:
8+
'/myapi/myendpoint':
9+
post:
10+
operationId: myOperation
11+
requestBody:
12+
required: true
13+
content:
14+
application/json:
15+
schema:
16+
$ref: '#/components/schemas/MyOperationRequest'
17+
responses:
18+
'200':
19+
description: OK
20+
components:
21+
schemas:
22+
MyOperationRequest:
23+
oneOf:
24+
- $ref: '#/components/schemas/VariantA'
25+
- $ref: '#/components/schemas/VariantB'
26+
VariantA:
27+
type: object
28+
properties:
29+
fieldA:
30+
type: string
31+
VariantB:
32+
type: object
33+
properties:
34+
fieldB:
35+
type: integer
36+

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,7 @@
12321232
<junit.version>5.10.2</junit.version>
12331233
<kotlin.version>1.6.21</kotlin.version>
12341234
<kotlin-compiler-embeddable.version>1.6.21</kotlin-compiler-embeddable.version>
1235-
<lombok.version>1.18.30</lombok.version>
1235+
<lombok.version>1.18.38</lombok.version>
12361236
<maven-dependency-plugin.version>3.8.1</maven-dependency-plugin.version>
12371237
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
12381238
<maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>

0 commit comments

Comments
 (0)