[java-support] 01/01: JSPT-94 - Add support classes to invert and join BiPredicates.
Scott Cantor
cantor.2 at osu.edu
Fri Apr 3 11:49:05 EDT 2020
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch dev/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