001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.functor.core.comparator;
018
019import java.io.Serializable;
020import java.util.Comparator;
021
022import org.apache.commons.functor.BinaryPredicate;
023import org.apache.commons.functor.UnaryPredicate;
024import org.apache.commons.functor.adapter.RightBoundPredicate;
025import org.apache.commons.lang3.Validate;
026
027/**
028 * A {@link BinaryPredicate BinaryPredicate} that {@link #test tests}
029 * <code>true</code> iff the left argument is less than or equal to the
030 * right argument under the specified {@link Comparator}.
031 * When no (or a <code>null</code> <code>Comparator</code> is specified,
032 * a {@link Comparable Comparable} <code>Comparator</code> is used.
033 *
034 * @param <T> the binary predicate input types
035 * @version $Revision: 1365328 $ $Date: 2012-07-24 18:19:23 -0400 (Tue, 24 Jul 2012) $
036 */
037public final class IsLessThanOrEqual<T> implements BinaryPredicate<T, T>, Serializable {
038
039    /**
040     * Basic IsLessThanOrEqual instance.
041     */
042    public static final IsLessThanOrEqual<Comparable<?>> INSTANCE = IsLessThanOrEqual.<Comparable<?>>instance();
043
044    /**
045     * serialVersionUID declaration.
046     */
047    private static final long serialVersionUID = -5791636848361450563L;
048
049    /**
050     * The wrapped comparator.
051     */
052    private final Comparator<? super T> comparator;
053
054    /**
055     * Construct a <code>IsLessThanOrEqual</code> {@link BinaryPredicate predicate}
056     * for {@link Comparable Comparable}s.
057     */
058    @SuppressWarnings("unchecked")
059    public IsLessThanOrEqual() {
060        this((Comparator<? super T>) ComparableComparator.INSTANCE);
061    }
062
063    /**
064     * Construct a <code>IsLessThanOrEqual</code> {@link BinaryPredicate predicate}
065     * for the given {@link Comparator Comparator}.
066     *
067     * @param comparator the {@link Comparator Comparator}, when <code>null</code>,
068     *        a <code>Comparator</code> for {@link Comparable Comparable}s will
069     *        be used.
070     */
071    public IsLessThanOrEqual(Comparator<? super T> comparator) {
072        this.comparator = Validate.notNull(comparator, "Comparator argument must not be null");
073    }
074
075    /**
076     * {@inheritDoc}
077     * Return <code>true</code> iff the <i>left</i> parameter is
078     * less than or equal to the <i>right</i> parameter under my current
079     * {@link Comparator Comparator}.
080     */
081    public boolean test(T left, T right) {
082        return comparator.compare(left, right) <= 0;
083    }
084
085    /**
086     * {@inheritDoc}
087     */
088    @Override
089    public boolean equals(Object that) {
090        return that == this || (that instanceof IsLessThanOrEqual<?> && equals((IsLessThanOrEqual<?>) that));
091    }
092
093    /**
094     * Learn whether another IsLessThanOrEqual is equal to this.
095     * @param that the IsLessThanOrEqual to test.
096     * @return boolean
097     */
098    public boolean equals(IsLessThanOrEqual<?> that) {
099        if (null != that) {
100            return comparator.equals(that.comparator);
101        }
102        return false;
103    }
104
105    /**
106     * {@inheritDoc}
107     */
108    @Override
109    public int hashCode() {
110        int hash = "IsLessThanOrEqual".hashCode();
111        // by construction, comparator is never null
112        hash ^= comparator.hashCode();
113        return hash;
114    }
115
116    /**
117     * {@inheritDoc}
118     */
119    @Override
120    public String toString() {
121        return "IsLessThanOrEqual<" + comparator + ">";
122    }
123
124    /**
125     * Get a typed IsLessThanOrEqual instance.
126     *
127     * @param <T> the binary predicate input types
128     * @return IsLessThanOrEqual<T>
129     */
130    public static <T extends Comparable<?>> IsLessThanOrEqual<T> instance() {
131        return new IsLessThanOrEqual<T>();
132    }
133
134    /**
135     * Get an IsLessThanOrEqual UnaryPredicate.
136     *
137     * @param <T> the binary predicate input types
138     * @param right the right side object of the comparison.
139     * @return UnaryPredicate
140     */
141    public static <T extends Comparable<?>> UnaryPredicate<T> instance(T right) {
142        return RightBoundPredicate.bind(new IsLessThanOrEqual<T>(), right);
143    }
144
145}