3 // Comparative FindBugs
5 // Tool to compare successive runs of FindBugs,
6 // flagging the change from one run to the next.
8 // Copyright (C) 2015 Christian Jaekl
11 import java.io.IOException;
12 import java.io.PrintWriter;
13 import java.sql.Connection;
14 import java.sql.SQLException;
15 import java.text.MessageFormat;
16 import java.util.Locale;
18 import net.jaekl.cfb.analyze.Analysis;
19 import net.jaekl.cfb.analyze.Analyzer;
20 import net.jaekl.cfb.db.CfbSchema;
21 import net.jaekl.cfb.db.driver.DbDriver;
22 import net.jaekl.cfb.db.driver.PostgresqlDriver;
23 import net.jaekl.qd.xml.XmlParseException;
25 import org.apache.commons.cli.CommandLine;
26 import org.apache.commons.cli.GnuParser;
27 import org.apache.commons.cli.HelpFormatter;
28 import org.apache.commons.cli.Options;
29 import org.apache.commons.cli.ParseException;
37 // Command-line parameters
38 String m_dbName; // db name
39 File m_fbp; // FindBugsProject file
40 File m_fbDir; // Directory where FindBugs is installed
41 String m_host; // db host
42 int m_port; // db port
43 String m_user; // db user
44 String m_pass; // db password
47 m_driver = new PostgresqlDriver();
48 m_schema = new CfbSchema(m_driver);
50 m_bundle = CfbBundle.getInst(m_locale);
61 Options createOptions() {
62 Options opt = new Options();
64 opt.addOption("d", "dbname", true, "DB name");
65 opt.addOption("f", "fbp", true, "FindBugsProject file");
66 opt.addOption("h", "host", true, "DB hostname");
67 opt.addOption("p", "pass", true, "DB password");
68 opt.addOption("t", "port", true, "DB port");
69 opt.addOption("u", "user", true, "DB username");
74 boolean parseArgs(PrintWriter pw, String[] args) {
75 Options opt = createOptions();
78 CommandLine line = new GnuParser().parse(opt, args);
79 if (line.hasOption("d")) {
80 m_dbName = line.getOptionValue("d");
82 if (line.hasOption("f")) {
83 m_fbp = new File(line.getOptionValue("f"));
85 if (line.hasOption("h")) {
86 m_host = line.getOptionValue("h");
88 if (line.hasOption("p")) {
89 m_pass = line.getOptionValue("p");
91 if (line.hasOption("t")) {
92 m_port = Integer.parseInt(line.getOptionValue("t"));
94 if (line.hasOption("u")) {
95 m_user = line.getOptionValue("u");
98 catch (ParseException exc) {
106 void usage(PrintWriter pw, Options opt) {
107 HelpFormatter help = new HelpFormatter();
108 help.printHelp(pw, 80, getClass().getName(), "", opt, 0, 0, "", true);
111 String trans(String key) {
112 return m_bundle.get(key);
115 String getenv(String varName) {
116 // This is a separate function so that we can override it at unit test time
117 return System.getenv(varName);
120 String getProperty(String propName) {
121 // This is a separate function so that we can override it at unit test time
122 return System.getProperty(propName);
126 String findBugsDir = getenv("FINDBUGS_HOME");
127 if (null != findBugsDir) {
128 m_fbDir = new File(findBugsDir);
130 findBugsDir = getProperty("findbugs.home");
131 if (null != findBugsDir) {
132 m_fbDir = new File(findBugsDir);
136 void doMain(PrintWriter pw, String[] args) throws SQLException, IOException, XmlParseException {
137 initArgs(); // read environment and system properties
138 if ( ! parseArgs(pw, args) ) {
142 try (Connection con = m_driver.connect(m_host, m_port, m_dbName, m_user, m_pass)) {
143 m_schema.ensureDbInitialized(con);
145 catch (SQLException exc) {
146 String cannotConnectFormat = trans(CfbBundle.CANNOT_CONNECT);
147 String cannotConnect = MessageFormat.format(cannotConnectFormat, m_host, ""+m_port, m_dbName, m_user);
148 exc.printStackTrace(pw);
149 pw.println(cannotConnect);
153 File findBugsDir = (null != m_fbDir) ? m_fbDir : new File(".");
154 File workDir = new File(".");
155 Analyzer analyzer = new Analyzer(findBugsDir);
156 Analysis analysis = analyzer.analyze(pw, workDir, m_fbp);
157 if (null != analysis) {
162 public static void main(String[] args) {
163 CFB cfb = new CFB(Locale.getDefault());
165 try (PrintWriter pw = new PrintWriter(System.out)){
166 cfb.doMain(pw, args);
168 } catch (SQLException | IOException | XmlParseException exc) {
169 exc.printStackTrace();