org.deephacks.tools4j.support.test.Criteria.java Source code

Java tutorial

Introduction

Here is the source code for org.deephacks.tools4j.support.test.Criteria.java

Source

/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.deephacks.tools4j.support.test;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Splitter;

/**
 * A criteria is used as a rule that evaluates to true or false on a
 * specific type of value.
 */
@SuppressWarnings("rawtypes")
public class Criteria implements Predicate {

    private final String fieldName;
    private Predicate p;

    private Criteria(String name, Predicate p) {
        this.fieldName = name;
        this.p = p;
    }

    public static Builder field(String name) {
        return new Builder(name);
    }

    @SuppressWarnings("unchecked")
    public Criteria and(Predicate predicate) {
        if (!Criteria.class.isInstance(predicate)) {
            predicate = new PredicateProxy(fieldName, predicate);
        }
        p = Predicates.and(p, predicate);
        return this;
    }

    @SuppressWarnings("unchecked")
    public Criteria or(Predicate predicate) {
        if (!Criteria.class.isInstance(predicate)) {
            predicate = new PredicateProxy(fieldName, predicate);
        }
        p = Predicates.or(p, predicate);
        return this;
    }

    public static class Builder {
        String fieldName;

        private Builder(String name) {
            this.fieldName = name;
        }

        public Criteria is(Predicate p) {
            return new Criteria(fieldName, new PredicateProxy(fieldName, p));
        }

        @SuppressWarnings("unchecked")
        public Criteria not(Predicate p) {
            return new Criteria(fieldName, new PredicateProxy(fieldName, Predicates.not(p)));
        }
    }

    /**
     * If a date is before.
     * 
     * @param value
     * @return A date criteria
     */
    public static Predicate<Date> before(final Date value) {
        return new Predicate<Date>() {

            @Override
            public boolean apply(Date field) {

                return field.before(value);
            }

        };
    }

    /**
     * If a date is before or equals.
     * 
     * @param value
     * @return A date criteria
     */
    public static Predicate<Date> beforeOrEquals(final Date value) {
        return new Predicate<Date>() {

            @Override
            public boolean apply(Date field) {
                return field.before(value) || field.equals(value);
            }

        };
    }

    /**
     * If a date is after.
     * 
     * @param value
     * @return A date criteria
     */
    public static Predicate<Date> after(final Date value) {
        return new Predicate<Date>() {

            @Override
            public boolean apply(Date field) {

                return field.after(value);
            }

        };
    }

    /**
     * If a date is after or equals.
     * 
     * @param value
     * @return A date criteria
     */
    public static Predicate<Date> afterOrEquals(final Date value) {
        return new Predicate<Date>() {

            @Override
            public boolean apply(Date field) {

                return field.after(value) || field.equals(value);
            }

        };
    }

    /**
     * If a a date is between two other dates.
     * 
     * @param start
     * @param end
     * @return A date criteria
     */
    public static Predicate<Date> between(final Date start, final Date end) {
        return new Predicate<Date>() {

            @Override
            public boolean apply(Date field) {
                boolean startMatch = field.after(start) || field.equals(start);
                boolean endMatch = field.before(end) || field.equals(end);
                return startMatch && endMatch;
            }

        };
    }

    /**
     * If a number is larger.
     * 
     * @param value
     * @return A number criteria
     */
    public static Predicate<Number> largerThan(final Number value) {
        return new Predicate<Number>() {

            @Override
            public boolean apply(Number field) {
                return field.doubleValue() > value.doubleValue();
            }

        };
    }

    /**
     * If a number is larger or equals.
     * 
     * @param value
     * @return A number criteria
     */
    public static Predicate<Number> largerOrEquals(final Number value) {
        return new Predicate<Number>() {

            @Override
            public boolean apply(Number field) {
                return field.doubleValue() >= value.doubleValue();
            }

        };
    }

    /**
     * If a number is less than.
     * 
     * @param value
     * @return A number criteria
     */
    public static Predicate<Number> lessThan(final Number value) {
        return new Predicate<Number>() {

            @Override
            public boolean apply(Number field) {
                return field.doubleValue() < value.doubleValue();
            }

        };
    }

    /**
     * If a number is less or equal.
     * 
     * @param value
     * @return A number criteria
     */
    public static Predicate<Number> lessOrEquals(final Number value) {
        return new Predicate<Number>() {

            @Override
            public boolean apply(Number field) {
                return field.doubleValue() < value.doubleValue();
            }

        };
    }

    /**
     * Evaluate if a Serializable if equal another Serializable.
     * 
     * @param value
     * @return A Serializable criteria
     */
    public static Predicate<Serializable> equal(final Object value) {
        return new Predicate<Serializable>() {

            @Override
            public boolean apply(Serializable field) {
                return field.equals(value);
            }

        };
    }

    /**
     * Evaluate if a string contains another string.
     * 
     * @param value
     * @return A string criteria
     */
    public static Predicate<String> contains(final String value) {
        return new Predicate<String>() {

            @Override
            public boolean apply(String field) {
                return field.contains(value);
            }

        };
    }

    /**
     * Evaluate if a string starts with another string.
     * 
     * @param value
     * @return A string criteria
     */
    public static Predicate<String> startsWith(final String value) {
        return new Predicate<String>() {

            @Override
            public boolean apply(String field) {
                return field.startsWith(value);
            }

        };
    }

    /**
     * Evaluate if a string ends with another string.
     * 
     * @param value
     * @return A string criteria
     */
    public static Predicate<String> endsWith(final String value) {
        return new Predicate<String>() {

            @Override
            public boolean apply(String field) {
                return field.endsWith(value);
            }

        };
    }

    /**
     * Evaluate a regular expression.
     * 
     * @param pattern
     * @return A string criteria
     */
    public static Predicate<String> regexp(final String pattern) {
        return new Predicate<String>() {

            @Override
            public boolean apply(String field) {
                return field.matches(pattern);
            }

        };
    }

    @SuppressWarnings("unchecked")
    @Override
    public boolean apply(Object input) {
        return p.apply(input);
    }

    private static class PredicateProxy implements Predicate {
        private final Predicate target;
        private final String fieldName;

        public PredicateProxy(String fieldName, Predicate target) {
            this.target = target;
            this.fieldName = fieldName;
        }

        @SuppressWarnings("unchecked")
        @Override
        public boolean apply(Object object) {
            return target.apply(Criteria.getValue(object, fieldName));
        }

    }

    @SuppressWarnings("cast")
    private static Object getValue(Object target, String fieldName) {
        Iterable<String> fieldNames = Splitter.on('.').split(fieldName);
        // reach into deeper object hierarchies.
        for (String field : fieldNames) {
            try {
                Field foundField = target.getClass().getDeclaredField(field);
                foundField.setAccessible(true);
                target = foundField.get(target);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
        return target;
    }
}