From 3083a1bf030528cd90c3917b4c5f0a0fe3579f40 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Thu, 4 Dec 2025 18:16:49 +0100 Subject: [PATCH 01/12] test --- .../ServiceNameMappingConsistencyTest.java | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 datamodel/odata/odata-generator/src/test/java/com/sap/cloud/sdk/datamodel/odata/generator/ServiceNameMappingConsistencyTest.java diff --git a/datamodel/odata/odata-generator/src/test/java/com/sap/cloud/sdk/datamodel/odata/generator/ServiceNameMappingConsistencyTest.java b/datamodel/odata/odata-generator/src/test/java/com/sap/cloud/sdk/datamodel/odata/generator/ServiceNameMappingConsistencyTest.java new file mode 100644 index 000000000..c7e4348fb --- /dev/null +++ b/datamodel/odata/odata-generator/src/test/java/com/sap/cloud/sdk/datamodel/odata/generator/ServiceNameMappingConsistencyTest.java @@ -0,0 +1,146 @@ +package com.sap.cloud.sdk.datamodel.odata.generator; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Properties; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import com.sap.cloud.sdk.datamodel.odata.utility.NameSource; + +/** + * Test to reproduce and verify the fix for the bug where service name mappings change between the first and second + * generation runs. + * + * Bug description: When generating VDM classes from an EDMX file with a service name like "API_MATERIAL_DOCUMENT_SRV", + * the first generation creates a mapping with packageName=apimaterialdocumentsrv, but the second generation changes it + * to packageName=materialdocumentsrv (the "api" prefix is removed). + */ +class ServiceNameMappingConsistencyTest +{ + @Test + void testServiceNameMappingRemainsConsistentAcrossMultipleGenerations( @TempDir final Path tempDir ) + throws IOException + { + // Setup: Create a minimal test EDMX file with API_MATERIAL_DOCUMENT_SRV as service name + final Path inputDir = tempDir.resolve("input"); + final Path outputDir = tempDir.resolve("output"); + final Path serviceMappingFile = inputDir.resolve("service-mappings.properties"); + + Files.createDirectories(inputDir); + Files.createDirectories(outputDir); + + // Create a minimal EDMX file + final String edmxContent = createMinimalEdmx("API_MATERIAL_DOCUMENT_SRV"); + Files.writeString(inputDir.resolve("API_MATERIAL_DOCUMENT_SRV.edmx"), edmxContent); + + // First generation - no service mapping file exists + final DataModelGenerator generator1 = + new DataModelGenerator() + .withInputDirectory(inputDir.toFile()) + .withOutputDirectory(outputDir.toFile()) + .withServiceNameMapping(serviceMappingFile.toFile()) + .withNameSource(NameSource.NAME) + .withPackageName("test.package") + .withDefaultBasePath("/sap/opu/odata/sap/") + .deleteOutputDirectory(); + + System.out.println("=== First Generation ==="); + System.out.println("Input dir: " + inputDir); + System.out.println("Output dir: " + outputDir); + System.out.println("Service mapping file: " + serviceMappingFile); + System.out.println("Service mapping file exists before: " + Files.exists(serviceMappingFile)); + + generator1.execute(); + + System.out.println("Service mapping file exists after: " + Files.exists(serviceMappingFile)); + if( Files.exists(serviceMappingFile) ) { + System.out.println("File content:"); + System.out.println(Files.readString(serviceMappingFile)); + } + + // Read the generated service mapping file after first run + assertThat(serviceMappingFile).exists(); + final Properties firstRunMappings = new Properties(); + firstRunMappings.load(Files.newInputStream(serviceMappingFile)); + + final String firstRunClassName = firstRunMappings.getProperty("API_MATERIAL_DOCUMENT_SRV.className"); + final String firstRunPackageName = firstRunMappings.getProperty("API_MATERIAL_DOCUMENT_SRV.packageName"); + + System.out.println("First run - className: " + firstRunClassName); + System.out.println("First run - packageName: " + firstRunPackageName); + + // Verify first run generated expected values + assertThat(firstRunClassName).as("First run should generate className").isNotNull().isNotEmpty(); + + assertThat(firstRunPackageName).as("First run should generate packageName").isNotNull().isNotEmpty(); + + // Second generation - service mapping file now exists + new DataModelGenerator() + .withInputDirectory(inputDir.toFile()) + .withOutputDirectory(outputDir.toFile()) + .withServiceNameMapping(serviceMappingFile.toFile()) + .withNameSource(NameSource.NAME) + .withPackageName("test.package") + .withDefaultBasePath("/sap/opu/odata/sap/") + .deleteOutputDirectory() + .execute(); + + // Read the service mapping file after second run + final Properties secondRunMappings = new Properties(); + secondRunMappings.load(Files.newInputStream(serviceMappingFile)); + + final String secondRunClassName = secondRunMappings.getProperty("API_MATERIAL_DOCUMENT_SRV.className"); + final String secondRunPackageName = secondRunMappings.getProperty("API_MATERIAL_DOCUMENT_SRV.packageName"); + + System.out.println("Second run - className: " + secondRunClassName); + System.out.println("Second run - packageName: " + secondRunPackageName); + + // THE BUG: The packageName changes between runs + // This assertion should FAIL before the fix, demonstrating the bug + assertThat(secondRunClassName) + .as("Service mapping className should remain consistent across multiple generation runs") + .isEqualTo(firstRunClassName); + + assertThat(secondRunPackageName) + .as( + "Service mapping packageName should remain consistent across multiple generation runs - BUG: 'api' prefix gets removed on second run") + .isEqualTo(firstRunPackageName); + } + + /** + * Creates a minimal valid OData V2 EDMX file for testing + */ + private String createMinimalEdmx( final String namespace ) + { + return "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + } +} From f6e02edc4f6f76994b3e9704e4c32bb23818dac9 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Dec 2025 10:29:51 +0100 Subject: [PATCH 02/12] Stop reprocessing of existing name --- .../odatav4/generator/EdmService.java | 6 +- .../datamodel/odata/generator/EdmService.java | 10 +- .../ServiceNameMappingConsistencyTest.java | 146 ------------------ 3 files changed, 8 insertions(+), 154 deletions(-) delete mode 100644 datamodel/odata/odata-generator/src/test/java/com/sap/cloud/sdk/datamodel/odata/generator/ServiceNameMappingConsistencyTest.java diff --git a/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java b/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java index 59a6bba61..d379f45e5 100644 --- a/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java +++ b/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java @@ -247,8 +247,7 @@ public Collection getAllServiceActions() public String getJavaPackageName() { final String javaPackageNameKey = name + SERVICE_MAPPINGS_PACKAGE_SUFFIX; - final String javaPackageName = serviceNameMappings.getString(javaPackageNameKey).orElseGet(this::getTitle); - return NamingUtils.serviceNameToJavaPackageName(javaPackageName); + return serviceNameMappings.getString(javaPackageNameKey).orElseGet(() -> NamingUtils.serviceNameToJavaPackageName(getTitle())); } @Override @@ -261,8 +260,7 @@ public String getName() public String getJavaClassName() { final String javaClassNameKey = name + SERVICE_MAPPINGS_CLASS_SUFFIX; - final String javaClassName = serviceNameMappings.getString(javaClassNameKey).orElseGet(this::getTitle); - return NamingUtils.serviceNameToBaseJavaClassName(javaClassName); + return serviceNameMappings.getString(javaClassNameKey).orElseGet(() -> NamingUtils.serviceNameToBaseJavaClassName(getTitle())); } @Override diff --git a/datamodel/odata/odata-generator/src/main/java/com/sap/cloud/sdk/datamodel/odata/generator/EdmService.java b/datamodel/odata/odata-generator/src/main/java/com/sap/cloud/sdk/datamodel/odata/generator/EdmService.java index 392ad6347..3ed45a34e 100644 --- a/datamodel/odata/odata-generator/src/main/java/com/sap/cloud/sdk/datamodel/odata/generator/EdmService.java +++ b/datamodel/odata/odata-generator/src/main/java/com/sap/cloud/sdk/datamodel/odata/generator/EdmService.java @@ -160,8 +160,9 @@ public Collection getAllFunctionImports() public String getJavaPackageName() { final String javaPackageNameKey = name + SERVICE_MAPPINGS_PACKAGE_SUFFIX; - final String javaPackageName = serviceNameMappings.getString(javaPackageNameKey).orElseGet(this::getTitle); - return NamingUtils.serviceNameToJavaPackageName(javaPackageName); + return serviceNameMappings + .getString(javaPackageNameKey) + .orElseGet(() -> NamingUtils.serviceNameToJavaPackageName(getTitle())); } @Override @@ -174,8 +175,9 @@ public String getName() public String getJavaClassName() { final String javaClassNameKey = name + SERVICE_MAPPINGS_CLASS_SUFFIX; - final String javaClassName = serviceNameMappings.getString(javaClassNameKey).orElseGet(this::getTitle); - return NamingUtils.serviceNameToBaseJavaClassName(javaClassName); + return serviceNameMappings + .getString(javaClassNameKey) + .orElseGet(() -> NamingUtils.serviceNameToBaseJavaClassName(getTitle())); } @Override diff --git a/datamodel/odata/odata-generator/src/test/java/com/sap/cloud/sdk/datamodel/odata/generator/ServiceNameMappingConsistencyTest.java b/datamodel/odata/odata-generator/src/test/java/com/sap/cloud/sdk/datamodel/odata/generator/ServiceNameMappingConsistencyTest.java deleted file mode 100644 index c7e4348fb..000000000 --- a/datamodel/odata/odata-generator/src/test/java/com/sap/cloud/sdk/datamodel/odata/generator/ServiceNameMappingConsistencyTest.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.sap.cloud.sdk.datamodel.odata.generator; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Properties; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import com.sap.cloud.sdk.datamodel.odata.utility.NameSource; - -/** - * Test to reproduce and verify the fix for the bug where service name mappings change between the first and second - * generation runs. - * - * Bug description: When generating VDM classes from an EDMX file with a service name like "API_MATERIAL_DOCUMENT_SRV", - * the first generation creates a mapping with packageName=apimaterialdocumentsrv, but the second generation changes it - * to packageName=materialdocumentsrv (the "api" prefix is removed). - */ -class ServiceNameMappingConsistencyTest -{ - @Test - void testServiceNameMappingRemainsConsistentAcrossMultipleGenerations( @TempDir final Path tempDir ) - throws IOException - { - // Setup: Create a minimal test EDMX file with API_MATERIAL_DOCUMENT_SRV as service name - final Path inputDir = tempDir.resolve("input"); - final Path outputDir = tempDir.resolve("output"); - final Path serviceMappingFile = inputDir.resolve("service-mappings.properties"); - - Files.createDirectories(inputDir); - Files.createDirectories(outputDir); - - // Create a minimal EDMX file - final String edmxContent = createMinimalEdmx("API_MATERIAL_DOCUMENT_SRV"); - Files.writeString(inputDir.resolve("API_MATERIAL_DOCUMENT_SRV.edmx"), edmxContent); - - // First generation - no service mapping file exists - final DataModelGenerator generator1 = - new DataModelGenerator() - .withInputDirectory(inputDir.toFile()) - .withOutputDirectory(outputDir.toFile()) - .withServiceNameMapping(serviceMappingFile.toFile()) - .withNameSource(NameSource.NAME) - .withPackageName("test.package") - .withDefaultBasePath("/sap/opu/odata/sap/") - .deleteOutputDirectory(); - - System.out.println("=== First Generation ==="); - System.out.println("Input dir: " + inputDir); - System.out.println("Output dir: " + outputDir); - System.out.println("Service mapping file: " + serviceMappingFile); - System.out.println("Service mapping file exists before: " + Files.exists(serviceMappingFile)); - - generator1.execute(); - - System.out.println("Service mapping file exists after: " + Files.exists(serviceMappingFile)); - if( Files.exists(serviceMappingFile) ) { - System.out.println("File content:"); - System.out.println(Files.readString(serviceMappingFile)); - } - - // Read the generated service mapping file after first run - assertThat(serviceMappingFile).exists(); - final Properties firstRunMappings = new Properties(); - firstRunMappings.load(Files.newInputStream(serviceMappingFile)); - - final String firstRunClassName = firstRunMappings.getProperty("API_MATERIAL_DOCUMENT_SRV.className"); - final String firstRunPackageName = firstRunMappings.getProperty("API_MATERIAL_DOCUMENT_SRV.packageName"); - - System.out.println("First run - className: " + firstRunClassName); - System.out.println("First run - packageName: " + firstRunPackageName); - - // Verify first run generated expected values - assertThat(firstRunClassName).as("First run should generate className").isNotNull().isNotEmpty(); - - assertThat(firstRunPackageName).as("First run should generate packageName").isNotNull().isNotEmpty(); - - // Second generation - service mapping file now exists - new DataModelGenerator() - .withInputDirectory(inputDir.toFile()) - .withOutputDirectory(outputDir.toFile()) - .withServiceNameMapping(serviceMappingFile.toFile()) - .withNameSource(NameSource.NAME) - .withPackageName("test.package") - .withDefaultBasePath("/sap/opu/odata/sap/") - .deleteOutputDirectory() - .execute(); - - // Read the service mapping file after second run - final Properties secondRunMappings = new Properties(); - secondRunMappings.load(Files.newInputStream(serviceMappingFile)); - - final String secondRunClassName = secondRunMappings.getProperty("API_MATERIAL_DOCUMENT_SRV.className"); - final String secondRunPackageName = secondRunMappings.getProperty("API_MATERIAL_DOCUMENT_SRV.packageName"); - - System.out.println("Second run - className: " + secondRunClassName); - System.out.println("Second run - packageName: " + secondRunPackageName); - - // THE BUG: The packageName changes between runs - // This assertion should FAIL before the fix, demonstrating the bug - assertThat(secondRunClassName) - .as("Service mapping className should remain consistent across multiple generation runs") - .isEqualTo(firstRunClassName); - - assertThat(secondRunPackageName) - .as( - "Service mapping packageName should remain consistent across multiple generation runs - BUG: 'api' prefix gets removed on second run") - .isEqualTo(firstRunPackageName); - } - - /** - * Creates a minimal valid OData V2 EDMX file for testing - */ - private String createMinimalEdmx( final String namespace ) - { - return "\n" - + "\n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + ""; - } -} From e3d1f4b84cf65b6c8a321c08063757e9afc99c3b Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Dec 2025 10:40:08 +0100 Subject: [PATCH 03/12] formatting --- .../src/main/resources/serviceNameMappings.properties | 2 +- .../cloud/sdk/datamodel/odatav4/generator/EdmService.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/datamodel/odata-v4/odata-v4-api-sample/src/main/resources/serviceNameMappings.properties b/datamodel/odata-v4/odata-v4-api-sample/src/main/resources/serviceNameMappings.properties index 3a6b8d231..da19d7196 100644 --- a/datamodel/odata-v4/odata-v4-api-sample/src/main/resources/serviceNameMappings.properties +++ b/datamodel/odata-v4/odata-v4-api-sample/src/main/resources/serviceNameMappings.properties @@ -1,4 +1,4 @@ # SDK Grocery Store -SDK_Grocery_Store.className = SdkGroceryStore +SDK_Grocery_Store.className = SDKGroceryStore SDK_Grocery_Store.packageName = sdkgrocerystore diff --git a/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java b/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java index d379f45e5..2e53d4363 100644 --- a/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java +++ b/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java @@ -247,7 +247,9 @@ public Collection getAllServiceActions() public String getJavaPackageName() { final String javaPackageNameKey = name + SERVICE_MAPPINGS_PACKAGE_SUFFIX; - return serviceNameMappings.getString(javaPackageNameKey).orElseGet(() -> NamingUtils.serviceNameToJavaPackageName(getTitle())); + return serviceNameMappings + .getString(javaPackageNameKey) + .orElseGet(() -> NamingUtils.serviceNameToJavaPackageName(getTitle())); } @Override @@ -260,7 +262,9 @@ public String getName() public String getJavaClassName() { final String javaClassNameKey = name + SERVICE_MAPPINGS_CLASS_SUFFIX; - return serviceNameMappings.getString(javaClassNameKey).orElseGet(() -> NamingUtils.serviceNameToBaseJavaClassName(getTitle())); + return serviceNameMappings + .getString(javaClassNameKey) + .orElseGet(() -> NamingUtils.serviceNameToBaseJavaClassName(getTitle())); } @Override From a31c1ab1d319d416adcb0f6157d4d3d7803944ee Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Dec 2025 12:23:25 +0100 Subject: [PATCH 04/12] Target NamingUtils --- .../cloud/sdk/datamodel/odata/utility/NamingUtils.java | 2 +- .../sdk/datamodel/odatav4/generator/EdmService.java | 5 ++--- .../sdk/datamodel/odata/generator/EdmService.java | 10 ++++------ 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java index 530854181..0131070be 100644 --- a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java +++ b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java @@ -82,7 +82,7 @@ public static String serviceNameToBaseJavaClassName( @Nonnull final String servi .replace("ODataServiceFor", "") .replace("RemoteApiFor", "") .replace("ApiFor", "") - .replace("Api", "") + .replaceAll("^(?i)Api", "") .replaceAll("Service$", ""); return formattedName; diff --git a/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java b/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java index 2e53d4363..6c519727c 100644 --- a/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java +++ b/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java @@ -247,9 +247,8 @@ public Collection getAllServiceActions() public String getJavaPackageName() { final String javaPackageNameKey = name + SERVICE_MAPPINGS_PACKAGE_SUFFIX; - return serviceNameMappings - .getString(javaPackageNameKey) - .orElseGet(() -> NamingUtils.serviceNameToJavaPackageName(getTitle())); + final String javaPackageName = serviceNameMappings.getString(javaPackageNameKey).orElseGet(this::getTitle); + return NamingUtils.serviceNameToJavaPackageName(javaPackageName); } @Override diff --git a/datamodel/odata/odata-generator/src/main/java/com/sap/cloud/sdk/datamodel/odata/generator/EdmService.java b/datamodel/odata/odata-generator/src/main/java/com/sap/cloud/sdk/datamodel/odata/generator/EdmService.java index 3ed45a34e..392ad6347 100644 --- a/datamodel/odata/odata-generator/src/main/java/com/sap/cloud/sdk/datamodel/odata/generator/EdmService.java +++ b/datamodel/odata/odata-generator/src/main/java/com/sap/cloud/sdk/datamodel/odata/generator/EdmService.java @@ -160,9 +160,8 @@ public Collection getAllFunctionImports() public String getJavaPackageName() { final String javaPackageNameKey = name + SERVICE_MAPPINGS_PACKAGE_SUFFIX; - return serviceNameMappings - .getString(javaPackageNameKey) - .orElseGet(() -> NamingUtils.serviceNameToJavaPackageName(getTitle())); + final String javaPackageName = serviceNameMappings.getString(javaPackageNameKey).orElseGet(this::getTitle); + return NamingUtils.serviceNameToJavaPackageName(javaPackageName); } @Override @@ -175,9 +174,8 @@ public String getName() public String getJavaClassName() { final String javaClassNameKey = name + SERVICE_MAPPINGS_CLASS_SUFFIX; - return serviceNameMappings - .getString(javaClassNameKey) - .orElseGet(() -> NamingUtils.serviceNameToBaseJavaClassName(getTitle())); + final String javaClassName = serviceNameMappings.getString(javaClassNameKey).orElseGet(this::getTitle); + return NamingUtils.serviceNameToBaseJavaClassName(javaClassName); } @Override From f862640cb845a219f4a6f513793767eeea84f49c Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Dec 2025 12:43:30 +0100 Subject: [PATCH 05/12] fix and test NamingUtils --- .../cloud/sdk/datamodel/odata/utility/NamingUtils.java | 8 ++++---- .../sdk/datamodel/odata/utility/NamingUtilsTest.java | 9 +++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java index 0131070be..61190098d 100644 --- a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java +++ b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java @@ -79,11 +79,11 @@ public static String serviceNameToBaseJavaClassName( @Nonnull final String servi formattedName = formattedName - .replace("ODataServiceFor", "") - .replace("RemoteApiFor", "") - .replace("ApiFor", "") + .replaceAll("^(?i)ODataServiceFor", "") + .replaceAll("^(?i)RemoteApiFor", "") + .replaceAll("^(?i)ApiFor", "") .replaceAll("^(?i)Api", "") - .replaceAll("Service$", ""); + .replaceAll("(?i)Service$", ""); return formattedName; } diff --git a/datamodel/odata-generator-utility/src/test/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java b/datamodel/odata-generator-utility/src/test/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java index 2fd2fcaab..859a75910 100644 --- a/datamodel/odata-generator-utility/src/test/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java +++ b/datamodel/odata-generator-utility/src/test/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java @@ -28,7 +28,10 @@ private static Stream getClassTestCases() Arguments.of("Lower,enumeration", "LowerEnumeration"), Arguments.of("KeepCamelCase", "KeepCamelCase"), Arguments.of("handle_snake_case", "HandleSnakeCase"), - Arguments.of("OData Service for Business Partner", "BusinessPartner")); + Arguments.of("OData Service for Business Partner", "BusinessPartner"), + Arguments.of("API MATERIAL DOCUMENT SRV", "MATERIALDOCUMENTSRV"), + Arguments.of("MATERIALDOCUMENTSRV", "MATERIALDOCUMENTSRV") + ); } @ParameterizedTest @@ -52,7 +55,9 @@ private static Stream getPackageTestCases() Arguments.of("Lower,enumeration", "lowerenumeration"), Arguments.of("KeepCamelCase", "keepcamelcase"), Arguments.of("handle_snake_case", "handlesnakecase"), - Arguments.of("OData Service for Business Partner", "businesspartner")); + Arguments.of("OData Service for Business Partner", "businesspartner"), + Arguments.of("API MATERIAL DOCUMENT SRV", "materialdocumentsrv"), + Arguments.of("materialdocumentsrv", "materialdocumentsrv")); } @ParameterizedTest From 3867d2064fcfea4e6408e1323561c87cc9e4a066 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Dec 2025 12:45:23 +0100 Subject: [PATCH 06/12] Revert change in EdmService --- .../cloud/sdk/datamodel/odatav4/generator/EdmService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java b/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java index 6c519727c..59a6bba61 100644 --- a/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java +++ b/datamodel/odata-v4/odata-v4-generator/src/main/java/com/sap/cloud/sdk/datamodel/odatav4/generator/EdmService.java @@ -261,9 +261,8 @@ public String getName() public String getJavaClassName() { final String javaClassNameKey = name + SERVICE_MAPPINGS_CLASS_SUFFIX; - return serviceNameMappings - .getString(javaClassNameKey) - .orElseGet(() -> NamingUtils.serviceNameToBaseJavaClassName(getTitle())); + final String javaClassName = serviceNameMappings.getString(javaClassNameKey).orElseGet(this::getTitle); + return NamingUtils.serviceNameToBaseJavaClassName(javaClassName); } @Override From ea3bec1222e3799f8ba39ee8dba36a1b12d11f36 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Dec 2025 12:48:09 +0100 Subject: [PATCH 07/12] test --- .../sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/datamodel/odata-generator-utility/src/test/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java b/datamodel/odata-generator-utility/src/test/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java index 859a75910..674ffc70b 100644 --- a/datamodel/odata-generator-utility/src/test/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java +++ b/datamodel/odata-generator-utility/src/test/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtilsTest.java @@ -30,8 +30,7 @@ private static Stream getClassTestCases() Arguments.of("handle_snake_case", "HandleSnakeCase"), Arguments.of("OData Service for Business Partner", "BusinessPartner"), Arguments.of("API MATERIAL DOCUMENT SRV", "MATERIALDOCUMENTSRV"), - Arguments.of("MATERIALDOCUMENTSRV", "MATERIALDOCUMENTSRV") - ); + Arguments.of("MATERIALDOCUMENTSRV", "MATERIALDOCUMENTSRV")); } @ParameterizedTest From c00c71199c1725ef160c7a53cc98e2f99531d22f Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Dec 2025 13:04:57 +0100 Subject: [PATCH 08/12] cleanup --- .../src/main/resources/serviceNameMappings.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datamodel/odata-v4/odata-v4-api-sample/src/main/resources/serviceNameMappings.properties b/datamodel/odata-v4/odata-v4-api-sample/src/main/resources/serviceNameMappings.properties index da19d7196..3a6b8d231 100644 --- a/datamodel/odata-v4/odata-v4-api-sample/src/main/resources/serviceNameMappings.properties +++ b/datamodel/odata-v4/odata-v4-api-sample/src/main/resources/serviceNameMappings.properties @@ -1,4 +1,4 @@ # SDK Grocery Store -SDK_Grocery_Store.className = SDKGroceryStore +SDK_Grocery_Store.className = SdkGroceryStore SDK_Grocery_Store.packageName = sdkgrocerystore From 0d0d9c9d13daacbd6270ee94bb5543eacc87b271 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Dec 2025 14:02:38 +0100 Subject: [PATCH 09/12] cleanup --- release_notes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/release_notes.md b/release_notes.md index 3112514a9..b03a236a7 100644 --- a/release_notes.md +++ b/release_notes.md @@ -20,4 +20,6 @@ ### 🐛 Fixed Issues -- +- Fix unintended modification of `serviceNameMappings.properties` during OData service regeneration altering stored mappings. + Additionally, service name cleanup is now case-insensitive for consistency. + From 11c07c03c012fb4e58accb55ef3a4e42d49f01fc Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Tue, 9 Dec 2025 11:01:20 +0100 Subject: [PATCH 10/12] Better regex --- .../cloud/sdk/datamodel/odata/utility/NamingUtils.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java index 61190098d..d918ef59b 100644 --- a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java +++ b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java @@ -79,11 +79,11 @@ public static String serviceNameToBaseJavaClassName( @Nonnull final String servi formattedName = formattedName - .replaceAll("^(?i)ODataServiceFor", "") - .replaceAll("^(?i)RemoteApiFor", "") - .replaceAll("^(?i)ApiFor", "") - .replaceAll("^(?i)Api", "") - .replaceAll("(?i)Service$", ""); + .replaceAll("O(data|DATA|Data)S(ervice|ERVICE)F(or|OR)", "") + .replaceAll("R(emote|EMOTE)A(pi|PI)F(or|OR)", "") + .replaceAll("A(pi|PI)F(or|OR)", "") + .replaceAll("A(pi|PI)", "") + .replaceAll("S(ervice|ERVICE)$", ""); return formattedName; } From 70d85b3f97d6cc48a262de1bb90c112600a3cffc Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 10 Dec 2025 13:29:34 +0100 Subject: [PATCH 11/12] replaceFirst instead of replaceAll --- .../cloud/sdk/datamodel/odata/utility/NamingUtils.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java index d918ef59b..43bbd24be 100644 --- a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java +++ b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java @@ -79,10 +79,10 @@ public static String serviceNameToBaseJavaClassName( @Nonnull final String servi formattedName = formattedName - .replaceAll("O(data|DATA|Data)S(ervice|ERVICE)F(or|OR)", "") - .replaceAll("R(emote|EMOTE)A(pi|PI)F(or|OR)", "") - .replaceAll("A(pi|PI)F(or|OR)", "") - .replaceAll("A(pi|PI)", "") + .replaceFirst("O(data|DATA|Data)S(ervice|ERVICE)F(or|OR)", "") + .replaceFirst("R(emote|EMOTE)A(pi|PI)F(or|OR)", "") + .replaceFirst("A(pi|PI)F(or|OR)", "") + .replaceFirst("A(pi|PI)", "") .replaceAll("S(ervice|ERVICE)$", ""); return formattedName; From ff611a5f46a871d8c714780122f63b5ecf2c809f Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 10 Dec 2025 13:32:28 +0100 Subject: [PATCH 12/12] Revert "replaceFirst instead of replaceAll" This reverts commit 70d85b3f97d6cc48a262de1bb90c112600a3cffc. --- .../cloud/sdk/datamodel/odata/utility/NamingUtils.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java index 43bbd24be..d918ef59b 100644 --- a/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java +++ b/datamodel/odata-generator-utility/src/main/java/com/sap/cloud/sdk/datamodel/odata/utility/NamingUtils.java @@ -79,10 +79,10 @@ public static String serviceNameToBaseJavaClassName( @Nonnull final String servi formattedName = formattedName - .replaceFirst("O(data|DATA|Data)S(ervice|ERVICE)F(or|OR)", "") - .replaceFirst("R(emote|EMOTE)A(pi|PI)F(or|OR)", "") - .replaceFirst("A(pi|PI)F(or|OR)", "") - .replaceFirst("A(pi|PI)", "") + .replaceAll("O(data|DATA|Data)S(ervice|ERVICE)F(or|OR)", "") + .replaceAll("R(emote|EMOTE)A(pi|PI)F(or|OR)", "") + .replaceAll("A(pi|PI)F(or|OR)", "") + .replaceAll("A(pi|PI)", "") .replaceAll("S(ervice|ERVICE)$", ""); return formattedName;