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 b8016fec25 Commons improvements
b8016fec25 is described below

commit b8016fec25107ded079d7e2ae0796d8f174b9231
Author: James Bognar <[email protected]>
AuthorDate: Tue Dec 16 15:15:09 2025 -0500

    Commons improvements
---
 .../main/java/org/apache/juneau/BeanContext.java   |   4 +
 .../commons/function/OptionalSupplier_Test.java    | 342 +++++++++++++++++++++
 .../commons/function/ResettableSupplier_Test.java  | 269 ++++++++++++++++
 .../juneau/commons/settings/Settings_Test.java     | 193 ++++++++++++
 4 files changed, 808 insertions(+)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index 2e022728d6..8ff5b036fc 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -175,6 +175,10 @@ public class BeanContext extends Context {
                private static final Cache<HashKey,BeanContext> CACHE = 
Cache.of(HashKey.class, BeanContext.class).build();
                private static final Settings SETTINGS = Settings.get();
 
+               private static <T> T env(String property, T def) {
+                       return SETTINGS.get(property, def)
+;              }
+
                private static Set<Class<?>> classSet() {
                        return new TreeSet<>(comparing(Class::getName));
                }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/function/OptionalSupplier_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/function/OptionalSupplier_Test.java
new file mode 100644
index 0000000000..447348fbda
--- /dev/null
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/function/OptionalSupplier_Test.java
@@ -0,0 +1,342 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.commons.function;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.juneau.*;
+import org.junit.jupiter.api.*;
+
+class OptionalSupplier_Test extends TestBase {
+
+       
//====================================================================================================
+       // Static factory methods
+       
//====================================================================================================
+       @Test
+       void a01_of() {
+               AtomicInteger callCount = new AtomicInteger();
+               OptionalSupplier<String> supplier = OptionalSupplier.of(() -> {
+                       callCount.incrementAndGet();
+                       return "value";
+               });
+
+               assertEquals("value", supplier.get());
+               assertEquals(1, callCount.get());
+               assertEquals("value", supplier.get());
+               assertEquals(2, callCount.get()); // Called again (not cached)
+       }
+
+       @Test
+       void a02_of_nullSupplier() {
+               assertThrows(IllegalArgumentException.class, () -> 
OptionalSupplier.of(null));
+       }
+
+       @Test
+       void a03_ofNullable() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertEquals("value", supplier.get());
+       }
+
+       @Test
+       void a04_ofNullable_null() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               assertNull(supplier.get());
+       }
+
+       @Test
+       void a05_empty() {
+               OptionalSupplier<String> supplier = OptionalSupplier.empty();
+               assertNull(supplier.get());
+       }
+
+       
//====================================================================================================
+       // isPresent() / isEmpty()
+       
//====================================================================================================
+       @Test
+       void b01_isPresent_true() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertTrue(supplier.isPresent());
+               assertFalse(supplier.isEmpty());
+       }
+
+       @Test
+       void b02_isPresent_false() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               assertFalse(supplier.isPresent());
+               assertTrue(supplier.isEmpty());
+       }
+
+       
//====================================================================================================
+       // map()
+       
//====================================================================================================
+       @Test
+       void c01_map_present() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("hello");
+               OptionalSupplier<Integer> mapped = supplier.map(String::length);
+               assertEquals(5, mapped.get());
+       }
+
+       @Test
+       void c02_map_empty() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               OptionalSupplier<Integer> mapped = supplier.map(String::length);
+               assertNull(mapped.get());
+       }
+
+       @Test
+       void c03_map_nullMapper() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertThrows(IllegalArgumentException.class, () -> 
supplier.map(null));
+       }
+
+       @Test
+       void c04_map_returnsNull() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               OptionalSupplier<String> mapped = supplier.map(s -> null);
+               assertNull(mapped.get());
+       }
+
+       
//====================================================================================================
+       // flatMap()
+       
//====================================================================================================
+       @Test
+       void d01_flatMap_present() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("hello");
+               OptionalSupplier<Integer> mapped = supplier.flatMap(s -> 
OptionalSupplier.ofNullable(s.length()));
+               assertEquals(5, mapped.get());
+       }
+
+       @Test
+       void d02_flatMap_empty() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               OptionalSupplier<Integer> mapped = supplier.flatMap(s -> 
OptionalSupplier.ofNullable(s.length()));
+               assertNull(mapped.get());
+       }
+
+       @Test
+       void d03_flatMap_returnsEmpty() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("hello");
+               OptionalSupplier<Integer> mapped = supplier.flatMap(s -> 
OptionalSupplier.empty());
+               assertNull(mapped.get());
+       }
+
+       @Test
+       void d04_flatMap_returnsNull() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("hello");
+               OptionalSupplier<Integer> mapped = supplier.flatMap(s -> null);
+               assertNull(mapped.get());
+       }
+
+       @Test
+       void d05_flatMap_nullMapper() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertThrows(IllegalArgumentException.class, () -> 
supplier.flatMap(null));
+       }
+
+       
//====================================================================================================
+       // filter()
+       
//====================================================================================================
+       @Test
+       void e01_filter_matches() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("hello");
+               OptionalSupplier<String> filtered = supplier.filter(s -> 
s.length() > 3);
+               assertEquals("hello", filtered.get());
+       }
+
+       @Test
+       void e02_filter_noMatch() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("hi");
+               OptionalSupplier<String> filtered = supplier.filter(s -> 
s.length() > 3);
+               assertNull(filtered.get());
+       }
+
+       @Test
+       void e03_filter_empty() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               OptionalSupplier<String> filtered = supplier.filter(s -> 
s.length() > 3);
+               assertNull(filtered.get());
+       }
+
+       @Test
+       void e04_filter_nullPredicate() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertThrows(IllegalArgumentException.class, () -> 
supplier.filter(null));
+       }
+
+       
//====================================================================================================
+       // orElse()
+       
//====================================================================================================
+       @Test
+       void f01_orElse_present() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertEquals("value", supplier.orElse("default"));
+       }
+
+       @Test
+       void f02_orElse_empty() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               assertEquals("default", supplier.orElse("default"));
+       }
+
+       @Test
+       void f03_orElse_nullDefault() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               assertNull(supplier.orElse(null));
+       }
+
+       
//====================================================================================================
+       // orElseGet()
+       
//====================================================================================================
+       @Test
+       void g01_orElseGet_present() {
+               AtomicInteger callCount = new AtomicInteger();
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               String result = supplier.orElseGet(() -> {
+                       callCount.incrementAndGet();
+                       return "default";
+               });
+               assertEquals("value", result);
+               assertEquals(0, callCount.get()); // Should not be called
+       }
+
+       @Test
+       void g02_orElseGet_empty() {
+               AtomicInteger callCount = new AtomicInteger();
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               String result = supplier.orElseGet(() -> {
+                       callCount.incrementAndGet();
+                       return "default";
+               });
+               assertEquals("default", result);
+               assertEquals(1, callCount.get());
+       }
+
+       @Test
+       void g03_orElseGet_nullSupplier() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertThrows(IllegalArgumentException.class, () -> 
supplier.orElseGet(null));
+       }
+
+       
//====================================================================================================
+       // orElseThrow()
+       
//====================================================================================================
+       @Test
+       void h01_orElseThrow_present() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertEquals("value", supplier.orElseThrow(() -> new 
RuntimeException("should not throw")));
+       }
+
+       @Test
+       void h02_orElseThrow_empty() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               assertThrows(RuntimeException.class, () -> 
supplier.orElseThrow(() -> new RuntimeException("expected")));
+       }
+
+       @Test
+       void h03_orElseThrow_nullSupplier() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertThrows(IllegalArgumentException.class, () -> 
supplier.orElseThrow(null));
+       }
+
+       
//====================================================================================================
+       // ifPresent()
+       
//====================================================================================================
+       @Test
+       void i01_ifPresent_present() {
+               AtomicInteger callCount = new AtomicInteger();
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               supplier.ifPresent(s -> callCount.incrementAndGet());
+               assertEquals(1, callCount.get());
+       }
+
+       @Test
+       void i02_ifPresent_empty() {
+               AtomicInteger callCount = new AtomicInteger();
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               supplier.ifPresent(s -> callCount.incrementAndGet());
+               assertEquals(0, callCount.get());
+       }
+
+       @Test
+       void i03_ifPresent_nullAction() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertThrows(IllegalArgumentException.class, () -> 
supplier.ifPresent(null));
+       }
+
+       
//====================================================================================================
+       // ifPresentOrElse()
+       
//====================================================================================================
+       @Test
+       void j01_ifPresentOrElse_present() {
+               AtomicInteger presentCount = new AtomicInteger();
+               AtomicInteger emptyCount = new AtomicInteger();
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               supplier.ifPresentOrElse(
+                       s -> presentCount.incrementAndGet(),
+                       () -> emptyCount.incrementAndGet()
+               );
+               assertEquals(1, presentCount.get());
+               assertEquals(0, emptyCount.get());
+       }
+
+       @Test
+       void j02_ifPresentOrElse_empty() {
+               AtomicInteger presentCount = new AtomicInteger();
+               AtomicInteger emptyCount = new AtomicInteger();
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               supplier.ifPresentOrElse(
+                       s -> presentCount.incrementAndGet(),
+                       () -> emptyCount.incrementAndGet()
+               );
+               assertEquals(0, presentCount.get());
+               assertEquals(1, emptyCount.get());
+       }
+
+       @Test
+       void j03_ifPresentOrElse_nullAction() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertThrows(IllegalArgumentException.class, () -> 
supplier.ifPresentOrElse(null, () -> {}));
+       }
+
+       @Test
+       void j04_ifPresentOrElse_nullEmptyAction() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               assertThrows(IllegalArgumentException.class, () -> 
supplier.ifPresentOrElse(s -> {}, null));
+       }
+
+       
//====================================================================================================
+       // toOptional()
+       
//====================================================================================================
+       @Test
+       void k01_toOptional_present() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable("value");
+               Optional<String> optional = supplier.toOptional();
+               assertTrue(optional.isPresent());
+               assertEquals("value", optional.get());
+       }
+
+       @Test
+       void k02_toOptional_empty() {
+               OptionalSupplier<String> supplier = 
OptionalSupplier.ofNullable(null);
+               Optional<String> optional = supplier.toOptional();
+               assertFalse(optional.isPresent());
+       }
+}
+
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/function/ResettableSupplier_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/function/ResettableSupplier_Test.java
index 2cbabfb92c..4204802a15 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/function/ResettableSupplier_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/function/ResettableSupplier_Test.java
@@ -257,5 +257,274 @@ class ResettableSupplier_Test extends TestBase {
                assertEquals("computed", supplier.get());
                assertEquals(1, callCount.get());
        }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // isSupplied()
