package org.vertexium.util;
import java.util.Iterator;
public abstract class SelectManyIterable<TSource, TDest> implements Iterable<TDest> {
private final Iterable<? extends TSource> source;
public SelectManyIterable(Iterable<? extends TSource> source) {
this.source = source;
}
@Override
public Iterator<TDest> iterator() {
final Iterator<? extends TSource> it = source.iterator();
return new Iterator<TDest>() {
private TDest next;
private TDest current;
public Iterator<? extends TDest> innerIterator = null;
@Override
public boolean hasNext() {
loadNext();
return next != null;
}
@Override
public TDest next() {
loadNext();
this.current = this.next;
this.next = null;
return this.current;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private void loadNext() {
if (this.next != null) {
return;
}
while (true) {
if (innerIterator != null) {
if (innerIterator.hasNext()) {
TDest dest = innerIterator.next();
if (isIncluded(dest)) {
this.next = dest;
return;
}
} else {
innerIterator = null;
}
} else {
if (it.hasNext()) {
TSource nextSource = it.next();
innerIterator = getIterable(nextSource).iterator();
} else {
return;
}
}
}
}
};
}
protected boolean isIncluded(TDest dest) {
return true;
}
protected abstract Iterable<? extends TDest> getIterable(TSource source);
protected Iterable<? extends TSource> getSource() {
return source;
}
}