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