+       
//------------------------------------------------------------------------------------------------------------------
+       @Test void b01_isSupplied_notCalled() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               assertTrue(supplier.isSupplied()); // Not called yet
+       }
+
+       @Test void b02_isSupplied_afterGet() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               supplier.get();
+               assertFalse(supplier.isSupplied()); // Has been called
+       }
+
+       @Test void b03_isSupplied_afterReset() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               supplier.get();
+               supplier.reset();
+               assertTrue(supplier.isSupplied()); // Reset, so not supplied 
anymore
+       }
+
+       @Test void b04_isSupplied_afterSet() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               supplier.set("injected");
+               assertFalse(supplier.isSupplied()); // Has a value (even if set 
directly)
+       }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // copy()
+       
//------------------------------------------------------------------------------------------------------------------
+       @Test void c01_copy_notCalled() {
+               var callCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> {
+                       callCount.incrementAndGet();
+                       return "value" + callCount.get();
+               });
+               var copy = supplier.copy();
+
+               // Copy should use original supplier
+               assertEquals("value1", copy.get());
+               assertEquals(1, callCount.get());
+       }
+
+       @Test void c02_copy_afterGet() {
+               var callCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> {
+                       callCount.incrementAndGet();
+                       return "value" + callCount.get();
+               });
+               supplier.get(); // Cache the value
+               var copy = supplier.copy();
+
+               // Copy should use cached value
+               assertEquals("value1", copy.get());
+               assertEquals(1, callCount.get()); // Original supplier not 
called again
+       }
+
+       @Test void c03_copy_independent() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               var copy = supplier.copy();
+
+               // Copy is independent
+               supplier.reset();
+               assertEquals("value", copy.get()); // Copy still has cached 
value
+       }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // map() - overridden to return ResettableSupplier
+       
//------------------------------------------------------------------------------------------------------------------
+       @Test void d01_map_present() {
+               var supplier = new ResettableSupplier<>(() -> "hello");
+               var mapped = supplier.map(String::length);
+               assertEquals(5, mapped.get());
+       }
+
+       @Test void d02_map_empty() {
+               @SuppressWarnings("cast")
+               var supplier = new ResettableSupplier<>(() -> (String)null);
+               var mapped = supplier.map(String::length);
+               assertNull(mapped.get());
+       }
+
+       @Test void d03_map_cached() {
+               var callCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> {
+                       callCount.incrementAndGet();
+                       return "hello";
+               });
+               var mapped = supplier.map(String::length);
+
+               // First call
+               assertEquals(5, mapped.get());
+               assertEquals(1, callCount.get());
+
+               // Second call - should use cached value from original supplier
+               assertEquals(5, mapped.get());
+               assertEquals(1, callCount.get()); // Original supplier not 
called again
+       }
+
+       @Test void d04_map_independent() {
+               var supplier = new ResettableSupplier<>(() -> "hello");
+               var mapped = supplier.map(String::length);
+
+               // Reset original
+               supplier.reset();
+               // Mapped should still have cached value
+               assertEquals(5, mapped.get());
+       }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // filter() - overridden to return ResettableSupplier
+       
//------------------------------------------------------------------------------------------------------------------
+       @Test void e01_filter_matches() {
+               var supplier = new ResettableSupplier<>(() -> "hello");
+               var filtered = supplier.filter(s -> s.length() > 3);
+               assertEquals("hello", filtered.get());
+       }
+
+       @Test void e02_filter_noMatch() {
+               var supplier = new ResettableSupplier<>(() -> "hi");
+               var filtered = supplier.filter(s -> s.length() > 3);
+               assertNull(filtered.get());
+       }
+
+       @Test void e03_filter_empty() {
+               @SuppressWarnings("cast")
+               var supplier = new ResettableSupplier<>(() -> (String)null);
+               var filtered = supplier.filter(s -> s.length() > 3);
+               assertNull(filtered.get());
+       }
+
+       @Test void e04_filter_cached() {
+               var callCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> {
+                       callCount.incrementAndGet();
+                       return "hello";
+               });
+               var filtered = supplier.filter(s -> s.length() > 3);
+
+               // First call
+               assertEquals("hello", filtered.get());
+               assertEquals(1, callCount.get());
+
+               // Second call - should use cached value
+               assertEquals("hello", filtered.get());
+               assertEquals(1, callCount.get());
+       }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // OptionalSupplier methods
+       
//------------------------------------------------------------------------------------------------------------------
+       @Test void f01_isPresent() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               assertTrue(supplier.isPresent());
+               assertFalse(supplier.isEmpty());
+       }
+
+       @Test void f02_isEmpty() {
+               var supplier = new ResettableSupplier<>(() -> null);
+               assertFalse(supplier.isPresent());
+               assertTrue(supplier.isEmpty());
+       }
+
+       @Test void f03_orElse() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               assertEquals("value", supplier.orElse("default"));
+       }
+
+       @Test void f04_orElse_empty() {
+               var supplier = new ResettableSupplier<>(() -> null);
+               assertEquals("default", supplier.orElse("default"));
+       }
+
+       @Test void f05_orElseGet() {
+               var callCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> "value");
+               var result = supplier.orElseGet(() -> {
+                       callCount.incrementAndGet();
+                       return "default";
+               });
+               assertEquals("value", result);
+               assertEquals(0, callCount.get());
+       }
+
+       @Test void f06_orElseGet_empty() {
+               var callCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> null);
+               var result = supplier.orElseGet(() -> {
+                       callCount.incrementAndGet();
+                       return "default";
+               });
+               assertEquals("default", result);
+               assertEquals(1, callCount.get());
+       }
+
+       @Test void f07_orElseThrow() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               assertEquals("value", supplier.orElseThrow(() -> new 
RuntimeException("should not throw")));
+       }
+
+       @Test void f08_orElseThrow_empty() {
+               var supplier = new ResettableSupplier<>(() -> null);
+               assertThrows(RuntimeException.class, () -> 
supplier.orElseThrow(() -> new RuntimeException("expected")));
+       }
+
+       @Test void f09_ifPresent() {
+               var callCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> "value");
+               supplier.ifPresent(s -> callCount.incrementAndGet());
+               assertEquals(1, callCount.get());
+       }
+
+       @Test void f10_ifPresent_empty() {
+               var callCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> null);
+               supplier.ifPresent(s -> callCount.incrementAndGet());
+               assertEquals(0, callCount.get());
+       }
+
+       @Test void f11_ifPresentOrElse() {
+               var presentCount = new AtomicInteger();
+               var emptyCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> "value");
+               supplier.ifPresentOrElse(
+                       s -> presentCount.incrementAndGet(),
+                       () -> emptyCount.incrementAndGet()
+               );
+               assertEquals(1, presentCount.get());
+               assertEquals(0, emptyCount.get());
+       }
+
+       @Test void f12_ifPresentOrElse_empty() {
+               var presentCount = new AtomicInteger();
+               var emptyCount = new AtomicInteger();
+               var supplier = new ResettableSupplier<>(() -> null);
+               supplier.ifPresentOrElse(
+                       s -> presentCount.incrementAndGet(),
+                       () -> emptyCount.incrementAndGet()
+               );
+               assertEquals(0, presentCount.get());
+               assertEquals(1, emptyCount.get());
+       }
+
+       @Test void f13_toOptional() {
+               var supplier = new ResettableSupplier<>(() -> "value");
+               var optional = supplier.toOptional();
+               assertTrue(optional.isPresent());
+               assertEquals("value", optional.get());
+       }
+
+       @Test void f14_toOptional_empty() {
+               var supplier = new ResettableSupplier<>(() -> null);
+               var optional = supplier.toOptional();
+               assertFalse(optional.isPresent());
+       }
+
+       @Test void f15_flatMap() {
+               var supplier = new ResettableSupplier<>(() -> "hello");
+               var mapped = supplier.flatMap(s -> 
OptionalSupplier.ofNullable(s.length()));
+               assertEquals(5, mapped.get());
+       }
+
+       @Test void f16_flatMap_empty() {
+               @SuppressWarnings("cast")
+               var supplier = new ResettableSupplier<>(() -> (String)null);
+               var mapped = supplier.flatMap(s -> 
OptionalSupplier.ofNullable(s.length()));
+               assertNull(mapped.get());
+       }
 }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/settings/Settings_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/settings/Settings_Test.java
