Some progress toward implementing store(Analysis).
authorChris Jaekl <chris@ringo.jaekl.net>
Sat, 26 Sep 2015 14:25:00 +0000 (23:25 +0900)
committerChris Jaekl <chris@ringo.jaekl.net>
Sat, 26 Sep 2015 14:25:00 +0000 (23:25 +0900)
16 files changed:
prod/net/jaekl/cfb/CFB.java
prod/net/jaekl/cfb/analyze/Analysis.java
prod/net/jaekl/cfb/analyze/Analyzer.java
prod/net/jaekl/cfb/analyze/MessageMap.java
prod/net/jaekl/cfb/db/CfbSchema.java
prod/net/jaekl/cfb/db/Table.java
prod/net/jaekl/cfb/store/DbStore.java
prod/net/jaekl/cfb/store/Location.java [new file with mode: 0644]
prod/net/jaekl/cfb/xml/BugClass.java
prod/net/jaekl/cfb/xml/BugCollection.java
prod/net/jaekl/cfb/xml/BugInstance.java
prod/net/jaekl/cfb/xml/BugMethod.java
prod/net/jaekl/cfb/xml/SourceLine.java
prod/net/jaekl/cfb/xml/messages/BugCategory.java
prod/net/jaekl/cfb/xml/messages/BugPattern.java
test/net/jaekl/cfb/analyze/AnalysisTest.java

index 924d33182d28c4824207b6fde0712d4362d6d6b7..a830b12c07aa8905b1463673e088ba6fc2abb94e 100644 (file)
@@ -20,6 +20,7 @@ import net.jaekl.cfb.analyze.Analysis;
 import net.jaekl.cfb.analyze.Analyzer;
 import net.jaekl.cfb.analyze.MessageMap;
 import net.jaekl.cfb.db.CfbSchema;
+import net.jaekl.cfb.db.TypeMismatchException;
 import net.jaekl.cfb.db.driver.DbDriver;
 import net.jaekl.cfb.db.driver.PostgresqlDriver;
 import net.jaekl.cfb.store.DbStore;
@@ -151,7 +152,7 @@ public class CFB {
                }
        } 
        
