Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ name: cui-java-tools
pages-reference: cui-java-tools
sonar-project-key: cuioss_cui-java-tools
release:
current-version: 2.6.0
current-version: 2.6.1
next-version: 2.6-SNAPSHOT
21 changes: 21 additions & 0 deletions doc/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Command Configuration

## ./mvnw -Ppre-commit clean install

### Last Execution Duration
- **Duration**: 57656ms (57.7 seconds)
- **Last Updated**: 2025-10-16

### Acceptable Warnings
- OpenRewrite `CuiLogRecordPatternRecipe` warnings about converting logging to LogRecord pattern
- Deprecation warning for `writeProperty` method in test code (intentional test of deprecated API)

## handle-pull-request

### CI/Sonar Duration
- **Duration**: 300000ms (5 minutes)
- **Last Updated**: 2025-10-16

### Notes
- This duration represents the time to wait for CI and SonarCloud checks to complete
- Includes buffer time for queue delays
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>de.cuioss</groupId>
<artifactId>cui-java-parent</artifactId>
<version>1.2.5</version>
<version>1.3.3</version>
<relativePath />
</parent>

Expand Down
1 change: 1 addition & 0 deletions src/main/java/de/cuioss/tools/io/ClassPathLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ private static URL resolveUrl(String path) {
return url;
}
}
// cui-rewrite:disable CuiLogRecordPatternRecipe - Recipe bug: Cannot detect LogRecord through nested class
LOGGER.info(INFO.CLASSPATH_RESOLUTION_FAILED, path);
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/de/cuioss/tools/io/FileSystemLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public static String checkPathName(final String pathName) {
newPathName = new File(".").getCanonicalPath() + FileTypePrefix.EXTERNAL.removePrefix(pathName);
LOGGER.debug("Loading config file from external path: %s", newPathName);
} catch (final IOException e) {
LOGGER.error(e, ERROR.CURRENT_DIR_RETRIEVAL_FAILED::format);
LOGGER.error(e, ERROR.CURRENT_DIR_RETRIEVAL_FAILED);
}
}

Expand Down
19 changes: 19 additions & 0 deletions src/main/java/de/cuioss/tools/property/PropertyUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,25 @@ public static void setProperty(Object bean, String propertyName, Object property
writePropertyWithChaining(bean, propertyName, propertyValue);
}

/**
* Writes a value to a property of a bean using reflection and returns the bean for method chaining.
* This method violates Command-Query Separation by both modifying state and returning a value.
* Consider using {@link #setProperty(Object, String, Object)} for pure command operations.
*
* @param bean the bean to write to, must not be null
* @param propertyName the name of the property to write, must not be null or empty
* @param propertyValue the value to write to the property
* @return the bean instance (for method chaining)
* @throws IllegalArgumentException if the property cannot be written or does not exist
* @since 2.0
* @deprecated Use {@link #setProperty(Object, String, Object)} for pure command operations
*/
@Deprecated(since = "2.4.1", forRemoval = true)
@SuppressWarnings("java:S1133") // Sonar: "Do not forget to remove this deprecated code someday"
// Intentionally deprecated with forRemoval=true. Removal planned for version 3.0.
public static Object writeProperty(Object bean, String propertyName, Object propertyValue) {
return writePropertyWithChaining(bean, propertyName, propertyValue);
}

/**
* Internal method for property writing with return value support.
Expand Down
1 change: 1 addition & 0 deletions src/main/java/de/cuioss/tools/reflect/FieldWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public Optional<Object> readValue(Object source) {
try {
return Optional.ofNullable(field.get(source));
} catch (IllegalArgumentException | IllegalAccessException e) {
// cui-rewrite:disable CuiLogRecordPatternRecipe - Recipe bug: Cannot detect LogRecord through nested class
LOGGER.warn(e, WARN.FIELD_READ_FAILED, field, initialAccessible, source);
return Optional.empty();
} finally {
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/de/cuioss/tools/io/FileSystemLoaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,21 @@ void shouldGetUrlForNonExistentFile() throws MalformedURLException {
assertNotNull(url);
assertEquals(Path.of(NOT_EXISTING_FILE_PATH).toUri().toURL().getPath(), url.getPath());
}

@Test
void shouldHandleExternalPathWithComplexScenarios() {
// Test external path handling - this exercises the code path with canonical path resolution
// Even though we can't easily trigger IOException in getCanonicalPath(), this test ensures
// the external path resolution logic is executed
var externalPath = "external:/pom.xml";
var result = FileSystemLoader.checkPathName(externalPath);
assertNotNull(result);
assertTrue(result.contains("pom.xml"));

// Also test that we can create a loader with this path - file should exist after resolution
var loader = new FileSystemLoader(externalPath);
assertNotNull(loader);
// The file should be readable since external:/pom.xml resolves to ./pom.xml
assertTrue(loader.isReadable(), "External path should resolve to readable pom.xml");
}
}
27 changes: 27 additions & 0 deletions src/test/java/de/cuioss/tools/property/PropertyUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,31 @@ void shouldResolvePropertyType() {
assertFalse(resolvePropertyType(BeanForTestingTypeResolving.class, "notThere").isPresent());
}

@Test
@SuppressWarnings("deprecation")
void shouldSupportDeprecatedWriteProperty() {
var underTest = new BeanWithReadWriteProperties();
Integer number = 4;

// Test that deprecated writeProperty returns the bean instance
Object result = writeProperty(underTest, ATTRIBUTE_READ_WRITE, number);
assertAll("Testing deprecated writeProperty",
() -> assertSame(underTest, result, "Should return the same bean instance for chaining"),
() -> assertEquals(number, readProperty(underTest, ATTRIBUTE_READ_WRITE), "Property value should be set correctly"));

// Test with null value
Object nullResult = writeProperty(underTest, ATTRIBUTE_READ_WRITE, null);
assertAll("Testing deprecated writeProperty with null",
() -> assertSame(underTest, nullResult, "Should return the bean instance even with null value"),
() -> assertNull(readProperty(underTest, ATTRIBUTE_READ_WRITE), "Property value should be null"));

// Test chaining multiple writes
Object chainResult = writeProperty(
writeProperty(underTest, ATTRIBUTE_READ_WRITE, 10),
ATTRIBUTE_READ_WRITE, 20);
assertAll("Testing method chaining",
() -> assertSame(underTest, chainResult, "Should return the bean for chaining"),
() -> assertEquals(20, readProperty(underTest, ATTRIBUTE_READ_WRITE), "Final value should be 20"));
}

}
Loading