1 19 20 package edu.umd.cs.findbugs; 21 22 import java.io.BufferedInputStream ; 23 import java.io.BufferedOutputStream ; 24 import java.io.BufferedReader ; 25 import java.io.ByteArrayInputStream ; 26 import java.io.File ; 27 import java.io.FileInputStream ; 28 import java.io.FileOutputStream ; 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.io.InputStreamReader ; 32 import java.io.OutputStream ; 33 import java.io.Reader ; 34 import java.io.StringWriter ; 35 import java.math.BigInteger ; 36 import java.security.MessageDigest ; 37 import java.util.Collection ; 38 import java.util.Comparator ; 39 import java.util.HashMap ; 40 import java.util.HashSet ; 41 import java.util.Iterator ; 42 import java.util.LinkedList ; 43 import java.util.List ; 44 import java.util.Map ; 45 import java.util.Set ; 46 import java.util.SortedSet ; 47 import java.util.TreeMap ; 48 import java.util.TreeSet ; 49 import java.util.zip.GZIPInputStream ; 50 51 import javax.xml.transform.TransformerException ; 52 53 import org.dom4j.Document; 54 import org.dom4j.DocumentException; 55 import org.dom4j.DocumentFactory; 56 import org.xml.sax.InputSource ; 57 import org.xml.sax.SAXException ; 58 import org.xml.sax.SAXParseException ; 59 import org.xml.sax.XMLReader ; 60 import org.xml.sax.helpers.XMLReaderFactory ; 61 62 import edu.umd.cs.findbugs.annotations.CheckForNull; 63 import edu.umd.cs.findbugs.ba.MissingClassException; 64 import edu.umd.cs.findbugs.model.ClassFeatureSet; 65 import edu.umd.cs.findbugs.xml.Dom4JXMLOutput; 66 import edu.umd.cs.findbugs.xml.OutputStreamXMLOutput; 67 import edu.umd.cs.findbugs.xml.XMLAttributeList; 68 import edu.umd.cs.findbugs.xml.XMLOutput; 69 import edu.umd.cs.findbugs.xml.XMLOutputUtil; 70 71 79 public class SortedBugCollection implements BugCollection { 80 long analysisTimestamp = System.currentTimeMillis(); 81 private boolean withMessages = false; 82 private static final boolean REPORT_SUMMARY_HTML = 83 SystemProperties.getBoolean("findbugs.report.SummaryHTML"); 84 85 public long getAnalysisTimestamp() { 86 return analysisTimestamp; 87 } 88 89 public void setAnalysisTimestamp(long timestamp) { 90 analysisTimestamp = timestamp; 91 } 92 93 99 public void addAll(Collection <BugInstance> collection) { 100 for (BugInstance aCollection : collection) { 101 add(aCollection); 102 } 103 } 104 105 112 public void addAll(Collection <BugInstance> collection, boolean updateActiveTime) { 113 for (BugInstance warning : collection) { 114 add(warning, updateActiveTime); 115 } 116 } 117 118 126 public boolean add(BugInstance bugInstance) { 127 return add(bugInstance, true); 128 } 129 130 135 public void addError(String message) { 136 addError(message, null); 137 } 138 139 142 public AppVersion getCurrentAppVersion() { 143 return new AppVersion(getSequenceNumber()) 144 .setReleaseName(getReleaseName()) 145 .setTimestamp(getTimestamp()) 146 .setNumClasses(getProjectStats().getNumClasses()) 147 .setCodeSize(getProjectStats().getCodeSize()); 148 } 149 150 157 public void readXML(String fileName, Project project) 158 throws IOException , DocumentException { 159 try { 160 InputStream in = new BufferedInputStream (new FileInputStream (fileName)); 161 if (fileName.endsWith(".gz")) 162 in = new GZIPInputStream (in); 163 readXML(in, project); 164 } catch (IOException e) { 165 IOException e2 = new IOException ("Error reading " + fileName + ": " + e.getMessage()); 166 e2.setStackTrace(e.getStackTrace()); 167 throw e2; 168 } 169 } 170 171 178 public void readXML(File file, Project project) 179 throws IOException , DocumentException { 180 InputStream in = new BufferedInputStream (new FileInputStream (file)); 181 if (file.getName().endsWith(".gz")) 182 in = new GZIPInputStream (in); 183 readXML(in, project); 184 } 185 186 195 public void readXML(InputStream in, Project project) 196 throws IOException , DocumentException { 197 if (in == null) throw new IllegalArgumentException (); 198 199 try { 200 if (project == null) throw new IllegalArgumentException (); 201 doReadXML(in, project); 202 } finally { 203 in.close(); 204 } 205 } 206 207 private void doReadXML(InputStream in, Project project) throws IOException , DocumentException { 208 209 checkInputStream(in); 210 211 try { 212 SAXBugCollectionHandler handler = new SAXBugCollectionHandler(this, project); 213 214 215 XMLReader xr = null; 216 if (false) try { xr = XMLReaderFactory.createXMLReader(); 218 } catch (SAXException e) { 219 System.err.println(e.getMessage()); 220 } 221 222 if (xr == null) { 223 xr = new org.dom4j.io.aelfred.SAXDriver(); 225 } 226 xr.setContentHandler(handler); 227 xr.setErrorHandler(handler); 228 229 Reader reader = new InputStreamReader (in); 230 231 xr.parse(new InputSource (reader)); 232 } catch (SAXParseException e) { 233 throw new DocumentException("Parse error at line " + e.getLineNumber() 234 + " : " + e.getColumnNumber(), e); 235 } catch (SAXException e) { 236 throw new DocumentException("Sax error ", e); 238 } 239 240 project.setModified(false); 242 } 243 244 250 public void writeXML(String fileName, Project project) throws IOException { 251 BufferedOutputStream out = new BufferedOutputStream (new FileOutputStream (fileName)); 252 writeXML(out, project); 253 } 254 255 261 public void writeXML(File file, Project project) throws IOException { 262 BufferedOutputStream out = new BufferedOutputStream (new FileOutputStream (file)); 263 writeXML(out, project); 264 } 265 266 272 public Document toDocument(Project project) { 273 DocumentFactory docFactory = new DocumentFactory(); 274 Document document = docFactory.createDocument(); 275 Dom4JXMLOutput treeBuilder = new Dom4JXMLOutput(document); 276 277 try { 278 writeXML(treeBuilder, project); 279 } catch (IOException e) { 280 } 282 283 return document; 284 } 285 286 293 public void writeXML(OutputStream out, Project project) throws IOException { 294 XMLOutput xmlOutput; 295 if (withMessages) xmlOutput= new OutputStreamXMLOutput(out, "http://findbugs.sourceforge.net/xsl/default.xsl"); 296 else xmlOutput= new OutputStreamXMLOutput(out); 297 298 writeXML(xmlOutput, project); 299 } 300 301 public void writePrologue(XMLOutput xmlOutput, Project project) throws IOException { 302 xmlOutput.beginDocument(); 303 xmlOutput.openTag(ROOT_ELEMENT_NAME, 304 new XMLAttributeList() 305 .addAttribute("version",Version.RELEASE) 306 .addAttribute("sequence",String.valueOf(getSequenceNumber())) 307 .addAttribute("timestamp", String.valueOf(getTimestamp())) 308 .addAttribute("analysisTimestamp", String.valueOf(getAnalysisTimestamp())) 309 310 .addAttribute("release", getReleaseName()) 311 ); 312 project.writeXML(xmlOutput); 313 } 314 315 private String getQuickInstanceHash(BugInstance bugInstance) { 316 String hash = bugInstance.getInstanceHash(); 317 if (hash != null) return hash; 318 MessageDigest digest = null; 319 try { digest = MessageDigest.getInstance("MD5"); 320 } catch (Exception e2) { 321 assert true; 323 } 324 hash = bugInstance.getInstanceKey(); 325 if (digest != null) { 326 byte [] data = digest.digest(hash.getBytes()); 327 String tmp = new BigInteger (1,data).toString(16); 328 if (false) System.out.println(hash + " -> " + tmp); 329 hash = tmp; 330 } 331 bugInstance.setInstanceHash(hash); 332 return hash; 333 } 334 335 public void computeBugHashes() { 336 if (preciseHashOccurrenceNumbersAvailable) return; 337 invalidateHashes(); 338 MessageDigest digest = null; 339 try { digest = MessageDigest.getInstance("MD5"); 340 } catch (Exception e2) { 341 } 343 344 HashMap <String , Integer > seen = new HashMap <String , Integer >(); 345 346 for(BugInstance bugInstance : getCollection()) { 347 String hash = bugInstance.getInstanceHash(); 348 if (hash == null) { 349 hash = bugInstance.getInstanceKey(); 350 351 if (digest != null) { 352 byte [] data = digest.digest(hash.getBytes()); 353 String tmp = new BigInteger (1,data).toString(16); 354 if (false) System.out.println(hash + " -> " + tmp); 355 hash = tmp; 356 } 357 bugInstance.setInstanceHash(hash); 358 } 359 Integer count = seen.get(hash); 360 if (count == null) { 361 bugInstance.setInstanceOccurrenceNum(0); 362 seen.put(hash,0); 363 } else { 364 bugInstance.setInstanceOccurrenceNum(count+1); 365 seen.put(hash, count+1); 366 } 367 } 368 for(BugInstance bugInstance : getCollection()) 369 bugInstance.setInstanceOccurrenceMax(seen.get(bugInstance.getInstanceHash())); 370 preciseHashOccurrenceNumbersAvailable = true; 371 } 372 385 public void writeXML(XMLOutput xmlOutput, Project project) throws IOException { 386 try { 387 writePrologue(xmlOutput, project); 388 if (withMessages) computeBugHashes(); 389 390 for(BugInstance bugInstance : getCollection()) 392 bugInstance.writeXML(xmlOutput, withMessages); 393 394 writeEpilogue(xmlOutput); 395 } finally { 396 xmlOutput.finish(); 397 } 398 } 399 400 public void writeEpilogue(XMLOutput xmlOutput) throws IOException { 401 if (withMessages) { 402 writeBugCategories( xmlOutput); 403 writeBugPatterns( xmlOutput); 404 writeBugCodes( xmlOutput); 405 } 406 emitErrors(xmlOutput); 408 409 getProjectStats().writeXML(xmlOutput); 411 412 420 xmlOutput.openTag("ClassFeatures"); 422 for (Iterator <ClassFeatureSet> i = classFeatureSetIterator(); i.hasNext();) { 423 ClassFeatureSet classFeatureSet = i.next(); 424 classFeatureSet.writeXML(xmlOutput); 425 } 426 xmlOutput.closeTag("ClassFeatures"); 427 428 xmlOutput.openTag(HISTORY_ELEMENT_NAME); 430 for (Iterator <AppVersion> i = appVersionIterator(); i.hasNext();) { 431 AppVersion appVersion = i.next(); 432 appVersion.writeXML(xmlOutput); 433 } 434 xmlOutput.closeTag(HISTORY_ELEMENT_NAME); 435 436 if ( REPORT_SUMMARY_HTML ) { 438 String html = getSummaryHTML(); 439 if (html != null && !html.equals("")) { 440 xmlOutput.openTag(SUMMARY_HTML_ELEMENT_NAME); 441 xmlOutput.writeCDATA(html); 442 xmlOutput.closeTag(SUMMARY_HTML_ELEMENT_NAME); 443 } 444 } 445 446 xmlOutput.closeTag(ROOT_ELEMENT_NAME); 447 } 448 449 private void writeBugPatterns(XMLOutput xmlOutput) throws IOException { 450 Set <String > bugTypeSet = new HashSet <String >(); 452 for (Iterator <BugInstance> i = iterator(); i.hasNext();) { 453 BugInstance bugInstance = i.next(); 454 BugPattern bugPattern = bugInstance.getBugPattern(); 455 if (bugPattern != null) { 456 bugTypeSet.add(bugPattern.getType()); 457 } 458 } 459 for (String bugType : bugTypeSet) { 461 BugPattern bugPattern = I18N.instance().lookupBugPattern(bugType); 462 if (bugPattern == null) 463 continue; 464 465 XMLAttributeList attributeList = new XMLAttributeList(); 466 attributeList.addAttribute("type", bugType); 467 attributeList.addAttribute("abbrev", bugPattern.getAbbrev()); 468 attributeList.addAttribute("category", bugPattern.getCategory()); 469 470 xmlOutput.openTag("BugPattern", attributeList); 471 472 xmlOutput.openTag("ShortDescription"); 473 xmlOutput.writeText(bugPattern.getShortDescription()); 474 xmlOutput.closeTag("ShortDescription"); 475 476 xmlOutput.openTag("Details"); 477 xmlOutput.writeCDATA(bugPattern.getDetailText()); 478 xmlOutput.closeTag("Details"); 479 480 xmlOutput.closeTag("BugPattern"); 481 } 482 } 483 484 private void writeBugCodes(XMLOutput xmlOutput) throws IOException { 485 Set <String > bugCodeSet = new HashSet <String >(); 487 for (Iterator <BugInstance> i = iterator(); i.hasNext();) { 488 BugInstance bugInstance = i.next(); 489 String bugCode = bugInstance.getAbbrev(); 490 if (bugCode != null) { 491 bugCodeSet.add(bugCode); 492 } 493 } 494 for (String bugCode : bugCodeSet) { 496 String bugCodeDescription = I18N.instance().getBugTypeDescription(bugCode); 497 if (bugCodeDescription == null) 498 continue; 499 500 XMLAttributeList attributeList = new XMLAttributeList(); 501 attributeList.addAttribute("abbrev", bugCode); 502 503 xmlOutput.openTag("BugCode", attributeList); 504 505 xmlOutput.openTag("Description"); 506 xmlOutput.writeText(bugCodeDescription); 507 xmlOutput.closeTag("Description"); 508 509 xmlOutput.closeTag("BugCode"); 510 } 511 } 512 513 private void writeBugCategories(XMLOutput xmlOutput) throws IOException { 514 Set <String > bugCatSet = new HashSet <String >(); 516 for (Iterator <BugInstance> i = iterator(); i.hasNext();) { 517 BugInstance bugInstance = i.next(); 518 BugPattern bugPattern = bugInstance.getBugPattern(); 519 if (bugPattern != null) { 520 bugCatSet.add(bugPattern.getCategory()); 521 } 522 } 523 for (String bugCat : bugCatSet) { 525 String bugCatDescription = I18N.instance().getBugCategoryDescription(bugCat); 526 if (bugCatDescription == null) 527 continue; 528 529 XMLAttributeList attributeList = new XMLAttributeList(); 530 attributeList.addAttribute("category", bugCat); 531 532 xmlOutput.openTag("BugCategory", attributeList); 533 534 xmlOutput.openTag("Description"); 535 xmlOutput.writeText(bugCatDescription); 536 xmlOutput.closeTag("Description"); 537 538 xmlOutput.closeTag("BugCategory"); 539 } 540 } 541 542 private void emitErrors(XMLOutput xmlOutput) throws IOException { 543 545 xmlOutput.openTag(ERRORS_ELEMENT_NAME); 546 547 for (Iterator <AnalysisError> i = errorIterator(); i.hasNext(); ) { 549 AnalysisError error = i.next(); 550 xmlOutput.openTag(ERROR_ELEMENT_NAME); 551 552 xmlOutput.openTag(ERROR_MESSAGE_ELEMENT_NAME); 553 xmlOutput.writeText(error.getMessage()); 554 xmlOutput.closeTag(ERROR_MESSAGE_ELEMENT_NAME); 555 556 if (error.getExceptionMessage() != null) { 557 xmlOutput.openTag(ERROR_EXCEPTION_ELEMENT_NAME); 558 xmlOutput.writeText(error.getExceptionMessage()); 559 xmlOutput.closeTag(ERROR_EXCEPTION_ELEMENT_NAME); 560 } 561 562 String stackTrace[] = error.getStackTrace(); 563 if (stackTrace != null) { 564 for (String aStackTrace : stackTrace) { 565 xmlOutput.openTag(ERROR_STACK_TRACE_ELEMENT_NAME); 566 xmlOutput.writeText(aStackTrace); 567 xmlOutput.closeTag(ERROR_STACK_TRACE_ELEMENT_NAME); 568 } 569 } 570 571 xmlOutput.closeTag(ERROR_ELEMENT_NAME); 572 } 573 574 XMLOutputUtil.writeElementList(xmlOutput, MISSING_CLASS_ELEMENT_NAME, 576 missingClassIterator()); 577 578 xmlOutput.closeTag(ERRORS_ELEMENT_NAME); 579 } 580 581 private void checkInputStream(InputStream in) throws IOException { 582 if (in.markSupported()) { 583 byte[] buf = new byte[200]; 584 in.mark(buf.length); 585 586 int numRead = 0; 587 while (numRead < buf.length) { 588 int n = in.read(buf, numRead, buf.length - numRead); 589 if (n < 0) 590 throw new IOException ("XML does not contain saved bug data"); 591 numRead += n; 592 } 593 594 in.reset(); 595 596 BufferedReader reader = new BufferedReader (new InputStreamReader (new ByteArrayInputStream (buf))); 597 String line; 598 while ((line = reader.readLine()) != null) { 599 if (line.startsWith("<BugCollection")) 600 return; 601 } 602 603 throw new IOException ("XML does not contain saved bug data"); 604 } 605 } 606 607 614 public static void cloneAll(Collection <BugInstance> dest, Collection <BugInstance> source) { 615 for (BugInstance obj : source) { 616 dest.add((BugInstance) obj.clone()); 617 } 618 } 619 620 public static class BugInstanceComparator implements Comparator <BugInstance> { 621 private BugInstanceComparator() {} 622 public int compare(BugInstance lhs, BugInstance rhs) { 623 ClassAnnotation lca = lhs.getPrimaryClass(); 624 ClassAnnotation rca = rhs.getPrimaryClass(); 625 if (lca == null || rca == null) 626 throw new IllegalStateException ("null class annotation: " + lca + "," + rca); 627 int cmp = lca.getClassName().compareTo(rca.getClassName()); 628 if (cmp != 0) 629 return cmp; 630 return lhs.compareTo(rhs); 631 } 632 public static final BugInstanceComparator instance = new BugInstanceComparator(); 633 } 634 635 public static class MultiversionBugInstanceComparator extends BugInstanceComparator { 636 @Override 637 public int compare(BugInstance lhs, BugInstance rhs) { 638 int result = super.compare(lhs,rhs); 639 if (result != 0) return result; 640 long diff = lhs.getFirstVersion() - rhs.getFirstVersion(); 641 if (diff == 0) 642 diff = lhs.getLastVersion() - rhs.getLastVersion(); 643 if (diff < 0) return -1; 644 if (diff > 0) return 1; 645 return 0; 646 } 647 public static final MultiversionBugInstanceComparator instance = new MultiversionBugInstanceComparator(); 648 } 649 private Comparator <BugInstance> comparator; 650 private TreeSet <BugInstance> bugSet; 651 private List <AnalysisError> errorList; 652 private TreeSet <String > missingClassSet; 653 @CheckForNull private String summaryHTML; 654 private ProjectStats projectStats; 655 private Map <String , ClassFeatureSet> classFeatureSetMap; 657 private List <AppVersion> appVersionList; 658 659 660 private boolean preciseHashOccurrenceNumbersAvailable = false; 661 665 private long sequence; 666 669 private String releaseName; 670 673 private long timestamp; 674 675 679 public SortedBugCollection() { 680 this(new ProjectStats()); 681 } 682 683 687 public SortedBugCollection(Comparator <BugInstance> comparator) { 688 this(new ProjectStats(), comparator); 689 } 690 691 697 public SortedBugCollection(ProjectStats projectStats) { 698 this(projectStats, MultiversionBugInstanceComparator.instance); 699 } 700 707 public SortedBugCollection(ProjectStats projectStats, Comparator <BugInstance> comparator) { 708 this.projectStats = projectStats; 709 this.comparator = comparator; 710 bugSet = new TreeSet <BugInstance>(comparator); 711 errorList = new LinkedList <AnalysisError>(); 712 missingClassSet = new TreeSet <String >(); 713 summaryHTML = null; 714 classFeatureSetMap = new TreeMap <String , ClassFeatureSet>(); 715 sequence = 0L; 716 appVersionList = new LinkedList <AppVersion>(); 717 releaseName = ""; 718 timestamp = -1L; 719 } 720 721 public boolean add(BugInstance bugInstance, boolean updateActiveTime) { 722 preciseHashOccurrenceNumbersAvailable = false; 723 if (updateActiveTime) { 724 bugInstance.setFirstVersion(sequence); 725 } 726 727 return bugSet.add(bugInstance); 728 } 729 730 731 732 private void invalidateHashes() { 733 preciseHashOccurrenceNumbersAvailable = false; 734 } 735 public boolean remove(BugInstance bugInstance) { 736 invalidateHashes(); 737 return bugSet.remove(bugInstance); 738 } 739 740 public Iterator <BugInstance> iterator() { 741 return bugSet.iterator(); 742 } 743 744 public Collection <BugInstance> getCollection() { 745 return bugSet; 746 } 747 748 749 public void addError(String message, Throwable exception) { 750 if (exception instanceof MissingClassException) { 751 MissingClassException e = (MissingClassException) exception; 752 addMissingClass(AbstractBugReporter.getMissingClassName(e.getClassNotFoundException())); 753 return; 754 } 755 if (exception instanceof ClassNotFoundException ) { 756 ClassNotFoundException e = (ClassNotFoundException ) exception; 757 addMissingClass(AbstractBugReporter.getMissingClassName(e)); 758 return; 759 } 760 errorList.add(new AnalysisError(message, exception)); 761 } 762 763 764 public void addError(AnalysisError error) { 765 errorList.add(error); 766 } 767 768 public void addMissingClass(String className) { 769 if (className.startsWith("[")) { 770 assert false : "Bad class name " + className; 771 return; 772 } 773 missingClassSet.add(className); 774 } 775 776 public Iterator <AnalysisError> errorIterator() { 777 return errorList.iterator(); 778 } 779 780 public Iterator <String > missingClassIterator() { 781 return missingClassSet.iterator(); 782 } 783 784 public boolean contains(BugInstance bugInstance) { 785 return bugSet.contains(bugInstance); 786 } 787 788 public BugInstance getMatching(BugInstance bugInstance) { 789 SortedSet <BugInstance> tailSet = bugSet.tailSet(bugInstance); 790 if (tailSet.isEmpty()) 791 return null; 792 BugInstance first = tailSet.first(); 793 return bugInstance.equals(first) ? first : null; 794 } 795 796 public String getSummaryHTML() throws IOException { 797 if ( summaryHTML == null ) { 798 try { 799 StringWriter writer = new StringWriter (); 800 ProjectStats stats = getProjectStats(); 801 stats.transformSummaryToHTML(writer); 802 summaryHTML = writer.toString(); 803 } catch (final TransformerException e) { 804 IOException ioe = new IOException ("Couldn't generate summary HTML"); 805 ioe.initCause(e); 806 throw ioe; 807 } 808 } 809 810 return summaryHTML; 811 } 812 813 public ProjectStats getProjectStats() { 814 return projectStats; 815 } 816 817 820 @Deprecated 821 public BugInstance lookupFromUniqueId(String uniqueId) { 822 for(BugInstance bug : bugSet) 823 if (bug.getInstanceHash().equals(uniqueId)) return bug; 824 return null; 825 } 826 827 public long getSequenceNumber() { 828 return sequence; 829 } 830 831 public void setSequenceNumber(long sequence) { 832 this.sequence = sequence; 833 } 834 835 836 837 public SortedBugCollection duplicate() { 838 SortedBugCollection dup = new SortedBugCollection((ProjectStats) projectStats.clone(), comparator); 839 840 SortedBugCollection.cloneAll(dup.bugSet, this.bugSet); 841 dup.errorList.addAll(this.errorList); 842 dup.missingClassSet.addAll(this.missingClassSet); 843 dup.summaryHTML = this.summaryHTML; 844 dup.classFeatureSetMap.putAll(this.classFeatureSetMap); 846 dup.sequence = this.sequence; 847 dup.timestamp = this.timestamp; 848 dup.releaseName = this.releaseName; 849 for (AppVersion appVersion : appVersionList) { 850 dup.appVersionList.add((AppVersion) appVersion.clone()); 851 } 852 853 return dup; 854 } 855 856 859 860 public void clearBugInstances() { 861 bugSet.clear(); 862 invalidateHashes(); 863 864 } 865 866 869 870 public String getReleaseName() { 871 return releaseName; 872 } 873 874 877 878 public void setReleaseName(String releaseName) { 879 this.releaseName = releaseName; 880 } 881 882 885 886 public Iterator <AppVersion> appVersionIterator() { 887 return appVersionList.iterator(); 888 } 889 890 893 894 public void addAppVersion(AppVersion appVersion) { 895 appVersionList.add(appVersion); 896 } 897 898 901 902 public void clearAppVersions() { 903 appVersionList.clear(); 904 } 905 906 909 910 public SortedBugCollection createEmptyCollectionWithMetadata() { 911 SortedBugCollection dup = new SortedBugCollection((ProjectStats) projectStats.clone(), comparator); 912 dup.errorList.addAll(this.errorList); 913 dup.missingClassSet.addAll(this.missingClassSet); 914 dup.summaryHTML = this.summaryHTML; 915 dup.classFeatureSetMap.putAll(this.classFeatureSetMap); 916 dup.sequence = this.sequence; 917 dup.timestamp = this.timestamp; 918 dup.releaseName = this.releaseName; 919 for (AppVersion appVersion : appVersionList) { 920 dup.appVersionList.add((AppVersion) appVersion.clone()); 921 } 922 923 return dup; 924 } 925 926 929 930 public void setTimestamp(long timestamp) { 931 this.timestamp = timestamp; 932 } 933 934 937 938 public long getTimestamp() { 939 return timestamp; 940 } 941 942 945 946 public ClassFeatureSet getClassFeatureSet(String className) { 947 return classFeatureSetMap.get(className); 948 } 949 950 953 954 public void setClassFeatureSet(ClassFeatureSet classFeatureSet) { 955 classFeatureSetMap.put(classFeatureSet.getClassName(), classFeatureSet); 956 } 957 958 961 962 public Iterator <ClassFeatureSet> classFeatureSetIterator() { 963 return classFeatureSetMap.values().iterator(); 964 } 965 966 969 public void clearClassFeatures() { 970 classFeatureSetMap.clear(); 971 } 972 973 976 public void setWithMessages(boolean withMessages) { 977 this.withMessages = withMessages; 978 } 979 980 983 public boolean getWithMessages() { 984 return withMessages; 985 } 986 987 990 public AppVersion getAppVersionFromSequenceNumber(long target) { 991 for(AppVersion av : appVersionList) 992 if (av.getSequenceNumber() == target) return av; 993 if(target == this.getSequenceNumber()) 994 return this.getCurrentAppVersion(); 995 return null; 996 } 997 998 1001 public BugInstance findBug(String instanceHash, String bugType, 1002 int lineNumber) { 1003 for(BugInstance bug : bugSet) 1004 if (bug.getInstanceHash().equals(instanceHash) && bug.getBugPattern().getType().equals(bugType) 1005 && bug.getPrimarySourceLineAnnotation().getStartLine() == lineNumber) return bug; 1006 return null; 1007 } 1008} 1009 1010 | Popular Tags |