package org.gridkit.jvmtool.event;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.Callable;
public abstract class ChainedEventReader<T extends Event> implements EventReader<T> {
public static <T extends Event> EventReader<T> chain(final EventReader<T>... readers) {
return new ChainedEventReader<T>() {
int next;
@Override
protected EventReader<T> produceNext() {
return next < readers.length ? readers[next++] : null;
}
};
}
public static <T extends Event> EventReader<T> chain(final EventReader<T> reader, final Callable<T> producer) {
return new ChainedEventReader<T>() {
boolean first;
boolean done;
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected EventReader<T> produceNext() {
if (!first) {
first = true;
return reader;
}
if (done) {
return null;
}
else {
done = true;
try {
return (EventReader<T>) producer.call();
} catch (Exception e) {
return new SingleEventReader(new SimpleErrorEvent(e));
}
}
}
};
}
private boolean init;
private EventReader<T> current;
public ChainedEventReader() {
}
@Override
public <M extends Event> EventReader<M> morph(EventMorpher<T, M> morpher) {
return MorphingEventReader.morph(this, morpher);
}
@Override
public Iterator<T> iterator() {
return this;
}
@Override
public boolean hasNext() {
if (!init) {
init = true;
current = produceNext();
}
if (current == null) {
return false;
}
while(true) {
if (current.hasNext()) {
return true;
}
else {
current.dispose();
current = produceNext();
if (current == null) {
return false;
}
}
}
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return current.next();
}
@Override
public T peekNext() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return current.peekNext();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
// @Override
// @SuppressWarnings({ "unchecked", "rawtypes" })
// public <X extends Event> EventReader<X> filterByClass(Class<X> typeFilter) {
// this.typeFilter = (Class)typeFilter;
// if (current != null) {
// current = (EventReader)current.filterByClass(typeFilter);
// }
// return (EventReader)this;
// }
//
@Override
public void dispose() {
if (current != null) {
current.dispose();
}
}
protected abstract EventReader<T> produceNext();
}