From d5f1c705b7a85c41f4397cd181df48478fac7862 Mon Sep 17 00:00:00 2001 From: Stefan Kapferer Date: Mon, 19 Oct 2026 23:13:51 +0200 Subject: [PATCH] Fix MDSL generation with empty protected regions (#219) If the end marker of a protected region directly followed the start marker, the computed substring indices overlapped and the MDSL generator failed with a StringIndexOutOfBoundsException. The reader also assumed the platform line separator, which broke files with other line endings. The content between the markers is now determined via the line breaks actually present in the file; an empty region returns an empty string. --- .../mdsl/ProtectedRegionReaderTest.java | 43 +++++++++++++++++++ .../generator/mdsl/ProtectedRegionReader.java | 20 ++++++--- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/generators/mdsl/ProtectedRegionReaderTest.java b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/generators/mdsl/ProtectedRegionReaderTest.java index 839a7883..fd45723f 100644 --- a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/generators/mdsl/ProtectedRegionReaderTest.java +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/generators/mdsl/ProtectedRegionReaderTest.java @@ -66,6 +66,49 @@ void canReadProtectedRegionContent() throws IOException { protectedRegion); } + @Test + void canReadEmptyProtectedRegion() { + // given + String mdslInput = "API description Test\n" + "// ** BEGIN PROTECTED REGION for data types\n" + + "// ** END PROTECTED REGION for data types\n"; + + // when + String protectedRegion = new ProtectedRegionReader().getProtectedRegionContent(mdslInput, + ProtectedRegionIdentifier.DATA_TYPE_REGION); + + // then + assertEquals("", protectedRegion); + } + + @Test + void canReadProtectedRegionWithEmptyLine() { + // given + String mdslInput = "API description Test\n" + "// ** BEGIN PROTECTED REGION for API providers\n" + "\n" + + "// ** END PROTECTED REGION for API providers\n"; + + // when + String protectedRegion = new ProtectedRegionReader().getProtectedRegionContent(mdslInput, + ProtectedRegionIdentifier.PROVIDER_REGION); + + // then + assertEquals("", protectedRegion); + } + + @Test + void canReadProtectedRegionWithWindowsLineEndings() { + // given + String mdslInput = "API description Test\r\n" + "// ** BEGIN PROTECTED REGION for data types\r\n" + + "data type Parameter1Type P\r\n" + "data type YetAnotherDataType P\r\n" + + "// ** END PROTECTED REGION for data types\r\n"; + + // when + String protectedRegion = new ProtectedRegionReader().getProtectedRegionContent(mdslInput, + ProtectedRegionIdentifier.DATA_TYPE_REGION); + + // then + assertEquals("data type Parameter1Type P\r\ndata type YetAnotherDataType P", protectedRegion); + } + @Test void canGetIdentifiersInDataTypeProtectedRegion() throws IOException { // given diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/generator/mdsl/ProtectedRegionReader.java b/org.contextmapper.dsl/src/org/contextmapper/dsl/generator/mdsl/ProtectedRegionReader.java index 8634d172..39b72bf3 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/generator/mdsl/ProtectedRegionReader.java +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/generator/mdsl/ProtectedRegionReader.java @@ -30,11 +30,21 @@ public class ProtectedRegionReader { public String getProtectedRegionContent(String mdslInput, ProtectedRegionIdentifier regionIdentifier) { - String regionStartString = getRegionStartString(regionIdentifier); - if (containsProtectedRegion(mdslInput, regionIdentifier)) - return mdslInput.substring(mdslInput.indexOf(regionStartString) + regionStartString.length() + System.lineSeparator().length(), - mdslInput.lastIndexOf(getRegionEndString(regionIdentifier)) - System.lineSeparator().length()); - return null; + if (!containsProtectedRegion(mdslInput, regionIdentifier)) + return null; + + // the content starts after the line break of the start line and ends before the line break of the end line + int startLineEnd = mdslInput.indexOf('\n', mdslInput.indexOf(getRegionStartString(regionIdentifier))); + int endIndex = mdslInput.lastIndexOf(getRegionEndString(regionIdentifier)); + if (startLineEnd < 0 || endIndex <= startLineEnd) + return ""; + + String content = mdslInput.substring(startLineEnd + 1, endIndex); + if (content.endsWith("\n")) + content = content.substring(0, content.length() - 1); + if (content.endsWith("\r")) + content = content.substring(0, content.length() - 1); + return content; } public boolean containsProtectedRegion(String mdslInput, ProtectedRegionIdentifier regionIdentifier) {