Skip to content

Commit e7158a0

Browse files
committed
feat(java-spring, kotlin-spring): add support for substituting generic PagedModel also in spring-cloud code generation
1 parent 1e60f43 commit e7158a0

4 files changed

Lines changed: 128 additions & 8 deletions

File tree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ public KotlinSpringServerCodegen() {
308308
"Detect schemas that represent paginated responses (an object with a 'content' array property and a 'page' "
309309
+ "pagination-metadata property) and replace their generated references with "
310310
+ "PagedModel<T>. By default this uses a generated type in the config package (default 'org.openapitools.configuration'), but `importMappings.PagedModel` can override it to a custom/FQCN-mapped type. The detected page schemas and the pagination metadata "
311-
+ "schema are suppressed from code generation. Only applies when library=spring-boot or spring-declarative-http-interface.",
311+
+ "schema are suppressed from code generation.",
312312
substituteGenericPagedModel);
313313
addSwitch(COMPANION_OBJECT, "Whether to generate companion objects in data classes, enabling companion extensions.", companionObject);
314314
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
@@ -750,7 +750,7 @@ public void processOpts() {
750750
this.setGeneratePageableConstraintValidation(convertPropertyToBoolean(GENERATE_PAGEABLE_CONSTRAINT_VALIDATION));
751751
}
752752
writePropertyBack(GENERATE_PAGEABLE_CONSTRAINT_VALIDATION, generatePageableConstraintValidation);
753-
if (additionalProperties.containsKey(SUBSTITUTE_GENERIC_PAGED_MODEL) && (library.equals(SPRING_BOOT) || library.equals(SPRING_DECLARATIVE_HTTP_INTERFACE_LIBRARY))) {
753+
if (additionalProperties.containsKey(SUBSTITUTE_GENERIC_PAGED_MODEL)) {
754754
this.setSubstituteGenericPagedModel(convertPropertyToBoolean(SUBSTITUTE_GENERIC_PAGED_MODEL));
755755
}
756756
writePropertyBack(SUBSTITUTE_GENERIC_PAGED_MODEL, substituteGenericPagedModel);
@@ -1211,7 +1211,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
12111211
}
12121212
}
12131213

