]> jaekl.net Git - cfb.git/commitdiff
Add local variable information to DB store.
authorChris Jaekl <cejaekl@yahoo.com>
Sun, 27 Sep 2015 13:06:25 +0000 (22:06 +0900)
committerChris Jaekl <cejaekl@yahoo.com>
Sun, 27 Sep 2015 13:06:25 +0000 (22:06 +0900)
prod/net/jaekl/cfb/analyze/Analyzer.java
prod/net/jaekl/cfb/db/CfbSchema.java
prod/net/jaekl/cfb/db/Condition.java
prod/net/jaekl/cfb/store/DbStore.java
prod/net/jaekl/cfb/store/Location.java
prod/net/jaekl/cfb/xml/BugInstance.java
prod/net/jaekl/cfb/xml/BugMethod.java
prod/net/jaekl/cfb/xml/LocalVariable.java

index 22d65edfcf5d83d1880e011a36fc1f5eb18806eb..1ac5677abb50da33a7e85cfaf0882b26af31edc7 100644 (file)
@@ -34,6 +34,8 @@ public class Analyzer {
                pw.println(cmdLine);
                pw.flush();
                Command.Result fbResult = new Command().exec(cmdLine);
+               pw.println("==> " + fbResult.getRetCode());
+               pw.flush();
                if (0 != fbResult.getRetCode()) {
                        // Our attempt to execute FindBugs failed.
                        // Report the error and return null.
index 49adde6c5a224c6cee2dad0952e82af671dc29e2..9a6cc3b78417168b3e68aa7509a71eb4a773c8ea 100644 (file)
@@ -23,43 +23,52 @@ public class CfbSchema extends Schema {
        public static final Sequence FOUND_SEQ    = new Sequence("FOUND_SEQ");
        public static final Sequence LOC_SEQ      = new Sequence("LOC_SEQ");
        public static final Sequence RUN_SEQ      = new Sequence("RUN_SEQ");
+       public static final Sequence VARIABLE_SEQ = new Sequence("VARIABLE_SEQ");
        
-       public static final Column BUGID       = new Column("BUGID",       INTEGER,      -1, NOT_NULL);
-       public static final Column CATEGORY    = new Column("CATEGORY",    VARCHAR,      80, NOT_NULL);
-       public static final Column CATEGORYID  = new Column("CATEGORYID",  INTEGER,      -1, NOT_NULL);
-       public static final Column CLASSNAME   = new Column("CLASSNAME",   VARCHAR,     256, NOT_NULL);
-       public static final Column ENDLINE     = new Column("ENDLINE",     INTEGER,      -1, NULL);
-       public static final Column ENDTIME     = new Column("ENDTIME",     TIMESTAMPTZ,  -1, NOT_NULL);
-       public static final Column FIRSTLOCID  = new Column("FIRSTLOCID",  INTEGER,      -1, NOT_NULL);
-       public static final Column FOUNDID     = new Column("FOUNDID",     INTEGER,      -1, NOT_NULL);
-       public static final Column LOCID       = new Column("LOCID",       INTEGER,      -1, NOT_NULL);
-       public static final Column METHODNAME  = new Column("METHODNAME",  VARCHAR,     256, NULL);
-       public static final Column RUNID       = new Column("RUNID",       INTEGER,      -1, NOT_NULL);
-       public static final Column SECONDLOCID = new Column("SECONDLOCID", INTEGER,      -1, NULL);
-       public static final Column STARTLINE   = new Column("STARTLINE",   INTEGER,      -1, NULL);
-       public static final Column STARTTIME   = new Column("STARTTIME",   TIMESTAMPTZ,  -1, NOT_NULL);
-       public static final Column THIRDLOCID  = new Column("THIRDLOCID",  INTEGER,      -1, NULL); 
-       public static final Column TYPE        = new Column("TYPE",        VARCHAR,      80, NOT_NULL );
-       public static final Column VERSION     = new Column("VERSION",     VARCHAR,      32, NULL);
+       public static final Column BUGID        = new Column("BUGID",       INTEGER,      -1, NOT_NULL);
+       public static final Column CATEGORY     = new Column("CATEGORY",    VARCHAR,      80, NOT_NULL);
+       public static final Column CATEGORYID   = new Column("CATEGORYID",  INTEGER,      -1, NOT_NULL);
+       public static final Column CLASSNAME    = new Column("CLASSNAME",   VARCHAR,     256, NOT_NULL);
+       public static final Column ENDLINE      = new Column("ENDLINE",     INTEGER,      -1, NULL);
+       public static final Column ENDTIME      = new Column("ENDTIME",     TIMESTAMPTZ,  -1, NOT_NULL);
+       public static final Column FIRSTLOCID   = new Column("FIRSTLOCID",  INTEGER,      -1, NOT_NULL);
+       public static final Column FOUNDID      = new Column("FOUNDID",     INTEGER,      -1, NOT_NULL);
+       public static final Column LOCID        = new Column("LOCID",       INTEGER,      -1, NOT_NULL);
+       public static final Column METHODNAME   = new Column("METHODNAME",  VARCHAR,     256, NULL);
+       public static final Column METHODROLE   = new Column("METHODROLE",  VARCHAR,      80, NULL);
+       public static final Column NAME         = new Column("NAME",        VARCHAR,     256, NOT_NULL);
+       public static final Column RUNID        = new Column("RUNID",       INTEGER,      -1, NOT_NULL);
+       public static final Column SECONDLOCID  = new Column("SECONDLOCID", INTEGER,      -1, NULL);
+       public static final Column STARTLINE    = new Column("STARTLINE",   INTEGER,      -1, NULL);
+       public static final Column STARTTIME    = new Column("STARTTIME",   TIMESTAMPTZ,  -1, NOT_NULL);
+       public static final Column THIRDLOCID   = new Column("THIRDLOCID",  INTEGER,      -1, NULL); 
+       public static final Column TYPE         = new Column("TYPE",        VARCHAR,      80, NOT_NULL);
+       public static final Column VARID_FK     = new Column("VARID",       INTEGER,      -1, NULL);            // foreign key
+       public static final Column VARID_PK     = new Column("VARID",       INTEGER,      -1, NOT_NULL);        // primary key
+       public static final Column VARROLE      = new Column("VARROLE",     VARCHAR,      80, NOT_NULL);
+       public static final Column VERSION      = new Column("VERSION",     VARCHAR,      32, NULL);
        
        private static final Column[] BUGS_COLS       = { BUGID, TYPE };
        private static final Column[] CATEGORIES_COLS = { CATEGORYID, CATEGORY };
-       private static final Column[] FOUND_COLS      = { FOUNDID, BUGID, CATEGORYID, FIRSTLOCID, SECONDLOCID, THIRDLOCID };
-       private static final Column[] LOCATIONS_COLS  = { LOCID, CLASSNAME, METHODNAME, STARTLINE, ENDLINE };
+       private static final Column[] FOUND_COLS      = { FOUNDID, BUGID, CATEGORYID, FIRSTLOCID, SECONDLOCID, THIRDLOCID, VARID_FK };
+       private static final Column[] LOCATIONS_COLS  = { LOCID, CLASSNAME, METHODNAME, METHODROLE, STARTLINE, ENDLINE };
        private static final Column[] RUNS_COLS       = { RUNID, VERSION, STARTTIME, ENDTIME };
+       private static final Column[] VARIABLES_COLS  = { VARID_PK, NAME, VARROLE };
 
        public static final Table BUGS       = new Table("BUGS",       BUGS_COLS);
        public static final Table CATEGORIES = new Table("CATEGORIES", CATEGORIES_COLS);
        public static final Table FOUND      = new Table("FOUND",      FOUND_COLS);
        public static final Table LOCATIONS  = new Table("LOCATIONS",  LOCATIONS_COLS);
        public static final Table RUNS       = new Table("RUNS",       RUNS_COLS);
+       public static final Table VARIABLES  = new Table("VARIABLES",  VARIABLES_COLS);
        
        private static final Sequence[] SEQUENCES = {
                                        BUG_SEQ,
                                        CATEGORY_SEQ,
                                        FOUND_SEQ,
                                        LOC_SEQ,
-                                       RUN_SEQ
+                                       RUN_SEQ,
+                                       VARIABLE_SEQ
                                };
        
        private static final Table[] TABLES = { 
@@ -67,7 +76,8 @@ public class CfbSchema extends Schema {
                                        CATEGORIES,
                                        FOUND,
                                        LOCATIONS,
-                                       RUNS
+                                       RUNS,
+                                       VARIABLES
                                };
        
        public CfbSchema(DbDriver driver) {
index b221551f15089c912c59a37ee9b200d9988a6ed7..98bd5f26f165c24b29f3c317a2c772c56aaea87e 100644 (file)
@@ -11,12 +11,22 @@ public class Condition {
                m_column = column;
                m_value = value;
                m_operation = operation;
+               
+               if ((null == m_value) && (Operation.EQUAL == m_operation)) {
+                       m_operation = Operation.NULL;
+               }
        }
        
        public Condition(Column column, Object value) {
                this(column, value, Operation.EQUAL);
        }
        
+       public Condition(Column column, Operation operation) {
+               this(column, null, operation);
+               
+               assert(Operation.NULL == operation || Operation.NOT_NULL == operation);
+       }
+       
        public Column getColumn() { return m_column; }
        public Object getValue() { return m_value; }
        public Operation getOperation() { return m_operation; }
index 6e17cffef5605c5a358fcfeb01d70e9c73c7011e..315ade579272e91cb8d91b22bd8b5d1d58fca54c 100644 (file)
@@ -17,6 +17,7 @@ import net.jaekl.cfb.db.driver.DbDriver;
 import net.jaekl.cfb.xml.BugClass;
 import net.jaekl.cfb.xml.BugInstance;
 import net.jaekl.cfb.xml.BugMethod;
+import net.jaekl.cfb.xml.LocalVariable;
 import net.jaekl.cfb.xml.SourceLine;
 import net.jaekl.cfb.xml.messages.MessageCollection;
 
@@ -76,6 +77,7 @@ public class DbStore {
                        values[row][3] = getLocId(firstLoc);
                        values[row][4] = getLocId(secondLoc);
                        values[row][5] = getLocId(thirdLoc);
+                       values[row][6] = getVarId(bug);
                        row++;
                }
                
@@ -87,11 +89,51 @@ public class DbStore {
        {
                ArrayList<Location> locs = new ArrayList<Location>();
                
-               for (SourceLine line : bug.getLines()) {
-                       locs.add(new Location(line));
+               /*
+                       Somewhat unfortunate special case.
+                       The primary "location" for a bug instance is split between tags.
+                       Most bugs have a pattern like this:
+                       <BugInstance>
+                               ...
+                               <Method>
+                                       <SourceLine .../>
+                               </Method>
+                               ...
+                               <SourceLine .../>
+                       </BugInstance>
+                       
+                       The primary location for a bug is given by the <Method> with no role attribute, 
+                       but the <SourceLine/> inside that method describes the whole range of lines 
+                       covered by that Method, not the spot where the bug is located--that is given 
+                       by the <SourceLine/> that is a direct child fo the <BugInstance/>.
+                */
+               
+               BugMethod primaryMethod = null;
+               SourceLine primaryLine = null;
+               
+               for (BugMethod method : bug.getMethods()) {
+                       if (null != method.getRole()) {
+                               primaryMethod = method;
+                               break;
+                       }
+               }
+               if (bug.getLines().size() > 0) {
+                       primaryLine = bug.getLines().get(0);
+               }
+               
+               if ((null != primaryMethod) && (null != primaryLine)) {
+                       locs.add(new Location(primaryMethod, primaryLine));
                }
+               
                for (BugMethod method : bug.getMethods()) {
-                       locs.add(new Location(method));
+                       if (primaryMethod != method) {
+                               locs.add(new Location(method));                         
+                       }
+               }
+               for (SourceLine line : bug.getLines()) {
+                       if (primaryLine != line) {
+                               locs.add(new Location(line));
+                       }
                }
                for (BugClass clazz : bug.getClasses()) {
                        locs.add(new Location(clazz));
@@ -117,9 +159,11 @@ public class DbStore {
        {
                Column[] columns = { CfbSchema.LOCID };
                Table[] tables = { CfbSchema.LOCATIONS };
+               
                Condition[] conditions = { 
                                                new Condition( CfbSchema.CLASSNAME,  loc.getClassName(),  Operation.EQUAL ),
                                                new Condition( CfbSchema.METHODNAME, loc.getMethodName(), Operation.EQUAL ),
+                                               new Condition( CfbSchema.METHODROLE, loc.getMethodRole(), Operation.EQUAL ),
                                                new Condition( CfbSchema.STARTLINE,  loc.getStart(),      Operation.EQUAL ),
                                                new Condition( CfbSchema.ENDLINE,    loc.getEnd(),        Operation.EQUAL )
                                        };
@@ -141,11 +185,80 @@ public class DbStore {
                                                        Long.valueOf(locId),
                                                        loc.getClassName(),
                                                        loc.getMethodName(),
+                                                       loc.getMethodRole(),
                                                        Long.valueOf(loc.getStart()),
                                                        Long.valueOf(loc.getEnd())
                                                } };
-               m_driver.insert(m_con, CfbSchema.LOCATIONS, values);
+               int count = m_driver.insert(m_con, CfbSchema.LOCATIONS, values);
+               if (1 != count) {
+                       return null;
+               }
                
                return Long.valueOf(locId);
        }
+       
+       Long getVarId(BugInstance bug) throws SQLException, TypeMismatchException
+       {
+               if (null == bug) {
+                       return null;
+               }
+               
+               List<LocalVariable> vars = bug.getVariables();
+               if ((null == vars) || (0 == vars.size())) {
+                       return null;
+               }
+               
+               return getVarId(vars.get(0));
+       }
+       
+       Long getVarId(LocalVariable var) throws SQLException, TypeMismatchException
+       {
+               if (null == var) {
+                       return null;
+               }
+               
+               Long result = findVarId(var);
+               
+               if (null != result) {
+                       return result;
+               }
+               
+               return storeVar(var);
+       }
+       
+       Long findVarId(LocalVariable var) throws SQLException, TypeMismatchException
+       {
+               Column[] columns = { CfbSchema.VARID_PK };
+               Table[] tables = { CfbSchema.VARIABLES };
+               
+               Condition[] conditions = { 
+                                               new Condition( CfbSchema.NAME,    var.getName(), Operation.EQUAL ),
+                                               new Condition( CfbSchema.VARROLE, var.getRole(), 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 null;    // not found
+       }
+       
+       Long storeVar(LocalVariable var) throws SQLException
+       {
+               long varId = m_driver.nextVal(m_con, CfbSchema.VARIABLE_SEQ);
+               
+               Object[][] values = { { 
+                                                       Long.valueOf(varId),
+                                                       var.getName(),
+                                                       var.getRole()
+                                               } };
+               int count = m_driver.insert(m_con, CfbSchema.VARIABLES, values);
+               if (1 != count) {
+                       return null;
+               }
+               
+               return Long.valueOf(varId);
+       }
 }
index 2cd91c80f70e5a81c5f5df4e8b00f97b55cd954b..1ffc7322522635999440f45ce8a10920884173f1 100644 (file)
@@ -7,6 +7,7 @@ import net.jaekl.cfb.xml.SourceLine;
 public class Location {
        String m_className;
        String m_methodName;
+       String m_methodRole;
        int m_startLine;
        int m_endLine;
        
@@ -20,6 +21,15 @@ public class Location {
                init(method.getSourceLines());
                m_className = method.getClassName();
                m_methodName = method.getMethodName();
+               m_methodRole = method.getRole();
+       }
+       
+       public Location(BugMethod method, SourceLine sourceLine)
+       {
+               init(sourceLine);
+               m_className = method.getClassName();
+               m_methodName = method.getMethodName();
+               m_methodRole = method.getRole();
        }
        
        public Location(BugClass bugClass)
@@ -30,6 +40,7 @@ public class Location {
        
        public String getClassName() { return m_className; }
        public String getMethodName() { return m_methodName; }
+       public String getMethodRole() { return m_methodRole; }
        public int getStart() { return m_startLine; }
        public int getEnd() { return m_endLine; }
        
@@ -45,6 +56,7 @@ public class Location {
        {
                m_className = sourceLine.getClassName();
                m_methodName = null;
+               m_methodRole = null;
                m_startLine = sourceLine.getStart();
                m_endLine = sourceLine.getEnd();
        }
index 4c78f8d5606d62ed6ab991e3248236801ac94ab5..3386e3f70fd2d47da0d820e174c617f5592e73b5 100644 (file)
@@ -44,6 +44,7 @@ public class BugInstance extends ParseResult {
        public List<BugClass> getClasses() { return Collections.unmodifiableList(m_classes); }
        public List<BugMethod> getMethods() { return Collections.unmodifiableList(m_methods); }
        public List<SourceLine> getLines() { return Collections.unmodifiableList(m_lines); }
+       public List<LocalVariable> getVariables() { return Collections.unmodifiableList(m_locals); }
        
        @Override
        public void endContents(String uri, String localName, String qName, String chars) 
index 33c615a858780cd79c0f76a5fe9d49412b0aa692..4e5fc47ceb6f1c6c4c61fdcf45975cb9a0f449ef 100644 (file)
@@ -39,6 +39,7 @@ public class BugMethod extends ParseResult {
        
        public String getClassName() { return m_className; }
        public String getMethodName() { return m_methodName; }
+       public String getRole() { return m_role; }
        public SourceLine[] getSourceLines() { return m_sourceLines.toArray(new SourceLine[m_sourceLines.size()]); }
        
        @Override
index fb198688068f58353ed80c3dd93bdbb65d4db1a1..a4d26d81b194043416c7b1f219b17e654ed025f6 100644 (file)
@@ -26,6 +26,9 @@ public class LocalVariable extends ParseResult {
                m_name = m_role = null;
        }
        
+       public String getName() { return m_name; }
+       public String getRole() { return m_role; }
+       
        @Override
        public void handleMainAttributes(Attributes attr)
                throws MissingAttributeException