    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.lang;
    018
    019    import org.apache.commons.lang.text.StrBuilder;
    020
    021    /**
    022     * <p>Represents a range of {@link Number} objects.</p>
    023     *
    024     * <p>This class uses <code>double</code> comparisons. This means that it
    025     * is unsuitable for dealing with large <code>Long</code>, <code>BigDecimal</code>
    026     * or <code>BigInteger</code> numbers.</p>
    027     *
    028     * @author Apache Software Foundation
    029     * @author <a href="mailto:chrise@esha.com">Christopher Elkins</a>
    030     * @since 1.0
    031     * @version $Revision: 1057072 $ $Date: 2011-01-10 01:55:57 +0000 (Mon, 10 Jan 2011) $
    032     *
    033     * @deprecated Use one of the Range classes in org.apache.commons.lang.math.
    034     *             Class will be removed in Commons Lang 3.0.
    035     *
    036     */
    037    public final class NumberRange {
    038
    039        /* The minimum number in this range. */
    040        private final Number min;
    041
    042        /* The maximum number in this range. */
    043        private final Number max;
    044
    045
    046        /**
    047         * <p>Constructs a new <code>NumberRange</code> using
    048         * <code>number</code> as both the minimum and maximum in
    049         * this range.</p>
    050         *
    051         * @param num the number to use for this range
    052         * @throws NullPointerException if the number is <code>null</code>
    053         */
    054        public NumberRange(Number num) {
    055            if (num == null) {
    056                throw new NullPointerException("The number must not be null");
    057            }
    058
    059            this.min = num;
    060            this.max = num;
    061        }
    062
    063        /**
    064         * <p>Constructs a new <code>NumberRange</code> with the specified
    065         * minimum and maximum numbers.</p>
    066         *
    067         * <p><em>If the maximum is less than the minimum, the range will be constructed
    068         * from the minimum value to the minimum value, not what you would expect!.</em></p>
    069         *
    070         * @param min the minimum number in this range
    071         * @param max the maximum number in this range
    072         * @throws NullPointerException if either the minimum or maximum number is
    073         *  <code>null</code>
    074         */
    075        public NumberRange(Number min, Number max) {
    076            if (min == null) {
    077                throw new NullPointerException("The minimum value must not be null");
    078            } else if (max == null) {
    079                throw new NullPointerException("The maximum value must not be null");
    080            }
    081
    082            if (max.doubleValue() < min.doubleValue()) {
    083                this.min = this.max = min;
    084            } else {
    085                this.min = min;
    086                this.max = max;
    087            }
    088        }
    089
    090        /**
    091         * <p>Returns the minimum number in this range.</p>
    092         *
    093         * @return the minimum number in this range
    094         */
    095        public Number getMinimum() {
    096            return min;
    097        }
    098
    099        /**
    100         * <p>Returns the maximum number in this range.</p>
    101         *
    102         * @return the maximum number in this range
    103         */
    104        public Number getMaximum() {
    105            return max;
    106        }
    107
    108        /**
    109         * <p>Tests whether the specified <code>number</code> occurs within
    110         * this range using <code>double</code> comparison.</p>
    111         *
    112         * @param number the number to test
    113         * @return <code>true</code> if the specified number occurs within this
    114         *  range; otherwise, <code>false</code>
    115         */
    116        public boolean includesNumber(Number number) {
    117            if (number == null) {
    118                return false;
    119            } else {
    120                return !(min.doubleValue() > number.doubleValue()) &&
    121                    !(max.doubleValue() < number.doubleValue());
    122            }
    123        }
    124
    125        /**
    126         * <p>Tests whether the specified range occurs entirely within this
    127         * range using <code>double</code> comparison.</p>
    128         *
    129         * @param range the range to test
    130         * @return <code>true</code> if the specified range occurs entirely within
    131         *  this range; otherwise, <code>false</code>
    132         */
    133        public boolean includesRange(NumberRange range) {
    134            if (range == null) {
    135                return false;
    136            } else {
    137                return includesNumber(range.min) && includesNumber(range.max);
    138            }
    139        }
    140
    141        /**
    142         * <p>Tests whether the specified range overlaps with this range
    143         * using <code>double</code> comparison.</p>
    144         *
    145         * @param range the range to test
    146         * @return <code>true</code> if the specified range overlaps with this
    147         *  range; otherwise, <code>false</code>
    148         */
    149        public boolean overlaps(NumberRange range) {
    150            if (range == null) {
    151                return false;
    152            } else {
    153                return range.includesNumber(min) || range.includesNumber(max) ||
    154                    includesRange(range);
    155            }
    156        }
    157
    158        /**
    159         * <p>Indicates whether some other <code>Object</code> is
    160         * &quot;equal&quot; to this one.</p>
    161         *
    162         * @param obj the reference object with which to compare
    163         * @return <code>true</code> if this object is the same as the obj
    164         *  argument; <code>false</code> otherwise
    165         */
    166        public boolean equals(Object obj) {
    167            if (obj == this) {
    168                return true;
    169            } else if (!(obj instanceof NumberRange)) {
    170                return false;
    171            } else {
    172                NumberRange range = (NumberRange)obj;
    173                return min.equals(range.min) && max.equals(range.max);
    174            }
    175        }
    176
    177        /**
    178         * <p>Returns a hash code value for this object.</p>
    179         *
    180         * @return a hash code value for this object
    181         */
    182        public int hashCode() {
    183            int result = 17;
    184            result = 37 * result + min.hashCode();
    185            result = 37 * result + max.hashCode();
    186            return result;
    187        }
    188
    189        /**
    190         * <p>Returns the string representation of this range.</p>
    191         *
    192         * <p>This string is the string representation of the minimum and
    193         * maximum numbers in the range, separated by a hyphen. If a number
    194         * is negative, then it is enclosed in parentheses.</p>
    195         *
    196         * @return the string representation of this range
    197         */
    198        public String toString() {
    199            StrBuilder sb = new StrBuilder();
    200
    201            if (min.doubleValue() < 0) {
    202                sb.append('(')
    203                    .append(min)
    204                    .append(')');
    205            } else {
    206                sb.append(min);
    207            }
    208
    209            sb.append('-');
    210
    211            if (max.doubleValue() < 0) {
    212                sb.append('(')
    213                    .append(max)
    214                    .append(')');
    215            } else {
    216                sb.append(max);
    217            }
    218
    219            return sb.toString();
    220        }
    221
    222    }