package org.etk.orm.plugins.common.collection.wrapped;
import java.lang.reflect.Array;
import java.util.AbstractList;
public abstract class WrappedArrayList<E, A> extends AbstractList<E> {
public static <E, A> WrappedArrayList<E, A> create(Class<E> elementType, Class<?> componentType, int size) {
if (elementType == null) {
throw new NullPointerException("No null element type can be provided");
}
if (size < 0) {
throw new IllegalArgumentException("No negative sized array can be created (" + size + ")");
}
return wrap(elementType, Array.newInstance(componentType, size));
}
public static <E, A> WrappedArrayList<E, A> wrap(Class<E> elementType, Object array) {
if (elementType == null) {
throw new NullPointerException("No null element type can be provided");
}
Class<?> arrayClass = array.getClass();
if (!arrayClass.isArray()) {
throw new IllegalArgumentException("Provided array is not an array");
}
Class<?> componentType = arrayClass.getComponentType();
if (componentType.isPrimitive()) {
if (elementType == Integer.class) {
if (!arrayClass.getComponentType().equals(int.class)) {
throw new IllegalArgumentException("Cannot wrap array with component type " + componentType.getName() + " to int");
}
@SuppressWarnings("unchecked") WrappedArrayList<E, A> list = (WrappedArrayList<E, A>)new IntWrappedArrayList((int[])array);
return list;
} else if (elementType == Boolean.class) {
if (!componentType.equals(boolean.class)) {
throw new IllegalArgumentException("Cannot wrap array with component type " + componentType.getName() + " to boolean");
}
@SuppressWarnings("unchecked") WrappedArrayList<E, A> list = (WrappedArrayList<E, A>)new BooleanWrappedArrayList((boolean[])array);
return list;
} else if (elementType == Long.class) {
if (!componentType.equals(long.class)) {
throw new IllegalArgumentException("Cannot wrap array with component type " + componentType.getName() + " to long");
}
@SuppressWarnings("unchecked") WrappedArrayList<E, A> list = (WrappedArrayList<E, A>)new LongWrappedArrayList((long[])array);
return list;
} else if (elementType == Double.class) {
if (!componentType.equals(double.class)) {
throw new IllegalArgumentException("Cannot wrap array with component type " + componentType.getName() + " to double");
}
@SuppressWarnings("unchecked") WrappedArrayList<E, A> list = (WrappedArrayList<E, A>)new DoubleWrappedArrayList((double[])array);
return list;
} else if (elementType == Float.class) {
if (!componentType.equals(float.class)) {
throw new IllegalArgumentException("Cannot wrap array with component type " + componentType.getName() + " to float");
}
@SuppressWarnings("unchecked") WrappedArrayList<E, A> list = (WrappedArrayList<E, A>)new FloatWrappedArrayList((float[])array);
return list;
} else {
throw new UnsupportedOperationException("Cannot create wrapper of class " + elementType);
}
} else {
if (!componentType.equals(elementType)) {
throw new IllegalArgumentException("Cannot wrap array with component type " + componentType.getName() + " to " + elementType.getName());
}
//
@SuppressWarnings("unchecked") WrappedArrayList<E, A> list = (WrappedArrayList<E, A>)new GenericWrappedArrayList<E>((E[])array);
return list;
}
}
/** . */
private final A array;
/** . */
private final int size;
protected WrappedArrayList(A array) throws NullPointerException {
this.array = array;
this.size = size(array);
}
protected abstract E get(A array, int index);
protected abstract void set(A array, int index, E element);
protected abstract int size(A array);
public final A getArray() {
return array;
}
@Override
public final E get(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("No negative index " + index);
}
if (index >= size) {
throw new IndexOutOfBoundsException("No index greater than the list size " + index);
}
//
return get(array, index);
}
@Override
public final E set(int index, E element) {
if (index < 0) {
throw new IndexOutOfBoundsException("No negative index " + index);
}
if (index >= size) {
throw new IndexOutOfBoundsException("No index greater than the list size " + index);
}
//
E previous = get(array, index);
set(array, index, element);
return previous;
}
@Override
public final int size() {
return size;
}
}