Skip to content

Commit 25c42df

Browse files
committed
keep original implementation conditionally when needed by @apiresponse annotation for springdoc
1 parent e63615c commit 25c42df

4 files changed

Lines changed: 122 additions & 6 deletions

File tree

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,10 +1147,14 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
11471147
codegenOperation.returnBaseType = "PagedModel";
11481148
// Clear any container flag — PagedModel is not itself a List/array
11491149
codegenOperation.returnContainer = null;
1150-
// Keep the paged schema import (needed for @ApiResponse / springdoc annotations)
11511150
// Add item type import (needed for PagedModel<User> in method signature)
11521151
codegenOperation.imports.add(detected.itemSchemaName);
11531152
codegenOperation.imports.add("PagedModel");
1153+
// Remove paged schema import when no annotations are generated —
1154+
// the class is suppressed and not referenced anywhere
1155+
if (getAnnotationLibrary() == AnnotationLibrary.NONE) {
1156+
codegenOperation.imports.remove(detected.schemaName);
1157+
}
11541158
LOGGER.info("substituteGenericPagedModel: operation '{}': replacing return type '{}' with PagedModel<{}>",
11551159
codegenOperation.operationId, oldType, detected.itemSchemaName);
11561160
}
@@ -1309,8 +1313,33 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
13091313
objs = super.postProcessAllModels(objs);
13101314

13111315
if (substituteGenericPagedModel && !pagedModelRegistry.isEmpty()) {
1312-
LOGGER.info("substituteGenericPagedModel: detected {} paged-model schema(s): {} — models kept for @ApiResponse annotations",
1313-
pagedModelRegistry.size(), pagedModelRegistry.keySet());
1316+
if (getAnnotationLibrary() == AnnotationLibrary.NONE) {
1317+
// No @ApiResponse annotations are generated when annotationLibrary=none,
1318+
// so paged schemas are not referenced anywhere → safe to suppress.
1319+
Set<String> metaSchemasToSuppress = new HashSet<>();
1320+
for (PagedModelScanUtils.DetectedPagedModel detected : pagedModelRegistry.values()) {
1321+
if (detected.metaSchemaName != null) {
1322+
metaSchemasToSuppress.add(detected.metaSchemaName);
1323+
}
1324+
}
1325+
for (Map.Entry<String, PagedModelScanUtils.DetectedPagedModel> entry : pagedModelRegistry.entrySet()) {
1326+
String schemaName = entry.getKey();
1327+
PagedModelScanUtils.DetectedPagedModel detected = entry.getValue();
1328+
if (objs.remove(schemaName) != null) {
1329+
LOGGER.info("substituteGenericPagedModel: suppressing model '{}' — replaced by PagedModel<{}>",
1330+
schemaName, detected.itemSchemaName);
1331+
}
1332+
}
1333+
for (String metaName : metaSchemasToSuppress) {
1334+
if (objs.remove(metaName) != null) {
1335+
LOGGER.info("substituteGenericPagedModel: suppressing pagination metadata model '{}'"
1336+
+ " — replaced by PagedModel.PageMetadata", metaName);
1337+
}
1338+
}
1339+
} else {
1340+
LOGGER.info("substituteGenericPagedModel: keeping paged-model schemas (annotationLibrary={}) — @ApiResponse annotations reference them",
1341+
getAnnotationLibrary().toCliOptValue());
1342+
}
13141343
}
13151344

13161345
return objs;

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,10 +1357,14 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
13571357
codegenOperation.returnBaseType = "PagedModel";
13581358
// Clear any container flag — PagedModel is not itself a List/array
13591359
codegenOperation.returnContainer = null;
1360-
// Keep the paged schema import (needed for @ApiResponse / springdoc annotations)
13611360
// Add item type import (needed for PagedModel<User> in method signature)
13621361
codegenOperation.imports.add(detected.itemSchemaName);
13631362
codegenOperation.imports.add("PagedModel");
1363+
// Remove paged schema import when no annotations are generated —
1364+
// the class is suppressed and not referenced anywhere
1365+
if (getAnnotationLibrary() == AnnotationLibrary.NONE) {
1366+
codegenOperation.imports.remove(detected.schemaName);
1367+
}
13641368
LOGGER.info("substituteGenericPagedModel: operation '{}': replacing return type '{}' with PagedModel<{}>",
13651369
codegenOperation.operationId, oldType, detected.itemSchemaName);
13661370
}
@@ -1421,8 +1425,33 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
14211425
}
14221426