1214-
if ((SPRING_BOOT.equals(library) || SPRING_DECLARATIVE_HTTP_INTERFACE_LIBRARY.equals(library)) && substituteGenericPagedModel) {
1214+
if (substituteGenericPagedModel) {
12151215
pagedModelRegistry = PagedModelScanUtils.scanPagedModels(openAPI);
12161216
if (!pagedModelRegistry.isEmpty()) {
12171217
boolean customMapping = importMapping.containsKey("PagedModel");

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ public SpringCodegen() {
380380
"Detect schemas that represent paginated responses (an object with a 'content' array property and a 'page' "
381381
+ "pagination-metadata property) and replace their generated references with "
382382
+ "PagedModel<T>. By default this uses a generated type in the config package (default 'org.openapitools.configuration'), but `importMappings.PagedModel` can override it to a custom/FQCN-mapped type. The detected page schemas and the pagination metadata "
383-
+ "schema are suppressed from code generation. Only applies when library=spring-boot or spring-http-interface.",
383+
+ "schema are suppressed from code generation.",
384384
substituteGenericPagedModel));
385385

386386
}
@@ -591,9 +591,7 @@ public void processOpts() {
591591

592592
convertPropertyToBooleanAndWriteBack(ADDITIONAL_NOT_NULL_ANNOTATIONS, this::setAdditionalNotNullAnnotations);
593593

594-
if (SPRING_BOOT.equals(library) || SPRING_HTTP_INTERFACE.equals(library)) {
595-
convertPropertyToBooleanAndWriteBack(SUBSTITUTE_GENERIC_PAGED_MODEL, this::setSubstituteGenericPagedModel);
596-
}
594+
convertPropertyToBooleanAndWriteBack(SUBSTITUTE_GENERIC_PAGED_MODEL, this::setSubstituteGenericPagedModel);
597595

598596
if (SPRING_BOOT.equals(library)) {
599597
convertPropertyToBooleanAndWriteBack(AUTO_X_SPRING_PAGINATED, this::setAutoXSpringPaginated);
@@ -873,7 +871,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
873871
}
874872
}
875873

876-
if ((SPRING_BOOT.equals(library) || SPRING_HTTP_INTERFACE.equals(library)) && substituteGenericPagedModel) {
874+
if (substituteGenericPagedModel) {
877875
pagedModelRegistry = PagedModelScanUtils.scanPagedModels(openAPI);
878876
if (!pagedModelRegistry.isEmpty()) {
879877
boolean customMapping = importMapping.containsKey("PagedModel");

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7498,6 +7498,61 @@ private Map<String, Object> springHttpInterfacePagedModelProps() {
74987498
return props;
74997499
}
75007500

7501+
// -------------------------------------------------------------------------
7502+
// substituteGenericPagedModel — spring-cloud
7503+
// -------------------------------------------------------------------------
7504+
7505+
@Test
7506+
public void substituteGenericPagedModel_springCloud_replacesReturnTypeInOperation() throws IOException {
7507+
Map<String, File> files = generateFromContract(
7508+
"src/test/resources/3_0/spring/petstore-paged-model.yaml", SPRING_CLOUD_LIBRARY,
7509+
springCloudPagedModelProps());
7510+
7511+
JavaFileAssert.assertThat(files.get("UserApi.java"))
7512+
.assertMethod("listUsers")
7513+
.hasReturnType("ResponseEntity<PagedModel<User>>");
7514+
}
7515+
7516+
@Test
7517+
public void substituteGenericPagedModel_springCloud_generatesPagedModelSupportingFile() throws IOException {
7518+
Map<String, File> files = generateFromContract(
7519+
"src/test/resources/3_0/spring/petstore-paged-model.yaml", SPRING_CLOUD_LIBRARY,
7520+
springCloudPagedModelProps());
7521+
7522+
assertThat(files).containsKey("PagedModel.java");
7523+
}
7524+
7525+
@Test
7526+
public void substituteGenericPagedModel_springCloud_doesNotGeneratePagedModelFileWhenCustomMapping() throws IOException {
7527+
Map<String, File> files = generateFromContract(
7528+
"src/test/resources/3_0/spring/petstore-paged-model.yaml", SPRING_CLOUD_LIBRARY,
7529+
springCloudPagedModelProps(),
7530+
configurator -> configurator.addImportMapping("PagedModel", "com.example.custom.MyPagedModel"));
7531+
7532+
assertThat(files).doesNotContainKey("PagedModel.java");
7533+
}
7534+
7535+
@Test
7536+
public void substituteGenericPagedModel_springCloud_respectsCustomImportMappingClassName() throws IOException {
7537+
Map<String, File> files = generateFromContract(
7538+
"src/test/resources/3_0/spring/petstore-paged-model.yaml", SPRING_CLOUD_LIBRARY,
7539+
springCloudPagedModelProps(),
7540+
configurator -> configurator.addImportMapping("PagedModel", "com.example.custom.MyPagedModel"));
7541+
7542+
JavaFileAssert.assertThat(files.get("UserApi.java"))
7543+
.hasImports("com.example.custom.MyPagedModel")
7544+
.assertMethod("listUsers")
7545+
.hasReturnType("ResponseEntity<MyPagedModel<User>>");
7546+
}
7547+
7548+
/** Common properties for substituteGenericPagedModel tests using spring-cloud. */
7549+
private Map<String, Object> springCloudPagedModelProps() {
7550+
Map<String, Object> props = new HashMap<>();
7551+
props.put(SpringCodegen.USE_TAGS, "true");
7552+
props.put(SpringCodegen.SUBSTITUTE_GENERIC_PAGED_MODEL, "true");
7553+
return props;
7554+
}
7555+
75017556

75027557
@DataProvider(name = "replaceOneOf")
75037558
public Object[][] replaceOneOf() {

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5833,6 +5833,73 @@ private Map<String, Object> commonDeclarativeHttpInterfacePagedModelProps() {
58335833
return props;
58345834
}
58355835

5836+
// -------------------------------------------------------------------------
5837+
// substituteGenericPagedModel — spring-cloud
5838+
// -------------------------------------------------------------------------
5839+
5840+
@Test
5841+
public void substituteGenericPagedModel_springCloud_replacesReturnTypeInOperation() throws IOException {
5842+
Map<String, File> files = generateFromContract(
5843+
"src/test/resources/3_0/spring/petstore-paged-model.yaml",
5844+
springCloudKotlinPagedModelProps(),
5845+
new HashMap<>(),
5846+
configurator -> configurator.setLibrary(SPRING_CLOUD_LIBRARY));
5847+
5848+
File userApi = files.get("UserApi.kt");
5849+
assertThat(userApi).isNotNull();
5850+
String content = Files.readString(userApi.toPath());
5851+
assertThat(content).contains("PagedModel<User>");
5852+
}
5853+
5854+
@Test
5855+
public void substituteGenericPagedModel_springCloud_generatesPagedModelSupportingFile() throws IOException {
5856+
Map<String, File> files = generateFromContract(
5857+
"src/test/resources/3_0/spring/petstore-paged-model.yaml",
5858+
springCloudKotlinPagedModelProps(),
5859+
new HashMap<>(),
5860+
configurator -> configurator.setLibrary(SPRING_CLOUD_LIBRARY));
5861+
5862+
assertThat(files).containsKey("PagedModel.kt");
5863+
}
5864+
5865+
@Test
5866+
public void substituteGenericPagedModel_springCloud_doesNotGeneratePagedModelFileWhenCustomMapping() throws IOException {
5867+
Map<String, File> files = generateFromContract(
5868+
"src/test/resources/3_0/spring/petstore-paged-model.yaml",
5869+
springCloudKotlinPagedModelProps(),
5870+
new HashMap<>(),
5871+
configurator -> configurator
5872+
.setLibrary(SPRING_CLOUD_LIBRARY)
5873+
.addImportMapping("PagedModel", "com.example.custom.MyPagedModel"));
5874+
5875+
assertThat(files).doesNotContainKey("PagedModel.kt");
5876+
}
5877+
5878+
@Test
5879+
public void substituteGenericPagedModel_springCloud_respectsCustomImportMappingClassName() throws IOException {
5880+
Map<String, File> files = generateFromContract(
5881+
"src/test/resources/3_0/spring/petstore-paged-model.yaml",
5882+
springCloudKotlinPagedModelProps(),
5883+
new HashMap<>(),
5884+
configurator -> configurator
5885+
.setLibrary(SPRING_CLOUD_LIBRARY)
5886+
.addImportMapping("PagedModel", "com.example.custom.MyPagedModel"));
5887+
5888+
File userApi = files.get("UserApi.kt");
5889+
assertThat(userApi).isNotNull();
5890+
String content = Files.readString(userApi.toPath());
5891+
assertThat(content).contains("MyPagedModel<User>");
5892+
assertThat(content).contains("import com.example.custom.MyPagedModel");
5893+
}
5894+
5895+
/** Common properties for substituteGenericPagedModel tests using spring-cloud. */
5896+
private Map<String, Object> springCloudKotlinPagedModelProps() {
5897+
Map<String, Object> props = new HashMap<>();
5898+
props.put(USE_TAGS, "true");
5899+
props.put(SUBSTITUTE_GENERIC_PAGED_MODEL, "true");
5900+
return props;
5901+
}
5902+
58365903
@Test(description = "oneOf with discriminator generates thin sealed interface with Jackson annotations")
58375904
public void testOneOfWithDiscriminatorGeneratesThinInterface() throws IOException {
58385905
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();

0 commit comments

Comments
 (0)