[java-shib-shared] branch main updated: Introduce, use and test nonnullCollector

Rod Widdowson rdw at steadingsoftware.com
Fri Jan 27 10:03:03 UTC 2023


This is an automated email from the git hooks/post-receive script.

rdw pushed a commit to branch main
in repository java-shib-shared.

View the commit online:
http://git.shibboleth.net/view/?p=java-shib-shared.git;a=commit;h=8c12c8ae34e9e3e4fff27d35838c1ebf2f834eab

The following commit(s) were added to refs/heads/main by this push:
     new 8c12c8ae Introduce, use and test nonnullCollector
8c12c8ae is described below

commit 8c12c8ae34e9e3e4fff27d35838c1ebf2f834eab
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Fri Jan 27 09:51:53 2023 +0000

    Introduce, use and test nonnullCollector
---
 .../spring/util/ApplicationContextBuilder.java     |  6 ++-
 .../shared/collection/CollectionSupport.java       | 27 +++++++++++
 .../shared/collection/CollectionTest.java          | 55 ++++++++++++++++++++++
 3 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/shib-spring/src/main/java/net/shibboleth/shared/spring/util/ApplicationContextBuilder.java b/shib-spring/src/main/java/net/shibboleth/shared/spring/util/ApplicationContextBuilder.java
index f6a0e402..1a9a9a61 100644
--- a/shib-spring/src/main/java/net/shibboleth/shared/spring/util/ApplicationContextBuilder.java
+++ b/shib-spring/src/main/java/net/shibboleth/shared/spring/util/ApplicationContextBuilder.java
@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
 
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
@@ -403,7 +404,7 @@ public class ApplicationContextBuilder {
         }
 
         if (configurationResources != null) {
-            final List<Resource> filtered = configurationResources.stream()
+            @Nonnull final List<Resource> filtered = configurationResources.stream()
                 .filter(r -> {
                     if (r.exists()) {
                         return true;
@@ -411,7 +412,8 @@ public class ApplicationContextBuilder {
                     log.info("Skipping non-existent resource: {}", r);
                     return false;
                 })
-                .collect(Collectors.toUnmodifiableList());
+                .collect(CollectionSupport.nonnullCollector(Collectors.toUnmodifiableList()))
+                .get();
             if (!filtered.isEmpty()) {
                 beanDefinitionReader.loadBeanDefinitions(filtered.toArray(new Resource[0]));
             }
diff --git a/shib-support/src/main/java/net/shibboleth/shared/collection/CollectionSupport.java b/shib-support/src/main/java/net/shibboleth/shared/collection/CollectionSupport.java
index 50c8c5b6..31d39c9d 100644
--- a/shib-support/src/main/java/net/shibboleth/shared/collection/CollectionSupport.java
+++ b/shib-support/src/main/java/net/shibboleth/shared/collection/CollectionSupport.java
@@ -23,6 +23,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.stream.Collector;
 import java.util.stream.Collectors;
 
 import javax.annotation.Nonnull;
@@ -33,7 +35,10 @@ import org.slf4j.Logger;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotLive;
 import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.NonnullFunction;
 import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.NonnullSupplier;
 
 /**
  * Support functions for Collection and Map Management.
@@ -68,6 +73,28 @@ public final class CollectionSupport {
         };        
     }
 
+    /**
+     * Return a collector which collects to a {@link NonnullSupplier} whose
+     * content is the value returned by the collector you were given.
+     *
+     * @param <T> the type of input elements to the reduction operation of the collector
+     * @param <A> the mutable accumulation type of the reduction operation of the collector (often
+     *            hidden as an implementation detail)
+     * @param <R> the result type of the reduction operation of the collector
+     * @param collector the collector
+     * @return the {@link NonnullSupplier}.
+     */
+    public static <T,A,R> Collector<T, A, NonnullSupplier<R>> nonnullCollector(final Collector<T,A,R> collector) {
+        final Function<R, NonnullSupplier<R>> func =
+                new NonnullFunction<R, NonnullSupplier<R>>() {
+                    @Override @Nonnull
+                    public NonnullSupplier<R> apply(@Nullable R input) {
+                        return NonnullSupplier.of(Constraint.isNotNull(input, "Null result from collector"));
+                    }
+                };
+        return Collectors.collectingAndThen(collector, func);
+    }
+
     /**
      * Gets an empty list with non-null guarantee.
      *
diff --git a/shib-support/src/test/java/net/shibboleth/shared/collection/CollectionTest.java b/shib-support/src/test/java/net/shibboleth/shared/collection/CollectionTest.java
index 8f1e3c31..246e574a 100644
--- a/shib-support/src/test/java/net/shibboleth/shared/collection/CollectionTest.java
+++ b/shib-support/src/test/java/net/shibboleth/shared/collection/CollectionTest.java
@@ -17,11 +17,18 @@
 
 package net.shibboleth.shared.collection;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -250,4 +257,52 @@ public class CollectionTest {
         }
 
     }
+
+    @Test
+    public void collectorTest() {
+        final List<Integer> input = CollectionSupport.listOf(1,2,3,2);
+
+        Set<Integer> set = input.stream().collect(CollectionSupport.nonnullCollector(Collectors.toSet())).get();
+        assertEquals(set.size(), 3);
+        set.add(1);
+        assertEquals(set.size(), 3);
+        assertTrue(set.contains(1));
+        assertTrue(set.contains(2));
+        assertTrue(set.contains(3));
+        set = input.stream().collect(CollectionSupport.nonnullCollector(Collectors.toUnmodifiableSet())).get();
+        assertEquals(set.size(), 3);
+        assertEquals(set.size(), 3);
+        assertTrue(set.contains(1));
+        assertTrue(set.contains(2));
+        assertTrue(set.contains(3));
+        try {
+            set.add(1);
+            fail();
+        } catch (final Exception e) {
+            // expected        }
+            assertTrue(e instanceof UnsupportedOperationException);
+        }
+        List<Integer> list = input.stream().collect(CollectionSupport.nonnullCollector(Collectors.toList())).get();
+        assertEquals(list.size(), 4);
+        list.add(4);
+        assertEquals(list.size(), 5);
+        assertEquals(list.get(0), 1);
+        assertEquals(list.get(1), 2);
+        assertEquals(list.get(2), 3);
+        assertEquals(list.get(3), 2);
+        assertEquals(list.get(4), 4);
+        list = input.stream().collect(CollectionSupport.nonnullCollector(Collectors.toUnmodifiableList())).get();
+        assertEquals(list.size(), 4);
+        assertEquals(list.get(0), 1);
+        assertEquals(list.get(1), 2);
+        assertEquals(list.get(2), 3);
+        assertEquals(list.get(3), 2);
+        try {
+            list.add(1);
+            fail();
+        } catch (final Exception e) {
+            // expected        }
+            assertTrue(e instanceof UnsupportedOperationException);
+        }
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list