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 @@ de.cuioss cui-java-parent - 1.0.8 + 1.1.0 diff --git a/src/main/java/de/cuioss/tools/collect/CollectionLiterals.java b/src/main/java/de/cuioss/tools/collect/CollectionLiterals.java index d054b6b4..9997ff9b 100644 --- a/src/main/java/de/cuioss/tools/collect/CollectionLiterals.java +++ b/src/main/java/de/cuioss/tools/collect/CollectionLiterals.java @@ -84,7 +84,8 @@ * * @author Oliver Wolff */ -@SuppressWarnings("javaarchitecture:S7027") // Intended circular dependency within collection utilities +@SuppressWarnings("javaarchitecture:S7027") +// Intended circular dependency within collection utilities @UtilityClass public class CollectionLiterals { diff --git a/src/main/java/de/cuioss/tools/io/FilenameUtils.java b/src/main/java/de/cuioss/tools/io/FilenameUtils.java index d4253dd3..af91a5c3 100644 --- a/src/main/java/de/cuioss/tools/io/FilenameUtils.java +++ b/src/main/java/de/cuioss/tools/io/FilenameUtils.java @@ -85,7 +85,8 @@ *

* */ -@SuppressWarnings("javaarchitecture:S7027") // Intended circular dependency with IOCase +@SuppressWarnings("javaarchitecture:S7027") +// Intended circular dependency with IOCase @UtilityClass public class FilenameUtils { diff --git a/src/main/java/de/cuioss/tools/io/StructuredFilename.java b/src/main/java/de/cuioss/tools/io/StructuredFilename.java index 1d32330d..34cb1b86 100644 --- a/src/main/java/de/cuioss/tools/io/StructuredFilename.java +++ b/src/main/java/de/cuioss/tools/io/StructuredFilename.java @@ -63,11 +63,11 @@ public StructuredFilename(final String filename) { suffix = null; break; case 2: - namePart = list.get(0); + namePart = list.getFirst(); suffix = list.get(1); break; default: - suffix = list.get(list.size() - 1); + suffix = list.getLast(); namePart = String.join(".", list.subList(0, list.size() - 1)); break; } diff --git a/src/main/java/de/cuioss/tools/net/UrlParameter.java b/src/main/java/de/cuioss/tools/net/UrlParameter.java index 25171829..c20c2183 100644 --- a/src/main/java/de/cuioss/tools/net/UrlParameter.java +++ b/src/main/java/de/cuioss/tools/net/UrlParameter.java @@ -178,7 +178,7 @@ public static final List getUrlParameterFromMap(final Map> entry : map.entrySet()) { String value = null; if (!MoreCollections.isEmpty(entry.getValue())) { - value = entry.getValue().get(0); + value = entry.getValue().getFirst(); } final var key = entry.getKey(); if (null == parameterFilter || !parameterFilter.isExcluded(key)) { @@ -269,10 +269,10 @@ public static List fromQueryString(String queryString) { queryString, element); break; case 1: - builder.add(createDecoded(splitted.get(0), null)); + builder.add(createDecoded(splitted.getFirst(), null)); break; case 2: - builder.add(createDecoded(splitted.get(0), splitted.get(1))); + builder.add(createDecoded(splitted.getFirst(), splitted.get(1))); break; default: LOGGER.debug( diff --git a/src/main/java/de/cuioss/tools/net/ssl/KeyMaterialHolder.java b/src/main/java/de/cuioss/tools/net/ssl/KeyMaterialHolder.java index 3bf72f6d..be738b27 100644 --- a/src/main/java/de/cuioss/tools/net/ssl/KeyMaterialHolder.java +++ b/src/main/java/de/cuioss/tools/net/ssl/KeyMaterialHolder.java @@ -31,7 +31,8 @@ * * @author Oliver Wolff */ -@SuppressWarnings("javaarchitecture:S7027") // Intended circular dependency with KeyStoreProvider +@SuppressWarnings("javaarchitecture:S7027") +// Intended circular dependency with KeyStoreProvider @Builder @EqualsAndHashCode(exclude = {"keyMaterial", "keyPassword"}, doNotUseGetters = true) @ToString(exclude = {"keyMaterial", "keyPassword"}, doNotUseGetters = true) diff --git a/src/main/java/de/cuioss/tools/reflect/MoreReflection.java b/src/main/java/de/cuioss/tools/reflect/MoreReflection.java index adfe1493..ee16c95d 100644 --- a/src/main/java/de/cuioss/tools/reflect/MoreReflection.java +++ b/src/main/java/de/cuioss/tools/reflect/MoreReflection.java @@ -410,7 +410,7 @@ public static Optional extractAnnotation(final Class children = Files.list(playGroundBackup).toList(); assertEquals(1, children.size()); - final var fileName = children.iterator().next().getFileName().toString(); + final var fileName = children.getFirst().getFileName().toString(); assertTrue(fileName.startsWith(POM_XML + BACKUP_FILE_SUFFIX)); - MorePaths.contentEquals(existing, children.get(0)); + MorePaths.contentEquals(existing, children.getFirst()); } diff --git a/src/test/java/de/cuioss/tools/net/UrlParameterTest.java b/src/test/java/de/cuioss/tools/net/UrlParameterTest.java index 97c1547e..9d646944 100644 --- a/src/test/java/de/cuioss/tools/net/UrlParameterTest.java +++ b/src/test/java/de/cuioss/tools/net/UrlParameterTest.java @@ -98,8 +98,8 @@ void testGetUrlParameterFromMap() { testMap.put("name1", mutableList("value")); testMap.put("name2", mutableList("value1", "value2")); var parameters = getUrlParameterFromMap(testMap, null, true); - assertEquals("name1", parameters.get(0).getName()); - assertEquals("value", parameters.get(0).getValue()); + assertEquals("name1", parameters.getFirst().getName()); + assertEquals("value", parameters.getFirst().getValue()); assertEquals("name2", parameters.get(1).getName()); assertEquals("value1", parameters.get(1).getValue()); testMap.clear(); @@ -107,7 +107,7 @@ void testGetUrlParameterFromMap() { testMap.put("name2", mutableList("value")); testMap.put("name1", mutableList("value1")); parameters = getUrlParameterFromMap(testMap, null, true); - assertEquals("name1", parameters.get(0).getName()); + assertEquals("name1", parameters.getFirst().getName()); assertEquals("name2", parameters.get(1).getName()); // Check exclude testMap.clear(); @@ -116,7 +116,7 @@ void testGetUrlParameterFromMap() { final var filter = new ParameterFilter(immutableList("name2"), true); parameters = getUrlParameterFromMap(testMap, filter, true); assertEquals(1, parameters.size()); - assertEquals("name1", parameters.get(0).getName()); + assertEquals("name1", parameters.getFirst().getName()); } @Test @@ -175,7 +175,7 @@ void shouldFilterCorrectly() { final var filtered = UrlParameter.filterParameter(list, filter); assertEquals(2, filtered.size()); - assertEquals(param2, filtered.get(0)); + assertEquals(param2, filtered.getFirst()); assertEquals(param3, filtered.get(1)); } @@ -210,7 +210,7 @@ void parseQueryParameterShouldBehaveWellOnUnexpectedInput() { void parseQueryParameterShouldHandleHappyCaseKeyValue() { var fromQueryString = fromQueryString("name1=value1"); assertEquals(1, fromQueryString.size()); - var urlParameter = fromQueryString.get(0); + var urlParameter = fromQueryString.getFirst(); assertEquals("name1", urlParameter.getName()); assertEquals("value1", urlParameter.getValue()); } @@ -219,13 +219,13 @@ void parseQueryParameterShouldHandleHappyCaseKeyValue() { void parseQueryParameterShouldHandleHappyCaseKeyOnly() { var fromQueryString = fromQueryString("name1="); assertEquals(1, fromQueryString.size()); - var urlParameter = fromQueryString.get(0); + var urlParameter = fromQueryString.getFirst(); assertEquals("name1", urlParameter.getName()); assertNull(urlParameter.getValue()); fromQueryString = fromQueryString("name1"); assertEquals(1, fromQueryString.size()); - urlParameter = fromQueryString.get(0); + urlParameter = fromQueryString.getFirst(); assertEquals("name1", urlParameter.getName()); assertNull(urlParameter.getValue()); } @@ -234,7 +234,7 @@ void parseQueryParameterShouldHandleHappyCaseKeyOnly() { void parseQueryParameterShouldHandleHappyCaseComlexSample() { var fromQueryString = fromQueryString("?name1=value1&name2&name3=&"); assertEquals(3, fromQueryString.size()); - var urlParameter = fromQueryString.get(0); + var urlParameter = fromQueryString.getFirst(); assertEquals("name1", urlParameter.getName()); assertEquals("value1", urlParameter.getValue()); } From 798d39a1a494d4ff041382a438dc9f4d77eb30f5 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <23139298+cuioss@users.noreply.github.com> Date: Fri, 4 Jul 2025 10:20:53 +0200 Subject: [PATCH 2/6] Update src/test/java/de/cuioss/tools/net/UrlParameterTest.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- src/test/java/de/cuioss/tools/net/UrlParameterTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/de/cuioss/tools/net/UrlParameterTest.java b/src/test/java/de/cuioss/tools/net/UrlParameterTest.java index 9d646944..50a04227 100644 --- a/src/test/java/de/cuioss/tools/net/UrlParameterTest.java +++ b/src/test/java/de/cuioss/tools/net/UrlParameterTest.java @@ -98,8 +98,9 @@ void testGetUrlParameterFromMap() { testMap.put("name1", mutableList("value")); testMap.put("name2", mutableList("value1", "value2")); var parameters = getUrlParameterFromMap(testMap, null, true); - assertEquals("name1", parameters.getFirst().getName()); - assertEquals("value", parameters.getFirst().getValue()); + final var firstParameter = parameters.getFirst(); + assertEquals("name1", firstParameter.getName()); + assertEquals("value", firstParameter.getValue()); assertEquals("name2", parameters.get(1).getName()); assertEquals("value1", parameters.get(1).getValue()); testMap.clear(); From 03f63839f1e0e7a6aa31e613aec671e62eec7164 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <23139298+cuioss@users.noreply.github.com> Date: Fri, 4 Jul 2025 10:21:04 +0200 Subject: [PATCH 3/6] Update src/main/java/de/cuioss/tools/io/StructuredFilename.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- src/main/java/de/cuioss/tools/io/StructuredFilename.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/de/cuioss/tools/io/StructuredFilename.java b/src/main/java/de/cuioss/tools/io/StructuredFilename.java index 34cb1b86..d6008efa 100644 --- a/src/main/java/de/cuioss/tools/io/StructuredFilename.java +++ b/src/main/java/de/cuioss/tools/io/StructuredFilename.java @@ -63,8 +63,7 @@ public StructuredFilename(final String filename) { suffix = null; break; case 2: - namePart = list.getFirst(); - suffix = list.get(1); + suffix = list.getLast(); break; default: suffix = list.getLast(); From 21d10eecea1e198279a706da0321e7ef46d1f1b5 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <23139298+cuioss@users.noreply.github.com> Date: Fri, 4 Jul 2025 11:54:09 +0200 Subject: [PATCH 4/6] Refactor FilenameUtils and Hex classes for improved readability and performance --- doc/ai-rules.md | 369 ++++++++++++++++++ src/main/java/de/cuioss/tools/codec/Hex.java | 21 +- .../de/cuioss/tools/io/FilenameUtils.java | 35 +- .../cuioss/tools/io/StructuredFilename.java | 3 +- .../java/de/cuioss/tools/codec/HexTest.java | 179 ++++++++- .../de/cuioss/tools/io/FilenameUtilsTest.java | 69 ++++ 6 files changed, 639 insertions(+), 37 deletions(-) create mode 100644 doc/ai-rules.md diff --git a/doc/ai-rules.md b/doc/ai-rules.md new file mode 100644 index 00000000..c089cdc9 --- /dev/null +++ b/doc/ai-rules.md @@ -0,0 +1,369 @@ +# AI Development Guidelines + +This file provides guidance to AI tools (IntelliJ Junie, Claude Code, GitHub Copilot, etc.) when working with code in CUI projects. + +## Configuration + +**Standards Base URL**: Configure this based on your development environment: +- **Remote (gitingest)**: `https://gitingest.com/github.com/cuioss/cui-llm-rules/tree/main` +- **Local checkout**: Use relative path to your local standards directory (e.g., `../cui-llm-rules`) + +Replace `{STANDARDS_BASE_URL}` in all references below with your chosen base URL. + +## Context Hierarchy and Priority Framework +**Critical for AI System Decision Making** + +When conflicting information exists, AI systems must follow this priority order: + +1. **Core Process Rules** (CRITICAL - highest priority, non-negotiable) +2. **Project-Specific Context** (CLAUDE.md, .github/copilot-instructions.md, local config) +3. **Standards References** (adaptable based on context and requirements) +4. **General Guidelines** (lowest priority, may be overridden by higher levels) + +### Context-Aware Response Patterns +- **New Project Context**: Emphasize architecture decisions and initial setup standards +- **Legacy Code Context**: Prioritize compatibility, incremental changes, and migration paths +- **Testing Context**: Focus on coverage requirements and quality standards +- **Documentation Context**: Emphasize clarity, completeness, and AsciiDoc standards +- **Security Context**: Apply strictest security standards without compromise + +## Core Process Rules (CRITICAL - READ FIRST) +**Reference**: `{STANDARDS_BASE_URL}/standards/process/general.adoc` + +These rules govern ALL development activities: + +### 🚨 PRE-1.0 PROJECT RULE (HIGHEST PRIORITY) +**This project is PRE-1.0 and therefore:** +- **NEVER deprecate code** - Remove it directly if not needed +- **NEVER add transitional comments** like "TODO: Remove in v2.0" +- **NEVER enforce backward compatibility** - Make breaking changes freely +- **NEVER add @Deprecated annotations** - Delete unnecessary code immediately +- **Clean APIs aggressively** - Remove unused methods, classes, and patterns +- **Focus on final API design** - Design for post-1.0 stability, not pre-1.0 transitions + +### General Process Rules +1. **If in doubt, ask the user** - Never make assumptions +2. **Always research topics** - Use available tools (WebSearch, WebFetch, etc.) to find the most recent best practices +3. **Never guess or be creative** - If you cannot find best practices, ask the user +4. **Do not proliferate documents** - Always use context-relevant documents, never create without user approval +5. **Never add dependencies without approval** - Always ask before adding any dependency + +## AI Safety and Validation Framework +**Mandatory for All AI-Generated Content** + +### Safety Constraints (NON-NEGOTIABLE) +- **Never bypass security measures**: AI must not suggest workarounds for security controls +- **Preserve data integrity**: All changes must maintain data consistency +- **Respect privacy**: No exposure of sensitive data in logs or outputs +- **Maintain auditability**: All AI-generated changes must be traceable +- **Follow standards hierarchy**: Respect the context priority framework above + +### Validation Requirements +Before any code implementation: +1. **Standards Compliance Check**: Verify output matches CUI standards +2. **Build Verification**: Ensure generated code compiles and passes pre-commit checks +3. **Security Review**: Check for security anti-patterns and vulnerabilities +4. **Documentation Sync**: Verify documentation reflects any code changes +5. **Test Coverage**: Ensure adequate test coverage for new functionality + +### Error Recovery Patterns +- **Standards Violation**: Provide specific correction guidance with reference links +- **Build Failures**: Include diagnostic steps and reference Build Commands Template +- **Test Failures**: Guide through debugging using Testing Standards +- **Integration Issues**: Escalate to human review with detailed context + +## Task Completion Standards (MANDATORY) +**Reference**: `{STANDARDS_BASE_URL}/standards/process/task-completion-standards.adoc` + +### Pre-Commit Checklist +Execute in sequence before ANY commit: + +1. **Quality Verification**: `./mvnw -Ppre-commit clean verify -DskipTests` + - Fix ALL errors and warnings (mandatory) + - Address code quality, formatting, and linting issues + +2. **Final Verification**: `./mvnw clean install` + - Must complete without errors or warnings + - All tests must pass + - Tasks are complete ONLY after this succeeds + +3. **Run Integration Tests**: `./mvnw clean verify -Pintegration-tests -pl cui-jwt-quarkus-parent/cui-jwt-quarkus-integration-tests` + - Ensure all integration tests pass + - Verify against the latest standards + +4. **Documentation**: Ensure all changes are documented + - Update Javadoc for public APIs + - Update AsciiDoc documentation if necessary + +5. **Documentation**: Update if changes affect APIs, features, or configuration + +6. **Commit Message**: Follow Git Commit Standards + +### Quality Requirements +- New code requires appropriate test coverage +- Existing tests must continue to pass +- Documentation must be updated for API/feature changes +- Link commits to relevant issues or tasks + +## Build Commands Template +Common Maven commands for CUI projects: +- Build project: `./mvnw clean install` +- Build Single Module: `./mvnw clean install -pl ` +- Run tests: `./mvnw test` +- Run single test: `./mvnw test -Dtest=ClassName#methodName` +- Clean-Up Code: `./mvnw -Ppre-commit clean install -DskipTests` -> Check the console after running the command and fix all errors and warnings, verify until they are all corrected + +## Standards Overview +**Base Reference**: `{STANDARDS_BASE_URL}/standards` + +## Java Standards +**References**: +- Java Code Standards: `{STANDARDS_BASE_URL}/standards/java` +- DSL-Style Constants: `{STANDARDS_BASE_URL}/standards/java/dsl-style-constants.adoc` + +### Language Standards +- Use latest Java LTS version features (Java 17+ minimum) +- Use records for data carriers and DTOs +- Use switch expressions over classic switch statements +- Use text blocks for multi-line strings +- Use var for local variables with obvious types +- Use sealed classes for restricted hierarchies +- Pattern matching in instanceof and switch +- Stream API for complex data transformations +- Use proper access modifiers (prefer package-private over public) +- Mark classes final unless designed for inheritance +- Prefer composition over inheritance +- Return empty collections instead of null +- Use Optional for nullable return values +- Never catch or throw generic Exception or RuntimeException - always use specific exception types +- Use DSL-style nested constants for logging messages +- Follow builder pattern for complex object creation +- Implement fluent interfaces where appropriate +- Use method references over lambdas when possible +- Keep lambda expressions short and clear +- Avoid side effects in streams +- Use immutable objects when possible +- Make fields final by default +- Use enum instead of constants for fixed sets +- Prefer immutable collections (List.of(), Set.of()) +- Avoid magic numbers, use named constants +- Use StringBuilder for string concatenation in loops +- Override toString() for debugging +- Implement equals() and hashCode() together +- Use @Override annotation consistently +- Avoid premature optimization +- See Lombok Usage section for annotation patterns + +### Lombok Usage +**Reference**: `{STANDARDS_BASE_URL}/standards/java/java-code-standards.adoc` +- Use `@Builder` for complex object creation +- Use `@Value` for immutable objects +- Use `@NonNull` for required parameters +- Use `@ToString` and `@EqualsAndHashCode` for value objects +- Use `@UtilityClass` for utility classes +- Make proper use of `lombok.config` settings + +## Logging Standards +**References**: +- Logging Core Standards: `{STANDARDS_BASE_URL}/standards/logging` +- Logging Implementation Guide: `{STANDARDS_BASE_URL}/standards/logging/implementation-guide.adoc` +- Logging Testing Guide: `{STANDARDS_BASE_URL}/standards/logging/testing-guide.adoc` +- Use `de.cuioss.tools.logging.CuiLogger` (private static final LOGGER) +- Logger must be private static final with constant name 'LOGGER' +- Module/artifact: cui-java-tools +- Exception parameter always comes first in logging methods +- Use '%s' for string substitutions (not '{}' or '%d') +- Use `de.cuioss.tools.logging.LogRecord` for template logging +- Follow logging level ranges: INFO (001-99), WARN (100-199), ERROR (200-299), FATAL (300-399) +- All log messages must be documented in doc/LogMessages.adoc +- No log4j, slf4j, System.out, or System.err usage + +## Testing Standards +**References**: +- Testing Core Standards: `{STANDARDS_BASE_URL}/standards/testing` +- Quality Standards: `{STANDARDS_BASE_URL}/standards/testing/quality-standards.adoc` +- CUI Test Generator Guide: `https://gitingest.com/github.com/cuioss/cui-test-generator` (separate repository) +- Use JUnit 5 (`@Test`, `@DisplayName`, `@Nested`) +- Follow AAA pattern (Arrange-Act-Assert) +- One logical assertion per test +- Tests must be independent and not rely on execution order +- Minimum 80% line and branch coverage +- Use Maven profile `-Pcoverage` for coverage verification +- All public APIs must be tested +- Use cui-test-juli-logger for logger testing with `@EnableTestLogger` +- Use assertLogMessagePresentContaining for testing log messages +- Critical paths must have 100% coverage +- Forbidden: Mockito, PowerMock, Hamcrest - use CUI alternatives + +### CUI Test Generator Usage +**Reference**: `https://gitingest.com/github.com/cuioss/cui-test-generator` (separate repository) +- Mandatory for all test data generation in CUI projects +- Primary framework for creating test objects and data +- Provides type-safe, consistent test data generation +- Use cui-test-value-objects for value object contract testing +- Integrates with parameterized tests via @GeneratorsSource +- See Parameterized Tests Standards for annotation hierarchy + +### Parameterized Tests Standards +**Reference**: `{STANDARDS_BASE_URL}/standards/testing/quality-standards.adoc#parameterized-tests-best-practices` +- **Mandatory** for 3+ similar test variants +- Annotation hierarchy (preferred order): + 1. `@GeneratorsSource` - Most preferred for complex objects + 2. `@CompositeTypeGeneratorSource` - For multiple related types + 3. `@CsvSource` - Standard choice for simple data + 4. `@ValueSource` - Single parameter variations + 5. `@MethodSource` - Last resort only +- Use `@ParameterizedTest` with `@DisplayName` +- Consolidate duplicate test methods +- Provide clear test data and expected outcomes +- Document why @MethodSource if used + +## Documentation Standards +**References**: +- General Documentation: `{STANDARDS_BASE_URL}/standards/documentation` +- Javadoc Standards: `{STANDARDS_BASE_URL}/standards/documentation/javadoc-standards.adoc` +- AsciiDoc Standards: `{STANDARDS_BASE_URL}/standards/documentation/asciidoc-standards.adoc` +- README Structure: `{STANDARDS_BASE_URL}/standards/documentation/readme-structure.adoc` + +### Javadoc Standards +- Every public and protected class/interface must be documented +- Include clear purpose statement in class documentation +- Document all public methods with parameters, returns, and exceptions +- Include `@since` tag with version information +- Document thread-safety considerations +- Include usage examples for complex classes and methods +- Every package must have package-info.java +- Use `{@link}` for references to classes, methods, and fields +- Document Builder classes with complete usage examples + +## CDI and Quarkus Standards +**References**: +- CDI Development Patterns: `{STANDARDS_BASE_URL}/standards/cdi-quarkus` +- Quarkus Testing Standards: `{STANDARDS_BASE_URL}/standards/cdi-quarkus/testing-standards.adoc` +- Container Standards: `{STANDARDS_BASE_URL}/standards/cdi-quarkus/container-standards.adoc` +- Use constructor injection (mandatory over field injection) +- Single constructor rule: No `@Inject` needed for single constructors +- Use `final` fields for injected dependencies +- Use `@ApplicationScoped` for stateless services +- Use `@QuarkusTest` for CDI context testing +- Use `@QuarkusIntegrationTest` for packaged app testing +- Container: Use Quarkus distroless base image (91.9MB) +- HTTPS required for all integration tests +- OWASP Docker Top 10 compliance mandatory + +## CSS Standards +**Reference**: `{STANDARDS_BASE_URL}/standards/css` +- Use CSS custom properties (variables) for theming +- Follow BEM methodology for class naming +- Use Stylelint for code quality enforcement +- Use Prettier for consistent formatting +- Mobile-first responsive design approach +- Semantic HTML with accessible CSS patterns +- Performance optimization: minimize CSS bundle size +- Support for modern browsers (last 2 versions) + +## JavaScript Standards +**Reference**: `{STANDARDS_BASE_URL}/standards/javascript` +- Use ES6+ modern JavaScript features +- Use ESLint with strict configuration +- Use Prettier for code formatting +- Use Jest for unit testing framework +- Follow functional programming patterns when appropriate +- Use JSDoc for comprehensive documentation +- Use Lit components for web components (Quarkus DevUI context) +- Maven integration via frontend-maven-plugin +- Cypress for E2E testing + +### General Documentation Standards +- Use AsciiDoc format with `.adoc` extension +- Include proper document header with TOC and section numbering +- Use `:source-highlighter: highlight.js` attribute +- Use `xref:` syntax for cross-references (not `<<>>`) +- Blank lines required before all lists +- Consistent heading hierarchy +- Update main README when adding new documents +- Reference AsciiDoc standards from all relevant documents + +## Process Standards +**Reference**: `{STANDARDS_BASE_URL}/standards/process` +- Follow standardized git commit message format +- Use structured refactoring process for code improvements +- Complete task completion standards for quality assurance +- Maintain Javadoc error resolution process +- Follow Java test maintenance procedures +- Implement logger maintenance standards compliance +- If in doubt, ask the user - never guess or be creative +- Always research topics using available tools + +## Requirements Standards +**References**: +- Requirements Documents: `{STANDARDS_BASE_URL}/standards/requirements` +- Specification Documents: `{STANDARDS_BASE_URL}/standards/requirements/specification-documents.adoc` +- New Project Guide: `{STANDARDS_BASE_URL}/standards/requirements/new-project-guide.adoc` +- All requirements must be traceable to specifications +- Requirements must be specific, measurable, achievable, relevant, time-bound +- Maintain consistent documentation structure across projects +- Link implemented specifications to actual implementation code +- Use standard directory structure: doc/Requirements.adoc, doc/Specification.adoc +- Update specifications when implementation is complete +- See Documentation Standards for AsciiDoc formatting rules + +## AI Tool Specific Instructions + +### For IntelliJ Junie +- Always check for pre-commit profile availability +- Use proper Maven module selection for focused builds +- Leverage IDE integration for testing and debugging +- **Context Management**: Use module-level context awareness for focused assistance +- **Incremental Guidance**: Apply progressive disclosure of standards based on task complexity + +### For Claude Code (Agentic Coding) +- **CLAUDE.md Integration**: Auto-generate and maintain project-specific CLAUDE.md files +- **Permission Management**: Configure safe tool allowlists using `/permissions` command +- **Custom Slash Commands**: Create CUI-specific workflow commands in `.claude/commands/` +- **MCP Integration**: Leverage Model Context Protocol for enhanced capabilities +- Use todo lists for complex multi-step tasks +- Batch tool calls for parallel operations +- Always run lint and typecheck commands after code changes +- **Context Window Optimization**: Prioritize recent and relevant context for token efficiency + +### For GitHub Copilot +- **Repository Instructions**: Maintain `.github/copilot-instructions.md` for repo-specific guidance +- **Setup Steps**: Configure `copilot-setup-steps.yml` for consistent development environments +- **Task Scoping**: Optimize issue descriptions as effective AI prompts +- **Review Iteration**: Structure PR comments for effective AI collaboration using batch reviews +- Context-aware suggestions based on CUI standards +- Follow established patterns in the codebase +- Respect existing code style and architecture + +### For All AI Tools +- **Standards Hierarchy**: Follow the Context Hierarchy and Priority Framework +- **Safety First**: Apply AI Safety and Validation Framework for all outputs +- Always refer to CUI standards documentation before making changes +- Validate against existing patterns in the codebase +- Run tests after any code modifications +- Follow the pre-commit process for code quality +- Document any new public APIs according to Javadoc standards +- Use gitingest.com links for accessing CUI standards repository content +- **Feedback Integration**: Learn from user corrections and adapt instruction effectiveness +- **Escalation Protocol**: When in doubt, ask the user rather than making assumptions + +## Performance and Context Optimization +**Guidelines for Efficient AI Interactions** + +### Context Window Management +- **Prioritize Recent Context**: Weight recent files and conversations higher in decision making +- **Dynamic Context Selection**: Load only relevant standards for current task context +- **Token Economy**: Balance instruction comprehensiveness with context window efficiency +- **Incremental Loading**: Request additional context only when needed for task completion + +### Iterative Improvement Patterns +- **Pattern Recognition**: Identify and codify successful interaction patterns within CUI projects +- **Continuous Calibration**: Adjust instruction effectiveness based on build outcomes and user feedback +- **Workflow Optimization**: Streamline common development workflows through custom commands and templates + +### Integration with Development Workflows +- **CI/CD Awareness**: Understand and respect automated build and deployment processes +- **Quality Gate Integration**: Ensure all outputs pass automated quality checks +- **Collaborative Development**: Optimize for effective human-AI pair programming +- **Knowledge Contribution**: Help maintain and improve team knowledge base and documentation diff --git a/src/main/java/de/cuioss/tools/codec/Hex.java b/src/main/java/de/cuioss/tools/codec/Hex.java index c5a6884d..1c92b24a 100644 --- a/src/main/java/de/cuioss/tools/codec/Hex.java +++ b/src/main/java/de/cuioss/tools/codec/Hex.java @@ -538,15 +538,18 @@ public byte[] encode(final ByteBuffer array) { */ public Object encode(final Object object) throws EncoderException { byte[] byteArray; - if (object instanceof String string) { - byteArray = string.getBytes(getCharset()); - } else if (object instanceof ByteBuffer buffer) { - byteArray = toByteArray(buffer); - } else { - try { - byteArray = (byte[]) object; - } catch (final ClassCastException e) { - throw new EncoderException(e.getMessage(), e); + switch (object) { + case String string -> + byteArray = string.getBytes(getCharset()); + case ByteBuffer buffer -> + byteArray = toByteArray(buffer); + + default -> { + try { + byteArray = (byte[]) object; + } catch (final ClassCastException e) { + throw new EncoderException(e.getMessage(), e); + } } } return encodeHex(byteArray); diff --git a/src/main/java/de/cuioss/tools/io/FilenameUtils.java b/src/main/java/de/cuioss/tools/io/FilenameUtils.java index af91a5c3..e469aa4e 100644 --- a/src/main/java/de/cuioss/tools/io/FilenameUtils.java +++ b/src/main/java/de/cuioss/tools/io/FilenameUtils.java @@ -98,12 +98,6 @@ public class FilenameUtils { */ public static final char EXTENSION_SEPARATOR = '.'; - /** - * The extension separator String. - * - */ - public static final String EXTENSION_SEPARATOR_STR = Character.toString(EXTENSION_SEPARATOR); - /** * The Unix separator character. */ @@ -540,11 +534,30 @@ public static boolean directoryContains(final String canonicalParent, final Stri throw new IllegalArgumentException("Directory must not be null"); } - if (canonicalChild == null || IOCase.SYSTEM.checkEquals(canonicalParent, canonicalChild)) { + if (canonicalChild == null) { + return false; + } + + // Normalize paths to handle trailing separators consistently + final String normalizedParent = normalizeNoEndSeparator(canonicalParent); + final String normalizedChild = normalizeNoEndSeparator(canonicalChild); + + // A directory does not contain itself + if (normalizedParent == null || normalizedChild == null || + IOCase.SYSTEM.checkEquals(normalizedParent, normalizedChild)) { return false; } - return IOCase.SYSTEM.checkStartsWith(canonicalChild, canonicalParent); + // Check if child path starts with parent path followed by a separator + // Special case: if parent is root directory, don't add extra separator + if ("/".equals(normalizedParent) || "\\".equals(normalizedParent) || + (normalizedParent.length() >= 2 && normalizedParent.charAt(1) == ':' && + (normalizedParent.endsWith("/") || normalizedParent.endsWith("\\")))) { + return IOCase.SYSTEM.checkStartsWith(normalizedChild, normalizedParent) && + !IOCase.SYSTEM.checkEquals(normalizedParent, normalizedChild); + } + + return IOCase.SYSTEM.checkStartsWith(normalizedChild, normalizedParent + SYSTEM_SEPARATOR); } // ----------------------------------------------------------------------- @@ -1446,7 +1459,7 @@ static String[] splitOnTokens(final String text) { char prevChar = 0; for (final char ch : array) { if (ch == '?' || ch == '*') { - if (buffer.length() != 0) { + if (!buffer.isEmpty()) { list.add(buffer.toString()); buffer.setLength(0); } @@ -1460,11 +1473,11 @@ static String[] splitOnTokens(final String text) { } prevChar = ch; } - if (buffer.length() != 0) { + if (!buffer.isEmpty()) { list.add(buffer.toString()); } - return list.toArray(new String[list.size()]); + return list.toArray(new String[0]); } } diff --git a/src/main/java/de/cuioss/tools/io/StructuredFilename.java b/src/main/java/de/cuioss/tools/io/StructuredFilename.java index d6008efa..57527d95 100644 --- a/src/main/java/de/cuioss/tools/io/StructuredFilename.java +++ b/src/main/java/de/cuioss/tools/io/StructuredFilename.java @@ -52,8 +52,6 @@ public class StructuredFilename implements Serializable { * * @param filename to be checked */ - @SuppressWarnings("squid:S1871") // owolff: Although duplicate code for case 0 and case 1 I find - // it better readable public StructuredFilename(final String filename) { originalName = filename; final var list = Splitter.on('.').omitEmptyStrings().splitToList(filename); @@ -63,6 +61,7 @@ public StructuredFilename(final String filename) { suffix = null; break; case 2: + namePart = list.getFirst(); suffix = list.getLast(); break; default: diff --git a/src/test/java/de/cuioss/tools/codec/HexTest.java b/src/test/java/de/cuioss/tools/codec/HexTest.java index 119d112f..bb74ecc1 100644 --- a/src/test/java/de/cuioss/tools/codec/HexTest.java +++ b/src/test/java/de/cuioss/tools/codec/HexTest.java @@ -30,6 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Tests for {@link Hex} class, based on Apache Commons Codec's HexTest. @@ -39,21 +40,6 @@ class HexTest { private static final String BAD_ENCODING_NAME = "UNKNOWN"; - /** - * Allocate a ByteBuffer. - * - *

