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.util.Comparator;
020
021import org.apache.commons.functor.BinaryPredicate;
022import org.apache.commons.functor.Predicate;
023import org.apache.commons.functor.adapter.RightBoundPredicate;
024import org.apache.commons.lang3.Validate;
025
026/**
027 * A {@link BinaryPredicate BinaryPredicate} that {@link #test tests}
028 * <code>true</code> iff the left argument is less than or equal to the
029 * right argument under the specified {@link Comparator}.
030 * When no (or a <code>null</code> <code>Comparator</code> is specified,
031 * a {@link Comparable Comparable} <code>Comparator</code> is used.
032 *
033 * @param <T> the binary predicate input types
034 * @version $Revision: 1537901 $ $Date: 2013-11-01 12:30:19 +0100 (Fr, 01 Nov 2013) $
035 */
036public final class IsLessThanOrEqual<T> implements BinaryPredicate<T, T> {
037
038    /**
039     * Basic IsLessThanOrEqual instance.
040     */
041    public static final IsLessThanOrEqual<Comparable<?>> INSTANCE = IsLessThanOrEqual.<Comparable<?>>instance();
042
043    /**
044     * The wrapped comparator.
045     */
046    private final Comparator<? super T> comparator;
047
048    /**
049     * Construct a <code>IsLessThanOrEqual</code> {@link BinaryPredicate predicate}
050     * for {@link Comparable Comparable}s.
051     */
052    @SuppressWarnings("unchecked")
053    public IsLessThanOrEqual() {
054        this((Comparator<? super T>) ComparableComparator.INSTANCE);
055    }
056
057    /**
058     * Construct a <code>IsLessThanOrEqual</code> {@link BinaryPredicate predicate}
059     * for the given {@link Comparator Comparator}.
060     *
061     * @param comparator the {@link Comparator Comparator}, when <code>null</code>,
062     *        a <code>Comparator</code> for {@link Comparable Comparable}s will
063     *        be used.
064     */
065    public IsLessThanOrEqual(Comparator<? super T> comparator) {
066        this.comparator = Validate.notNull(comparator, "Comparator argument must not be null");
067    }
068
069    /**
070     * {@inheritDoc}
071     * Return <code>true</code> iff the <i>left</i> parameter is
072     * less than or equal to the <i>right</i> parameter under my current
073     * {@link Comparator Comparator}.
074     */
075    public boolean test(T left, T right) {
076        return comparator.compare(left, right) <= 0;
077    }
078
079    /**
080     * {@inheritDoc}
081     */
082    @Override
083    public boolean equals(Object obj) {
084        if (obj == this) {
085            return true;
086        }
087        if (!(obj instanceof IsLessThanOrEqual<?>)) {
088            return false;
089        }
090        IsLessThanOrEqual<?> that = (IsLessThanOrEqual<?>) obj;
091        return this.comparator.equals(that.comparator);
092    }
093
094    /**
095     * {@inheritDoc}
096     */
097    @Override
098    public int hashCode() {
099        int hash = "IsLessThanOrEqual".hashCode();
100        // by construction, comparator is never null
101        hash ^= comparator.hashCode();
102        return hash;
103    }
104
105    /**
106     * {@inheritDoc}
107     */
108    @Override
109    public String toString() {
110        return "IsLessThanOrEqual<" + comparator + ">";
111    }
112
113    /**
114     * Get a typed IsLessThanOrEqual instance.
115     *
116     * @param <T> the binary predicate input types
117     * @return IsLessThanOrEqual<T>
118     */
119    public static <T extends Comparable<?>> IsLessThanOrEqual<T> instance() {
120        return new IsLessThanOrEqual<T>();
121    }
122
123    /**
124     * Get an IsLessThanOrEqual Predicate.
125     *
126     * @param <T> the binary predicate input types
127     * @param right the right side object of the comparison.
128     * @return Predicate
129     */
130    public static <T extends Comparable<?>> Predicate<T> instance(T right) {
131        return RightBoundPredicate.bind(new IsLessThanOrEqual<T>(), right);
132    }
133
134}