Skip to content

Commit 0f9b9c6

Browse files
committed
Merge branch 'bugfix/allow-useTags=false-for-http-interface2' of https://github.com/Picazsoo/openapi-generator into Picazsoo-bugfix/allow-useTags=false-for-http-interface2
2 parents cc2e80d + 70948e0 commit 0f9b9c6

42 files changed

Lines changed: 577 additions & 218 deletions

File tree

Some content is hidden

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

‎bin/configs/spring-http-interface-reactive-noResponseEntity.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ additionalProperties:
1818
# performBeanValidation should default to "false" when not specified
1919
useResponseEntity: "false"
2020
useSpringBoot3: "true"
21+
useTags: "true"
2122

‎bin/configs/spring-http-interface-reactive.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ additionalProperties:
1717
# useBeanValidation should default to "false" when not specified
1818
# performBeanValidation should default to "false" when not specified
1919
useSpringBoot3: "true"
20-
20+
useTags: "true"

‎bin/configs/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfiguration.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ additionalProperties:
1818
performBeanValidation: "true"
1919
useHttpServiceProxyFactoryInterfacesConfigurator: "true"
2020
useSpringBoot3: "true"
21+
useTags: "true"

‎bin/configs/spring-http-interface.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ additionalProperties:
1818
# useBeanValidation should default to "false" when not specified
1919
# performBeanValidation should default to "false" when not specified
2020
useSpringBoot3: "true"
21+
useTags: "true"

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

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ protected ImmutableMap.Builder<String, Lambda> addMustacheLambdas() {
10731073

10741074
@Override
10751075
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
1076-
if (library.equals(SPRING_BOOT) && !useTags) {
1076+
if ((library.equals(SPRING_BOOT) || library.equals(SPRING_DECLARATIVE_HTTP_INTERFACE_LIBRARY)) && !useTags) {
10771077
String basePath = resourcePath;
10781078
if (basePath.startsWith("/")) {
10791079
basePath = basePath.substring(1);
@@ -1088,6 +1088,10 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera
10881088
} else {
10891089
co.subresourceOperation = !co.path.isEmpty();
10901090
}
1091+
if (SPRING_DECLARATIVE_HTTP_INTERFACE_LIBRARY.equals(library)) {
1092+
super.addOperationToGroup(getUniquePathGroupName(basePath, operations), resourcePath, operation, co, operations);
1093+
return;
1094+
}
10911095
List<CodegenOperation> opList = operations.computeIfAbsent(basePath, k -> new ArrayList<>());
10921096
opList.add(co);
10931097
co.baseName = basePath;
@@ -1096,6 +1100,30 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera
10961100
}
10971101
}
10981102

1103+
private String getUniquePathGroupName(String basePath, Map<String, List<CodegenOperation>> operations) {
1104+
String sanitizedBasePath = sanitizeName(basePath);
1105+
if (sanitizedBasePath.isEmpty()) {
1106+
sanitizedBasePath = "Path";
1107+
} else if (sanitizedBasePath.matches("^\\d.*")) {
1108+
sanitizedBasePath = "Class" + sanitizedBasePath;
1109+
}
1110+
String groupName = camelize(sanitizedBasePath, LOWERCASE_FIRST_LETTER);
1111+
String uniqueGroupName = groupName;
1112+
int suffix = 2;
1113+
while (operations.containsKey(uniqueGroupName)
1114+
&& !getFirstPathSegment(operations.get(uniqueGroupName).get(0).path).equals(basePath)) {
1115+
uniqueGroupName = groupName + suffix++;
1116+
}
1117+
return uniqueGroupName;
1118+
}
1119+
1120+
private String getFirstPathSegment(String path) {
1121+
String basePath = path.startsWith("/") ? path.substring(1) : path;
1122+
int pos = basePath.indexOf("/");
1123+
basePath = pos > 0 ? basePath.substring(0, pos) : basePath;
1124+
return basePath.isEmpty() ? "default" : basePath;
1125+
}
1126+
10991127
/**
11001128
* Whether the current library supports the {@code x-spring-paginated} extension (i.e. a
11011129
* Spring Data {@code Pageable} parameter). Supported for the {@code spring-boot} server and

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,9 @@ protected void applyJackson3Package() {
910910
}
911911

912912
private boolean supportLibraryUseTags() {
913-
return SPRING_BOOT.equals(library) || SPRING_CLOUD_LIBRARY.equals(library);
913+
return SPRING_BOOT.equals(library)
914+
|| SPRING_CLOUD_LIBRARY.equals(library)
915+
|| SPRING_HTTP_INTERFACE.equals(library);
914916
}
915917

916918
/**
@@ -940,6 +942,10 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera
940942
} else {
941943
co.subresourceOperation = !co.path.isEmpty();
942944
}
945+
if (SPRING_HTTP_INTERFACE.equals(library)) {
946+
super.addOperationToGroup(getUniquePathGroupName(basePath, operations), resourcePath, operation, co, operations);
947+
return;
948+
}
943949
final List<CodegenOperation> opList = operations.computeIfAbsent(basePath, k -> new ArrayList<>());
944950
opList.add(co);
945951
co.baseName = basePath;
@@ -949,6 +955,30 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera
949955

950956
}
951957

958+
private String getUniquePathGroupName(String basePath, Map<String, List<CodegenOperation>> operations) {
959+
String sanitizedBasePath = sanitizeName(basePath);
960+
if (sanitizedBasePath.isEmpty()) {
961+
sanitizedBasePath = "Path";
962+
} else if (sanitizedBasePath.matches("^\\d.*")) {
963+
sanitizedBasePath = "Class" + sanitizedBasePath;
964+
}
965+
String groupName = camelize(sanitizedBasePath, LOWERCASE_FIRST_LETTER);
966+
String uniqueGroupName = groupName;
967+
int suffix = 2;
968+
while (operations.containsKey(uniqueGroupName)
969+
&& !getFirstPathSegment(operations.get(uniqueGroupName).get(0).path).equals(basePath)) {
970+
uniqueGroupName = groupName + suffix++;
971+
}
972+
return uniqueGroupName;
973+
}
974+
975+
private String getFirstPathSegment(String path) {
976+
String basePath = path.startsWith("/") ? path.substring(1) : path;
977+
int pos = basePath.indexOf("/");
978+
basePath = pos > 0 ? basePath.substring(0, pos) : basePath;
979+
return basePath.isEmpty() ? "default" : basePath;
980+
}
981+
952982
@Override
953983
public void preprocessOpenAPI(OpenAPI openAPI) {
954984
super.preprocessOpenAPI(openAPI);

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

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,158 @@ public void shouldNotUseTagsForClassname() throws IOException {
13431343
assertThat(notExisting).isNull();
13441344
}
13451345

1346+
@Test
1347+
public void useTags_false_groupsByFirstPathSegment_springHttpInterface() {
1348+
SpringCodegen codegen = new SpringCodegen();
1349+
codegen.setLibrary(SPRING_HTTP_INTERFACE);
1350+
codegen.additionalProperties().put(USE_TAGS, "false");
1351+
codegen.processOpts();
1352+
1353+
CodegenOperation co = new CodegenOperation();
1354+
co.operationId = "findByStatus";
1355+
co.path = "/pet/findByStatus";
1356+
Map<String, List<CodegenOperation>> groups = new HashMap<>();
1357+
1358+
codegen.addOperationToGroup("Pet", "/pet/findByStatus", new Operation(), co, groups);
1359+
1360+
assertTrue(groups.containsKey("pet"));
1361+
assertEquals(co.baseName, "pet");
1362+
}
1363+
1364+
@Test
1365+
public void useTags_true_groupsByTag_springHttpInterface() {
1366+
SpringCodegen codegen = new SpringCodegen();
1367+
codegen.setLibrary(SPRING_HTTP_INTERFACE);
1368+
codegen.additionalProperties().put(USE_TAGS, "true");
1369+
codegen.processOpts();
1370+
1371+
CodegenOperation co = new CodegenOperation();
1372+
co.operationId = "findByStatus";
1373+
Map<String, List<CodegenOperation>> groups = new HashMap<>();
1374+
1375+
codegen.addOperationToGroup("Pet", "/pet/findByStatus", new Operation(), co, groups);
1376+
1377+
assertTrue(groups.containsKey("Pet"));
1378+
}
1379+
1380+
@Test
1381+
public void useTags_false_groupsByFirstPathSegment_sanitizesInvalidIdentifierChars_springHttpInterface() {
1382+
SpringCodegen codegen = new SpringCodegen();
1383+
codegen.setLibrary(SPRING_HTTP_INTERFACE);
1384+
codegen.additionalProperties().put(USE_TAGS, "false");
1385+
codegen.processOpts();
1386+
1387+
CodegenOperation co = new CodegenOperation();
1388+
co.operationId = "dummy";
1389+
co.path = "/another-fake/dummy";
1390+
Map<String, List<CodegenOperation>> groups = new HashMap<>();
1391+
1392+
codegen.addOperationToGroup("$another-fake?", "/another-fake/dummy", new Operation(), co, groups);
1393+
1394+
// the first path segment "another-fake" must be sanitized into a valid Java identifier
1395+
// (no hyphen) instead of being used as-is, which previously produced e.g.
1396+
// "AnotherFakeApi another-fakeHttpProxy()" - invalid Java syntax.
1397+
assertTrue(groups.containsKey("anotherFake"));
1398+
assertEquals(co.baseName, "anotherFake");
1399+
}
1400+
1401+
@Test
1402+
public void useTags_false_pathGroupsRemainDistinctAndOperationIdsUnique_springHttpInterface() {
1403+
SpringCodegen codegen = new SpringCodegen();
1404+
codegen.setLibrary(SPRING_HTTP_INTERFACE);
1405+
codegen.additionalProperties().put(USE_TAGS, "false");
1406+
codegen.processOpts();
1407+
1408+
CodegenOperation first = new CodegenOperation();
1409+
first.operationId = "dummy";
1410+
first.path = "/another-fake/dummy";
1411+
CodegenOperation duplicate = new CodegenOperation();
1412+
duplicate.operationId = "dummy";
1413+
duplicate.path = "/another-fake/other";
1414+
CodegenOperation colliding = new CodegenOperation();
1415+
colliding.operationId = "dummy";
1416+
colliding.path = "/another_fake/dummy";
1417+
Map<String, List<CodegenOperation>> groups = new HashMap<>();
1418+
1419+
codegen.addOperationToGroup("First", "/another-fake/dummy", new Operation(), first, groups);
1420+
codegen.addOperationToGroup("Second", "/another-fake/other", new Operation(), duplicate, groups);
1421+
codegen.addOperationToGroup("Third", "/another_fake/dummy", new Operation(), colliding, groups);
1422+
1423+
assertTrue(groups.containsKey("anotherFake"));
1424+
assertTrue(groups.containsKey("anotherFake2"));
1425+
assertEquals(duplicate.operationId, "dummy_0");
1426+
assertEquals(colliding.baseName, "anotherFake2");
1427+
}
1428+
1429+
@Test
1430+
public void useTags_false_groupsRootOperationsAndPrefixesDigitLeadingPath_springHttpInterface() {
1431+
SpringCodegen codegen = new SpringCodegen();
1432+
codegen.setLibrary(SPRING_HTTP_INTERFACE);
1433+
codegen.additionalProperties().put(USE_TAGS, "false");
1434+
codegen.processOpts();
1435+
1436+
CodegenOperation rootGet = new CodegenOperation();
1437+
rootGet.operationId = "getRoot";
1438+
rootGet.path = "/";
1439+
CodegenOperation rootPost = new CodegenOperation();
1440+
rootPost.operationId = "postRoot";
1441+
rootPost.path = "/";
1442+
CodegenOperation digitLeading = new CodegenOperation();
1443+
digitLeading.operationId = "getPets";
1444+
digitLeading.path = "/123/pets";
1445+
Map<String, List<CodegenOperation>> groups = new HashMap<>();
1446+
1447+
codegen.addOperationToGroup("Root", "/", new Operation(), rootGet, groups);
1448+
codegen.addOperationToGroup("Root", "/", new Operation(), rootPost, groups);
1449+
codegen.addOperationToGroup("Pets", "/123/pets", new Operation(), digitLeading, groups);
1450+
1451+
assertEquals(groups.get("default").size(), 2);
1452+
assertTrue(groups.containsKey("class123"));
1453+
assertEquals(digitLeading.baseName, "class123");
1454+
assertEquals(codegen.toApiName(digitLeading.baseName), "Class123Api");
1455+
}
1456+
1457+
@Test
1458+
public void useTags_false_pathGroupsWithEmptySanitizedNamesRemainDistinct_springHttpInterface() {
1459+
SpringCodegen codegen = new SpringCodegen();
1460+
codegen.setLibrary(SPRING_HTTP_INTERFACE);
1461+
codegen.additionalProperties().put(USE_TAGS, "false");
1462+
codegen.processOpts();
1463+
1464+
CodegenOperation first = new CodegenOperation();
1465+
first.operationId = "first";
1466+
first.path = "/@/first";
1467+
CodegenOperation second = new CodegenOperation();
1468+
second.operationId = "second";
1469+
second.path = "/!/second";
1470+
Map<String, List<CodegenOperation>> groups = new HashMap<>();
1471+
1472+
codegen.addOperationToGroup("First", "/@/first", new Operation(), first, groups);
1473+
codegen.addOperationToGroup("Second", "/!/second", new Operation(), second, groups);
1474+
1475+
assertTrue(groups.containsKey("path"));
1476+
assertTrue(groups.containsKey("path2"));
1477+
assertEquals(codegen.toApiName(second.baseName), "Path2Api");
1478+
}
1479+
1480+
@Test
1481+
public void useTags_false_preservesRawPathGroupName_springCloud() {
1482+
SpringCodegen codegen = new SpringCodegen();
1483+
codegen.setLibrary(SPRING_CLOUD_LIBRARY);
1484+
codegen.additionalProperties().put(USE_TAGS, "false");
1485+
codegen.processOpts();
1486+
1487+
CodegenOperation co = new CodegenOperation();
1488+
co.operationId = "dummy";
1489+
co.path = "/another-fake/dummy";
1490+
Map<String, List<CodegenOperation>> groups = new HashMap<>();
1491+
1492+
codegen.addOperationToGroup("AnotherFake", "/another-fake/dummy", new Operation(), co, groups);
1493+
1494+
assertTrue(groups.containsKey("another-fake"));
1495+
assertEquals(co.baseName, "another-fake");
1496+
}
1497+
13461498
@Test
13471499
public void shouldAddValidAnnotationIntoCollectionWhenBeanValidationIsEnabled_issue14723() throws IOException {
13481500
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();

0 commit comments

Comments
 (0)