blob: e04bd669e4eefa6948cba5af20baa0530c940a70 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.commons.jexl3.internal;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* A range of integers.
*/
public abstract class IntegerRange implements Collection<Integer> {
/** The lower boundary. */
protected final int min;
/** The upper boundary. */
protected final int max;
/**
* Creates a range, ascending or descending depending on boundaries order.
* @param from the lower inclusive boundary
* @param to the higher inclusive boundary
* @return a range
*/
public static IntegerRange create(final int from, final int to) {
if (from <= to) {
return new IntegerRange.Ascending(from, to);
} else {
return new IntegerRange.Descending(to, from);
}
}
/**
* Creates a new range.
* @param from the lower inclusive boundary
* @param to the higher inclusive boundary
*/
public IntegerRange(final int from, final int to) {
min = from;
max = to;
}
/**
* Gets the interval minimum value.
* @return the low boundary
*/
public int getMin() {
return min;
}
/**
* Gets the interval maximum value.
* @return the high boundary
*/
public int getMax() {
return max;
}
@Override
public int hashCode() {
int hash = getClass().hashCode();
//CSOFF: MagicNumber
hash = 13 * hash + this.min;
hash = 13 * hash + this.max;
//CSON: MagicNumber
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final IntegerRange other = (IntegerRange) obj;
if (this.min != other.min) {
return false;
}
if (this.max != other.max) {
return false;
}
return true;
}
@Override
public abstract Iterator<Integer> iterator();
@Override
public int size() {
return max - min + 1;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean contains(final Object o) {
if (o instanceof Number) {
final long v = ((Number) o).intValue();
return min <= v && v <= max;
} else {
return false;
}
}
@Override
public Object[] toArray() {
final int size = size();
final Object[] array = new Object[size];
for(int a = 0; a < size; ++a) {
array[a] = min + a;
}
return array;
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(final T[] array) {
final Class<?> ct = array.getClass().getComponentType();
final int length = size();
T[] copy = array;
if (ct.isAssignableFrom(Integer.class)) {
if (array.length < length) {
copy = (T[]) Array.newInstance(ct, length);
}
for (int a = 0; a < length; ++a) {
Array.set(copy, a, min + a);
}
if (length < copy.length) {
copy[length] = null;
}
return copy;
}
throw new UnsupportedOperationException();
}
@Override
public boolean containsAll(final Collection<?> c) {
for(final Object cc : c) {
if (!contains(cc)) {
return false;
}
}
return true;
}
@Override
public boolean add(final Integer e) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(final Object o) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(final Collection<? extends Integer> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
/**
* Ascending integer range.
*/
public static class Ascending extends IntegerRange {
/**
* Constructor.
* @param from lower boundary
* @param to upper boundary
*/
protected Ascending(final int from, final int to) {
super(from, to);
}
@Override
public Iterator<Integer> iterator() {
return new AscIntegerIterator(min, max);
}
}
/**
* Descending integer range.
*/
public static class Descending extends IntegerRange {
/**
* Constructor.
* @param from upper boundary
* @param to lower boundary
*/
protected Descending(final int from, final int to) {
super(from, to);
}
@Override
public Iterator<Integer> iterator() {
return new DescIntegerIterator(min, max);
}
}
}
/**
* An ascending iterator on an integer range.
*/
class AscIntegerIterator implements Iterator<Integer> {
/** The lower boundary. */
private final int min;
/** The upper boundary. */
private final int max;
/** The current value. */
private int cursor;
/**
* Creates a iterator on the range.
* @param l low boundary
* @param h high boundary
*/
public AscIntegerIterator(final int l, final int h) {
min = l;
max = h;
cursor = min;
}
@Override
public boolean hasNext() {
return cursor <= max;
}
@Override
public Integer next() {
if (cursor <= max) {
return cursor++;
}
throw new NoSuchElementException();
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not supported.");
}
}
/**
* A descending iterator on an integer range.
*/
class DescIntegerIterator implements Iterator<Integer> {
/** The lower boundary. */
private final int min;
/** The upper boundary. */
private final int max;
/** The current value. */
private int cursor;
/**
* Creates a iterator on the range.
* @param l low boundary
* @param h high boundary
*/
public DescIntegerIterator(final int l, final int h) {
min = l;
max = h;
cursor = max;
}
@Override
public boolean hasNext() {
return cursor >= min;
}
@Override
public Integer next() {
if (cursor >= min) {
return cursor--;
}
throw new NoSuchElementException();
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not supported.");
}
}