package com.tddinaction.concurrency.waitforthreads;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
public class MergedFailure extends Failure {
public MergedFailure(Description description,
Throwable[] thrownExceptions) {
super(description, merge(thrownExceptions));
}
private static Throwable merge(final Throwable[] exceptions) {
if (exceptions.length == 1) {
return exceptions[0];
}
Throwable merged = new Throwable() {
@Override
public String getMessage() {
StringBuffer s = new StringBuffer();
s.append("MULTIPLE FAILURES:");
for (Throwable t : exceptions) {
s.append("\n");
StringWriter sw = new StringWriter();
printThreadInformation(new PrintWriter(sw), t);
s.append(sw.toString()).append("\n");
s.append(t.getMessage());
}
return s.toString();
}
@Override
public void printStackTrace() {
printStackTrace(System.err);
}
@Override
public void printStackTrace(PrintWriter s) {
s.println("MULTIPLE FAILURES:");
for (Throwable t : exceptions) {
printThreadInformation(s, t);
s.println();
t.printStackTrace(s);
}
}
private void printThreadInformation(PrintWriter s,
Throwable t) {
String type = "Thread";
String name = Thread.currentThread().getName();
if (t instanceof ThrowableFromSpawnedThread) {
ThrowableFromSpawnedThread spawned = (ThrowableFromSpawnedThread) t;
type = "Spawned thread";
name = spawned.getThreadName();
}
s.print("[");
s.print(type);
s.print(" '");
s.print(name);
s.print("']");
}
@Override
public void printStackTrace(PrintStream s) {
printStackTrace(new PrintWriter(
new OutputStreamWriter(s)));
}
};
return merged;
}
}