/*
* FindBugs - Find bugs in Java programs
* Copyright (C) 2003,2004 University of Maryland
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.umd.cs.findbugs;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import edu.umd.cs.findbugs.classfile.ClassDescriptor;
import edu.umd.cs.findbugs.config.CommandLine;
import edu.umd.cs.findbugs.util.Bag;
/**
* A simple BugReporter which simply prints the formatted message to the output
* stream.
*/
public class PrintingBugReporter extends TextUIBugReporter {
private final HashSet<BugInstance> seenAlready = new HashSet<BugInstance>();
public void observeClass(ClassDescriptor classDescriptor) {
// Don't need to do anything special, since we won't be
// reporting statistics.
}
@Override
protected void doReportBug(BugInstance bugInstance) {
if (seenAlready.add(bugInstance)) {
printBug(bugInstance);
notifyObservers(bugInstance);
}
}
public void finish() {
outputStream.close();
}
class PrintingCommandLine extends CommandLine {
private String stylesheet = null;
private boolean annotationUploadFormat = false;
private int maxRank = 20;
private int summarizeMaxRank = 20;
private Project project;
public PrintingCommandLine() {
project = new Project();
addSwitch("-longBugCodes", "use long bug codes when generating text");
addSwitch("-rank", "list rank when generating text");
addOption("-maxRank", "max rank", "only list bugs of this rank or less");
addOption("-summarizeMaxRank", "max rank", "summary bugs with of this rank or less");
addSwitch("-designations", "report user designations for each bug");
addSwitch("-history", "report first and last versions for each bug");
addSwitch("-applySuppression", "exclude any bugs that match suppression filters");
addSwitch("-annotationUpload", "generate annotations in upload format");
addSwitchWithOptionalExtraPart("-html", "stylesheet", "Generate HTML output (default stylesheet is default.xsl)");
addOption("-pluginList", "jar1[" + File.pathSeparator + "jar2...]", "specify list of plugin Jar files to load");
}
public @Nonnull
Project getProject() {
return project;
}
@Override
protected void handleOption(String option, String optionExtraPart) throws IOException {
if (option.equals("-longBugCodes"))
setUseLongBugCodes(true);
else if (option.equals("-rank"))
setShowRank(true);
else if (option.equals("-designations"))
setReportUserDesignations(true);
else if (option.equals("-applySuppression"))
setApplySuppressions(true);
else if (option.equals("-history"))
setReportHistory(true);
else if (option.equals("-annotationUpload"))
annotationUploadFormat = true;
else if (option.equals("-html")) {
if (!optionExtraPart.equals("")) {
stylesheet = optionExtraPart;
} else {
stylesheet = "default.xsl";
}
} else
throw new IllegalArgumentException("Unknown option '" + option + "'");
}
@Override
protected void handleOptionWithArgument(String option, String argument) throws IOException {
if (option.equals("-pluginList")) {
String pluginListStr = argument;
Map<String, Boolean> customPlugins = getProject().getConfiguration().getCustomPlugins();
StringTokenizer tok = new StringTokenizer(pluginListStr, File.pathSeparator);
while (tok.hasMoreTokens()) {
customPlugins.put(new File(tok.nextToken()).getAbsolutePath(), Boolean.TRUE);
}
} else if (option.equals("-maxRank")) {
maxRank = Integer.parseInt(argument);
} else if (option.equals("-summarizeMaxRank")) {
summarizeMaxRank = Integer.parseInt(argument);
} else {
throw new IllegalStateException();
}
}
}
public static void main(String[] args) throws Exception {
FindBugs.setNoAnalysis();
PrintingBugReporter reporter = new PrintingBugReporter();
PrintingCommandLine commandLine = reporter.new PrintingCommandLine();
int argCount = commandLine.parse(args, 0, 2, "Usage: " + PrintingCommandLine.class.getName()
+ " [options] [<xml results> [<test results]] ");
if (commandLine.stylesheet != null) {
// actually do xsl via HTMLBugReporter instead of
// PrintingBugReporter
xslt(commandLine.stylesheet, reporter.isApplySuppressions(), args, argCount);
return;
}
SortedBugCollection bugCollection = new SortedBugCollection(commandLine.getProject());
if (argCount < args.length)
bugCollection.readXML(args[argCount++]);
else
bugCollection.readXML(System.in);
if (argCount < args.length)
reporter.setOutputStream(new PrintStream(new FileOutputStream(args[argCount++]), true));
RuntimeException storedException = null;
if (commandLine.annotationUploadFormat) {
bugCollection.computeBugHashes();
for (Iterator<BugInstance> i = bugCollection.iterator(); i.hasNext();) {
BugInstance warning = i.next();
try {
String fHash = "fb-" + warning.getInstanceHash() + "-" + warning.getInstanceOccurrenceNum() + "-"
+ warning.getInstanceOccurrenceMax();
System.out.print("#" + fHash);
String key = warning.getUserDesignationKey();
if (key.equals(BugDesignation.UNCLASSIFIED) || key.equals("NEEDS_FURTHER_STUDY"))
System.out.print("#-1#" + key);
else if (key.equals("MUST_FIX") || key.equals("SHOULD_FIX") || key.equals("I_WILL_FIX"))
System.out.print("#7#" + key);
else
System.out.print("#0#" + key);
SourceLineAnnotation sourceLine = warning.getPrimarySourceLineAnnotation();
if (sourceLine != null)
System.out.println("#" + sourceLine.getSourceFile() + "#" + sourceLine.getStartLine());
else
System.out.println("##");
System.out.println(warning.getAnnotationText());
} catch (RuntimeException e) {
if (storedException == null)
storedException = e;
}
}
} else {
Bag<String> lowRank = new Bag<String>(new TreeMap<String, Integer>());
for (BugInstance warning : bugCollection.getCollection())
if (!reporter.isApplySuppressions() || !bugCollection.getProject().getSuppressionFilter().match(warning)) {
int rank = warning.getBugRank();
BugPattern pattern = warning.getBugPattern();
if (rank <= commandLine.maxRank) {
try {
reporter.printBug(warning);
} catch (RuntimeException e) {
if (storedException == null)
storedException = e;
}
} else if (rank <= commandLine.summarizeMaxRank) {
lowRank.add(pattern.getCategory());
}
}
reporter.finish();
for (Map.Entry<String, Integer> e : lowRank.entrySet()) {
System.out.printf("%4d low ranked %s issues%n", e.getValue(),
I18N.instance().getBugCategoryDescription(e.getKey()));
}
}
if (storedException != null)
throw storedException;
}
public static void xslt(String stylesheet, boolean applySuppression, String[] args, int argCount) throws Exception {
Project proj = new Project();
HTMLBugReporter reporter = new HTMLBugReporter(proj, stylesheet);
BugCollection bugCollection = reporter.getBugCollection();
bugCollection.setApplySuppressions(applySuppression);
if (argCount < args.length) {
bugCollection.readXML(args[argCount++]);
} else
bugCollection.readXML(System.in);
if (argCount < args.length)
reporter.setOutputStream(new PrintStream(new FileOutputStream(args[argCount++]), true));
reporter.finish();
Exception e = reporter.getFatalException();
if (e != null)
throw e;
}
public @CheckForNull
BugCollection getBugCollection() {
return null;
}
}
// vim:ts=4