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 org.apache.commons.functor.UnaryPredicate;
021import org.apache.commons.lang3.Validate;
022
023/**
024 * A {@link UnaryPredicate} that tests whether a {@link Comparable} object is
025 * within a range. The range is defined in the constructor.
026 *
027 * @since 1.0
028 * @param <A> the predicate argument type.
029 * @version $Revision: 1345136 $ $Date: 2012-06-01 08:47:06 -0400 (Fri, 01 Jun 2012) $
030 */
031public class IsWithinRange<A extends Comparable<A>> implements UnaryPredicate<A>, Serializable {
032    /**
033     * serialVersionUID declaration.
034     */
035    private static final long serialVersionUID = -7584005207181667878L;
036
037    /** Hashcode of the name of this Predicate. */
038    private static final int NAME_HASH_CODE = "IsWithinRange".hashCode();
039
040    /** Base Hashcode. */
041    private static final int BASE_HASH_CODE = 29;
042
043    /***************************************************
044     *  Instance variables
045     ***************************************************/
046
047    /** The minimum value of the range. */
048    private final A min;
049    /** The maximum value of the range. */
050    private final A max;
051
052    /***************************************************
053     *  Constructors
054     ***************************************************/
055
056    /**
057     * Create a new IsWithinRange by passing in the range that will
058     * be used in the {@link #test}.
059     * @param min Comparable
060     * @param max Comparable
061     */
062    public IsWithinRange(A min, A max) {
063        Validate.notNull(min, "min must not be null");
064        Validate.notNull(max, "max must not be null");
065        if (min.compareTo(max) > 0) {
066            throw new IllegalArgumentException("min must be <= max");
067        }
068        this.min = min;
069        this.max = max;
070    }
071
072    /***************************************************
073     *  Instance methods
074     ***************************************************/
075
076    /**
077     * {@inheritDoc}
078     * Test if the passed in object is within the specified range.
079     */
080    public final boolean test(A o) {
081        return o.compareTo(min) >= 0 && o.compareTo(max) <= 0;
082    }
083
084    /**
085     * {@inheritDoc}
086     */
087    @Override
088    public final boolean equals(Object o) {
089        if (this == o) {
090            return true;
091        }
092        if (!(o instanceof IsWithinRange<?>)) {
093            return false;
094        }
095        final IsWithinRange<?> isWithinRange = (IsWithinRange<?>) o;
096        return max.equals(isWithinRange.max) && min.equals(isWithinRange.min);
097    }
098
099    /**
100     * {@inheritDoc}
101     */
102    @Override
103    public int hashCode() {
104        return BASE_HASH_CODE * min.hashCode() + max.hashCode() + NAME_HASH_CODE;
105    }
106
107    /**
108     * {@inheritDoc}
109     */
110    @Override
111    public String toString() {
112        return "IsWithinRange(" + min + ", " + max + ")";
113    }
114
115    /**
116     * Obtain an IsWithinRange instance.
117     * @param <A> the argument type.
118     * @param min the min value
119     * @param max the max value
120     * @return IsWithinRange<A>
121     */
122    public static <A extends Comparable<A>> IsWithinRange<A> instance(A min, A max) {
123        return new IsWithinRange<A>(min, max);
124    }
125}