001/*
002 * Copyright (C) 2007 Google Inc., adapted in 2010 by Mathias Doenitz
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
017package org.parboiled.common;
018
019import java.util.Collection;
020
021public final class Predicates {
022
023    private Predicates() {}
024
025    /**
026     * Returns a predicate that always evaluates to {@code true}.
027     *
028     * @return a predicate
029     */
030    @SuppressWarnings("unchecked")
031    public static <T> Predicate<T> alwaysTrue() {
032        return (Predicate<T>) AlwaysTruePredicate.INSTANCE;
033    }
034
035    /**
036     * Returns a predicate that always evaluates to {@code false}.
037     *
038     * @return a predicate
039     */
040    @SuppressWarnings("unchecked")
041    public static <T> Predicate<T> alwaysFalse() {
042        return (Predicate<T>) AlwaysFalsePredicate.INSTANCE;
043    }
044
045    /**
046     * Returns a predicate that evaluates to {@code true} if the object reference
047     * being tested is null.
048     *
049     * @return a predicate
050     */
051    @SuppressWarnings("unchecked")
052    public static <T> Predicate<T> isNull() {
053        return (Predicate<T>) IsNullPredicate.INSTANCE;
054    }
055
056    /**
057     * Returns a predicate that evaluates to {@code true} if the object reference
058     * being tested is not null.
059     *
060     * @return a predicate
061     */
062    @SuppressWarnings("unchecked")
063    public static <T> Predicate<T> notNull() {
064        return (Predicate<T>) NotNullPredicate.INSTANCE;
065    }
066
067    /**
068     * Returns a predicate that evaluates to {@code true} if the given predicate
069     * evaluates to {@code false}.
070     *
071     * @param predicate the inner predicate
072     * @return a predicate
073     */
074    public static <T> Predicate<T> not(Predicate<T> predicate) {
075        return new NotPredicate<T>(predicate);
076    }
077
078    /**
079     * Returns a predicate that evaluates to {@code true} if each of its
080     * components evaluates to {@code true}. The components are evaluated in
081     * order, and evaluation will be "short-circuited" as soon as a false
082     * predicate is found. It defensively copies the iterable passed in, so future
083     * changes to it won't alter the behavior of this predicate. If {@code
084     * components} is empty, the returned predicate will always evaluate to {@code
085     * true}.
086     *
087     * @param components the components
088     * @return a predicate
089     */
090    public static <T> Predicate<T> and(Collection<? extends Predicate<? super T>> components) {
091        return new AndPredicate<T>(components);
092    }
093
094    /**
095     * Returns a predicate that evaluates to {@code true} if each of its
096     * components evaluates to {@code true}. The components are evaluated in
097     * order, and evaluation will be "short-circuited" as soon as a false
098     * predicate is found. It defensively copies the array passed in, so future
099     * changes to it won't alter the behavior of this predicate. If {@code
100     * components} is empty, the returned predicate will always evaluate to {@code
101     * true}.
102     *
103     * @param components the components
104     * @return a predicate
105     */
106    public static <T> Predicate<T> and(Predicate<? super T>... components) {
107        return new AndPredicate<T>(ImmutableList.of(components));
108    }
109
110    /**
111     * Returns a predicate that evaluates to {@code true} if both of its
112     * components evaluate to {@code true}. The components are evaluated in
113     * order, and evaluation will be "short-circuited" as soon as a false
114     * predicate is found.
115     *
116     * @param first the first
117     * @param second the second
118     * @return a predicate
119     */
120    public static <T> Predicate<T> and(Predicate<? super T> first, Predicate<? super T> second) {
121        Preconditions.checkArgNotNull(first, "first");
122        Preconditions.checkArgNotNull(second, "second");
123        return new AndPredicate<T>(ImmutableList.<Predicate<? super T>>of(first, second));
124    }
125
126    /**
127     * Returns a predicate that evaluates to {@code true} if any one of its
128     * components evaluates to {@code true}. The components are evaluated in
129     * order, and evaluation will be "short-circuited" as soon as as soon as a
130     * true predicate is found. It defensively copies the iterable passed in, so
131     * future changes to it won't alter the behavior of this predicate. If {@code
132     * components} is empty, the returned predicate will always evaluate to {@code
133     * false}.
134     *
135     * @param components the components
136     * @return a predicate
137     */
138    public static <T> Predicate<T> or(Collection<? extends Predicate<? super T>> components) {
139        return new OrPredicate<T>(components);
140    }
141
142    /**
143     * Returns a predicate that evaluates to {@code true} if any one of its
144     * components evaluates to {@code true}. The components are evaluated in
145     * order, and evaluation will be "short-circuited" as soon as as soon as a
146     * true predicate is found. It defensively copies the array passed in, so
147     * future changes to it won't alter the behavior of this predicate. If {@code
148     * components} is empty, the returned predicate will always evaluate to {@code
149     * false}.
150     *
151     * @param components the components
152     * @return a predicate
153     */
154    public static <T> Predicate<T> or(Predicate<? super T>... components) {
155        return new OrPredicate<T>(ImmutableList.of(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 as soon as a
162     * true predicate is found.
163     *
164     * @param first the first
165     * @param second the second
166     * @return a predicate
167     */
168    public static <T> Predicate<T> or(Predicate<? super T> first, Predicate<? super T> second) {
169        Preconditions.checkArgNotNull(first, "first");
170        Preconditions.checkArgNotNull(second, "second");
171        return new OrPredicate<T>(ImmutableList.<Predicate<? super T>>of(first, second));
172    }
173
174    /**
175     * Returns a predicate that evaluates to {@code true} if the object being
176     * tested {@code equals()} the given target or both are null.
177     *
178     * @param target the target
179     * @return a predicate
180     */
181    public static <T> Predicate<T> equalTo(T target) {
182        return (target == null) ? Predicates.<T>isNull() : new IsEqualToPredicate<T>(target);
183    }
184
185    /**
186     * Returns a predicate that evaluates to {@code true} if the object being
187     * tested is an instance of the given class. If the object being tested
188     * is {@code null} this predicate evaluates to {@code false}.
189     *
190     * @param clazz the clazz
191     * @return a predicate
192     */
193    public static Predicate<Object> instanceOf(Class<?> clazz) {
194        return new InstanceOfPredicate(clazz);
195    }
196
197    /**
198     * Returns a predicate that evaluates to {@code true} if the object reference
199     * being tested is a member of the given collection. It does not defensively
200     * copy the collection passed in, so future changes to it will alter the
201     * behavior of the predicate.
202     *
203     * This method can technically accept any {@code Collection<?>}, but using a typed
204     * collection helps prevent bugs. This approach doesn't block any potential
205     * users since it is always possible to use {@code Predicates.<Object>in()}.
206     *
207     * @param target the collection that may contain the function input
208     * @return a predicate
209     */
210    public static <T> Predicate<T> in(Collection<? extends T> target) {
211        return new InPredicate<T>(target);
212    }
213
214    private static class AlwaysTruePredicate implements Predicate<Object> {
215        private static final Predicate<Object> INSTANCE = new AlwaysTruePredicate();
216
217        public boolean apply(Object o) {
218            return true;
219        }
220
221        @Override
222        public
223        String toString() {
224            return "AlwaysTrue";
225        }
226    }
227
228    private static class AlwaysFalsePredicate implements Predicate<Object> {
229        private static final Predicate<Object> INSTANCE = new AlwaysFalsePredicate();
230
231        public boolean apply(Object o) {
232            return false;
233        }
234
235        @Override
236        public String toString() {
237            return "AlwaysFalse";
238        }
239    }
240
241    private static class NotPredicate<T> implements Predicate<T> {
242        private final Predicate<T> predicate;
243
244        private NotPredicate(Predicate<T> predicate) {
245            Preconditions.checkArgNotNull(predicate, "predicate");
246            this.predicate = predicate;
247        }
248
249        public boolean apply(T t) {
250            return !predicate.apply(t);
251        }
252
253        public String toString() {
254            return "Not(" + predicate.toString() + ")";
255        }
256    }
257
258    private static class AndPredicate<T> implements Predicate<T> {
259        private final Collection<? extends Predicate<? super T>> components;
260
261        private AndPredicate(Collection<? extends Predicate<? super T>> components) {
262            this.components = components;
263        }
264
265        public boolean apply(T t) {
266            for (Predicate<? super T> predicate : components) {
267                if (!predicate.apply(t)) {
268                    return false;
269                }
270            }
271            return true;
272        }
273
274        @Override
275        public String toString() {
276            return "And(" + StringUtils.join(components, ", ") + ")";
277        }
278    }
279
280    private static class OrPredicate<T> implements Predicate<T> {
281        private final Collection<? extends Predicate<? super T>> components;
282
283        private OrPredicate(Collection<? extends Predicate<? super T>> components) {
284            this.components = components;
285        }
286
287        public boolean apply(T t) {
288            for (Predicate<? super T> predicate : components) {
289                if (predicate.apply(t)) {
290                    return true;
291                }
292            }
293            return false;
294        }
295
296        @Override
297        public String toString() {
298            return "Or(" + StringUtils.join(components, ", ") + ")";
299        }
300    }
301
302    private static class IsEqualToPredicate<T> implements Predicate<T> {
303        private final T target;
304
305        private IsEqualToPredicate(T target) {
306            this.target = target;
307        }
308
309        public boolean apply(T t) {
310            return target.equals(t);
311        }
312
313        @Override
314        public String toString() {
315            return "IsEqualTo(" + target + ")";
316        }
317    }
318
319    private static class InstanceOfPredicate implements Predicate<Object> {
320        private final Class<?> clazz;
321
322        private InstanceOfPredicate(Class<?> clazz) {
323            Preconditions.checkArgNotNull(clazz, "clazz");
324            this.clazz = clazz;
325        }
326
327        public boolean apply(Object o) {
328            return clazz.isInstance(o);
329        }
330
331        @Override
332        public String toString() {
333            return "IsInstanceOf(" + clazz.getName() + ")";
334        }
335    }
336
337    private static class IsNullPredicate implements Predicate<Object> {
338        private static final Predicate<Object> INSTANCE = new IsNullPredicate();
339
340        public boolean apply(Object o) {
341            return o == null;
342        }
343
344        @Override
345        public String toString() {
346            return "IsNull";
347        }
348    }
349
350    private static class NotNullPredicate implements Predicate<Object> {
351        private static final Predicate<Object> INSTANCE = new NotNullPredicate();
352
353        public boolean apply(Object o) {
354            return o != null;
355        }
356
357        @Override
358        public String toString() {
359            return "NotNull";
360        }
361    }
362
363    private static class InPredicate<T> implements Predicate<T> {
364        private final Collection<?> target;
365
366        private InPredicate(Collection<?> target) {
367            Preconditions.checkArgNotNull(target, "target");
368            this.target = target;
369        }
370
371        public boolean apply(T t) {
372            try {
373                return target.contains(t);
374            } catch (NullPointerException e) {
375                return false;
376            } catch (ClassCastException e) {
377                return false;
378            }
379        }
380
381        @Override
382        public String toString() {
383            return "In(" + target + ")";
384        }
385    }
386
387}