    001    /*
    002     * Copyright (C) 2007 The Guava Authors
    003     *
    004     * Licensed under the Apache License, Version 2.0 (the "License");
    005     * you may not use this file except in compliance with the License.
    006     * You may obtain a copy of the License at
    007     *
    008     * http://www.apache.org/licenses/LICENSE-2.0
    009     *
    010     * Unless required by applicable law or agreed to in writing, software
    011     * distributed under the License is distributed on an "AS IS" BASIS,
    012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    013     * See the License for the specific language governing permissions and
    014     * limitations under the License.
    015     */
    016
    017    package com.google.common.base;
    018
    019    import static com.google.common.base.Preconditions.checkNotNull;
    020
    021    import com.google.common.annotations.Beta;
    022    import com.google.common.annotations.GwtCompatible;
    023    import com.google.common.annotations.GwtIncompatible;
    024
    025    import java.io.Serializable;
    026    import java.util.ArrayList;
    027    import java.util.Arrays;
    028    import java.util.Collection;
    029    import java.util.List;
    030    import java.util.regex.Pattern;
    031
    032    import javax.annotation.Nullable;
    033
    034    /**
    035     * Static utility methods pertaining to {@code Predicate} instances.
    036     *
    037     * <p>All methods returns serializable predicates as long as they're given
    038     * serializable parameters.
    039     *
    040     * @author Kevin Bourrillion
    041     * @since 2.0 (imported from Google Collections Library)
    042     */
    043    @GwtCompatible(emulated = true)
    044    public final class Predicates {
    045      private Predicates() {}
    046
    047      // TODO(kevinb): considering having these implement a VisitablePredicate
    048      // interface which specifies an accept(PredicateVisitor) method.
    049
    050      /**
    051       * Returns a predicate that always evaluates to {@code true}.
    052       */
    053      @GwtCompatible(serializable = true)
    054      public static <T> Predicate<T> alwaysTrue() {
    055        return ObjectPredicate.ALWAYS_TRUE.withNarrowedType();
    056      }
    057
    058      /**
    059       * Returns a predicate that always evaluates to {@code false}.
    060       */
    061      @GwtCompatible(serializable = true)
    062      public static <T> Predicate<T> alwaysFalse() {
    063        return ObjectPredicate.ALWAYS_FALSE.withNarrowedType();
    064      }
    065
    066      /**
    067       * Returns a predicate that evaluates to {@code true} if the object reference
    068       * being tested is null.
    069       */
    070      @GwtCompatible(serializable = true)
    071      public static <T> Predicate<T> isNull() {
    072        return ObjectPredicate.IS_NULL.withNarrowedType();
    073      }
    074
    075      /**
    076       * Returns a predicate that evaluates to {@code true} if the object reference
    077       * being tested is not null.
    078       */
    079      @GwtCompatible(serializable = true)
    080      public static <T> Predicate<T> notNull() {
    081        return ObjectPredicate.NOT_NULL.withNarrowedType();
    082      }
    083
    084      /**
    085       * Returns a predicate that evaluates to {@code true} if the given predicate
    086       * evaluates to {@code false}.
    087       */
    088      public static <T> Predicate<T> not(Predicate<T> predicate) {
    089        return new NotPredicate<T>(predicate);
    090      }
    091
    092      /**
    093       * Returns a predicate that evaluates to {@code true} if each of its
    094       * components evaluates to {@code true}. The components are evaluated in
    095       * order, and evaluation will be "short-circuited" as soon as a false
    096       * predicate is found. It defensively copies the iterable passed in, so future
    097       * changes to it won't alter the behavior of this predicate. If {@code
    098       * components} is empty, the returned predicate will always evaluate to {@code
    099       * true}.
    100       */
    101      public static <T> Predicate<T> and(
    102          Iterable<? extends Predicate<? super T>> components) {
    103        return new AndPredicate<T>(defensiveCopy(components));
    104      }
    105
    106      /**
    107       * Returns a predicate that evaluates to {@code true} if each of its
    108       * components evaluates to {@code true}. The components are evaluated in
    109       * order, and evaluation will be "short-circuited" as soon as a false
    110       * predicate is found. It defensively copies the array passed in, so future
    111       * changes to it won't alter the behavior of this predicate. If {@code
    112       * components} is empty, the returned predicate will always evaluate to {@code
    113       * true}.
    114       */
    115      public static <T> Predicate<T> and(Predicate<? super T>... components) {
    116        return new AndPredicate<T>(defensiveCopy(components));
    117      }
    118
    119      /**
    120       * Returns a predicate that evaluates to {@code true} if both of its
    121       * components evaluate to {@code true}. The components are evaluated in
    122       * order, and evaluation will be "short-circuited" as soon as a false
    123       * predicate is found.
    124       */
    125      public static <T> Predicate<T> and(Predicate<? super T> first,
    126          Predicate<? super T> second) {
    127        return new AndPredicate<T>(Predicates.<T>asList(
    128            checkNotNull(first), checkNotNull(second)));
    129      }
    130
    131      /**
    132       * Returns a predicate that evaluates to {@code true} if any one of its
    133       * components evaluates to {@code true}. The components are evaluated in
    134       * order, and evaluation will be "short-circuited" as soon as a
    135       * true predicate is found. It defensively copies the iterable passed in, so
    136       * future changes to it won't alter the behavior of this predicate. If {@code
    137       * components} is empty, the returned predicate will always evaluate to {@code
    138       * false}.
    139       */
    140      public static <T> Predicate<T> or(
    141          Iterable<? extends Predicate<? super T>> components) {
    142        return new OrPredicate<T>(defensiveCopy(components));
    143      }
    144
    145      /**
    146       * Returns a predicate that evaluates to {@code true} if any one of its
    147       * components evaluates to {@code true}. The components are evaluated in
    148       * order, and evaluation will be "short-circuited" as soon as a
    149       * true predicate is found. It defensively copies the array passed in, so
    150       * future changes to it won't alter the behavior of this predicate. If {@code
    151       * components} is empty, the returned predicate will always evaluate to {@code
    152       * false}.
    153       */
    154      public static <T> Predicate<T> or(Predicate<? super T>... components) {
    155        return new OrPredicate<T>(defensiveCopy(components));
    156      }
    157
    158      /**
    159       * Returns a predicate that evaluates to {@code true} if either of its
    160       * components evaluates to {@code true}. The components are evaluated in
    161       * order, and evaluation will be "short-circuited" as soon as a
    162       * true predicate is found.
    163       */
    164      public static <T> Predicate<T> or(
    165          Predicate<? super T> first, Predicate<? super T> second) {
    166        return new OrPredicate<T>(Predicates.<T>asList(
    167            checkNotNull(first), checkNotNull(second)));
    168      }
    169
    170      /**
    171       * Returns a predicate that evaluates to {@code true} if the object being
    172       * tested {@code equals()} the given target or both are null.
    173       */
    174      public static <T> Predicate<T> equalTo(@Nullable T target) {
    175        return (target == null)
    176            ? Predicates.<T>isNull()
    177            : new IsEqualToPredicate<T>(target);
    178      }
    179
    180      /**
    181       * Returns a predicate that evaluates to {@code true} if the object being
    182       * tested is an instance of the given class. If the object being tested
    183       * is {@code null} this predicate evaluates to {@code false}.
    184       *
    185       * <p>If you want to filter an {@code Iterable} to narrow its type, consider
    186       * using {@link com.google.common.collect.Iterables#filter(Iterable, Class)}
    187       * in preference.
    188       *
    189       * <p><b>Warning:</b> contrary to the typical assumptions about predicates (as
    190       * documented at {@link Predicate#apply}), the returned predicate may not be
    191       * <i>consistent with equals</i>. For example, {@code
    192       * instanceOf(ArrayList.class)} will yield different results for the two equal
    193       * instances {@code Lists.newArrayList(1)} and {@code Arrays.asList(1)}.
    194       */
    195      @GwtIncompatible("Class.isInstance")
    196      public static Predicate<Object> instanceOf(Class<?> clazz) {
    197        return new InstanceOfPredicate(clazz);
    198      }
    199
    200      /**
    201       * Returns a predicate that evaluates to {@code true} if the class being
    202       * tested is assignable from the given class.  The returned predicate
    203       * does not allow null inputs.
    204       *
    205       * @since 10.0
    206       */
    207      @GwtIncompatible("Class.isAssignableFrom")
    208      @Beta
    209      public static Predicate<Class<?>> assignableFrom(Class<?> clazz) {
    210        return new AssignableFromPredicate(clazz);
    211      }
    212
    213      /**
    214       * Returns a predicate that evaluates to {@code true} if the object reference
    215       * being tested is a member of the given collection. It does not defensively
    216       * copy the collection passed in, so future changes to it will alter the
    217       * behavior of the predicate.
    218       *
    219       * <p>This method can technically accept any {@code Collection<?>}, but using
    220       * a typed collection helps prevent bugs. This approach doesn't block any
    221       * potential users since it is always possible to use {@code
    222       * Predicates.<Object>in()}.
    223       *
    224       * @param target the collection that may contain the function input
    225       */
    226      public static <T> Predicate<T> in(Collection<? extends T> target) {
    227        return new InPredicate<T>(target);
    228      }
    229
    230      /**
    231       * Returns the composition of a function and a predicate. For every {@code x},
    232       * the generated predicate returns {@code predicate(function(x))}.
    233       *
    234       * @return the composition of the provided function and predicate
    235       */
    236      public static <A, B> Predicate<A> compose(
    237          Predicate<B> predicate, Function<A, ? extends B> function) {
    238        return new CompositionPredicate<A, B>(predicate, function);
    239      }
    240
    241      /**
    242       * Returns a predicate that evaluates to {@code true} if the
    243       * {@code CharSequence} being tested contains any match for the given
    244       * regular expression pattern. The test used is equivalent to
    245       * {@code Pattern.compile(pattern).matcher(arg).find()}
    246       *
    247       * @throws java.util.regex.PatternSyntaxException if the pattern is invalid
    248       * @since 3.0
    249       */
    250      @GwtIncompatible(value = "java.util.regex.Pattern")
    251      public static Predicate<CharSequence> containsPattern(String pattern) {
    252        return new ContainsPatternPredicate(pattern);
    253      }
    254
    255      /**
    256       * Returns a predicate that evaluates to {@code true} if the
    257       * {@code CharSequence} being tested contains any match for the given
    258       * regular expression pattern. The test used is equivalent to
    259       * {@code regex.matcher(arg).find()}
    260       *
    261       * @since 3.0
    262       */
    263      @GwtIncompatible(value = "java.util.regex.Pattern")
    264      public static Predicate<CharSequence> contains(Pattern pattern) {
    265        return new ContainsPatternPredicate(pattern);
    266      }
    267
    268      // End public API, begin private implementation classes.
    269
    270      // Package private for GWT serialization.
    271      enum ObjectPredicate implements Predicate<Object> {
    272        ALWAYS_TRUE {
    273          @Override public boolean apply(@Nullable Object o) {
    274            return true;
    275          }
    276        },
    277        ALWAYS_FALSE {
    278          @Override public boolean apply(@Nullable Object o) {
    279            return false;
    280          }
    281        },
    282        IS_NULL {
    283          @Override public boolean apply(@Nullable Object o) {
    284            return o == null;
    285          }
    286        },
    287        NOT_NULL {
    288          @Override public boolean apply(@Nullable Object o) {
    289            return o != null;
    290          }
    291        };
    292
    293        @SuppressWarnings("unchecked") // these Object predicates work for any T
    294        <T> Predicate<T> withNarrowedType() {
    295          return (Predicate<T>) this;
    296        }
    297      }
    298
    299      /** @see Predicates#not(Predicate) */
    300      private static class NotPredicate<T> implements Predicate<T>, Serializable {
    301        final Predicate<T> predicate;
    302
    303        NotPredicate(Predicate<T> predicate) {
    304          this.predicate = checkNotNull(predicate);
    305        }
    306        @Override
    307        public boolean apply(T t) {
    308          return !predicate.apply(t);
    309        }
    310        @Override public int hashCode() {
    311          return ~predicate.hashCode();
    312        }
    313        @Override public boolean equals(@Nullable Object obj) {
    314          if (obj instanceof NotPredicate) {
    315            NotPredicate<?> that = (NotPredicate<?>) obj;
    316            return predicate.equals(that.predicate);
    317          }
    318          return false;
    319        }
    320        @Override public String toString() {
    321          return "Not(" + predicate.toString() + ")";
    322        }
    323        private static final long serialVersionUID = 0;
    324      }
    325
    326      private static final Joiner COMMA_JOINER = Joiner.on(",");
    327
    328      /** @see Predicates#and(Iterable) */
    329      private static class AndPredicate<T> implements Predicate<T>, Serializable {
    330        private final List<? extends Predicate<? super T>> components;
    331
    332        private AndPredicate(List<? extends Predicate<? super T>> components) {
    333          this.components = components;
    334        }
    335        @Override
    336        public boolean apply(T t) {
    337          for (Predicate<? super T> predicate : components) {
    338            if (!predicate.apply(t)) {
    339              return false;
    340            }
    341          }
    342          return true;
    343        }
    344        @Override public int hashCode() {
    345          // 0x12472c2c is a random number to help avoid collisions with OrPredicate
    346          return components.hashCode() + 0x12472c2c;
    347        }
    348        @Override public boolean equals(@Nullable Object obj) {
    349          if (obj instanceof AndPredicate) {
    350            AndPredicate<?> that = (AndPredicate<?>) obj;
    351            return components.equals(that.components);
    352          }
    353          return false;
    354        }
    355        @Override public String toString() {
    356          return "And(" + COMMA_JOINER.join(components) + ")";
    357        }
    358        private static final long serialVersionUID = 0;
    359      }
    360
    361      /** @see Predicates#or(Iterable) */
    362      private static class OrPredicate<T> implements Predicate<T>, Serializable {
    363        private final List<? extends Predicate<? super T>> components;
    364
    365        private OrPredicate(List<? extends Predicate<? super T>> components) {
    366          this.components = components;
    367        }
    368        @Override
    369        public boolean apply(T t) {
    370          for (Predicate<? super T> predicate : components) {
    371            if (predicate.apply(t)) {
    372              return true;
    373            }
    374          }
    375          return false;
    376        }
    377        @Override public int hashCode() {
    378          // 0x053c91cf is a random number to help avoid collisions with AndPredicate
    379          return components.hashCode() + 0x053c91cf;
    380        }
    381        @Override public boolean equals(@Nullable Object obj) {
    382          if (obj instanceof OrPredicate) {
    383            OrPredicate<?> that = (OrPredicate<?>) obj;
    384            return components.equals(that.components);
    385          }
    386          return false;
    387        }
    388        @Override public String toString() {
    389          return "Or(" + COMMA_JOINER.join(components) + ")";
    390        }
    391        private static final long serialVersionUID = 0;
    392      }
    393
    394      /** @see Predicates#equalTo(Object) */
    395      private static class IsEqualToPredicate<T>
    396          implements Predicate<T>, Serializable {
    397        private final T target;
    398
    399        private IsEqualToPredicate(T target) {
    400          this.target = target;
    401        }
    402        @Override
    403        public boolean apply(T t) {
    404          return target.equals(t);
    405        }
    406        @Override public int hashCode() {
    407          return target.hashCode();
    408        }
    409        @Override public boolean equals(@Nullable Object obj) {
    410          if (obj instanceof IsEqualToPredicate) {
    411            IsEqualToPredicate<?> that = (IsEqualToPredicate<?>) obj;
    412            return target.equals(that.target);
    413          }
    414          return false;
    415        }
    416        @Override public String toString() {
    417          return "IsEqualTo(" + target + ")";
    418        }
    419        private static final long serialVersionUID = 0;
    420      }
    421
    422      /** @see Predicates#instanceOf(Class) */
    423      @GwtIncompatible("Class.isInstance")
    424      private static class InstanceOfPredicate
    425          implements Predicate<Object>, Serializable {
    426        private final Class<?> clazz;
    427
    428        private InstanceOfPredicate(Class<?> clazz) {
    429          this.clazz = checkNotNull(clazz);
    430        }
    431        @Override
    432        public boolean apply(@Nullable Object o) {
    433          return clazz.isInstance(o);
    434        }
    435        @Override public int hashCode() {
    436          return clazz.hashCode();
    437        }
    438        @Override public boolean equals(@Nullable Object obj) {
    439          if (obj instanceof InstanceOfPredicate) {
    440            InstanceOfPredicate that = (InstanceOfPredicate) obj;
    441            return clazz == that.clazz;
    442          }
    443          return false;
    444        }
    445        @Override public String toString() {
    446          return "IsInstanceOf(" + clazz.getName() + ")";
    447        }
    448        private static final long serialVersionUID = 0;
    449      }
    450
    451      /** @see Predicates#assignableFrom(Class) */
    452      @GwtIncompatible("Class.isAssignableFrom")
    453      private static class AssignableFromPredicate
    454          implements Predicate<Class<?>>, Serializable {
    455        private final Class<?> clazz;
    456
    457        private AssignableFromPredicate(Class<?> clazz) {
    458          this.clazz = checkNotNull(clazz);
    459        }
    460        @Override
    461        public boolean apply(Class<?> input) {
    462          return clazz.isAssignableFrom(input);
    463        }
    464        @Override public int hashCode() {
    465          return clazz.hashCode();
    466        }
    467        @Override public boolean equals(@Nullable Object obj) {
    468          if (obj instanceof AssignableFromPredicate) {
    469            AssignableFromPredicate that = (AssignableFromPredicate) obj;
    470            return clazz == that.clazz;
    471          }
    472          return false;
    473        }
    474        @Override public String toString() {
    475          return "IsAssignableFrom(" + clazz.getName() + ")";
    476        }
    477        private static final long serialVersionUID = 0;
    478      }
    479
    480      /** @see Predicates#in(Collection) */
    481      private static class InPredicate<T> implements Predicate<T>, Serializable {
    482        private final Collection<?> target;
    483
    484        private InPredicate(Collection<?> target) {
    485          this.target = checkNotNull(target);
    486        }
    487
    488        @Override
    489        public boolean apply(T t) {
    490          try {
    491            return target.contains(t);
    492          } catch (NullPointerException e) {
    493            return false;
    494          } catch (ClassCastException e) {
    495            return false;
    496          }
    497        }
    498
    499        @Override public boolean equals(@Nullable Object obj) {
    500          if (obj instanceof InPredicate) {
    501            InPredicate<?> that = (InPredicate<?>) obj;
    502            return target.equals(that.target);
    503          }
    504          return false;
    505        }
    506
    507        @Override public int hashCode() {
    508          return target.hashCode();
    509        }
    510
    511        @Override public String toString() {
    512          return "In(" + target + ")";
    513        }
    514        private static final long serialVersionUID = 0;
    515      }
    516
    517      /** @see Predicates#compose(Predicate, Function) */
    518      private static class CompositionPredicate<A, B>
    519          implements Predicate<A>, Serializable {
    520        final Predicate<B> p;
    521        final Function<A, ? extends B> f;
    522
    523        private CompositionPredicate(Predicate<B> p, Function<A, ? extends B> f) {
    524          this.p = checkNotNull(p);
    525          this.f = checkNotNull(f);
    526        }
    527
    528        @Override
    529        public boolean apply(A a) {
    530          return p.apply(f.apply(a));
    531        }
    532
    533        @Override public boolean equals(@Nullable Object obj) {
    534          if (obj instanceof CompositionPredicate) {
    535            CompositionPredicate<?, ?> that = (CompositionPredicate<?, ?>) obj;
    536            return f.equals(that.f) && p.equals(that.p);
    537          }
    538          return false;
    539        }
    540
    541        @Override public int hashCode() {
    542          return f.hashCode() ^ p.hashCode();
    543        }
    544
    545        @Override public String toString() {
    546          return p.toString() + "(" + f.toString() + ")";
    547        }
    548
    549        private static final long serialVersionUID = 0;
    550      }
    551
    552      /**
    553       * @see Predicates#contains(Pattern)
    554       * @see Predicates#containsPattern(String)
    555       */
    556      @GwtIncompatible("Only used by other GWT-incompatible code.")
    557      private static class ContainsPatternPredicate
    558          implements Predicate<CharSequence>, Serializable {
    559        final Pattern pattern;
    560
    561        ContainsPatternPredicate(Pattern pattern) {
    562          this.pattern = checkNotNull(pattern);
    563        }
    564
    565        ContainsPatternPredicate(String patternStr) {
    566          this(Pattern.compile(patternStr));
    567        }
    568
    569        @Override
    570        public boolean apply(CharSequence t) {
    571          return pattern.matcher(t).find();
    572        }
    573
    574        @Override public int hashCode() {
    575          // Pattern uses Object.hashCode, so we have to reach
    576          // inside to build a hashCode consistent with equals.
    577
    578          return Objects.hashCode(pattern.pattern(), pattern.flags());
    579        }
    580
    581        @Override public boolean equals(@Nullable Object obj) {
    582          if (obj instanceof ContainsPatternPredicate) {
    583            ContainsPatternPredicate that = (ContainsPatternPredicate) obj;
    584
    585            // Pattern uses Object (identity) equality, so we have to reach
    586            // inside to compare individual fields.
    587            return Objects.equal(pattern.pattern(), that.pattern.pattern())
    588                && Objects.equal(pattern.flags(), that.pattern.flags());
    589          }
    590          return false;
    591        }
    592
    593        @Override public String toString() {
    594          return Objects.toStringHelper(this)
    595              .add("pattern", pattern)
    596              .add("pattern.flags", Integer.toHexString(pattern.flags()))
    597              .toString();
    598        }
    599
    600        private static final long serialVersionUID = 0;
    601      }
    602
    603      @SuppressWarnings("unchecked")
    604      private static <T> List<Predicate<? super T>> asList(
    605          Predicate<? super T> first, Predicate<? super T> second) {
    606        return Arrays.<Predicate<? super T>>asList(first, second);
    607      }
    608
    609      private static <T> List<T> defensiveCopy(T... array) {
    610        return defensiveCopy(Arrays.asList(array));
    611      }
    612
    613      static <T> List<T> defensiveCopy(Iterable<T> iterable) {
    614        ArrayList<T> list = new ArrayList<T>();
    615        for (T element : iterable) {
    616          list.add(checkNotNull(element));
    617        }
    618        return list;
    619      }
    620    }