From 8a853ce4a1188f72f042e9c71d5c952601ee82dd Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Fri, 4 Jul 2025 08:13:00 +0000
Subject: [PATCH 1/6] Update project version to 2.4.0
- Updated current-version to 2.4.0 in .github/project.yml.
- Updated next-version to 2.4.1-SNAPSHOT in .github/project.yml.
---
.github/project.yml | 4 ++--
.github/workflows/maven-release.yml | 4 ++--
.github/workflows/maven.yml | 10 +++++-----
pom.xml | 2 +-
.../tools/collect/CollectionLiterals.java | 3 ++-
.../java/de/cuioss/tools/io/FilenameUtils.java | 3 ++-
.../de/cuioss/tools/io/StructuredFilename.java | 4 ++--
.../java/de/cuioss/tools/net/UrlParameter.java | 6 +++---
.../tools/net/ssl/KeyMaterialHolder.java | 3 ++-
.../cuioss/tools/reflect/MoreReflection.java | 2 +-
.../java/de/cuioss/tools/io/MorePathsTest.java | 4 ++--
.../de/cuioss/tools/net/UrlParameterTest.java | 18 +++++++++---------
12 files changed, 33 insertions(+), 30 deletions(-)
diff --git a/.github/project.yml b/.github/project.yml
index a8fcec34..89cdfd59 100644
--- a/.github/project.yml
+++ b/.github/project.yml
@@ -2,5 +2,5 @@ name: cui-java-tools
pages-reference: cui-java-tools
sonar-project-key: cuioss_cui-java-tools
release:
- current-version: 2.3.1
- next-version: 2.3-SNAPSHOT
+ current-version: 2.4.0
+ next-version: 2.4.1-SNAPSHOT
diff --git a/.github/workflows/maven-release.yml b/.github/workflows/maven-release.yml
index d945c92c..e0069837 100644
--- a/.github/workflows/maven-release.yml
+++ b/.github/workflows/maven-release.yml
@@ -31,10 +31,10 @@ jobs:
metadata-file-path: '.github/project.yml'
local-file: true
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
server-id: central
server-username: MAVEN_USERNAME
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 483129b6..6c79629c 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- version: [ 17,21,24 ]
+ version: [ 21,24 ]
steps:
- name: Harden the runner (Audit all outbound calls)
@@ -45,10 +45,10 @@ jobs:
with:
fetch-depth: 0
- - name: Set up JDK 17 for Sonar-build
+ - name: Set up JDK 21 for Sonar-build
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
cache: maven
@@ -84,10 +84,10 @@ jobs:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- - name: Set up JDK 17 for snapshot release
+ - name: Set up JDK 21 for snapshot release
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
server-id: central
server-username: MAVEN_USERNAME
diff --git a/pom.xml b/pom.xml
index c730e233..709db2f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
- * The default implementation uses {@link ByteBuffer#allocate(int)}. The method
- * is overridden in AllocateDirectHexTest to use
- * {@link ByteBuffer#allocateDirect(int)}
- *
- * @param capacity the capacity
- * @return the byte buffer
- */
- protected ByteBuffer allocate(final int capacity) {
- return ByteBuffer.allocate(capacity);
- }
-
private boolean charsetSanityCheck(final String name) {
final var source = "the quick brown dog jumped over the lazy fox";
try {
@@ -174,6 +160,169 @@ void encodeReadOnlyByteBuffer() {
}
}
+ @Nested
+ @DisplayName("handle static method operations")
+ class StaticMethodOperations {
+
+ @Test
+ @DisplayName("decode hex string correctly")
+ void decodeHexString() throws DecoderException {
+ final var input = "48656c6c6f20576f726c64";
+ final var expected = "Hello World".getBytes(StandardCharsets.UTF_8);
+ assertArrayEquals(expected, Hex.decodeHex(input));
+ }
+
+ @Test
+ @DisplayName("decode hex char array correctly")
+ void decodeHexCharArray() throws DecoderException {
+ final var input = "48656c6c6f20576f726c64".toCharArray();
+ final var expected = "Hello World".getBytes(StandardCharsets.UTF_8);
+ assertArrayEquals(expected, Hex.decodeHex(input));
+ }
+
+ @Test
+ @DisplayName("throw exception for odd length hex string")
+ void decodeHexOddLength() {
+ assertThrows(DecoderException.class, () -> Hex.decodeHex("ABC"));
+ assertThrows(DecoderException.class, () -> Hex.decodeHex("ABC".toCharArray()));
+ }
+
+ @Test
+ @DisplayName("throw exception for invalid hex characters")
+ void decodeHexInvalidCharacters() {
+ assertThrows(DecoderException.class, () -> Hex.decodeHex("XY"));
+ assertThrows(DecoderException.class, () -> Hex.decodeHex("XY".toCharArray()));
+ }
+
+ @Test
+ @DisplayName("encode byte array to hex chars")
+ void encodeHexByteArray() {
+ final var input = "Hello World".getBytes(StandardCharsets.UTF_8);
+ final var result = Hex.encodeHex(input);
+ final var expected = "48656c6c6f20576f726c64".toCharArray();
+ assertArrayEquals(expected, result);
+ }
+
+ @Test
+ @DisplayName("encode byte buffer to hex chars")
+ void encodeHexByteBuffer() {
+ final var input = "Hello World".getBytes(StandardCharsets.UTF_8);
+ final var buffer = ByteBuffer.wrap(input);
+ final var result = Hex.encodeHex(buffer);
+ final var expected = "48656c6c6f20576f726c64".toCharArray();
+ assertArrayEquals(expected, result);
+ }
+
+ @Test
+ @DisplayName("encode byte array with case control")
+ void encodeHexByteArrayWithCase() {
+ final var input = new byte[]{(byte) 0xAB, (byte) 0xCD, (byte) 0xEF};
+
+ final var lowerResult = Hex.encodeHex(input, true);
+ assertArrayEquals("abcdef".toCharArray(), lowerResult);
+
+ final var upperResult = Hex.encodeHex(input, false);
+ assertArrayEquals("ABCDEF".toCharArray(), upperResult);
+ }
+
+ @Test
+ @DisplayName("encode byte buffer with case control")
+ void encodeHexByteBufferWithCase() {
+ final var input = new byte[]{(byte) 0xAB, (byte) 0xCD, (byte) 0xEF};
+ final var buffer = ByteBuffer.wrap(input);
+
+ final var lowerResult = Hex.encodeHex(buffer, true);
+ assertArrayEquals("abcdef".toCharArray(), lowerResult);
+
+ buffer.rewind();
+ final var upperResult = Hex.encodeHex(buffer, false);
+ assertArrayEquals("ABCDEF".toCharArray(), upperResult);
+ }
+
+ @Test
+ @DisplayName("encode hex string from byte array")
+ void encodeHexStringByteArray() {
+ final var input = "Hello World".getBytes(StandardCharsets.UTF_8);
+ final var result = Hex.encodeHexString(input);
+ assertEquals("48656c6c6f20576f726c64", result);
+ }
+
+ @Test
+ @DisplayName("encode hex string from byte array with case control")
+ void encodeHexStringByteArrayWithCase() {
+ final var input = new byte[]{(byte) 0xAB, (byte) 0xCD, (byte) 0xEF};
+
+ final var lowerResult = Hex.encodeHexString(input, true);
+ assertEquals("abcdef", lowerResult);
+
+ final var upperResult = Hex.encodeHexString(input, false);
+ assertEquals("ABCDEF", upperResult);
+ }
+
+ @Test
+ @DisplayName("encode hex string from byte buffer")
+ void encodeHexStringByteBuffer() {
+ final var input = "Hello World".getBytes(StandardCharsets.UTF_8);
+ final var buffer = ByteBuffer.wrap(input);
+ final var result = Hex.encodeHexString(buffer);
+ assertEquals("48656c6c6f20576f726c64", result);
+ }
+
+ @Test
+ @DisplayName("encode hex string from byte buffer with case control")
+ void encodeHexStringByteBufferWithCase() {
+ final var input = new byte[]{(byte) 0xAB, (byte) 0xCD, (byte) 0xEF};
+ final var buffer = ByteBuffer.wrap(input);
+
+ final var lowerResult = Hex.encodeHexString(buffer, true);
+ assertEquals("abcdef", lowerResult);
+
+ buffer.rewind();
+ final var upperResult = Hex.encodeHexString(buffer, false);
+ assertEquals("ABCDEF", upperResult);
+ }
+
+ @Test
+ @DisplayName("handle empty inputs")
+ void handleEmptyInputs() throws DecoderException {
+ // Empty string decode
+ assertArrayEquals(new byte[0], Hex.decodeHex(""));
+ assertArrayEquals(new byte[0], Hex.decodeHex(new char[0]));
+
+ // Empty byte array encode
+ assertArrayEquals(new char[0], Hex.encodeHex(new byte[0]));
+ assertEquals("", Hex.encodeHexString(new byte[0]));
+
+ // Empty byte buffer encode
+ final var emptyBuffer = ByteBuffer.allocate(0);
+ assertArrayEquals(new char[0], Hex.encodeHex(emptyBuffer));
+
+ emptyBuffer.rewind();
+ assertEquals("", Hex.encodeHexString(emptyBuffer));
+ }
+ }
+
+ @Nested
+ @DisplayName("handle constructor operations")
+ class ConstructorOperations {
+
+ @Test
+ @DisplayName("create with default constructor")
+ void defaultConstructor() {
+ final var hex = new Hex();
+ assertEquals(StandardCharsets.UTF_8, hex.getCharset());
+ }
+
+ @Test
+ @DisplayName("verify toString method")
+ void toStringMethod() {
+ final var hex = new Hex();
+ final var result = hex.toString();
+ // Just verify it doesn't throw and contains class name
+ assertTrue(result.contains("Hex"));
+ }
+ }
+
@Nested
@DisplayName("handle round trip operations")
class RoundTripOperations {
diff --git a/src/test/java/de/cuioss/tools/io/FilenameUtilsTest.java b/src/test/java/de/cuioss/tools/io/FilenameUtilsTest.java
index 06920c8a..f2bbece8 100644
--- a/src/test/java/de/cuioss/tools/io/FilenameUtilsTest.java
+++ b/src/test/java/de/cuioss/tools/io/FilenameUtilsTest.java
@@ -1070,4 +1070,73 @@ void isExtensionCollection() {
assertFalse(FilenameUtils.isExtension("a.b\\file.txt", new ArrayList<>(List.of("TXT"))));
assertFalse(FilenameUtils.isExtension("a.b\\file.txt", new ArrayList<>(Arrays.asList("TXT", "RTF"))));
}
+
+ @Test
+ void directoryContains() {
+ // Test null parent - should throw IllegalArgumentException
+ assertThrows(IllegalArgumentException.class, () -> FilenameUtils.directoryContains(null, "/child"));
+ assertThrows(IllegalArgumentException.class, () -> FilenameUtils.directoryContains(null, null));
+
+ // Test null child - should return false
+ assertFalse(FilenameUtils.directoryContains("/parent", null));
+
+ // Test same paths - should return false (directory does not contain itself)
+ assertFalse(FilenameUtils.directoryContains("/parent", "/parent"));
+ assertFalse(FilenameUtils.directoryContains("/parent/", "/parent/"));
+ assertFalse(FilenameUtils.directoryContains("/parent", "/parent/"));
+ assertFalse(FilenameUtils.directoryContains("/parent/", "/parent"));
+
+ // Test normal containment cases - Unix style paths
+ assertTrue(FilenameUtils.directoryContains("/parent", "/parent/child"));
+ assertTrue(FilenameUtils.directoryContains("/parent", "/parent/child/grandchild"));
+ assertTrue(FilenameUtils.directoryContains("/parent/", "/parent/child"));
+ assertTrue(FilenameUtils.directoryContains("/parent", "/parent/child/"));
+ assertTrue(FilenameUtils.directoryContains("/parent/", "/parent/child/"));
+
+ // Test normal containment cases - Windows style paths
+ assertTrue(FilenameUtils.directoryContains("C:\\parent", "C:\\parent\\child"));
+ assertTrue(FilenameUtils.directoryContains("C:\\parent", "C:\\parent\\child\\grandchild"));
+ assertTrue(FilenameUtils.directoryContains("C:\\parent\\", "C:\\parent\\child"));
+ assertTrue(FilenameUtils.directoryContains("C:\\parent", "C:\\parent\\child\\"));
+ assertTrue(FilenameUtils.directoryContains("C:\\parent\\", "C:\\parent\\child\\"));
+
+ // Test non-containment cases
+ assertFalse(FilenameUtils.directoryContains("/parent", "/other"));
+ assertFalse(FilenameUtils.directoryContains("/parent", "/parent2"));
+ assertFalse(FilenameUtils.directoryContains("/parent", "/parentchild"));
+ assertFalse(FilenameUtils.directoryContains("/parent/child", "/parent"));
+ assertFalse(FilenameUtils.directoryContains("/parent/child", "/parent/sibling"));
+
+ // Test mixed separators
+ assertTrue(FilenameUtils.directoryContains("/parent", "/parent\\child"));
+ assertTrue(FilenameUtils.directoryContains("C:\\parent", "C:\\parent/child"));
+
+ // Test relative paths
+ assertTrue(FilenameUtils.directoryContains("parent", "parent/child"));
+ assertTrue(FilenameUtils.directoryContains("parent", "parent\\child"));
+ assertFalse(FilenameUtils.directoryContains("parent", "parent"));
+ assertFalse(FilenameUtils.directoryContains("parent", "other"));
+
+ // Test empty strings
+ assertFalse(FilenameUtils.directoryContains("", "child"));
+ assertFalse(FilenameUtils.directoryContains("parent", ""));
+ assertFalse(FilenameUtils.directoryContains("", ""));
+
+ // Test root directory cases
+ assertTrue(FilenameUtils.directoryContains("/", "/child"));
+ assertTrue(FilenameUtils.directoryContains("C:\\", "C:\\child"));
+ assertFalse(FilenameUtils.directoryContains("/", "/"));
+ assertFalse(FilenameUtils.directoryContains("C:\\", "C:\\"));
+
+ // Test complex paths
+ assertTrue(FilenameUtils.directoryContains("/home/user", "/home/user/documents"));
+ assertTrue(FilenameUtils.directoryContains("/home/user", "/home/user/documents/file.txt"));
+ assertFalse(FilenameUtils.directoryContains("/home/user", "/home/other"));
+ assertFalse(FilenameUtils.directoryContains("/home/user", "/home/username"));
+
+ // Test UNC paths (Windows network paths)
+ assertTrue(FilenameUtils.directoryContains("\\\\server\\share", "\\\\server\\share\\folder"));
+ assertFalse(FilenameUtils.directoryContains("\\\\server\\share", "\\\\server\\share"));
+ assertFalse(FilenameUtils.directoryContains("\\\\server\\share", "\\\\other\\share\\folder"));
+ }
}
From 57f4576b43bb54933fd636ccbaf7415d60a6926d Mon Sep 17 00:00:00 2001
From: Oliver Wolff <23139298+cuioss@users.noreply.github.com>
Date: Fri, 4 Jul 2025 12:03:03 +0200
Subject: [PATCH 5/6] Removing codeql
---
.github/workflows/codeql.yml | 78 ------------------------------------
1 file changed, 78 deletions(-)
delete mode 100644 .github/workflows/codeql.yml
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
deleted file mode 100644
index 0f989b20..00000000
--- a/.github/workflows/codeql.yml
+++ /dev/null
@@ -1,78 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL"
-
-on:
- push:
- branches: ["main"]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: ["main"]
- schedule:
- - cron: "0 0 * * 1"
-
-permissions:
- contents: read
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
- permissions:
- actions: read
- contents: read
- security-events: write
-
- strategy:
- fail-fast: false
- matrix:
- language: ["java"]
- # CodeQL supports [ $supported-codeql-languages ]
- # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
-
- steps:
- - name: Harden the runner (Audit all outbound calls)
- uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
- with:
- egress-policy: audit
-
- - name: Checkout repository
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
-
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
-
- # âšī¸ Command-line programs to run using the OS shell.
- # đ See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
-
- # If the Autobuild fails above, remove it and uncomment the following three lines.
- # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
-
- # - run: |
- # echo "Run, Build Application using script"
- # ./location_of_script_within_repo/buildscript.sh
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
- with:
- category: "/language:${{matrix.language}}"
From 81e5f1dcebfd2b6720ffe11eb0c4cc589a20fc91 Mon Sep 17 00:00:00 2001
From: Oliver Wolff <23139298+cuioss@users.noreply.github.com>
Date: Fri, 4 Jul 2025 12:11:54 +0200
Subject: [PATCH 6/6] Refactor UrlParameter class: remove unused constants and
update method signatures for clarity
---
.../java/de/cuioss/tools/net/UrlParameter.java | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/src/main/java/de/cuioss/tools/net/UrlParameter.java b/src/main/java/de/cuioss/tools/net/UrlParameter.java
index c20c2183..fb563414 100644
--- a/src/main/java/de/cuioss/tools/net/UrlParameter.java
+++ b/src/main/java/de/cuioss/tools/net/UrlParameter.java
@@ -61,12 +61,6 @@ public class UrlParameter implements Serializable, Comparable