package edu.umd.cs.findbugs;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Iterator;
import edu.umd.cs.findbugs.charsets.UTF8;
public abstract class TextUIBugReporter extends AbstractBugReporter {
private boolean reportStackTrace;
private boolean useLongBugCodes = false;
private boolean showRank = false;
private boolean reportHistory = false;
private boolean reportUserDesignations = false;
private boolean applySuppressions = false;
static final String OTHER_CATEGORY_ABBREV = "X";
protected PrintWriter outputStream = UTF8.printWriter(System.out, true);
public TextUIBugReporter() {
reportStackTrace = true;
}
public void setOutputStream(PrintStream outputStream) {
this.outputStream = UTF8.printWriter(outputStream, true);
}
public void setWriter(PrintWriter writer) {
this.outputStream = writer;
}
public void setReportStackTrace(boolean reportStackTrace) {
this.reportStackTrace = reportStackTrace;
}
protected void printBug(BugInstance bugInstance) {
if (showRank) {
int rank = BugRanker.findRank(bugInstance);
outputStream.printf("%2d ", rank);
}
switch (bugInstance.getPriority()) {
case Priorities.EXP_PRIORITY:
outputStream.print("E ");
break;
case Priorities.LOW_PRIORITY:
outputStream.print("L ");
break;
case Priorities.NORMAL_PRIORITY:
outputStream.print("M ");
break;
case Priorities.HIGH_PRIORITY:
outputStream.print("H ");
break;
default:
assert false;
}
BugPattern pattern = bugInstance.getBugPattern();
if (pattern != null) {
String categoryAbbrev = null;
BugCategory bcat = DetectorFactoryCollection.instance().getBugCategory(pattern.getCategory());
if (bcat != null) {
categoryAbbrev = bcat.getAbbrev();
}
if (categoryAbbrev == null) {
categoryAbbrev = OTHER_CATEGORY_ABBREV;
}
outputStream.print(categoryAbbrev);
outputStream.print(" ");
}
if (useLongBugCodes) {
outputStream.print(bugInstance.getType());
outputStream.print(" ");
}
if (reportUserDesignations) {
outputStream.print(bugInstance.getUserDesignationKey());
outputStream.print(" ");
}
if (reportHistory) {
long first = bugInstance.getFirstVersion();
long last = bugInstance.getLastVersion();
outputStream.print(first);
outputStream.print(" ");
outputStream.print(last);
outputStream.print(" ");
}
SourceLineAnnotation line = bugInstance.getPrimarySourceLineAnnotation();
outputStream.println(bugInstance.getMessage().replace('\n', ' ') + " " + line.toString());
}
private boolean analysisErrors;
private boolean missingClasses;
@Override
public void reportQueuedErrors() {
boolean errors = analysisErrors || missingClasses || getQueuedErrors().size() > 0;
analysisErrors = missingClasses = false;
super.reportQueuedErrors();
if (errors) {
emitLine("");
}
}
@Override
public void reportAnalysisError(AnalysisError error) {
if (!analysisErrors) {
emitLine("The following errors occurred during analysis:");
analysisErrors = true;
}
emitLine("\t" + error.getMessage());
if (error.getExceptionMessage() != null) {
emitLine("\t\t" + error.getExceptionMessage());
if (reportStackTrace) {
String[] stackTrace = error.getStackTrace();
if (stackTrace != null) {
for (String aStackTrace : stackTrace) {
emitLine("\t\t\tAt " + aStackTrace);
}
}
}
}
}
@Override
public void reportMissingClass(String message) {
if (!missingClasses) {
emitLine("The following classes needed for analysis were missing:");
missingClasses = true;
}
emitLine("\t" + message);
}
protected void emitLine(String line) {
line = line.replaceAll("\t", " ");
System.err.println(line);
}
public boolean getUseLongBugCodes() {
return useLongBugCodes;
}
public void setReportHistory(boolean reportHistory) {
this.reportHistory = reportHistory;
}
public void setUseLongBugCodes(boolean useLongBugCodes) {
this.useLongBugCodes = useLongBugCodes;
}
public void setShowRank(boolean showRank) {
this.showRank = showRank;
}
public void setApplySuppressions(boolean applySuppressions) {
this.applySuppressions = applySuppressions;
}
public void setReportUserDesignations(boolean reportUserDesignations) {
this.reportUserDesignations = reportUserDesignations;
}
public BugReporter getRealBugReporter() {
return this;
}
protected void checkBugInstance(BugInstance bugInstance) {
for (Iterator<BugAnnotation> i = bugInstance.annotationIterator(); i.hasNext();) {
BugAnnotation bugAnnotation = i.next();
if (bugAnnotation instanceof PackageMemberAnnotation) {
PackageMemberAnnotation pkgMember = (PackageMemberAnnotation) bugAnnotation;
if (pkgMember.getSourceLines() == null) {
throw new IllegalStateException("Package member " + pkgMember + " reported without source lines!");
}
}
}
}
public boolean isApplySuppressions() {
return applySuppressions;
}
}