org.gridkit.jvmtool.event.ShieldedEventReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sjk-stacktrace Show documentation
Show all versions of sjk-stacktrace Show documentation
Thread dumps: capture and encoding
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 ([email protected])
*/
public class ShieldedEventReader implements EventReader {
private static final ErrorHandler THROW_HANDLER = new ErrorHandler() {
@Override
public boolean onException(Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException)e;
}
else {
throw new RuntimeException(e);
}
}
};
private static final ErrorHandler SILENT_ERROR_HANDLER = new ErrorHandler() {
@Override
public boolean onException(Exception e) {
return true; // suppress
}
};
public static EventReader shield(EventReader super T> reader, Class event, boolean suppressErrors) {
return new ShieldedEventReader(reader, event, suppressErrors ? SILENT_ERROR_HANDLER : THROW_HANDLER);
}
private final EventReader extends Event> nested;
private final Class classFilter;
private final ErrorHandler errorHandler;
private T nextEvent;
public ShieldedEventReader(EventReader extends Event> nested, Class classFilter) {
this(nested, classFilter, THROW_HANDLER);
}
public ShieldedEventReader(EventReader extends Event> nested, Class classFilter, ErrorHandler errorHandler) {
this.nested = nested;
this.classFilter = classFilter;
this.errorHandler = errorHandler;
}
@Override
public EventReader morph(EventMorpher morpher) {
return MorphingEventReader.morph(this, morpher);
}
@Override
public Iterator iterator() {
return this;
}
private void seekNext() {
try {
while(nested.hasNext()) {
Event e = nested.next();
if (e instanceof ErrorEvent) {
// forward to error handler
if (errorHandler.onException(((ErrorEvent) e).exception())) {
// suppress
continue;
}
}
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();
}
}