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