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     */
017    package org.apache.commons.functor.core.comparator;
018    
019    import java.io.Serializable;
020    import org.apache.commons.functor.UnaryPredicate;
021    
022    /**
023     * A {@link UnaryPredicate} that tests whether a {@link Comparable} object is
024     * within a range. The range is defined in the constructor.
025     *
026     * @since 1.0
027     * @version $Revision: 1171154 $ $Date: 2011-09-15 17:58:38 +0200 (Thu, 15 Sep 2011) $
028     * @author  Jason Horman (jason@jhorman.org)
029     */
030    
031    public 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            if (min == null || max == null) {
064                throw new IllegalArgumentException("min and max must not be null");
065            }
066            if (min.compareTo(max) > 0) {
067                throw new IllegalArgumentException("min must be <= max");
068            }
069            this.min = min;
070            this.max = max;
071        }
072    
073        /***************************************************
074         *  Instance methods
075         ***************************************************/
076    
077        /**
078         * {@inheritDoc}
079         * Test if the passed in object is within the specified range.
080         */
081        public final boolean test(A o) {
082            return o.compareTo(min) >= 0 && o.compareTo(max) <= 0;
083        }
084    
085        /**
086         * {@inheritDoc}
087         */
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        public int hashCode() {
103            return BASE_HASH_CODE * min.hashCode() + max.hashCode() + NAME_HASH_CODE;
104        }
105    
106        /**
107         * {@inheritDoc}
108         */
109        public String toString() {
110            return "IsWithinRange(" + min + ", " + max + ")";
111        }
112    
113        /**
114         * Obtain an IsWithinRange instance.
115         * @param <A>
116         * @param min A
117         * @param max A
118         * @return IsWithinRange<A>
119         */
120        public static <A extends Comparable<A>> IsWithinRange<A> instance(A min, A max) {
121            return new IsWithinRange<A>(min, max);
122        }
123    }