// CopyrightGoogle Inc. All rights reserved. package com.google.ical.util; import java.io.Serializable; import java.util.Collection; /** * static methods for creating the standard set of {@link Predicate} objects. */ public class Predicates { private Predicates() { // uninstantiable } /* * For constant Predicates a single instance will suffice; we'll cast it to * the right parameterized type on demand. */ private static final Predicate<?> ALWAYS_TRUE = new AlwaysTruePredicate<Object>(); private static final Predicate<?> ALWAYS_FALSE = new AlwaysFalsePredicate<Object>(); /** * Returns a Predicate that always evaluates to true. */ @SuppressWarnings("unchecked") public static <T> Predicate<T> alwaysTrue() { return (Predicate<T>) ALWAYS_TRUE; } /** * Returns a Predicate that always evaluates to false. */ @SuppressWarnings("unchecked") public static <T> Predicate<T> alwaysFalse() { return (Predicate<T>) ALWAYS_FALSE; } /** * Returns a Predicate that evaluates to true iff the given Predicate * evaluates to false. */ public static <T> Predicate<T> not(Predicate<? super T> predicate) { assert null != predicate; return new NotPredicate<T>(predicate); } /** * Returns a Predicate that evaluates to true iff each of its components * evaluates to true. The components are evaluated in order, and evaluation * will be "short-circuited" as soon as the answer is determined. Does not * defensively copy the array passed in, so future changes to it will alter * the behavior of this Predicate. */ public static <T> Predicate<T> and(Predicate<? super T>... components) { assert null != components; components = components.clone(); int n = components.length; for (int i = 0; i < n; ++i) { Predicate<? super T> p = components[i]; if (p == ALWAYS_FALSE) { return alwaysFalse(); } if (p == ALWAYS_TRUE) { components[i] = components[n - 1]; --i; --n; } } if (n == 0) { return alwaysTrue(); } if (n != components.length) { @SuppressWarnings("unchecked") Predicate<? super T>[] newComponents = new Predicate[n]; System.arraycopy(newComponents, 0, components, 0, n); components = newComponents; } return new AndPredicate<T>(components); } /** * Returns a Predicate that evaluates to true iff each of its components * evaluates to true. The components are evaluated in order, and evaluation * will be "short-circuited" as soon as the answer is determined. Does not * defensively copy the array passed in, so future changes to it will alter * the behavior of this Predicate. */ public static <T> Predicate<T> and( Collection<Predicate<? super T>> components) { int n = components.size(); @SuppressWarnings("unchecked") Predicate<? super T>[] arr = new Predicate[n]; components.toArray(arr); return and(arr); } /** * Returns a Predicate that evaluates to true iff any one of its components * evaluates to true. The components are evaluated in order, and evaluation * will be "short-circuited" as soon as the answer is determined. Does not * defensively copy the array passed in, so future changes to it will alter * the behavior of this Predicate. */ public static <T> Predicate<T> or(Predicate<? super T>... components) { assert components != null; components = components.clone(); int n = components.length; for (int i = 0; i < n; ++i) { Predicate<? super T> p = components[i]; if (p == ALWAYS_TRUE) { return alwaysTrue(); } if (p == ALWAYS_FALSE) { components[i] = components[n - 1]; --i; --n; } } if (components.length == 0) { return alwaysFalse(); } if (n != components.length) { @SuppressWarnings("unchecked") Predicate<? super T>[] newComponents = new Predicate[n]; System.arraycopy(newComponents, 0, components, 0, n); components = newComponents; } return new OrPredicate<T>(components); } /** @see Predicates#alwaysTrue */ private static class AlwaysTruePredicate<T> implements Predicate<T>, Serializable { private static final long serialVersionUID = 8759914710239461322L; public boolean apply(T t) { return true; } @Override public String toString() { return "true"; } } /** @see Predicates#alwaysFalse */ private static class AlwaysFalsePredicate<T> implements Predicate<T>, Serializable { private static final long serialVersionUID = -565481022115659695L; public boolean apply(T t) { return false; } @Override public String toString() { return "false"; } } /** @see Predicates#not */ private static class NotPredicate<T> implements Predicate<T>, Serializable { private static final long serialVersionUID = -5113445916422049953L; private final Predicate<? super T> predicate; private NotPredicate(Predicate<? super T> predicate) { this.predicate = predicate; } public boolean apply(T t) { return !predicate.apply(t); } } /** @see Predicates#and */ private static class AndPredicate<T> implements Predicate<T>, Serializable { private static final long serialVersionUID = 1022358602593297546L; private final Predicate<? super T>[] components; private AndPredicate(Predicate<? super T>... components) { this.components = components; } public boolean apply(T t) { for (Predicate<? super T> predicate : components) { if (!predicate.apply(t)) { return false; } } return true; } } /** @see Predicates#or */ private static class OrPredicate<T> implements Predicate<T>, Serializable { private static final long serialVersionUID = -7942366790698074803L; private final Predicate<? super T>[] components; private OrPredicate(Predicate<? super T>... components) { this.components = components; } public boolean apply(T t) { for (Predicate<? super T> predicate : components) { if (predicate.apply(t)) { return true; } } return false; } } }