package pl.net.bluesoft.util.lang.cquery; import pl.net.bluesoft.util.lang.Lang; import pl.net.bluesoft.util.lang.cquery.func.P; import java.lang.reflect.Method; import java.util.Collection; import java.util.regex.Pattern; import static pl.net.bluesoft.util.lang.cquery.CQuery.from; /** * User: POlszewski * Date: 2011-10-20 * Time: 09:23:04 */ public final class Predicates { public static abstract class ComposedPredicate<T> implements P<T> { public abstract boolean invoke(T t); public ComposedPredicate<T> and(final P<? super T> pred) { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { return ComposedPredicate.this.invoke(t) && pred.invoke(t); } }; } public ComposedPredicate<T> or(final P<? super T> pred) { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { return ComposedPredicate.this.invoke(t) || pred.invoke(t); } }; } public ComposedPredicate<T> not() { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { return !ComposedPredicate.this.invoke(t); } }; } } private static abstract class ComposedPropertyPredicate<T> extends ComposedPredicate<T> { private final String property; private Method getAccessor; public ComposedPropertyPredicate(String property) { this.property = property; } public Object getValue(T t) { if (getAccessor == null) { getAccessor = extractAccessor(t, property); } try { return getAccessor.invoke(t); } catch (Exception e) { throw new RuntimeException(e); } } private static Method extractAccessor(Object x, String property) { String Property = Character.toUpperCase(property.charAt(0)) + property.substring(1); try { return x.getClass().getMethod("get" + Property); } catch (Exception e) { try { return x.getClass().getMethod("is" + Property); } catch (Exception e1) { throw new RuntimeException(e); } } } } public static <T> ComposedPredicate<T> not(final P<T> pred) { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { return !pred.invoke(t); } }; } // property comparisons public static <T, V> ComposedPredicate<T> eq(String property, final V value) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return Lang.equals(getValue(t), value); } }; } public static <T, V> ComposedPredicate<T> ne(String property, final V value) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return !Lang.equals(getValue(t), value); } }; } public static <T, C> ComposedPredicate<T> lt(final String property, final Comparable<C> value) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return ((Comparable)getValue(t)).compareTo(value) < 0; } }; } public static <T, C> ComposedPredicate<T> le(final String property, final Comparable<C> value) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return ((Comparable)getValue(t)).compareTo(value) <= 0; } }; } public static <T, C> ComposedPredicate<T> gt(final String property, final Comparable<C> value) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return ((Comparable)getValue(t)).compareTo(value) > 0; } }; } public static <T, C> ComposedPredicate<T> ge(final String property, final Comparable<C> value) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return ((Comparable)getValue(t)).compareTo(value) >= 0; } }; } public static <T, C> ComposedPredicate<T> between(final String property, final Comparable<C> fromValue, final Comparable<C> toValue) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { Comparable value = (Comparable)getValue(t); return value != null && value.compareTo(fromValue) >= 0 && value.compareTo(toValue) <= 0; } }; } // property others public static <T> ComposedPredicate<T> isNull(String property) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return getValue(t) == null; } }; } public static <T> ComposedPredicate<T> isNotNull(String property) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return getValue(t) != null; } }; } public static <T> ComposedPredicate<T> isTrue(final String property) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return Boolean.TRUE.equals(getValue(t)); } }; } public static <T> ComposedPredicate<T> isFalse(final String property) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return Boolean.FALSE.equals(getValue(t)); } }; } public static <T> ComposedPredicate<T> in(String property, final Collection<T> collection) { return new ComposedPropertyPredicate<T>(property) { @Override public boolean invoke(T t) { return collection.contains(t); } }; } public static <T> ComposedPredicate<T> in(String property, final T... array) { return new ComposedPropertyPredicate<T>(property) { Collection collection = from(array); @Override public boolean invoke(T t) { return collection.contains(t); } }; } public static <T> ComposedPredicate<T> matches(final String property, final String regex) { return new ComposedPropertyPredicate<T>(property) { private final Pattern pattern = Pattern.compile(regex); @Override public boolean invoke(T t) { String s = (String)getValue(t); return s != null && pattern.matcher(s).matches(); } }; } // value comparisons public static <T> P<T> eq(final T value) { return new P<T>() { @Override public boolean invoke(T t) { return Lang.equals(t, value); } }; } public static <T, V> P<T> ne(final T value) { return new P<T>() { @Override public boolean invoke(T t) { return !Lang.equals(t, value); } }; } public static <T extends Comparable<T>> ComposedPredicate<T> lt(final T value) { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { return t.compareTo(value) < 0; } }; } public static <T extends Comparable<T>> ComposedPredicate<T> le(final T value) { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { return t.compareTo(value) <= 0; } }; } public static <T extends Comparable<T>> ComposedPredicate<T> gt(final T value) { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { return t.compareTo(value) > 0; } }; } public static <T extends Comparable<T>> ComposedPredicate<T> ge(final T value) { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { return t.compareTo(value) >= 0; } }; } public static <T extends Comparable<T>> ComposedPredicate<T> between(final T fromValue, final T toValue) { return new ComposedPredicate<T>() { @Override public boolean invoke(T t) { Comparable value = (Comparable)t; return value != null && value.compareTo(fromValue) >= 0 && value.compareTo(toValue) <= 0; } }; } // others public static P<Object> isNull() { return new P<Object>() { @Override public boolean invoke(Object t) { return t == null; } }; } public static P<Object> isNotNull() { return new P<Object>() { @Override public boolean invoke(Object t) { return t != null; } }; } public static P<Boolean> isTrue() { return new P<Boolean>() { @Override public boolean invoke(Boolean t) { return Boolean.TRUE.equals(t); } }; } public static P<Boolean> isFalse() { return new P<Boolean>() { @Override public boolean invoke(Boolean t) { return Boolean.FALSE.equals(t); } }; } public static <T> P<T> in(final Collection<T> collection) { return new P<T>() { @Override public boolean invoke(T t) { return collection.contains(t); } }; } public static <T> P<T> in(final T... array) { return new P<T>() { Collection collection = from(array); @Override public boolean invoke(T t) { return collection.contains(t); } }; } public static P<String> matches(final String regex) { return new P<String>() { @Override public boolean invoke(String t) { return t != null && t.matches(regex); } }; } }