001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.tools;
003
004import java.util.Collection;
005import java.util.Objects;
006import java.util.regex.Pattern;
007
008import org.openstreetmap.josm.data.osm.OsmPrimitive;
009
010/**
011 * Utility class for creating {@link Predicate}s.
012 */
013public final class Predicates {
014
015    private Predicates() {
016    }
017
018    /**
019     * Creates a predicate that returns true every time.
020     * @param <T> The type of the predicate.
021     * @return A predicate returning <code>true</code>
022     * @since 10040
023     */
024    public static <T> Predicate<T> alwaysTrue() {
025        return new Predicate<T>() {
026            @Override
027            public boolean evaluate(T object) {
028                return true;
029            }
030        };
031    }
032
033    /**
034     * Creates a predicate that returns false every time.
035     * @param <T> The type of the predicate.
036     * @return A predicate returning <code>false</code>
037     * @since 10040
038     */
039    public static <T> Predicate<T> alwaysFalse() {
040        return new Predicate<T>() {
041            @Override
042            public boolean evaluate(T object) {
043                return false;
044            }
045        };
046    }
047
048    /**
049     * Returns the negation of {@code predicate}.
050     * @param <T> type of items
051     * @param predicate the predicate to negate
052     * @return the negation of {@code predicate}
053     */
054    public static <T> Predicate<T> not(final Predicate<T> predicate) {
055        return new Predicate<T>() {
056            @Override
057            public boolean evaluate(T obj) {
058                return !predicate.evaluate(obj);
059            }
060        };
061    }
062
063    /**
064     * Returns a {@link Predicate} executing {@link Objects#equals}.
065     * @param <T> type of items
066     * @param ref the reference object
067     * @return a {@link Predicate} executing {@link Objects#equals}
068     */
069    public static <T> Predicate<T> equalTo(final T ref) {
070        return new Predicate<T>() {
071            @Override
072            public boolean evaluate(T obj) {
073                return Objects.equals(obj, ref);
074            }
075        };
076    }
077
078    /**
079     * Creates a new predicate that checks if elements are exactly of that class.
080     * @param <T> The predicate type.
081     * @param clazz The class the elements must have.
082     * @return The new predicate.
083     * @throws IllegalArgumentException if clazz is null
084     */
085    public static <T> Predicate<T> isOfClass(final Class<? extends T> clazz) {
086        CheckParameterUtil.ensureParameterNotNull(clazz, "clazz");
087        return new Predicate<T>() {
088            @Override
089            public boolean evaluate(T obj) {
090                return obj != null && obj.getClass() == clazz;
091            }
092        };
093    }
094
095    /**
096     * Creates a new predicate that checks if the object is of a given class.
097     * @param <T> The predicate type.
098     * @param clazz The class objects need to be of.
099     * @return The new predicate.
100     * @throws IllegalArgumentException if clazz is null
101     * @since 10286
102     */
103    public static <T> Predicate<T> isInstanceOf(final Class<? extends T> clazz) {
104        CheckParameterUtil.ensureParameterNotNull(clazz, "clazz");
105        return new Predicate<T>() {
106            @Override
107            public boolean evaluate(T o) {
108                return clazz.isInstance(o);
109            }
110        };
111    }
112
113    /**
114     * Returns a {@link Predicate} executing {@link Pattern#matcher(CharSequence)} and {@link java.util.regex.Matcher#matches}.
115     * @param pattern the pattern
116     * @return a {@link Predicate} executing {@link Pattern#matcher(CharSequence)} and {@link java.util.regex.Matcher#matches}
117     */
118    public static Predicate<String> stringMatchesPattern(final Pattern pattern) {
119        return new Predicate<String>() {
120            @Override
121            public boolean evaluate(String string) {
122                return pattern.matcher(string).matches();
123            }
124        };
125    }
126
127    /**
128     * Returns a {@link Predicate} executing {@link Pattern#matcher(CharSequence)} and {@link java.util.regex.Matcher#find}.
129     * @param pattern the pattern
130     * @return a {@link Predicate} executing {@link Pattern#matcher(CharSequence)} and {@link java.util.regex.Matcher#find}
131     */
132    public static Predicate<String> stringContainsPattern(final Pattern pattern) {
133        return new Predicate<String>() {
134            @Override
135            public boolean evaluate(String string) {
136                return pattern.matcher(string).find();
137            }
138        };
139    }
140
141    /**
142     * Returns a {@link Predicate} executing {@link String#contains(CharSequence)}.
143     * @param pattern the pattern
144     * @return a {@link Predicate} executing {@link String#contains(CharSequence)}
145     */
146    public static Predicate<String> stringContains(final String pattern) {
147        return new Predicate<String>() {
148            @Override
149            public boolean evaluate(String string) {
150                return string.contains(pattern);
151            }
152        };
153    }
154
155    /**
156     * Returns a {@link Predicate} executing {@link OsmPrimitive#hasTag(String, String...)}.
157     * @param key the key forming the tag
158     * @param values one or many values forming the tag
159     * @return a {@link Predicate} executing {@link OsmPrimitive#hasTag(String, String...)}
160     */
161    public static Predicate<OsmPrimitive> hasTag(final String key, final String... values) {
162        return new Predicate<OsmPrimitive>() {
163            @Override
164            public boolean evaluate(OsmPrimitive p) {
165                return p.hasTag(key, values);
166            }
167        };
168    }
169
170    /**
171     * Returns a {@link Predicate} executing {@link OsmPrimitive#hasKey(String)}.
172     * @param key the key
173     * @return a {@link Predicate} executing {@link OsmPrimitive#hasKey(String)}
174     */
175    public static Predicate<OsmPrimitive> hasKey(final String key) {
176        return new Predicate<OsmPrimitive>() {
177            @Override
178            public boolean evaluate(OsmPrimitive p) {
179                return p.hasKey(key);
180            }
181        };
182    }
183
184    /**
185     * Returns a {@link Predicate} executing {@link Collection#contains(Object)}.
186     * @param <T> type of items
187     * @param target collection
188     * @return a {@link Predicate} executing {@link Collection#contains(Object)}
189     */
190    public static <T> Predicate<T> inCollection(final Collection<? extends T> target) {
191        return new Predicate<T>() {
192            @Override
193            public boolean evaluate(T object) {
194                return target.contains(object);
195            }
196        };
197    }
198
199    /**
200     * Returns a {@link Predicate} testing whether objects are {@code null}.
201     * @param <T> type of items
202     * @return a {@link Predicate} testing whether objects are {@code null}
203     */
204    public static <T> Predicate<T> isNull() {
205        return new Predicate<T>() {
206            @Override
207            public boolean evaluate(T object) {
208                return object == null;
209            }
210        };
211    }
212
213}