-       void doMain(PrintWriter pw, String[] args) throws SQLException, IOException, XmlParseException, SAXException {
+       void doMain(PrintWriter pw, String[] args) throws SQLException, IOException, XmlParseException, SAXException, TypeMismatchException {
                initArgs();     // read environment and system properties
                if ( ! parseArgs(pw, args) ) {
                        return;
@@ -169,7 +170,8 @@ public class CFB {
                                m_schema.purge(con);
                                return;
                        }
-                       m_schema.ensureDbInitialized(con);      
+                       m_schema.ensureDbInitialized(con);
+                       messageMap.loadIds(con, m_driver);
                }
                catch (SQLException exc) {
                        reportUnableToConnect(pw, exc);
@@ -184,7 +186,7 @@ public class CFB {
                }
                
                try (Connection con = m_driver.connect(m_host, m_port, m_dbName, m_user, m_pass)) {
-                       DbStore store = new DbStore(con);
+                       DbStore store = new DbStore(con, m_driver, messageMap.getColl());
                        
                        store.put(analysis);
                }
@@ -207,7 +209,7 @@ public class CFB {
                try (PrintWriter pw = new PrintWriter(System.out)){
                        cfb.doMain(pw, args);
                        pw.flush();
-               } catch (SQLException | IOException | XmlParseException | SAXException exc) {
+               } catch (SQLException | IOException | XmlParseException | SAXException | TypeMismatchException exc) {
                        exc.printStackTrace();
                }
        }
index e2f090f32b0245c701532c27606d2c7b01c0d979..f61d44dbabf4db52d869a7d81b47ded8b69a802d 100644 (file)
@@ -19,15 +19,20 @@ import org.xml.sax.helpers.XMLReaderFactory;
 public class Analysis {
        BugCollection m_bugCollection;
        String m_buildNumber;
-       Date m_date;    // Date/time when analysis was started
+       Date m_start;   // Date/time when analysis was started
+       Date m_end;
        
        public Analysis(String buildNumber) {
                m_bugCollection = null;
                m_buildNumber = buildNumber;
-               m_date = new Date();
+               m_start = new Date();
+               m_end = null;
        }
        
        public BugCollection getBugCollection() { return m_bugCollection; }
+       public String getBuildNumber() { return m_buildNumber; }
+       public Date getStart() { return m_start; }
+       public Date getEnd() { return m_end; }
        
        public void parse(InputSource xml) throws FileNotFoundException, IOException, SAXException 
        {
@@ -41,6 +46,12 @@ public class Analysis {
            reader.parse(xml);
        }
        
+       // Set the end time (when FindBugs was done analyzing)
+       public void setEnd(Date date) 
+       {
+               m_end = date;
+       }
+       
        public void dump(PrintWriter pw)
        {
                if (null != m_bugCollection) {
index 03aeb1c6a4db718198e2eca9da9b9538829eab39..22d65edfcf5d83d1880e011a36fc1f5eb18806eb 100644 (file)
@@ -6,6 +6,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.text.MessageFormat;
+import java.util.Date;
 import java.util.Locale;
 import java.util.Locale.Category;
 
@@ -46,6 +47,7 @@ public class Analyzer {
                        return null;
                }
                
+               result.setEnd(new Date());
                result.parse(new InputSource(fbOutput.getAbsolutePath()));
                result.dump(pw);                        
                return result;
index 97180030af8a9b80e109278532fe81f4afc29436..0db78babfdaa2974a0c4d366841ed10c5a71f33f 100644 (file)
@@ -4,8 +4,20 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
 import java.util.Locale;
 
+import net.jaekl.cfb.db.CfbSchema;
+import net.jaekl.cfb.db.Column;
+import net.jaekl.cfb.db.Condition;
+import net.jaekl.cfb.db.Row;
+import net.jaekl.cfb.db.Table;
+import net.jaekl.cfb.db.TypeMismatchException;
+import net.jaekl.cfb.db.driver.DbDriver;
+import net.jaekl.cfb.xml.messages.BugCategory;
+import net.jaekl.cfb.xml.messages.BugPattern;
 import net.jaekl.cfb.xml.messages.MessageCollection;
 import net.jaekl.qd.xml.ParseErrorHandler;
 import net.jaekl.qd.xml.ParseHandler;
@@ -30,6 +42,59 @@ public class MessageMap {
        public MessageCollection getColl() { return m_msgColl; }
        public File getFindBugsDir() { return m_findBugsDir; }
 
+       // Load the list of primary keys (sequence numbers) from the database
+       public void loadIds(Connection con, DbDriver driver) throws SQLException, TypeMismatchException
+       {
+               loadCategoryIds(con, driver);
+               loadBugPatternIds(con, driver);
+               
+       }
+       
+       void loadCategoryIds(Connection con, DbDriver driver) throws SQLException, TypeMismatchException
+       {
+               Column[] columns = { CfbSchema.CATEGORIES.getColumn(CfbSchema.CATEGORYID),
+                                            CfbSchema.CATEGORIES.getColumn(CfbSchema.CATEGORY)   };
+               Table[] tables = { CfbSchema.CATEGORIES };
+               Condition[] conditions = { };
+               List<Row> rows = driver.select(con, columns, tables, conditions);
+               
+               for (Row row : rows) {
+                       long catId = row.getLong(0);
+                       String catName = row.getString(1);
+                       
+                       BugCategory cat = getColl().getCategory(catName);
+                       if (null == cat) {
+                               throw new SQLException("Database result (" + catId + ", \"" + catName + "\") not found in messages.xml.  "
+                                                              + "Perhaps your database and findbugs versions are out of sync?");
+                       }
+                       
+                       cat.setId(catId);
+               }
+       }
+       
+       void loadBugPatternIds(Connection con, DbDriver driver) throws SQLException, TypeMismatchException
+       {
+               Column[] columns = { CfbSchema.BUGS.getColumn(CfbSchema.BUGID),
+                                    CfbSchema.BUGS.getColumn(CfbSchema.TYPE)   }; 
+               Table[] tables = { CfbSchema.BUGS };
+               Condition[] conditions = { };
+               List<Row> rows = driver.select(con, columns, tables, conditions);
+               
+               for (Row row: rows) {
+                       long bugId = row.getLong(0);
+                       String type = row.getString(1);
+                       
+                       BugPattern bug = getColl().getPattern(type);
+                       if (null == bug) {
+                               throw new SQLException("Database result (" + bugId + ", \"" + type + "\") not found in messages.xml.  "
+                                      + "Perhaps your database and findbugs versions are out of sync?");
+                       }
+                       
+                       bug.setId(bugId);
+               }
+       }
+
+       // Load the list of bug patterns and categories from the FindBugs messages.xml file.
        public void load(File findBugsDir, Locale locale) throws FileNotFoundException, IOException, SAXException
        {
                m_findBugsDir = findBugsDir;
@@ -51,6 +116,7 @@ public class MessageMap {
                
        }
        
+       // Parse the FindBugs messages.xml file
        void parse(InputSource xml) throws FileNotFoundException, IOException, SAXException 
        {
                m_msgColl = new MessageCollection();
index d80be57940a084ebeb81dbe17844f7d5cde4c103..33c1b9e1c8ceb1baff08b20fa8964c2368175051 100644 (file)
@@ -25,10 +25,19 @@ public class CfbSchema extends Schema {
        public static final Sequence RUN_SEQ      = new Sequence("RUN_SEQ");
        
        public static final String BUGID = "BUGID";
+       public static final String CATEGORY = "CATEGORY";
        public static final String CATEGORYID = "CATEGORYID";
+       public static final String CLASSNAME = "CLASSNAME";
+       public static final String ENDLINE = "ENDLINE";
+       public static final String FIRSTLOCID = "FIRSTLOCID";
        public static final String FOUNDID = "FOUNDID";
        public static final String LOCID = "LOCID";
+       public static final String METHODNAME = "METHODNAME";
        public static final String RUNID = "RUNID";
+       public static final String SECONDLOCID = "SECONDLOCID";
+       public static final String STARTLINE = "STARTLINE";
+       public static final String THIRDLOCID = "THIRDLOCID";
+       public static final String TYPE = "TYPE";
        
        // Define each table as follows:
        // {
@@ -40,34 +49,35 @@ public class CfbSchema extends Schema {
                                        // Description of each possible bug
                                        { "BUG" },
                                        { BUGID, INTEGER, -1, NOT_NULL },
-                                       { "TYPE", VARCHAR, 80, NOT_NULL }
+                                       { TYPE, VARCHAR, 80, NOT_NULL }, 
+                                       { "CATEGORYID", INTEGER, -1, NOT_NULL }
                                };
        private static final Object[][] CATEGORIES_DEFN = 
                                {
                                        // Description of each possible bug category
-                                       { "CATEGORY" },
+                                       { "CATEGORIES" },
                                        { CATEGORYID, INTEGER, -1, NOT_NULL },
-                                       { "CATEGORY", VARCHAR, 80, NOT_NULL }
+                                       { CATEGORY, VARCHAR, 80, NOT_NULL }
                                };
        private static final Object[][] FOUND_DEFN = 
                                { 
                                        // One BugInstance, found during an analysis
                                        { "FOUND" },
                                        { FOUNDID, INTEGER, -1, NOT_NULL },
-                                       { "BUGID", INTEGER, -1, NOT_NULL },
-                                       { "CATEGORYID", INTEGER, -1, NOT_NULL },
-                                       { "FIRSTLOCID", INTEGER, -1, NOT_NULL },
-                                       { "SECONDLOCID", INTEGER, -1, NULL },
-                                       { "THIRDLOCID", INTEGER, -1, NULL }
+                                       { BUGID, INTEGER, -1, NOT_NULL },
+                                       { FIRSTLOCID, INTEGER, -1, NOT_NULL },
+                                       { SECONDLOCID, INTEGER, -1, NULL },
+                                       { THIRDLOCID, INTEGER, -1, NULL }
                                };
        private static final Object[][] LOCATIONS_DEFN = 
                                {
                                        // Location in the source code referenced by a BugInstance
                                        { "LOCATION" },
                                        { LOCID, INTEGER, -1, NOT_NULL },
-                                       { "CLASSNAME", VARCHAR, 256, NOT_NULL },
-                                       { "STARTLINE", INTEGER, -1, NULL },
-                                       { "ENDLINE", INTEGER, -1, NULL }
+                                       { CLASSNAME, VARCHAR, 256, NOT_NULL },
+                                       { METHODNAME, VARCHAR, 256, NULL },
+                                       { STARTLINE, INTEGER, -1, NULL },
+                                       { ENDLINE, INTEGER, -1, NULL }
                                };
        private static final Object[][] RUNS_DEFN = 
                                {
@@ -136,6 +146,7 @@ public class CfbSchema extends Schema {
                int row = 0;
                for (BugCategory cat : categories) {
                        long categoryId = m_driver.nextVal(con, CATEGORY_SEQ);
+                       cat.setId(categoryId);
                        
                        values[row][0] = Long.valueOf(categoryId);
                        values[row][1] = cat.getCategory();
@@ -155,6 +166,7 @@ public class CfbSchema extends Schema {
                int row = 0;
                for (BugPattern bug : patterns) {
                        long bugId = m_driver.nextVal(con, BUG_SEQ);
+                       bug.setId(bugId);
                        
                        values[row][0] = Long.valueOf(bugId);
                        values[row][1] = bug.getType();
index a68784223e6c716d919b0d58add30dd8520e015d..e20552daa109e4af9133618b95b8502cb151b5bb 100644 (file)
@@ -4,20 +4,30 @@ package net.jaekl.cfb.db;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 
 public class Table {
        String m_name;
+       HashMap<String, Column> m_columnsByName;
        ArrayList<Column> m_columns;
        
        public Table(String name, Column[] columns) {
                m_name = name;
-               m_columns = new ArrayList<Column>(Arrays.asList(columns));              
+
+               m_columns = new ArrayList<Column>();
+               m_columns.addAll(Arrays.asList(columns));
+
+               m_columnsByName = new HashMap<String, Column>();
+               for (int i = 0; i < columns.length; ++i) {
+                       m_columnsByName.put(columns[i].getName(), columns[i]);
+               }
        }
        
        public String getName() { return m_name; }
        public int getNumColumns() { return m_columns.size(); }
        public Column getColumn(int idx) { return m_columns.get(idx); }
-       
+       public Column getColumn(String name) { return m_columnsByName.get(name); }
+
        // Construct a table from an array of objects like this:
        // {
        //   { table_name },
index 7a1e6102febaf6916ad34c705033d01757451893..7591c88d5ef8633ee4cfeafbd3a94b10070528a1 100644 (file)
 package net.jaekl.cfb.store;
 
 import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
 
 import net.jaekl.cfb.analyze.Analysis;
+import net.jaekl.cfb.db.CfbSchema;
+import net.jaekl.cfb.db.Column;
+import net.jaekl.cfb.db.Condition;
+import net.jaekl.cfb.db.Operation;
+import net.jaekl.cfb.db.Row;
+import net.jaekl.cfb.db.Table;
+import net.jaekl.cfb.db.TypeMismatchException;
+import net.jaekl.cfb.db.driver.DbDriver;
+import net.jaekl.cfb.xml.BugInstance;
+import net.jaekl.cfb.xml.SourceLine;
+import net.jaekl.cfb.xml.messages.MessageCollection;
 
 public class DbStore {
-       Connection m_conn;
+       Connection m_con;
+       DbDriver m_driver;
+       MessageCollection m_msgColl;
        
-       public DbStore(Connection conn) {
-               m_conn = conn;
+       public DbStore(Connection con, DbDriver driver, MessageCollection msgColl) {
+               m_con = con;
+               m_driver = driver;
+               m_msgColl = msgColl;
        }
        
-       public boolean put(Analysis analysis) {
+       public boolean put(Analysis analysis) throws SQLException {
                if (null == analysis) {
                        return false;
                }
                
+               // ----------------------------------
+               // Add a run record for this analysis
                
+               long runId = m_driver.nextVal(m_con, CfbSchema.RUN_SEQ);
+               Object[][] values = { 
+                                                               {
+                                                                       Long.valueOf(runId),
+                                                                       analysis.getBuildNumber(),
+                                                                       analysis.getStart(),
+                                                                       analysis.getEnd() 
+                                                               } 
+                                                       };
+               int count = m_driver.insert(m_con, CfbSchema.RUNS, values);
+               if (1 != count) {
+                       return false;
+               }
+               
+               // -------------------------------------
+               // Add a found record for each bug found
+               
+               List<BugInstance> bugs = analysis.getBugCollection().getBugs();
+               values = new Object[bugs.size()][CfbSchema.FOUND.getNumColumns()];
+               
+               int row = 0;
+               for (BugInstance bug : bugs)
+               {
+                       long foundId = m_driver.nextVal(m_con, CfbSchema.FOUND_SEQ);
+                       long bugId = m_msgColl.getPattern(bug.getType()).getId();
+                       // values[row] = { foundId, bugId, firstLocId, secondLocId, thirdLocId }; 
+                       row++;
+               }
                
                return true;
        }
+       
+       Location[] computeLocations(BugInstance bug)
+       {
+               throw new UnsupportedOperationException("UNIMPLEMENTED");
+       }
+       
+       long getLocId(SourceLine loc) throws SQLException, TypeMismatchException 
+       {
+               long locId = findLocId(loc);
+               if (locId >= 0) {
+                       return locId;
+               }
+
+               return storeLoc(loc);
+       }
+       
+       long findLocId(SourceLine loc) throws SQLException, TypeMismatchException
+       {
+               Column[] columns = { CfbSchema.LOCATIONS.getColumn(CfbSchema.LOCID) };
+               Table[] tables = { CfbSchema.LOCATIONS };
+               Condition[] conditions = { 
+                                               new Condition( CfbSchema.LOCATIONS.getColumn(CfbSchema.CLASSNAME),
+                                                              loc.getClassName(),
+                                                              Operation.EQUAL 
+                                                            ),
+                                               new Condition( CfbSchema.LOCATIONS.getColumn(CfbSchema.STARTLINE),
+                                                                      loc.getStart(),
+                                                                      Operation.EQUAL
+                                                                    ),
+                                               new Condition( CfbSchema.LOCATIONS.getColumn(CfbSchema.ENDLINE),
+                                                                      loc.getEnd(),
+                                                                      Operation.EQUAL
+                                                                    )
+                                       };
+               List<Row> rows = m_driver.select(m_con, columns, tables, conditions);
+               if (rows.size() > 0) {
+                       assert(1 == rows.size());       // should only have one match
+                       
+                       return rows.get(0).getLong(0);
+               }
+               
+               return (-1);    // not found
+       }
+       
+       long storeLoc(SourceLine loc) throws SQLException
+       {
+               long locId = m_driver.nextVal(m_con, CfbSchema.LOC_SEQ);
+               
+               Object[][] values = { { 
+                                                       locId,
+                                                       loc.getClassName(),
+                                                       Long.valueOf(loc.getStart()),
+                                                       Long.valueOf(loc.getEnd())
+                                               } };
+               m_driver.insert(m_con, CfbSchema.LOCATIONS, values);
+               
+               return locId;
+       }
 }
diff --git a/prod/net/jaekl/cfb/store/Location.java b/prod/net/jaekl/cfb/store/Location.java
new file mode 100644 (file)
index 0000000..208c3db
--- /dev/null
@@ -0,0 +1,46 @@
+package net.jaekl.cfb.store;
+
+import net.jaekl.cfb.xml.BugClass;
+import net.jaekl.cfb.xml.BugMethod;
+import net.jaekl.cfb.xml.SourceLine;
+
+public class Location {
+       String m_className;
+       String m_methodName;
+       int m_startLine;
+       int m_endLine;
+       
+       public Location(SourceLine sourceLine)
+       {
+               init(sourceLine);
+       }
+       
+       public Location(BugMethod method) 
+       {
+               init(method.getSourceLines());
+               m_className = method.getClassName();
+               m_methodName = method.getMethodName();
+       }
+       
+       public Location(BugClass bugClass)
+       {
+               init(bugClass.getSourceLines());
+               m_className = bugClass.getClassName();
+       }
+       
+       private void init(SourceLine[] sourceLines) 
+       {
+               if (sourceLines.length > 0) {
+                       assert(null != sourceLines[0]);
+                       init(sourceLines[0]);
+               }               
+       }
+
+       private void init(SourceLine sourceLine)
+       {
+               m_className = sourceLine.getClassName();
+               m_methodName = null;
+               m_startLine = sourceLine.getStart();
+               m_endLine = sourceLine.getEnd();
+       }
+}
index 40cc84b8a3874dd550be2e201ffec705f928d040..99a561f9bb0a24e66ddff1ba48826f2deca938bf 100644 (file)
@@ -25,6 +25,9 @@ public class BugClass extends ParseResult {
                m_className = "";
                m_lines = new ArrayList<SourceLine>();
        }
+       
+       public String getClassName() { return m_className; }
+       public SourceLine[] getSourceLines() { return m_lines.toArray(new SourceLine[m_lines.size()]); }
 
        @Override
        public void handleMainAttributes(Attributes attr) throws MissingAttributeException 
index d906ff983f9bb5b50c98d8b0c9ea512567b3c8e3..6fbf4460ec43d0b7105ae06d3b16b3bd7f68cac9 100644 (file)
@@ -2,6 +2,8 @@ package net.jaekl.cfb.xml;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import net.jaekl.qd.xml.ParseResult;
 import net.jaekl.qd.xml.XmlParseException;
@@ -19,8 +21,7 @@ public class BugCollection extends ParseResult {
                m_bugs = new ArrayList<BugInstance>();
        }
        
-       public int size() { return m_bugs.size(); }
-       public BugInstance get(int idx) { return m_bugs.get(idx); }
+       public List<BugInstance> getBugs() { return Collections.unmodifiableList(m_bugs); }
        
        @Override
        public void endContents(String uri, String localName, String qName,     String chars) 
index 4764c1ca5cef826a83bf0e6bf411b891370478c0..ee5bac0474aa3a24e38dcbfae3c8f7b7fb1f1db9 100644 (file)
@@ -3,6 +3,8 @@ package net.jaekl.cfb.xml;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import javax.tools.JavaFileManager.Location;
+
 import org.xml.sax.Attributes;
 
 import net.jaekl.qd.xml.MissingAttributeException;
index 80afa93392a69b632cd3c9023982a5fc18d9c850..33c615a858780cd79c0f76a5fe9d49412b0aa692 100644 (file)
@@ -37,6 +37,10 @@ public class BugMethod extends ParseResult {
                m_sourceLines = new ArrayList<SourceLine>();
        }
        
+       public String getClassName() { return m_className; }
+       public String getMethodName() { return m_methodName; }
+       public SourceLine[] getSourceLines() { return m_sourceLines.toArray(new SourceLine[m_sourceLines.size()]); }
+       
        @Override
        public void handleMainAttributes(Attributes attr) throws MissingAttributeException 
        {
index 085c3fbf46765d3d7a713139d18b4403ffcaa91f..e5e82f6aa3e8e88f47042bdf9795dfee1049e668 100644 (file)
@@ -28,6 +28,10 @@ public class SourceLine extends ParseResult {
                m_start = m_end = (-1);
        }       
        
+       public String getClassName() { return m_className; }
+       public int getStart() { return m_start; }
+       public int getEnd() { return m_end; }
+       
        @Override
        public void handleMainAttributes(Attributes attr) throws MissingAttributeException {
                String scratch;
index 9e1f53920766e89bd2d8fbd384761b9f58d174ec..757aacfb124472981e597da46b6c826da810e1ed 100644 (file)
@@ -20,6 +20,7 @@ public class BugCategory extends ParseResult {
        String m_descr;
        String m_abbrev;
        String m_details;
+       long m_id;
        
        public BugCategory() 
        {
@@ -32,6 +33,9 @@ public class BugCategory extends ParseResult {
        public String getAbbrev() { return m_abbrev; }
        public String getDetails() { return m_details; }
 
+       public void setId(long id) { m_id = id; }
+       public long getId() { return m_id; }
+
        @Override
        public void endContents(String uri, String localName, String qName, String chars) throws XmlParseException 
        {
index b75733b162d14e39ccc16e835b4873b502119412..e8e381c55410cd0bb1f16752a1751c5ad40f05a1 100644 (file)
@@ -20,6 +20,7 @@ public class BugPattern extends ParseResult {
        String m_short;
        String m_long;
        String m_details;
+       long m_id;
        
        public BugPattern() 
        {
@@ -32,6 +33,9 @@ public class BugPattern extends ParseResult {
        public String getLong() { return m_long; }
        public String getDetails() { return m_details; }
 
+       public void setId(long id) { m_id = id; }
+       public long getId() { return m_id; }
+       
        @Override
        public void endContents(String uri, String localName, String qName, String chars) throws XmlParseException 
        {
index f0b28c78db075e6f6ca9483b976f5be3b3ed59ee..5b48927e8f9cf5ef99dd2839608e5752f55330ea 100644 (file)
@@ -6,6 +6,7 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.util.HashMap;
+import java.util.List;
 
 import net.jaekl.cfb.xml.BugCollection;
 import net.jaekl.cfb.xml.BugInstance;
@@ -66,14 +67,14 @@ public class AnalysisTest {
                        assertNotNull(analysis);
                        
                        BugCollection bugColl = analysis.getBugCollection();
+                       List<BugInstance> bugs = bugColl.getBugs();
                        
                        assertNotNull(bugColl);
-                       assertEquals(2, bugColl.size());
+                       assertEquals(2, bugs.size());
                        
                        HashMap<String, BugInstance> typeMap = new HashMap<String, BugInstance>();
-                       for (int idx = 0; idx < bugColl.size(); ++idx) {
-                               inst = bugColl.get(idx);
-                               typeMap.put(inst.getType(), inst);
+                       for (BugInstance bug : bugs) {
+                               typeMap.put(bug.getType(), bug);
                        }
                        
                        inst = typeMap.get("DM_DEFAULT_ENCODING");