[java-support] 01/01: JSPT-94 - Add support classes to invert and join BiPredicates.

Scott Cantor cantor.2 at osu.edu
Tue Mar 31 15:59:15 EDT 2020


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

scantor pushed a commit to branch JSPT-94
in repository java-support.

View the commit online:
http://git.shibboleth.net/view/?p=java-support.git;a=commit;h=f5fa6a8a25f80b0420174f1e03c630ecaf31d0e9

commit f5fa6a8a25f80b0420174f1e03c630ecaf31d0e9
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Mar 31 15:58:33 2020 -0400

    JSPT-94 - Add support classes to invert and join BiPredicates.
    
    https://issues.shibboleth.net/jira/browse/JSPT-94
    
    BiPredicateSupport and BiFunctionSupport added.
    Additional wildcarding applied.
---
 .../java/support/logic/BiFunctionSupport.java      |  91 ++++++++
 .../java/support/logic/BiPredicateSupport.java     | 240 +++++++++++++++++++++
 .../java/support/logic/FunctionSupport.java        |   8 +-
 .../java/support/logic/PredicateSupport.java       |   4 +-
 4 files changed, 338 insertions(+), 5 deletions(-)

diff --git a/src/main/java/net/shibboleth/utilities/java/support/logic/BiFunctionSupport.java b/src/main/java/net/shibboleth/utilities/java/support/logic/BiFunctionSupport.java
new file mode 100644
index 0000000..33b7fa1
--- /dev/null
+++ b/src/main/java/net/shibboleth/utilities/java/support/logic/BiFunctionSupport.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.utilities.java.support.logic;
+
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+
+/**
+ * Helper class for constructing {@link BiFunction}s in a Spring-friendly manner.
+ * 
+ * @since 8.1.0
+ */
+public final class BiFunctionSupport {
+
+    /** Constructor. */
+    private BiFunctionSupport() {
+        
+    }
+
+    /**
+     * Creates a {@link BiFunction} that returns a constant value.
+     * 
+     * @param <T> type of object the function needs to act on
+     * @param <U> type of object the function needs to act on
+     * @param <V> type of object being returned
+     * @param target the value to return from the function
+     * 
+     * @return the constructed function
+     */
+    @Nonnull public static <T,U,V> BiFunction<T,U,V> constant(@Nonnull @ParameterName(name="target") final V target) {
+        return (t,u) -> {
+            return target;
+            };
+    }
+
+    /**
+     * A static version of {@link BiFunction#andThen(Function)}.
+     *
+     * @param <A> input to composed {@link BiFunction}
+     * @param <B> input to composed {@link BiFunction}
+     * @param <C> output of input {@link BiFunction}
+     * @param <D> output of composed {@link BiFunction}
+     *
+     * @param g the second function to apply
+     * @param f the first {@link BiFunction} to apply
+     * 
+     * @return the composition of {@code f} and {@code g}
+     * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
+     */
+    @Nonnull public static <A,B,C,D> BiFunction<A,B,D> compose(
+            @Nonnull @ParameterName(name="g") final Function<? super C,? extends D> g,
+            @Nonnull @ParameterName(name="f") final BiFunction<A,B,? extends C> f) {
+        return f.andThen(g);
+    }
+
+    /**
+     * Creates a {@link BiFunction} that returns the same boolean output as the given {@link BiPredicate} for all
+     * inputs.
+     * 
+     * @param <T> input type
+     * @param <U> input type
+     * @param predicate input {@link BiPredicate}
+     * 
+     * @return a corresponding {@link BiFunction} 
+     */
+    @Nonnull public static <T,U> BiFunction<T,U,Boolean> forBiPredicate(
+            @Nonnull @ParameterName(name="predicate") final BiPredicate<? super T,? super U> predicate) {
+        return predicate::test;
+    }
+    
+}
\ No newline at end of file
diff --git a/src/main/java/net/shibboleth/utilities/java/support/logic/BiPredicateSupport.java b/src/main/java/net/shibboleth/utilities/java/support/logic/BiPredicateSupport.java
new file mode 100644
index 0000000..2e83780
--- /dev/null
+++ b/src/main/java/net/shibboleth/utilities/java/support/logic/BiPredicateSupport.java
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID 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 net.shibboleth.utilities.java.support.logic;
+
+import java.util.ArrayList;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ * Helper class for constructing BiPredicates in a Spring-friendly manner.
+ * 
+ *  @since 8.1.0
+ */
+public final class BiPredicateSupport {
+
+    /** Constructor. */
+    private BiPredicateSupport() {
+    }
+    
+    /**
+     * Creates a {@link BiPredicate} that applies a {@link BiFunction} to inputs and returns its result,
+     * or a default value if null.
+     * 
+     * @param <T> type of function input
+     * @param <U> type of function input
+     * 
+     * @param function function to apply to inputs
+     * @param defValue default predicate to apply if function returns null
+     * 
+     * @return a {@link BiPredicate} adapter
+     */
+    @Nonnull public static <T,U> BiPredicate<T,U> fromBiFunction(
+            @Nonnull final BiFunction<? super T, ? super U,Boolean> function,
+            @Nonnull final BiPredicate<T,U> defValue) {
+        return new BiPredicate<>() {
+            public boolean test(@Nullable final T input1, @Nullable final U input2) {
+                final Boolean result = function.apply(input1, input2);
+                return result != null ? result : defValue.test(input1, input2);
+            }
+        };
+    }
+    
+    /**
+     * Returns a {@link BiPredicate} that evaluates to {@code true} if the given {@link BiPredicate} evaluates to {@code
+     * false}.
+     * 
+     * @param <T> predicate input type
+     * @param <U> predicate input type
+     * @param predicate the predicate to negate
+     * 
+     * @return the negated {@link BiPredicate}
+     */
+    @Nonnull public static <T,U> BiPredicate<T,U> not(@Nonnull final BiPredicate<? super T, ? super U> predicate) {
+        return predicate.negate()::test;
+    }
+
+    /**
+     * Returns a {@link BiPredicate} that evaluates to {@code true} if each of its components evaluates to
+     * {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
+     * as soon as a false {@link BiPredicate} is found. It defensively copies the iterable passed in, so future
+     * changes to it won't alter the behavior of this {@link BiPredicate}. If {@code components} is empty, the
+     * returned {@link BiPredicate} will always evaluate to {@code true}.
+     * 
+     * @param <T> predicate input type
+     * @param <U> predicate input type
+     * @param components the {@link BiPredicate}s to combine
+     * 
+     * @return the composite {@link BiPredicate}
+     */
+    @Nonnull public static <T,U> BiPredicate<T,U> and(
+            @Nonnull final Iterable<? extends BiPredicate<? super T, ? super U>> components) {
+        
+        final ArrayList<BiPredicate<? super T, ? super U>> copy = new ArrayList<>();
+        for (final BiPredicate<? super T,? super U> p : components) {
+            copy.add(p);
+        }
+
+        return (t, u) -> {
+            for (final BiPredicate<? super T, ? super U> p : copy) {
+                if (!p.test(t, u)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+    }
+
+    /**
+     * Returns a {@link BiPredicate} that evaluates to {@code true} if each of its components evaluates to
+     * {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
+     * as soon as a false {@link BiPredicate} is found. It defensively copies the iterable passed in, so future
+     * changes to it won't alter the behavior of this predicate. If {@code components} is empty, the
+     * returned {@link BiPredicate} will always evaluate to {@code true}.
+     * 
+     * @param <T> predicate input type
+     * @param <U> predicate input type
+     * @param components the {@link BiPredicate}s to combine
+     * 
+     * @return the composite {@link BiPredicate}
+     */
+    @SafeVarargs
+    @Nonnull public static <T,U> BiPredicate<T,U> and(
+            @Nonnull final BiPredicate<? super T,? super U>... components) {
+        final ArrayList<BiPredicate<? super T,? super U>> copy = new ArrayList<>();
+        for (final BiPredicate<? super T,? super U> p : components) {
+            copy.add(p);
+        }
+        
+        return (t, u) -> {
+            for (final BiPredicate<? super T, ? super U> p : copy) {
+                if (!p.test(t, u)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+    }
+
+    /**
+     * Returns a {@link BiPredicate} that evaluates to {@code true} if each of its components evaluates to
+     * {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
+     * as soon as a false {@link BiPredicate} is found. It defensively copies the iterable passed in, so future
+     * changes to it won't alter the behavior of this {@link BiPredicate}. If {@code components} is empty, the
+     * returned {@link BiPredicate} will always evaluate to {@code true}.
+     * 
+     * @param <T> predicate input type
+     * @param <U> predicate input type
+     * @param first the first {@link BiPredicate}
+     * @param second the second {@link BiPredicate}
+     * 
+     * @return the composite {@link BiPredicate}
+     */
+    @Nonnull public static <T,U> BiPredicate<T,U> and(@Nonnull final BiPredicate<T,U> first,
+            @Nonnull final BiPredicate<? super T,? super U> second) {
+        
+        return first.and(second);
+    }
+    
+    /**
+     * Returns a {@link BiPredicate} that evaluates to {@code true} if any one of its components evaluates to
+     * {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
+     * as soon as a true {@link BiPredicate} is found. It defensively copies the iterable passed in, so future
+     * changes to it won't alter the behavior of this {@link BiPredicate}. If {@code components} is empty, the
+     * returned {@link BiPredicate} will always evaluate to {@code false}.
+     * 
+     * @param <T> predicate input type
+     * @param <U> predicate input type
+     * @param components the {@link BiPredicate}s to combine
+     * 
+     * @return the composite {@link BiPredicate}
+     */
+    @Nonnull public static <T,U> BiPredicate<T,U> or(
+            @Nonnull final Iterable<? extends BiPredicate<? super T,? super U>> components) {
+        
+        final ArrayList<BiPredicate<? super T,? super U>> copy = new ArrayList<>();
+        for (final BiPredicate<? super T,? super U> p : components) {
+            copy.add(p);
+        }
+        
+        return (t, u) -> {
+            for (final BiPredicate<? super T, ? super U> p : copy) {
+                if (p.test(t, u)) {
+                    return true;
+                }
+            }
+            return false;
+        };
+    }
+
+    /**
+     * Returns a {@link BiPredicate} that evaluates to {@code true} if any one of its components evaluates to
+     * {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
+     * as soon as a true {@link BiPredicate} is found. It defensively copies the iterable passed in, so future
+     * changes to it won't alter the behavior of this {@link BiPredicate}. If {@code components} is empty, the
+     * returned {@link BiPredicate} will always evaluate to {@code false}.
+     * 
+     * @param <T> predicate input type
+     * @param <U> predicate input type
+     * @param components the {@link BiPredicate}s to combine
+     * 
+     * @return the composite {@link BiPredicate}
+     */
+    @SafeVarargs
+    @Nonnull public static <T,U> BiPredicate<T,U> or(
+            @Nonnull final BiPredicate<? super T,? super U>... components) {
+        
+        final ArrayList<BiPredicate<? super T,? super U>> copy = new ArrayList<>();
+        for (final BiPredicate<? super T,? super U> p : components) {
+            copy.add(p);
+        }
+        
+        return (t, u) -> {
+            for (final BiPredicate<? super T, ? super U> p : copy) {
+                if (p.test(t, u)) {
+                    return true;
+                }
+            }
+            return false;
+        };
+    }
+
+    /**
+     * Returns a {@link BiPredicate} that evaluates to {@code true} if any one of its components evaluates to
+     * {@code true}. The components are evaluated in order, and evaluation will be "short-circuited"
+     * as soon as a true {@link BiPredicate} is found. It defensively copies the iterable passed in, so future
+     * changes to it won't alter the behavior of this {@link BiPredicate}. If {@code components} is empty, the
+     * returned {@link BiPredicate} will always evaluate to {@code false}.
+     * 
+     * @param <T> predicate input type
+     * @param <U> predicate input type
+     * @param first the first {@link BiPredicate}
+     * @param second the second {@link BiPredicate}
+     * 
+     * @return the composite predicate
+     */
+    @Nonnull public static <T,U> BiPredicate<T,U> or(@Nonnull final BiPredicate<T,U> first,
+            @Nonnull final BiPredicate<? super T,? super U> second) {
+        
+        return first.or(second);
+    }
+    
+}
\ No newline at end of file
diff --git a/src/main/java/net/shibboleth/utilities/java/support/logic/FunctionSupport.java b/src/main/java/net/shibboleth/utilities/java/support/logic/FunctionSupport.java
index 4dd1f6e..463e053 100644
--- a/src/main/java/net/shibboleth/utilities/java/support/logic/FunctionSupport.java
+++ b/src/main/java/net/shibboleth/utilities/java/support/logic/FunctionSupport.java
@@ -63,9 +63,10 @@ public final class FunctionSupport {
      * @return the composition of {@code f} and {@code g}
      * @see <a href="//en.wikipedia.org/wiki/Function_composition">function composition</a>
      */
-    @Nonnull public static <A,B,C> Function<A,C> compose(@Nonnull @ParameterName(name="g") final Function<B,C> g,
+    @Nonnull public static <A,B,C> Function<A,C> compose(
+            @Nonnull @ParameterName(name="g") final Function<? super B,? extends C> g,
             @Nonnull @ParameterName(name="f") final Function<A,? extends B> f) {
-        return g.compose(f);
+        return f.andThen(g);
     }
 
     /**
@@ -78,7 +79,8 @@ public final class FunctionSupport {
      * 
      * @return a corresponding function 
      */
-    @Nonnull public static <T> Function<T,Boolean> forPredicate(@Nonnull final Predicate<T> predicate) {
+    @Nonnull public static <T> Function<T,Boolean> forPredicate(
+            @Nonnull @ParameterName(name="predicate") final Predicate<? super T> predicate) {
         return predicate::test;
     }
     
diff --git a/src/main/java/net/shibboleth/utilities/java/support/logic/PredicateSupport.java b/src/main/java/net/shibboleth/utilities/java/support/logic/PredicateSupport.java
index c7394f6..e6c26d8 100644
--- a/src/main/java/net/shibboleth/utilities/java/support/logic/PredicateSupport.java
+++ b/src/main/java/net/shibboleth/utilities/java/support/logic/PredicateSupport.java
@@ -84,7 +84,7 @@ public final class PredicateSupport {
      *  @since 7.4.0
      */
     @Nonnull public static <T> Predicate<T> fromFunction(@Nonnull final Function<T,Boolean> function,
-            @Nonnull final java.util.function.Predicate<T> defValue) {
+            @Nonnull final java.util.function.Predicate<? super T> defValue) {
         return new Predicate<>() {
             public boolean test(@Nullable final T input) {
                 final Boolean result = function.apply(input);
@@ -102,7 +102,7 @@ public final class PredicateSupport {
      * 
      * @return the negated predicate
      */
-    @Nonnull public static <T> Predicate<T> not(@Nonnull final java.util.function.Predicate<T> predicate) {
+    @Nonnull public static <T> Predicate<T> not(@Nonnull final java.util.function.Predicate<? super T> predicate) {
         return predicate.negate()::test;
     }
 

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


More information about the commits mailing list