package com.ldbc.driver.runtime;
import com.google.common.collect.ImmutableList;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import static java.lang.String.format;
// TODO rewrite like sync GCT tracker class, to be more threadsafe
public class ConcurrentErrorReporter
{
public static String stackTraceToString( Throwable e )
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw );
e.printStackTrace( pw );
return sw.toString();
}
public static String whoAmI( Object caller )
{
Thread myThread = Thread.currentThread();
return format( "%s [%s] (Thread: ID=%s, Name=%s, Priority=%s)",
caller.getClass().getSimpleName(),
Thread.currentThread().getStackTrace()[3].getLineNumber(),
myThread.getId(),
myThread.getName(),
myThread.getPriority() );
}
public static String formatErrors( List<ErrorReport> errors )
{
StringBuilder sb = new StringBuilder();
sb.append( "\n- Start Error Log -" );
// Do this to avoid ConcurrentModificationException in case error is reported while iterating through errors
Iterator<ErrorReport> errorsIterator = ImmutableList.copyOf( errors ).iterator();
while ( errorsIterator.hasNext() )
{
ErrorReport error = errorsIterator.next();
sb.append( "\n\tSOURCE:\t" ).append( error.source() );
sb.append( "\n\tERROR:\t" ).append( error.error() );
}
sb.append( "\n- End Error Log -\n" );
return sb.toString();
}
private final List<ErrorReport> errorMessages = new ArrayList<>();
synchronized public void reportError( Object caller, String errMsg )
{
syncGetErrorMessages().add( new ErrorReport( whoAmI( caller ), errMsg ) );
}
public boolean errorEncountered()
{
return !syncGetErrorMessages().isEmpty();
}
public List<ErrorReport> errorMessages()
{
return syncGetErrorMessages();
}
@Override
public String toString()
{
if ( syncGetErrorMessages().isEmpty() )
{
return "No Reported Errors";
}
else
{
return formatErrors( syncGetErrorMessages() );
}
}
private synchronized List<ErrorReport> syncGetErrorMessages()
{
return errorMessages;
}
public static class ErrorReport
{
private final String source;
private final String error;
public ErrorReport( String source, String error )
{
this.source = source;
this.error = error;
}
public String source()
{
return source;
}
public String error()
{
return error;
}
}
}