From 06641db12c32554611c1456c9989b8ad25addeb8 Mon Sep 17 00:00:00 2001 From: "zxBCN Esperalta_Gata,Sergio (IT EDP) EXTERNAL" Date: Fri, 20 Feb 2026 09:13:07 +0100 Subject: [PATCH 1/4] - Add a private constructor to hide the implicit public one. - Refactored stripInlineCommentPreserveFormat to reduce cognitive complexity. --- .../services/CodeownersCommentStripper.java | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java b/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java index e2e679c..b2f9290 100644 --- a/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java +++ b/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java @@ -5,13 +5,16 @@ public class CodeownersCommentStripper { + private CodeownersCommentStripper() { + } + // --- existing methods (strip(List), helpers, etc.) stay unchanged --- /** * Strips comments from a CODEOWNERS file content provided as a single String. * Preserves: - * - original line separators (LF, CRLF, or CR) - * - blank lines + * - original line separators (LF, CRLF, or CR) + * - blank lines * * @param content CODEOWNERS file content as one full string * @return same content with full-line and inline comments removed @@ -100,7 +103,7 @@ private static int firstNonWhitespaceIndex(String s) { * odd number of backslashes), it is treated as literal and kept (one backslash is consumed). * Trailing spaces right before the comment marker are preserved (we only cut at the marker). */ - private static String stripInlineCommentPreserveFormat(String line) { + private static String stripInlineCommentPreserveFormat2(String line) { StringBuilder sb = new StringBuilder(line.length()); int i = 0; while (i < line.length()) { @@ -137,4 +140,61 @@ private static String stripInlineCommentPreserveFormat(String line) { } return sb.toString(); } + + /** + * Returns the line with inline comment removed, preserving leading whitespace + * and internal spacing up to the first unescaped '#'. + * If the '#' is escaped (preceded by an odd number of backslashes), it is kept + * as a literal and one backslash is consumed. + * Trailing spaces before the comment marker are preserved. + */ + private static String stripInlineCommentPreserveFormat(String line) { + StringBuilder sb = new StringBuilder(line.length()); + int pendingBackslashes = 0; + + for (int i = 0; i < line.length(); i++) { + char ch = line.charAt(i); + + if (ch == '\\') { + // Acumula la racha de backslashes + pendingBackslashes++; + continue; + } + + if (ch == '#') { + if ((pendingBackslashes & 1) == 1) { + // '#' escapado: emite (n-1) backslashes y el '#' + if (pendingBackslashes > 1) { + sb.append("\\".repeat(pendingBackslashes - 1)); + } + sb.append('#'); + pendingBackslashes = 0; + continue; + } else { + // '#' no escapado: fin del contenido útil + // Emite los backslashes pendientes (pares) antes de cortar + if (pendingBackslashes > 0) { + sb.append("\\".repeat(pendingBackslashes)); + } + pendingBackslashes = 0; // ← FIX CRÍTICO + break; // Cortar aquí sin incluir '#' + } + } + + // Cualquier otro carácter: primero vacía los backslashes pendientes + if (pendingBackslashes > 0) { + sb.append("\\".repeat(pendingBackslashes)); + pendingBackslashes = 0; + } + + sb.append(ch); + } + + // Al final, si quedan backslashes pendientes, emítelos + if (pendingBackslashes > 0) { + sb.append("\\".repeat(pendingBackslashes)); + } + + return sb.toString(); + } } \ No newline at end of file From a9024c7273b1f2deeb29f0e9d428cb8076efd31b Mon Sep 17 00:00:00 2001 From: "zxBCN Esperalta_Gata,Sergio (IT EDP) EXTERNAL" Date: Fri, 20 Feb 2026 09:13:52 +0100 Subject: [PATCH 2/4] Removed unused method --- .../services/CodeownersCommentStripper.java | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java b/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java index b2f9290..fe02a03 100644 --- a/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java +++ b/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java @@ -97,50 +97,6 @@ private static int firstNonWhitespaceIndex(String s) { return -1; } - /** - * Returns the line with inline comment removed, preserving leading whitespace - * and internal spacing up to the first unescaped '#'. If the '#' is escaped (i.e., preceded by an - * odd number of backslashes), it is treated as literal and kept (one backslash is consumed). - * Trailing spaces right before the comment marker are preserved (we only cut at the marker). - */ - private static String stripInlineCommentPreserveFormat2(String line) { - StringBuilder sb = new StringBuilder(line.length()); - int i = 0; - while (i < line.length()) { - char ch = line.charAt(i); - if (ch == '#') { - // count consecutive backslashes immediately before '#' - int backslashCount = 0; - int j = i - 1; - while (j >= 0 && line.charAt(j) == '\\') { - backslashCount++; - j--; - } - boolean escaped = (backslashCount % 2 == 1); - if (escaped) { - // remove one escaping backslash and keep '#' - // We need to replace the last '\' with nothing, then add '#' - // Copy content up to (but not including) that last backslash, - // but since we're streaming, we effectively drop one backslash. - // Implementation detail: remove the last char if it's '\' - int lastIndex = sb.length() - 1; - if (lastIndex >= 0 && sb.charAt(lastIndex) == '\\') { - sb.deleteCharAt(lastIndex); - } - sb.append('#'); - i++; - continue; - } else { - // unescaped -> start of inline comment: cut here - break; - } - } - sb.append(ch); - i++; - } - return sb.toString(); - } - /** * Returns the line with inline comment removed, preserving leading whitespace * and internal spacing up to the first unescaped '#'. From 4e72e89243777f5c407eb3ad899d0e20a08c1235 Mon Sep 17 00:00:00 2001 From: "zxBCN Esperalta_Gata,Sergio (IT EDP) EXTERNAL" Date: Fri, 20 Feb 2026 10:02:41 +0100 Subject: [PATCH 3/4] Cleaned some code and translated some comments. --- .../services/CodeownersCommentStripper.java | 60 +++++++++++-------- .../CodeownersCommentStripperTest.java | 12 ++-- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java b/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java index fe02a03..1352335 100644 --- a/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java +++ b/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java @@ -1,8 +1,11 @@ package org.opendevstack.component_catalog.server.services; +import lombok.extern.slf4j.Slf4j; + import java.util.ArrayList; import java.util.List; +@Slf4j public class CodeownersCommentStripper { private CodeownersCommentStripper() { @@ -44,29 +47,34 @@ public static String strip(String content) { */ public static List strip(List lines) { List out = new ArrayList<>(lines.size()); + for (String line : lines) { - if (line.isEmpty()) { // preserve blank lines - out.add(line); - continue; - } - // Check for full-line comment (after leading whitespace) - int firstNonWs = firstNonWhitespaceIndex(line); - if (firstNonWs == -1) { // line is all whitespace: preserve it - out.add(line); - continue; - } - if (line.charAt(firstNonWs) == '#') { - // Drop full-line comment completely - continue; - } + String result = null; + + if (line.isEmpty()) { + result = line; - // Strip inline comments, respecting escaped '#' - String withoutInline = stripInlineCommentPreserveFormat(line); + } else { + int firstNonWs = firstNonWhitespaceIndex(line); - // If after stripping the line becomes only whitespace, preserve it as whitespace - out.add(withoutInline); + if (firstNonWs == -1) { + result = line; + + } else if (line.charAt(firstNonWs) == '#') { + // Full line comment -> Do nothing + log.debug("strip - full line comment, do nothing"); + + } else { + result = stripInlineCommentPreserveFormat(line); + } + } + + if (result != null) { + out.add(result); + } } + return out; } @@ -112,14 +120,14 @@ private static String stripInlineCommentPreserveFormat(String line) { char ch = line.charAt(i); if (ch == '\\') { - // Acumula la racha de backslashes + //Accumulate the contiguous backslashes pendingBackslashes++; continue; } if (ch == '#') { if ((pendingBackslashes & 1) == 1) { - // '#' escapado: emite (n-1) backslashes y el '#' + // '#' escapado: writes (n-1) backslashes if (pendingBackslashes > 1) { sb.append("\\".repeat(pendingBackslashes - 1)); } @@ -127,17 +135,17 @@ private static String stripInlineCommentPreserveFormat(String line) { pendingBackslashes = 0; continue; } else { - // '#' no escapado: fin del contenido útil - // Emite los backslashes pendientes (pares) antes de cortar + // '#' not escaped: end of useful content + // Writes all pending backslashes (even quantity) before ending if (pendingBackslashes > 0) { sb.append("\\".repeat(pendingBackslashes)); } - pendingBackslashes = 0; // ← FIX CRÍTICO - break; // Cortar aquí sin incluir '#' + pendingBackslashes = 0; // Restart the count + break; // End here without including '#' } } - // Cualquier otro carácter: primero vacía los backslashes pendientes + // Any other caracter: empty pending backslashes if (pendingBackslashes > 0) { sb.append("\\".repeat(pendingBackslashes)); pendingBackslashes = 0; @@ -146,7 +154,7 @@ private static String stripInlineCommentPreserveFormat(String line) { sb.append(ch); } - // Al final, si quedan backslashes pendientes, emítelos + // At the end, if there are pending backslashes, write them if (pendingBackslashes > 0) { sb.append("\\".repeat(pendingBackslashes)); } diff --git a/src/test/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripperTest.java b/src/test/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripperTest.java index 3f2f8de..3355ad1 100644 --- a/src/test/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripperTest.java +++ b/src/test/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripperTest.java @@ -219,11 +219,15 @@ void givenWhitespaceOnlyLinesInString_whenStrip_thenTheyRemain() { void givenEscapedHashInString_whenStrip_thenLiteralHashIsPreserved() { // given String input = - "scripts/** @devops/ci \\#not-a-comment # real comment\n" + - "frontend/** @web/ux # UX owns frontend\n"; + """ + scripts/** @devops/ci \\#not-a-comment # real comment + frontend/** @web/ux # UX owns frontend + """; String expected = - "scripts/** @devops/ci #not-a-comment \n" + - "frontend/** @web/ux \n"; + """ + scripts/** @devops/ci #not-a-comment \s + frontend/** @web/ux \s + """; // when String out = CodeownersCommentStripper.strip(input); From e9890fe018dfff74516fa8cf5c63101fda8d5b2c Mon Sep 17 00:00:00 2001 From: "zxBCN Esperalta_Gata,Sergio (IT EDP) EXTERNAL" Date: Fri, 20 Feb 2026 10:37:16 +0100 Subject: [PATCH 4/4] Loops should not contain more than a single "break" or "continue" statement java:S135 --- .../services/CodeownersCommentStripper.java | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java b/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java index 1352335..5637289 100644 --- a/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java +++ b/src/main/java/org/opendevstack/component_catalog/server/services/CodeownersCommentStripper.java @@ -115,47 +115,44 @@ private static int firstNonWhitespaceIndex(String s) { private static String stripInlineCommentPreserveFormat(String line) { StringBuilder sb = new StringBuilder(line.length()); int pendingBackslashes = 0; + boolean stop = false; - for (int i = 0; i < line.length(); i++) { + for (int i = 0; i < line.length() && !stop; i++) { char ch = line.charAt(i); if (ch == '\\') { - //Accumulate the contiguous backslashes pendingBackslashes++; - continue; - } + // no continue + } else if (ch == '#') { + boolean escaped = (pendingBackslashes & 1) == 1; - if (ch == '#') { - if ((pendingBackslashes & 1) == 1) { - // '#' escapado: writes (n-1) backslashes + if (escaped) { if (pendingBackslashes > 1) { sb.append("\\".repeat(pendingBackslashes - 1)); } sb.append('#'); pendingBackslashes = 0; - continue; } else { - // '#' not escaped: end of useful content - // Writes all pending backslashes (even quantity) before ending + // '#' not escaped → end if (pendingBackslashes > 0) { sb.append("\\".repeat(pendingBackslashes)); } - pendingBackslashes = 0; // Restart the count - break; // End here without including '#' + pendingBackslashes = 0; + stop = true; } - } - // Any other caracter: empty pending backslashes - if (pendingBackslashes > 0) { - sb.append("\\".repeat(pendingBackslashes)); - pendingBackslashes = 0; + } else { + // normal character + if (pendingBackslashes > 0) { + sb.append("\\".repeat(pendingBackslashes)); + pendingBackslashes = 0; + } + sb.append(ch); } - - sb.append(ch); } - // At the end, if there are pending backslashes, write them - if (pendingBackslashes > 0) { + // reach the end without finding a '#' not escaped + if (!stop && pendingBackslashes > 0) { sb.append("\\".repeat(pendingBackslashes)); }