14231427
if (substituteGenericPagedModel && !pagedModelRegistry.isEmpty()) {
1424-
LOGGER.info("substituteGenericPagedModel: detected {} paged-model schema(s): {} — models kept for @ApiResponse annotations",
1425-
pagedModelRegistry.size(), pagedModelRegistry.keySet());
1428+
if (getAnnotationLibrary() == AnnotationLibrary.NONE) {
1429+
// No @ApiResponse annotations are generated when annotationLibrary=none,
1430+
// so paged schemas are not referenced anywhere → safe to suppress.
1431+
Set<String> metaSchemasToSuppress = new HashSet<>();
1432+
for (PagedModelScanUtils.DetectedPagedModel detected : pagedModelRegistry.values()) {
1433+
if (detected.metaSchemaName != null) {
1434+
metaSchemasToSuppress.add(detected.metaSchemaName);
1435+
}
1436+
}
1437+
for (Map.Entry<String, PagedModelScanUtils.DetectedPagedModel> entry : pagedModelRegistry.entrySet()) {
1438+
String schemaName = entry.getKey();
1439+
PagedModelScanUtils.DetectedPagedModel detected = entry.getValue();
1440+
if (objs.remove(schemaName) != null) {
1441+
LOGGER.info("substituteGenericPagedModel: suppressing model '{}' — replaced by PagedModel<{}>",
1442+
schemaName, detected.itemSchemaName);
1443+
}
1444+
}
1445+
for (String metaName : metaSchemasToSuppress) {
1446+
if (objs.remove(metaName) != null) {
1447+
LOGGER.info("substituteGenericPagedModel: suppressing pagination metadata model '{}'"
1448+
+ " — replaced by PagedModel.PageMetadata", metaName);
1449+
}
1450+
}
1451+
} else {
1452+
LOGGER.info("substituteGenericPagedModel: keeping paged-model schemas (annotationLibrary={}) — @ApiResponse annotations reference them",
1453+
getAnnotationLibrary().toCliOptValue());
1454+
}
14261455
}
14271456

14281457
return objs;

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7271,4 +7271,33 @@ private Map<String, Object> commonPagedModelProps() {
72717271
props.put(SpringCodegen.SUBSTITUTE_GENERIC_PAGED_MODEL, "true");
72727272
return props;
72737273
}
7274+
7275+
/** Properties with annotations disabled — triggers model suppression. */
7276+
private Map<String, Object> noAnnotationPagedModelProps() {
7277+
Map<String, Object> props = commonPagedModelProps();
7278+
props.put(DOCUMENTATION_PROVIDER, "none");
7279+
props.put(ANNOTATION_LIBRARY, "none");
7280+
return props;
7281+
}
7282+
7283+
@Test
7284+
public void substituteGenericPagedModel_suppressesPagedSchemasWhenNoAnnotations() throws IOException {
7285+
// With annotationLibrary=none, @ApiResponse is not generated → paged schemas not referenced
7286+
// → they should be suppressed to avoid generating unused classes
7287+
Map<String, File> files = generateFromContract(
7288+
"src/test/resources/3_0/spring/petstore-paged-model.yaml", SPRING_BOOT, noAnnotationPagedModelProps());
7289+
7290+
assertThat(files).doesNotContainKey("UserPage.java");
7291+
assertThat(files).doesNotContainKey("OrderPage.java");
7292+
assertThat(files).doesNotContainKey("PetPageAllOf.java");
7293+
}
7294+
7295+
@Test
7296+
public void substituteGenericPagedModel_suppressesPageMetaWhenNoAnnotations() throws IOException {
7297+
Map<String, File> files = generateFromContract(
7298+
"src/test/resources/3_0/spring/petstore-paged-model.yaml", SPRING_BOOT, noAnnotationPagedModelProps());
7299+
7300+
assertThat(files).doesNotContainKey("PageMeta.java");
7301+
assertThat(files).doesNotContainKey("PageMetadata.java");
7302+
}
72747303
}

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5630,4 +5630,33 @@ private Map<String, Object> commonKotlinPagedModelProps() {
56305630
props.put(SUBSTITUTE_GENERIC_PAGED_MODEL, "true");
56315631
return props;
56325632
}
5633+
5634+
/** Properties with annotations disabled — triggers model suppression. */
5635+
private Map<String, Object> noAnnotationKotlinPagedModelProps() {
5636+
Map<String, Object> props = commonKotlinPagedModelProps();
5637+
props.put(DOCUMENTATION_PROVIDER, "none");
5638+
props.put(ANNOTATION_LIBRARY, "none");
5639+
return props;
5640+
}
5641+
5642+
@Test
5643+
public void substituteGenericPagedModel_suppressesPagedSchemasWhenNoAnnotations() throws IOException {
5644+
// With annotationLibrary=none, @ApiResponse is not generated → paged schemas not referenced
5645+
// → they should be suppressed to avoid generating unused classes
5646+
Map<String, File> files = generateFromContract(
5647+
"src/test/resources/3_0/spring/petstore-paged-model.yaml", noAnnotationKotlinPagedModelProps());
5648+
5649+
assertThat(files).doesNotContainKey("UserPage.kt");
5650+
assertThat(files).doesNotContainKey("OrderPage.kt");
5651+
assertThat(files).doesNotContainKey("PetPageAllOf.kt");
5652+
}
5653+
5654+
@Test
5655+
public void substituteGenericPagedModel_suppressesPageMetaWhenNoAnnotations() throws IOException {
5656+
Map<String, File> files = generateFromContract(
5657+
"src/test/resources/3_0/spring/petstore-paged-model.yaml", noAnnotationKotlinPagedModelProps());
5658+
5659+
assertThat(files).doesNotContainKey("PageMeta.kt");
5660+
assertThat(files).doesNotContainKey("PageMetadata.kt");
5661+
}
56335662
}

0 commit comments

Comments
 (0)