This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new c1921a5f4b New org.apache.juneau.commons.inject package
c1921a5f4b is described below
commit c1921a5f4bf2bcd149433dde4d37fe2839ed3aba
Author: James Bognar <[email protected]>
AuthorDate: Tue Jan 6 16:18:34 2026 -0500
New org.apache.juneau.commons.inject package
---
.../org/apache/juneau/commons/utils/BeanUtils.java | 4 +-
.../juneau/commons/utils/PredicateUtils.java | 23 +++++++++-
juneau-rest/juneau-rest-common/pom.xml | 1 +
.../juneau/commons/collections/HashKey_Test.java | 1 +
.../juneau/commons/lang/StringFormat_Test.java | 52 +++++++---------------
5 files changed, 42 insertions(+), 39 deletions(-)
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/BeanUtils.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/BeanUtils.java
index 216f9d592b..01b89834e7 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/BeanUtils.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/BeanUtils.java
@@ -327,7 +327,7 @@ public class BeanUtils {
} else if (pt.innerType() instanceof ParameterizedType) {
// If pt is already a parameterized type (e.g.,
List<TestService> after unwrapping Optional),
// use pt.innerType() as the parameterizedType
- parameterizedType = (ParameterizedType) pt.innerType();
+ parameterizedType = pt.innerType();
}
// Handle List<T> or Set<T>
@@ -413,7 +413,7 @@ public class BeanUtils {
} else if (pt.innerType() instanceof ParameterizedType)
{
// If pt is already a parameterized type (e.g.,
Map<String,TestService> after unwrapping Optional),
// use pt.innerType() as the parameterizedType
- parameterizedType = (ParameterizedType)
pt.innerType();
+ parameterizedType = pt.innerType();
}
if (parameterizedType instanceof ParameterizedType pt2)
{
var typeArgs = pt2.getActualTypeArguments();
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/PredicateUtils.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/PredicateUtils.java
index 808dde66d5..9b8bf39570 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/PredicateUtils.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/PredicateUtils.java
@@ -99,9 +99,28 @@ public final class PredicateUtils {
return (predicate == null || predicate.test(value));
}
+ /**
+ * Returns a predicate that filters out duplicate elements based on a
key extractor function.
+ *
+ * <p>
+ * This is useful for filtering streams to keep only the first
occurrence of each unique key.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * <jc>// Filter a stream to keep only methods with unique
signatures</jc>
+ * Stream<Method> <jv>methods</jv> = ...;
+ * Stream<Method> <jv>unique</jv> = <jv>methods</jv>
+ *
.filter(PredicateUtils.<jsm>distinctByKey</jsm>(Method::<jsm>getName</jsm>));
+ * </p>
+ *
+ * @param <T> The element type.
+ * @param keyExtractor A function that extracts the key from each
element.
+ * @return A predicate that returns <jk>true</jk> for the first
occurrence of each unique key,
+ * and <jk>false</jk> for subsequent occurrences with the same key.
+ */
public static <T> Predicate<T> distinctByKey(Function<? super T, ?>
keyExtractor) {
- var seen = ConcurrentHashMap.newKeySet();
- return t -> seen.add(keyExtractor.apply(t));
+ var seen = ConcurrentHashMap.newKeySet();
+ return t -> seen.add(keyExtractor.apply(t));
}
private PredicateUtils() {}
diff --git a/juneau-rest/juneau-rest-common/pom.xml
b/juneau-rest/juneau-rest-common/pom.xml
index 326fb2a8d0..682262b5fa 100644
--- a/juneau-rest/juneau-rest-common/pom.xml
+++ b/juneau-rest/juneau-rest-common/pom.xml
@@ -59,6 +59,7 @@
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
+
<supportIncrementalBuild>true</supportIncrementalBuild>
</configuration>
<executions>
<execution>
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/HashKey_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/HashKey_Test.java
index 1794803d3d..30ef26b3c8 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/collections/HashKey_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/collections/HashKey_Test.java
@@ -159,6 +159,7 @@ class HashKey_Test extends TestBase {
assertNotEquals(key, null);
}
+ @SuppressWarnings("unlikely-arg-type")
@Test
void b11_equals_withNonHashKeyObject() {
HashKey key = HashKey.of("a", "b");
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/lang/StringFormat_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/lang/StringFormat_Test.java
index 82eb80fdbc..704de9385c 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/lang/StringFormat_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/lang/StringFormat_Test.java
@@ -119,24 +119,6 @@ class StringFormat_Test extends TestBase {
}
}
- private static void assertMixedFormat(String expected, String pattern,
Locale locale, Object... args) {
- var actual = "";
- var fmt = (StringFormat)null;
- try {
- var fmt2 = fs(pattern);
- fmt = fmt2;
- actual = stringify(()->fmt2.format(locale, args));
- } catch (Throwable t) {
- actual = t.getClass().getSimpleName() + ": " +
t.getLocalizedMessage();
- }
- if (!expected.equals(actual)) {
- System.out.println("Pattern: " + pattern);
- var toPattern = opt(fmt).map(x ->
x.toPattern()).orElse(null);
- System.out.println("toPattern(): " + toPattern);
- fail("Pattern: " + pattern + ", toPattern(): " +
toPattern + ", expected: <" + expected + "> but was: <" + actual + ">");
- }
- }
-
private static void assertMixedFormat(String expected, String pattern,
Object... args) {
var actual = "";
var fmt = (StringFormat)null;
@@ -324,7 +306,7 @@ class StringFormat_Test extends TestBase {
assertTrue(result.contains("19.99"), "Result should contain
'19.99', but was: " + result);
assertTrue(result.contains("Price: "), "Result should contain
'Price: ', but was: " + result);
// Accept either old format ($19.99) or new format (USD 19.99)
for Java 25 compatibility
- assertTrue(result.contains("$") || result.contains("USD"),
+ assertTrue(result.contains("$") || result.contains("USD"),
"Result should contain '$' or 'USD' for currency, but
was: " + result);
}
@@ -358,18 +340,18 @@ class StringFormat_Test extends TestBase {
// Test equals - covers line 623
assertEquals(fmt1, fmt2);
assertNotEquals(fmt1, fmt3);
-
+
// Test equals with null - covers line 623 (instanceof check
fails)
assertNotEquals(fmt1, null);
-
+
// Test equals with different type - covers line 623
(instanceof check fails)
assertNotEquals(fmt1, "Hello {0}");
assertNotEquals(fmt1, new Object());
-
+
// Test equals with different pattern - covers line 623
(pattern comparison)
var fmt4 = StringFormat.of("Different pattern");
assertNotEquals(fmt1, fmt4);
-
+
// Test hashCode
assertEquals(fmt1.hashCode(), fmt2.hashCode());
}
@@ -433,30 +415,30 @@ class StringFormat_Test extends TestBase {
var fmt1 = StringFormat.of("Hello {0}");
var result1 = fmt1.format((Object[])null);
assertEquals("Hello {0}", result1);
-
+
// Test with complex format and null args
var fmt2 = StringFormat.of("Price: {0,number,currency}");
var result2 = fmt2.format((Object[])null);
assertEquals("Price: {0,number,currency}", result2);
-
+
// Test locale == null branch - covers line 167 (locale == null
? Locale.getDefault() : locale)
// When locale is null, should use Locale.getDefault()
var fmt3 = StringFormat.of("Hello {0}");
var result3 = fmt3.format((Locale)null, "World");
// Should format using default locale
assertEquals("Hello World", result3);
-
+
// Test locale != null branch - covers line 167 (else branch)
// When locale is provided, should use that locale
var fmt4 = StringFormat.of("Price: {0,number,currency}");
var result4 = fmt4.format(Locale.US, 19.99);
// Should format using US locale (dollar sign)
assertTrue(result4.contains("19.99") ||
result4.contains("$19.99"));
-
+
var result5 = fmt4.format(Locale.FRANCE, 19.99);
// Should format using France locale (different currency symbol)
assertTrue(result5.contains("19.99") ||
result5.contains("19,99"));
-
+
// Note on other branches:
// - index >= args.length: This branch exists but testing it is
complex because MessageFormat
// behavior with missing arguments may vary. The existing
test a01_messageFormat() already
@@ -478,15 +460,15 @@ class StringFormat_Test extends TestBase {
// Test args == null branch - covers line 217 (args == null)
var fmt1 = StringFormat.of("Hello %s");
assertThrows(java.util.MissingFormatArgumentException.class, ()
-> fmt1.format((Object[])null));
-
+
// Test with complex format and null args
var fmt2 = StringFormat.of("Price: %.2f");
assertThrows(java.util.MissingFormatArgumentException.class, ()
-> fmt2.format((Object[])null));
-
+
// Test with explicit index format and null args
var fmt3 = StringFormat.of("First: %1$s, Second: %2$s");
assertThrows(java.util.MissingFormatArgumentException.class, ()
-> fmt3.format((Object[])null));
-
+
// Note on other branches:
// - index >= args.length: This branch exists but testing it is
complex because the index
// calculation depends on how sequential vs explicit indices
are handled. The existing
@@ -532,17 +514,17 @@ class StringFormat_Test extends TestBase {
// Test with empty args - covers lines 413-414 (args.length ==
0, return pattern)
String result1 = StringFormat.format("Hello", Locale.US);
assertEquals("Hello", result1);
-
+
String result2 = StringFormat.format("Test pattern",
Locale.FRANCE);
assertEquals("Test pattern", result2);
-
+
// Test with args - covers line 415 (calls
of(pattern).format(locale, args))
String result3 = StringFormat.format("Hello %s", Locale.US,
"World");
assertEquals("Hello World", result3);
-
+
String result4 = StringFormat.format("Price:
{0,number,currency}", Locale.US, 19.99);
assertTrue(result4.contains("19.99") ||
result4.contains("$19.99"));
-
+
// Test with null locale and empty args - covers line 413-414
String result5 = StringFormat.format("Test", (Locale)null);
assertEquals("Test", result5);