package org.gridkit.jvmtool.event; import java.util.Iterator; import java.util.NoSuchElementException; /** * This reader adds special handling for {@link ErrorEvent} and * enforces class type restriction on stream events. * * @author Alexey Ragozin (alexey.ragozin@gmail.com) */ public class ShieldedEventReader<T extends Event> implements EventReader<T> { private static final ErrorHandler THROW_HANDLER = new ErrorHandler() { @Override public void onException(Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException)e; } else { throw new RuntimeException(e); } } }; private final EventReader<Event> nested; private final Class<T> classFilter; private final ErrorHandler errorHandler; private T nextEvent; public ShieldedEventReader(EventReader<Event> nested, Class<T> classFilter) { this(nested, classFilter, THROW_HANDLER); } public ShieldedEventReader(EventReader<Event> nested, Class<T> classFilter, ErrorHandler errorHandler) { this.nested = nested; this.classFilter = classFilter; this.errorHandler = errorHandler; } @Override public <M extends Event> EventReader<M> morph(EventMorpher<T, M> morpher) { return MorphingEventReader.morph(this, morpher); } @Override public Iterator<T> iterator() { return this; } private void seekNext() { try { while(nested.hasNext()) { Event e = nested.next(); if (e instanceof SimpleErrorEvent) { // forward to error handler errorHandler.onException(((SimpleErrorEvent) e).exception()); } if (classFilter.isInstance(e)) { nextEvent = classFilter.cast(e); break; } } } catch(Exception e) { errorHandler.onException(e); if (classFilter.isAssignableFrom(SimpleErrorEvent.class)) { nextEvent = classFilter.cast(new SimpleErrorEvent(e)); } else { seekNext(); } } } @Override public boolean hasNext() { if (nextEvent == null) { seekNext(); } return nextEvent != null; } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } T event = nextEvent; nextEvent = null; return event; } @Override public T peekNext() { if (!hasNext()) { throw new NoSuchElementException(); } T event = nextEvent; return event; } @Override public void remove() { throw new UnsupportedOperationException(); } @Override public void dispose() { nested.dispose(); } }