index e0bce38301..fb5acc07db 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/settings/Settings_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/settings/Settings_Test.java
@@ -23,6 +23,7 @@ import java.io.File;
 import java.net.URI;
 import java.nio.charset.Charset;
 import java.nio.file.Paths;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.juneau.*;
 import org.apache.juneau.commons.function.*;
@@ -1099,5 +1100,197 @@ class Settings_Test extends TestBase {
                var result = settings.get(TEST_PROP, defaultCharset);
                assertEquals(Charset.forName("UTF-8"), result);
        }
+
+       
//====================================================================================================
+       // StringSetting.filter()
+       
//====================================================================================================
+       @Test
+       void r01_stringSetting_filter_returnsStringSetting() {
+               System.setProperty(TEST_PROP, "hello");
+               var setting = Settings.get().get(TEST_PROP);
+               var filtered = setting.filter(s -> s.length() > 3);
+               assertEquals("hello", filtered.get());
+       }
+
+       @Test
+       void r02_stringSetting_filter_noMatch() {
+               System.setProperty(TEST_PROP, "hi");
+               var setting = Settings.get().get(TEST_PROP);
+               var filtered = setting.filter(s -> s.length() > 3);
+               assertNull(filtered.get());
+       }
+
+       @Test
+       void r03_stringSetting_filter_empty() {
+               var setting = Settings.get().get("nonexistent.property");
+               var filtered = setting.filter(s -> s.length() > 3);
+               assertNull(filtered.get());
+       }
+
+       @Test
+       void r04_stringSetting_filter_cached() {
+               var callCount = new AtomicInteger();
+               var settings = Settings.create()
+                       .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
+                       .addSource(Settings.SYSTEM_ENV_SOURCE)
+                       .build();
+               System.setProperty(TEST_PROP, "hello");
+               var setting = settings.get(TEST_PROP);
+               var filtered = setting.filter(s -> {
+                       callCount.incrementAndGet();
+                       return s.length() > 3;
+               });
+
+               // First call
+               assertEquals("hello", filtered.get());
+               assertEquals(1, callCount.get());
+
+               // Second call - should use cached value
+               assertEquals("hello", filtered.get());
+               assertEquals(1, callCount.get());
+       }
+
+       @Test
+       void r05_stringSetting_filter_independent() {
+               System.setProperty(TEST_PROP, "hello");
+               var setting = Settings.get().get(TEST_PROP);
+               var filtered = setting.filter(s -> s.length() > 3);
+
+               // Reset original
+               setting.reset();
+               // Filtered should still have cached value
+               assertEquals("hello", filtered.get());
+       }
+
+       
//====================================================================================================
+       // StringSetting.mapString()
+       
//====================================================================================================
+       @Test
+       void s01_stringSetting_mapString_returnsStringSetting() {
+               System.setProperty(TEST_PROP, "hello");
+               var setting = Settings.get().get(TEST_PROP);
+               var mapped = setting.mapString(String::toUpperCase);
+               assertEquals("HELLO", mapped.get());
+       }
+
+       @Test
+       void s02_stringSetting_mapString_empty() {
+               var setting = Settings.get().get("nonexistent.property");
+               var mapped = setting.mapString(String::toUpperCase);
+               assertNull(mapped.get());
+       }
+
+       @Test
+       void s03_stringSetting_mapString_cached() {
+               var callCount = new AtomicInteger();
+               var settings = Settings.create()
+                       .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
+                       .addSource(Settings.SYSTEM_ENV_SOURCE)
+                       .build();
+               System.setProperty(TEST_PROP, "hello");
+               var setting = settings.get(TEST_PROP);
+               var mapped = setting.mapString(s -> {
+                       callCount.incrementAndGet();
+                       return s.toUpperCase();
+               });
+
+               // First call
+               assertEquals("HELLO", mapped.get());
+               assertEquals(1, callCount.get());
+
+               // Second call - should use cached value
+               assertEquals("HELLO", mapped.get());
+               assertEquals(1, callCount.get());
+       }
+
+       @Test
+       void s04_stringSetting_mapString_independent() {
+               System.setProperty(TEST_PROP, "hello");
+               var setting = Settings.get().get(TEST_PROP);
+               var mapped = setting.mapString(String::toUpperCase);
+
+               // Reset original
+               setting.reset();
+               // Mapped should still have cached value
+               assertEquals("HELLO", mapped.get());
+       }
+
+       @Test
+       void s05_stringSetting_mapString_returnsNull() {
+               System.setProperty(TEST_PROP, "hello");
+               var setting = Settings.get().get(TEST_PROP);
+               var mapped = setting.mapString(s -> null);
+               assertNull(mapped.get());
+       }
+
+       
//====================================================================================================
+       // Setting.asOptional()
+       
//====================================================================================================
+       @Test
+       void t01_setting_asOptional_present() {
+               System.setProperty(TEST_PROP, "value");
+               var setting = Settings.get().get(TEST_PROP);
+               var optional = setting.asOptional();
+               assertTrue(optional.isPresent());
+               assertEquals("value", optional.get());
+       }
+
+       @Test
+       void t02_setting_asOptional_empty() {
+               var setting = Settings.get().get("nonexistent.property");
+               var optional = setting.asOptional();
+               assertFalse(optional.isPresent());
+       }
+
+       @Test
+       void t03_setting_asOptional_snapshot() {
+               var settings = Settings.create()
+                       .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
+                       .addSource(Settings.SYSTEM_ENV_SOURCE)
+                       .build();
+               System.setProperty(TEST_PROP, "value1");
+               var setting = settings.get(TEST_PROP);
+               var optional1 = setting.asOptional();
+               assertTrue(optional1.isPresent());
+               assertEquals("value1", optional1.get());
+
+               // Change the value
+               System.setProperty(TEST_PROP, "value2");
+               setting.reset(); // Force recomputation
+
+               // Original Optional should still have old value (snapshot)
+               assertTrue(optional1.isPresent());
+               assertEquals("value1", optional1.get());
+
+               // New Optional should have new value
+               var optional2 = setting.asOptional();
+               assertTrue(optional2.isPresent());
+               assertEquals("value2", optional2.get());
+       }
+
+       @Test
+       void t04_setting_asOptional_resetDoesNotAffect() {
+               var settings = Settings.create()
+                       .addSource(Settings.SYSTEM_PROPERTY_SOURCE)
+                       .addSource(Settings.SYSTEM_ENV_SOURCE)
+                       .build();
+               System.setProperty(TEST_PROP, "value1");
+               var setting = settings.get(TEST_PROP);
+               var optional = setting.asOptional();
+               assertTrue(optional.isPresent());
+               assertEquals("value1", optional.get());
+
+               // Reset the setting
+               setting.reset();
+
+               // Optional should still have the original value (snapshot)
+               assertTrue(optional.isPresent());
+               assertEquals("value1", optional.get());
+
+               // Getting a new Optional after reset should get the current 
value
+               var optional2 = setting.asOptional();
+               assertTrue(optional2.isPresent());
+               assertEquals("value1", optional2.get()); // Still value1 since 
system property hasn't changed
+       }
 }
 

Reply via email to