/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package openbook.domain; /** * A simple numeric range. * Minimum value is included, maximum value is excluded. * * @author Pinaki Poddar * */ public class Range<N extends Number> { private N min; private N max; private final Class<N> type; @SuppressWarnings("unchecked") public Range(Object min, Object max) { this((N)min, (N)max); } /** * Creates a range. Empty range i.e. where minimum equals maximum is allowed. * * @param min non-null minimum value. * @param max non-null maximum value. */ @SuppressWarnings("unchecked") public Range(N min, N max) { if (min == null || max == null) throw new IllegalArgumentException("Supplied Min or Max is null"); if (max.doubleValue() < min.doubleValue()) throw new IllegalArgumentException("Invalid range (" + min + "," + max + ")"); this.min = min; this.max = max; type = (Class<N>)min.getClass(); } public Class<N> type() { return type; } /** * Affirms if the given value is within this range. * Minimum is included, maximum is excluded. * * @param x a non-null value * @return true if the given value is greater than or equals to minimum and less than the maximum. */ public boolean contains(Number x) { return x != null && x.doubleValue() >= min.doubleValue() && x.doubleValue() < max.doubleValue(); } /** * Affirms if the given range is within this range. * Minimum is included, maximum is excluded. * * @param x a non-null value * @return true if the given value is greater than or equals to minimum and less than the maximum. */ public <X extends Number> boolean contains(Range<X> r) { return r != null && r.getMinimum().doubleValue() >= min.doubleValue() && r.getMaximum().doubleValue() <= max.doubleValue(); } /** * Gets the minimum value. */ public N getMinimum() { return min; } /** * Gets the maximum value. */ public N getMaximum() { return max; } /** * Adjusts this range by the given number. * * @param x a non-null value. * * @return if this range is adjusted by this value. */ public boolean adjust(N x) { if (x == null) return false; if (x.doubleValue() < min.doubleValue()) { min = x; return true; } if (x.doubleValue() > max.doubleValue()) { max = x; return true; } return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((max == null) ? 0 : max.hashCode()); result = prime * result + ((min == null) ? 0 : min.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Range other = (Range) obj; if (max == null) { if (other.max != null) return false; } else if (!max.equals(other.max)) return false; if (min == null) { if (other.min != null) return false; } else if (!min.equals(other.min)) return false; if (type == null) { if (other.type != null) return false; } else if (!type.equals(other.type)) return false; return true; } }