/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.predicates; import java.util.Comparator; import java.util.List; /** * This class provides static methods for the straightforward creation of * predicates. * * <p>The implemented <code>predicate</code> methods create predicates that can * be used for the comparision of objects. The desired predicate can be * specified by a binary operator and a comparator. As binary operators the * <code>String</code> objects <code>==</code> (or <code>=</code>), * <code>!=</code>, <code><</code>, <code><=</code>, <code>></code> * and <code>>=</code> can be used. When a comparator is specified, it will * be used for comparing the given objects.</p> * * @see Equal * @see Greater * @see GreaterEqual * @see Less * @see LessEqual * @see NotEqual */ public class Predicates { /** * The default constructor has private access in order to ensure * non-instantiability. */ private Predicates() { // private access in order to ensure non-instantiability } /** * Predicate that always returns true. */ public static Predicate<Object> TRUE = new AbstractPredicate<Object>() { @Override public boolean invoke() { return true; } @Override public boolean invoke(Object o ) { return true; } @Override public boolean invoke(Object o1, Object o2) { return true; } @Override public boolean invoke(List<? extends Object> o) { return true; } }; /** * Predicate that always returns false. */ public static Predicate<Object> FALSE = new AbstractPredicate<Object>() { @Override public boolean invoke() { return false; } @Override public boolean invoke(Object o ) { return false; } @Override public boolean invoke(Object o1, Object o2) { return false; } @Override public boolean invoke(List<? extends Object> o) { return false; } }; /** * Predicate, which decides if an integer is even. */ public static Predicate<Integer> EVEN = new AbstractPredicate<Integer>() { @Override public boolean invoke(Integer i) { return i%2 == 0; } }; /** * Returns a binary predicate that realizes the given binary operator. The * factory method accepts the following binary operators and returns the * following predicates: * * <center> * <table border rules=groups cellpadding=6> * <thead> * <tr> * <th>operator</th> * <th>predicate</th> * </tr> * </thead> * <tbody> * <tr> * <td><code>==</code> or <code>=</code></td> * <td>{@link Equal}</td> * </tr> * <tr> * <td><code>!=</code></td> * <td>{@link NotEqual}</td> * </tr> * <tr> * <td><code><</code></td> * <td>{@link Less}</td> * </tr> * <tr> * <td><code><=</code></td> * <td>{@link LessEqual}</td> * </tr> * <tr> * <td><code>></code></td> * <td>{@link Greater}</td> * </tr> * <tr> * <td><code>>=</code></td> * <td>{@link GreaterEqual}</td> * </tr> * </tbody> * </table> * </center> * * @param op the operator that should be implemented by the predicate * (<code>==</code> or <code>=</code>, <code>!=</code>, * <code><</code>, <code><=</code>, <code>></code>, * <code>>=</code>). * @return a binary predicate that implements the specified operator. * @throws IllegalArgumentException if an invalid operator is specified. */ public static Predicate<Object> predicate(String op) { if (op.equals("==") || op.equals("=")) return Equal.DEFAULT_INSTANCE; if (op.equals("!=")) return NotEqual.DEFAULT_INSTANCE; if (op.equals("<") || op.equals("<=") || op.equals(">") || op.equals(">=")) throw new IllegalArgumentException("cannot create a predicate for operator [" + op + "] without a given comparator"); throw new IllegalArgumentException("invalid operator [" + op + "]"); } /** * Returns a binary predicate that realizes the given binary operator. The * specified comparator is used for object comparision. The factory method * accepts the following binary operators and returns the following * predicates: * * <center> * <table border rules=groups cellpadding=6> * <thead> * <tr> * <th>operator</th> * <th>predicate</th> * </tr> * </thead> * <tbody> * <tr> * <td><code>==</code> or <code>=</code></td> * <td>{@link Equal}</td> * </tr> * <tr> * <td><code>!=</code></td> * <td>{@link NotEqual}</td> * </tr> * <tr> * <td><code><</code></td> * <td>{@link Less}</td> * </tr> * <tr> * <td><code><=</code></td> * <td>{@link LessEqual}</td> * </tr> * <tr> * <td><code>></code></td> * <td>{@link Greater}</td> * </tr> * <tr> * <td><code>>=</code></td> * <td>{@link GreaterEqual}</td> * </tr> * </tbody> * </table> * </center> * * @param <P> the type of the predicate's parameters. * @param op the operator that should be implemented by the predicate * (<code>==</code> or <code>=</code>, <code>!=</code>, * <code><</code>, <code><=</code>, <code>></code>, * <code>>=</code>). * @param comparator the comparator that should be used for object * comparision. * @return a binary predicate that implements the specified operator. * @throws IllegalArgumentException if an invalid operator is specified. */ public static <P> Predicate<P> predicate(String op, Comparator<? super P> comparator) { if (op.equals("==") || op.equals("=")) return new ComparatorBasedEqual<P>(comparator); if (op.equals("!=")) return new Not<P>(new ComparatorBasedEqual<P>(comparator)); if (op.equals("<")) return new Less<P>(comparator); if (op.equals("<=")) return new LessEqual<P>(comparator); if (op.equals(">")) return new Greater<P>(comparator); if (op.equals(">=")) return new GreaterEqual<P>(comparator); throw new IllegalArgumentException("invalid operator [" + op + "]"); } /** * Returns a predicate able to handle null values. The given flag controls * whether two passed null values should be equal or not. Notice the * difference in semantics when evaluating join predicates using the two * different kinds of Equal-predicates returned by this method. * * @param flag controls whether two passed null values should be equal or * not.<br /> * if true - null == null<br /> * if false - null != null * @return the predicate able to handle null values. */ public static Predicate<Object> newNullSensitiveEqual(boolean flag) { return flag ? new AbstractPredicate<Object>() { @Override public boolean invoke(Object o1, Object o2) { return o1 == null ? o2 == null : o1.equals(o2); } } : new AbstractPredicate<Object>() { @Override public boolean invoke(Object o1, Object o2) { return o1 == null ? false : o1.equals(o2); } }; } /** * Makes a given predicate able to handle null values. The defaultValue is * the return value of the predicate if one of the parameters is a null * value. If no null value is handed over the given predicate is called. * * @param <P> the type of the predicate's parameters. * @param predicate the given predicate. * @param defaultValue the default value. * @return the predicate able to handle null values. */ public static <P> Predicate<P> newNullSensitivePredicate(final Predicate<? super P> predicate, final boolean defaultValue) { return new AbstractPredicate<P>() { @Override public boolean invoke(List<? extends P> arguments){ for (P argument : arguments) if (argument == null) return defaultValue; return predicate.invoke(arguments); } }; } /** * Returns a new predicate, which has the same invoke function with the * given predicate, but the order of the arguments is swapped. * * @param <P> the type of the predicate's parameters. * @param predicate the given predicate. * @return the new predicate. */ public static <P> Predicate<P> swapArguments(final Predicate<? super P> predicate) { return new AbstractPredicate<P>() { @Override public boolean invoke(P o1, P o2) { return predicate.invoke(o2, o1); } }; } }