package pl.net.bluesoft.util.lang.cquery;
import pl.net.bluesoft.util.lang.cquery.func.P;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* User: POlszewski
* Date: 2011-07-29
*/
/**
* Collection wrapper that mimics .NET LINQ functionality
*/
public final class CQuery {
public static <T> CQueryCollection<T> from(final Set<T> collection) {
return collection == null ? CQuery.<T>empty() : new CollectionWrapper<T>(collection) {
@Override
public CQueryCollection<T> distinct() {
return this;
}
};
}
public static <T> CQueryCollection<T> from(final Collection<T> collection) {
return collection == null ? CQuery.<T>empty() : new CollectionWrapper<T>(collection);
}
public static <T> CQueryCollection<T> from(final Iterable<T> iterable) {
return iterable == null ? CQuery.<T>empty() : new CQueryCollection<T>() {
@Override
public Iterator<T> iterator() {
return iterable.iterator();
}
};
}
public static <T> CQueryCollection<T> from(final T...array) {
return array == null ? CQuery.<T>empty() : new ArrayWrapper<T>(array);
}
public static CQueryCollection<Boolean> from(final boolean...array) {
return array == null ? CQuery.<Boolean>empty() : new BooleanArrayWrapper(array);
}
public static CQueryCollection<Integer> from(final int...array) {
return array == null ? CQuery.<Integer>empty() : new IntArrayWrapper(array);
}
public static <T> CQueryCollection<T> repeat(final T value, final int n) {
return new RepeatWrapper<T>(n, value);
}
public static CQueryCollection<Integer> range(final int start, final int end) {
return range(start, end, 1);
}
public static CQueryCollection<Integer> range(final int start, final int end, final int step) {
return new RangeWrapper(start, end, step);
}
@SuppressWarnings("rawtypes")
private static CQueryCollection empty = new CQueryCollection() {
Iterator iterator = new ReadOnlyIterator() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Object next() {
throw new IllegalStateException();
}
};
@Override
public Iterator iterator() {
return iterator;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public boolean any() {
return false;
}
@Override
public int count() {
return 0;
}
@Override
public int count(P pred) {
return 0;
}
@Override
public int size() {
return 0;
}
};
@SuppressWarnings("unchecked")
public static <T> CQueryCollection<T> empty(Class<T> clazz) {
return empty;
}
@SuppressWarnings("unchecked")
public static <T> CQueryCollection<T> empty() {
return empty;
}
private static class CollectionWrapper<T> extends CQueryCollection<T> {
private final Collection<T> collection;
public CollectionWrapper(Collection<T> collection) {
this.collection = collection;
}
@Override
public Iterator<T> iterator() {
return collection.iterator();
}
@Override
public boolean any() {
return collection.isEmpty();
}
@Override
public boolean isEmpty() {
return collection.isEmpty();
}
@Override
public int count() {
return collection.size();
}
@Override
public int size() {
return collection.size();
}
@Override
public boolean add(T t) {
return collection.add(t);
}
@Override
public boolean remove(Object o) {
return collection.remove(o);
}
@Override
public boolean addAll(Collection<? extends T> c) {
return collection.addAll(c);
}
@Override
public boolean removeAll(Collection<?> c) {
return collection.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return collection.retainAll(c);
}
@Override
public void clear() {
collection.clear();
}
}
private static class ArrayWrapper<T> extends CQueryCollection<T> {
private final T[] array;
public ArrayWrapper(T... array) {
this.array = array;
}
@Override
public Iterator<T> iterator() {
return new ReadOnlyIterator<T>() {
private int pos = 0;
@Override
public boolean hasNext() {
return pos < array.length;
}
@Override
public T next() {
return array[pos++];
}
};
}
@Override
public boolean isEmpty() {
return array.length == 0;
}
@Override
public boolean any() {
return array.length > 0;
}
@Override
public int count() {
return array.length;
}
@Override
public int size() {
return array.length;
}
@Override
public T elementAt(int index) {
return array[index];
}
@Override
public T elementAtOrDefault(int index, T default_) {
return index < array.length ? array[index] : default_;
}
}
private static class BooleanArrayWrapper extends CQueryCollection<Boolean> {
private final boolean[] array;
public BooleanArrayWrapper(boolean... array) {
this.array = array;
}
@Override
public Iterator<Boolean> iterator() {
return new ReadOnlyIterator<Boolean>() {
private int pos = 0;
@Override
public boolean hasNext() {
return pos < array.length;
}
@Override
public Boolean next() {
return array[pos++];
}
};
}
@Override
public boolean isEmpty() {
return array.length == 0;
}
@Override
public boolean any() {
return array.length > 0;
}
@Override
public int count() {
return array.length;
}
@Override
public int size() {
return array.length;
}
@Override
public Boolean elementAt(int index) {
return array[index];
}
@Override
public Boolean elementAtOrDefault(int index, Boolean default_) {
return index < array.length ? array[index] : default_;
}
}
private static class IntArrayWrapper extends CQueryCollection<Integer> {
private final int[] array;
public IntArrayWrapper(int... array) {
this.array = array;
}
@Override
public Iterator<Integer> iterator() {
return new ReadOnlyIterator<Integer>() {
private int pos = 0;
@Override
public boolean hasNext() {
return pos < array.length;
}
@Override
public Integer next() {
return array[pos++];
}
};
}
@Override
public boolean isEmpty() {
return array.length == 0;
}
@Override
public boolean any() {
return array.length > 0;
}
@Override
public int count() {
return array.length;
}
@Override
public int size() {
return array.length;
}
@Override
public Integer elementAt(int index) {
return array[index];
}
@Override
public Integer elementAtOrDefault(int index, Integer default_) {
return index < array.length ? array[index] : default_;
}
}
private static class RepeatWrapper<T> extends CQueryCollection<T> {
private final int n;
private final T value;
public RepeatWrapper(int n, T value) {
this.n = n;
this.value = value;
}
@Override
public Iterator<T> iterator() {
return new ReadOnlyIterator<T>() {
int pos = 0;
@Override
public boolean hasNext() {
return pos < n;
}
@Override
public T next() {
if (pos < n) {
++pos;
return value;
}
throw new IllegalStateException();
}
};
}
}
private static class RangeWrapper extends CQueryCollection<Integer> {
private final int start;
private final int end;
private final int step;
public RangeWrapper(int start, int end, int step) {
this.start = start;
this.end = end;
this.step = step;
}
@Override
public Iterator<Integer> iterator() {
return new ReadOnlyIterator<Integer>() {
int pos = start;
@Override
public boolean hasNext() {
return pos <= end;
}
@Override
public Integer next() {
if (pos <= end) {
int result = pos;
pos += step;
return result;
}
throw new IllegalStateException();
}
};
}
}
}