- * 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 { private static final CuiLogger LOGGER = new CuiLogger(UrlParameter.class); - /** Shortcut constant for faces redirect parameter. */ - public static final UrlParameter FACES_REDIRECT = new UrlParameter("faces-redirect", "true"); - - /** Shortcut constant parameter for includeViewParams. */ - public static final UrlParameter INCLUDE_VIEW_PARAMETER = new UrlParameter("includeViewParams", "true"); - @Serial private static final long serialVersionUID = 634175928228707534L; @@ -135,8 +129,8 @@ public static String createParameterString(final UrlParameter... parameters) { /** * Create a String-representation of the URL-Parameter * - * @param encode - * @param parameters + * @param encode indicating whether the string elements should be encoded or not + * @param parameters to be appended, must not be null * @return the created parameter String */ public static String createParameterString(final boolean encode, final UrlParameter... parameters) { @@ -169,7 +163,7 @@ public static String createParameterString(final boolean encode, final UrlParame * is null or empty. The List is always sorted by #getName() */ @SuppressWarnings("squid:S1166") // now need to throw exception - public static final List getUrlParameterFromMap(final Map> map, + public static List getUrlParameterFromMap(final Map> map, final ParameterFilter parameterFilter, final boolean encode) { if (MoreCollections.isEmpty(map)) { return Collections.emptyList(); @@ -224,7 +218,7 @@ public static List filterParameter(final List toBeFi * @return parameter Map, may be empty if urlParameters is empty. The list of * String will solely contain one element. */ - public static final Map> createParameterMap(final List urlParameters) { + public static Map> createParameterMap(final List urlParameters) { final Map> result = new HashMap<>(); if (null != urlParameters && !urlParameters.isEmpty()) { for (final UrlParameter urlParameter : urlParameters) { @@ -272,7 +266,7 @@ public static List fromQueryString(String queryString) { builder.add(createDecoded(splitted.getFirst(), null)); break; case 2: - builder.add(createDecoded(splitted.getFirst(), splitted.get(1))); + builder.add(createDecoded(splitted.getFirst(), splitted.getLast())); break; default: LOGGER.debug(