Predicates.java
package com.github.dakusui.pcond.forms;
import com.github.dakusui.pcond.core.printable.PrintablePredicateFactory;
import com.github.dakusui.pcond.core.printable.PrintablePredicateFactory.Leaf;
import com.github.dakusui.pcond.core.printable.PrintablePredicateFactory.ParameterizedLeafFactory;
import com.github.dakusui.pcond.core.refl.MethodQuery;
import com.github.dakusui.pcond.core.refl.Parameter;
import com.github.dakusui.pcond.internals.InternalChecks;
import java.util.Collection;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static com.github.dakusui.pcond.core.refl.ReflUtils.invokeMethod;
import static com.github.dakusui.pcond.forms.Printables.function;
import static com.github.dakusui.pcond.forms.Printables.predicate;
import static com.github.dakusui.pcond.internals.InternalUtils.formatObject;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
/**
* An entry point for acquiring predicate objects.
* Predicates retrieved by methods in this class are all "printable".
*/
public class Predicates {
private Predicates() {
}
public static <T> Predicate<T> alwaysTrue() {
return Leaf.ALWAYS_TRUE.instance();
}
public static Predicate<Boolean> isTrue() {
return Leaf.IS_TRUE.instance();
}
public static Predicate<Boolean> isFalse() {
return Leaf.IS_FALSE.instance();
}
public static <T> Predicate<T> isNull() {
return Leaf.IS_NULL.instance();
}
public static <T> Predicate<T> isNotNull() {
return Leaf.IS_NOT_NULL.instance();
}
public static <T> Predicate<T> isEqualTo(T value) {
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.IS_EQUAL_TO, singletonList(value));
}
public static <T> Predicate<T> isSameReferenceAs(T value) {
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.OBJECT_IS_SAME_AS, singletonList(value));
}
@SuppressWarnings({"unchecked", "RedundantClassCall"})
public static <T> Function<Class<?>, Predicate<T>> isInstanceOf() {
return Function.class.cast(Def.IS_INSTANCE_OF$2);
}
public static Predicate<Object> isInstanceOf(Class<?> value) {
return applyOnceExpectingPredicate(requireNonNull(value), isInstanceOf());
}
private static <T, R> Predicate<R> applyOnceExpectingPredicate(T value, Function<T, Predicate<R>> p) {
return predicate(() -> format("%s[%s]", p, formatObject(value)), p.apply(value));
}
public static <T extends Comparable<? super T>> Predicate<T> gt(T value) {
return greaterThan(value);
}
public static <T extends Comparable<? super T>> Predicate<T> greaterThan(T value) {
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.GREATER_THAN, singletonList(value));
}
public static <T extends Comparable<? super T>> Predicate<T> ge(T value) {
return greaterThanOrEqualTo(value);
}
public static <T extends Comparable<? super T>> Predicate<T> greaterThanOrEqualTo(T value) {
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.GREATER_THAN_OR_EQUAL_TO, singletonList(value));
}
public static <T extends Comparable<? super T>> Predicate<T> lt(T value) {
return lessThan(value);
}
public static <T extends Comparable<? super T>> Predicate<T> lessThan(T value) {
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.LESS_THAN, singletonList(value));
}
public static <T extends Comparable<? super T>> Predicate<T> le(T value) {
return lessThanOrEqualTo(value);
}
public static <T extends Comparable<? super T>> Predicate<T> lessThanOrEqualTo(T value) {
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.LESS_THAN_OR_EQUAL_TO, singletonList(value));
}
public static <T extends Comparable<T>> Predicate<T> eq(T value) {
return equalTo(value);
}
public static <T extends Comparable<T>> Predicate<T> equalTo(T value) {
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.EQUAL_TO, singletonList(value));
}
public static Predicate<String> matchesRegex(String regex) {
requireNonNull(regex);
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.MATCHES_REGEX, singletonList(regex));
}
public static Predicate<String> containsString(String string) {
requireNonNull(string);
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.CONTAINS_STRING, singletonList(string));
}
public static Predicate<String> startsWith(String string) {
requireNonNull(string);
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.STARTS_WITH, singletonList(string));
}
public static Predicate<String> endsWith(String string) {
requireNonNull(string);
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.ENDS_WITH, singletonList(string));
}
public static Predicate<String> equalsIgnoreCase(String string) {
requireNonNull(string);
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.EQUALS_IGNORE_CASE, singletonList(string));
}
public static Predicate<String> isEmptyString() {
return Leaf.IS_EMPTY_STRING.instance();
}
public static Predicate<String> isNullOrEmptyString() {
return Leaf.IS_NULL_OR_EMPTY_STRING.instance();
}
public static <E> Predicate<Collection<E>> contains(Object entry) {
return ParameterizedLeafFactory.create(ParameterizedLeafFactory.CONTAINS, singletonList(entry));
}
public static Predicate<Object[]> isEmptyArray() {
return Leaf.IS_EMPTY_ARRAY.instance();
}
public static Predicate<? super Collection<?>> isEmpty() {
return Leaf.IS_EMPTY_COLLECTION.instance();
}
public static <E> Predicate<Stream<E>> allMatch(Predicate<E> predicate) {
requireNonNull(predicate);
return PrintablePredicateFactory.allMatch(predicate);
}
public static <E> Predicate<Stream<E>> noneMatch(Predicate<E> predicate) {
requireNonNull(predicate);
return PrintablePredicateFactory.noneMatch(predicate);
}
public static <E> Predicate<Stream<E>> anyMatch(Predicate<E> predicate) {
requireNonNull(predicate);
return PrintablePredicateFactory.anyMatch(predicate);
}
@SafeVarargs
public static <T> Predicate<T> and(Predicate<? super T>... predicates) {
return PrintablePredicateFactory.and(asList(predicates));
}
@SafeVarargs
public static <T> Predicate<T> or(Predicate<? super T>... predicates) {
return PrintablePredicateFactory.or(asList(predicates));
}
@SafeVarargs
public static <T> Predicate<T> allOf(Predicate<? super T>... predicates) {
return PrintablePredicateFactory.allOf(asList(predicates));
}
@SafeVarargs
public static <T> Predicate<T> anyOf(Predicate<? super T>... predicates) {
return PrintablePredicateFactory.anyOf(asList(predicates));
}
public static <T> Predicate<T> not(Predicate<T> cond) {
return PrintablePredicateFactory.not(cond);
}
public static <O, P> PrintablePredicateFactory.TransformingPredicate.Factory<P, O> transform(String funcName, Function<O, P> func) {
return transform(function(funcName, func));
}
public static <O, P> PrintablePredicateFactory.TransformingPredicate.Factory<P, O> transform(Function<O, P> function) {
return PrintablePredicateFactory.transform(function);
}
/**
* // @formatter:off
* Returns a {@link Predicate} created from a method specified by a {@code methodQuery}.
* If the {@code methodQuery} matches none or more than one methods, a {@code RuntimeException} will be thrown.
*
* The suffix {@code p} stands for "predicate" following the custom in LISP culture
* and it is necessary to avoid collision with {@link Functions#call(MethodQuery)} method.
*
* // @formatter:on
*
* @param methodQuery A query object that specifies a method to be invoked by the returned predicate.
* @param <T> the type of the input to the returned predicate
* @return Created predicate.
* @see Functions#classMethod(Class, String, Object[])
* @see Functions#instanceMethod(Object, String, Object[])
* @see Functions#parameter()
*/
@SuppressWarnings("ConstantConditions")
public static <T> Predicate<T> callp(MethodQuery methodQuery) {
return predicate(
methodQuery.describe(),
t -> InternalChecks.ensureValue(
invokeMethod(methodQuery.bindActualArguments((o) -> o instanceof Parameter, o -> t)),
v -> v instanceof Boolean,
v -> format("Method matched with '%s' must return a boolean value but it gave: '%s'.", methodQuery.describe(), v)));
}
/**
* // @formatter:off
* Returns a predicate that calls a method which matches the given {@code methodName}
* and {@code args} on the object given as input to it.
*
* Note that method look up is done when the predicate is applied.
* This means this method does not throw any exception by itself and in case
* you give wrong {@code methodName} or {@code arguments}, an exception will be
* thrown when the returned function is applied.
* // @formatter:on
*
* @param methodName The method name
* @param arguments Arguments passed to the method.
* @param <T> The type of input to the returned predicate
* @return A predicate that invokes the method matching the {@code methodName} and {@code args}
* @see Functions#parameter()
*/
public static <T> Predicate<T> callp(String methodName, Object... arguments) {
return callp(Functions.instanceMethod(Functions.parameter(), methodName, arguments));
}
enum Def {
;
public static final Function<Class<?>, Predicate<?>> IS_INSTANCE_OF$2 = function(() -> "isInstanceOf", (Class<?> c) -> c::isInstance);
}
}