/*
* FindBugs - Find Bugs in Java programs
* Copyright (C) 2003-2008 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.workflow;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Date;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.dom4j.DocumentException;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugRankCategory;
import edu.umd.cs.findbugs.FindBugs;
import edu.umd.cs.findbugs.ProjectStats;
import edu.umd.cs.findbugs.SortedBugCollection;
import edu.umd.cs.findbugs.charsets.UTF8;
import edu.umd.cs.findbugs.charsets.UserTextFile;
import edu.umd.cs.findbugs.cloud.Cloud;
import edu.umd.cs.findbugs.config.CommandLine;
/**
* @author bill.pugh
*/
public class CloudSyncAndReport {
public static class CSPoptions {
public String analysisFile;
public String cloudSummary;
public String cloudId;
public int ageInHours = 22;
}
static class CSRCommandLine extends CommandLine {
final CSPoptions options;
public CSRCommandLine(CSPoptions options) {
this.options = options;
addOption("-cloud", "id", "id of the cloud to use");
addOption("-recent", "hours", "maximum age in hours for an issue to be recent");
addOption("-cloudSummary", "file", "write a cloud summary to thie file");
}
/*
* (non-Javadoc)
*
* @see
* edu.umd.cs.findbugs.config.CommandLine#handleOption(java.lang.String,
* java.lang.String)
*/
@Override
protected void handleOption(String option, String optionExtraPart) throws IOException {
throw new IllegalArgumentException("Unknown option : " + option);
}
/*
* (non-Javadoc)
*
* @see
* edu.umd.cs.findbugs.config.CommandLine#handleOptionWithArgument(java
* .lang.String, java.lang.String)
*/
@Override
protected void handleOptionWithArgument(String option, String argument) throws IOException {
if (option.equals("-cloud")) {
options.cloudId = argument;
} else if (option.equals("-recent")) {
options.ageInHours = Integer.parseInt(argument);
} else if (option.equals("-cloudSummary")) {
options.cloudSummary = argument;
} else
throw new IllegalArgumentException("Unknown option : " + option);
}
}
public static void main(String[] argv) throws Exception {
FindBugs.setNoAnalysis();
final CSPoptions options = new CSPoptions();
final CSRCommandLine commandLine = new CSRCommandLine(options);
int argCount = commandLine.parse(argv, 0, 1, "Usage: " + CloudSyncAndReport.class.getName()
+ " [options] [<results1> <results2> ... <resultsn>] ");
if (argCount < argv.length)
options.analysisFile = argv[argCount];
CloudSyncAndReport csr = new CloudSyncAndReport(options);
csr.load();
csr.sync();
PrintWriter out = UTF8.printWriter(System.out);
csr.report(out);
out.flush();
csr.shutdown();
out.close();
}
final CSPoptions options;
final SortedBugCollection bugCollection = new SortedBugCollection();
/**
* @param options
*/
public CloudSyncAndReport(CSPoptions options) {
this.options = options;
}
public void load() throws IOException, DocumentException {
if (options.analysisFile == null)
bugCollection.readXML(UTF8.bufferedReader(System.in));
else
bugCollection.readXML(options.analysisFile);
if (options.cloudId != null && !options.cloudId.equals(bugCollection.getProject().getCloudId())) {
bugCollection.getProject().setCloudId(options.cloudId);
bugCollection.reinitializeCloud();
}
}
public void sync() {
Cloud cloud = bugCollection.getCloud();
cloud.initiateCommunication();
cloud.waitUntilIssueDataDownloaded();
}
static class Stats {
int total, recent;
}
public void report(PrintWriter out) {
TreeMap<BugRankCategory, Stats> stats = new TreeMap<BugRankCategory, Stats>();
ProjectStats projectStats = bugCollection.getProjectStats();
Collection<BugInstance> bugs = bugCollection.getCollection();
Cloud cloud = bugCollection.getCloud();
cloud.setMode(Cloud.Mode.COMMUNAL);
out.printf("Cloud sync and summary report for %s%n", bugCollection.getProject().getProjectName());
out.printf("Code dated %s%n", new Date(bugCollection.getTimestamp()));
out.printf("Code analyzed %s%n", new Date(bugCollection.getAnalysisTimestamp()));
out.printf("%7d total classes%n", projectStats.getNumClasses());
out.printf("%7d total issues%n", bugs.size());
long recentTimestamp = System.currentTimeMillis() - options.ageInHours * 3600 * 1000L;
int allRecentIssues = 0;
for (BugInstance b : bugs) {
Stats s = stats.get(BugRankCategory.getRank(b.getBugRank()));
if (s == null) {
s = new Stats();
stats.put(BugRankCategory.getRank(b.getBugRank()), s);
}
s.total++;
long firstSeen = cloud.getFirstSeen(b);
if (firstSeen > recentTimestamp) {
s.recent++;
allRecentIssues++;
}
}
out.printf("%7d recent issues%n", allRecentIssues);
if (options.cloudSummary != null && cloud.supportsCloudSummaries()) {
try {
PrintWriter cs = UserTextFile.printWriter(options.cloudSummary);
cs.printf("%6s %6s %s%n", "recent", "total", "Rank category");
for (Entry<BugRankCategory, Stats> e : stats.entrySet()) {
Stats s = e.getValue();
if (s.total > 0)
cs.printf("%6d %6d %s%n", s.recent, s.total, e.getKey());
}
cs.println();
cloud.printCloudSummary(cs, bugs, null);
cs.close();
} catch (Exception e) {
out.println("Error writing cloud summary to " + options.cloudSummary);
e.printStackTrace(out);
}
}
}
public void shutdown() {
Cloud cloud = bugCollection.getCloud();
cloud.shutdown();
}
}