📄 bughistory.java
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003-2005, 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.BufferedOutputStream;import java.io.BufferedReader;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.util.Collection;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.LinkedList;import java.util.List;import java.util.Set;import java.util.TreeSet;import java.util.Map.Entry;import org.dom4j.DocumentException;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.FuzzyBugComparator;import edu.umd.cs.findbugs.Project;import edu.umd.cs.findbugs.SloppyBugComparator;import edu.umd.cs.findbugs.SortedBugCollection;import edu.umd.cs.findbugs.VersionInsensitiveBugComparator;import edu.umd.cs.findbugs.WarningComparator;import edu.umd.cs.findbugs.config.CommandLine;import edu.umd.cs.findbugs.model.MovedClassMap;import edu.umd.cs.findbugs.util.Util;/** * Analyze bug results to find new, fixed, and retained bugs * between versions of the same program. Uses VersionInsensitiveBugComparator * (or FuzzyBugComparator) * to determine when two BugInstances are the "same". * The new BugCollection returned is a deep copy of one of the input collections * (depending on the operation performed), with only a subset of the original * BugInstances retained. Because it is a deep copy, it may be freely modified. * * @author David Hovemeyer */@Deprecatedpublic class BugHistory { private static final boolean DEBUG = false; private static class BugCollectionAndProject { SortedBugCollection bugCollection; Project project; public BugCollectionAndProject(SortedBugCollection bugCollection, Project project) { this.bugCollection = bugCollection; this.project = project; } /** * @return Returns the bugCollection. */ public SortedBugCollection getBugCollection() { return bugCollection; } /** * @return Returns the project. */ public Project getProject() { return project; } } /** * Cache of BugCollections and Projects for when we're operating in bulk mode. * If the pairs of files form a chronological sequence, then we won't have to * repeatedly perform I/O. */ private static class BugCollectionAndProjectCache extends LinkedHashMap<String,BugCollectionAndProject> { private static final long serialVersionUID = 1L; // 2 should be sufficient if the pairs are sorted private static final int CACHE_SIZE = 5; /* (non-Javadoc) * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) */ @Override protected boolean removeEldestEntry(Entry<String, BugCollectionAndProject> eldest) { return size() > CACHE_SIZE; } /** * Fetch an entry, reading it if necessary. * * @param fileName file to get * @return the BugCollectionAndProject for the file * @throws IOException * @throws DocumentException */ public BugCollectionAndProject fetch(String fileName) throws IOException, DocumentException { BugCollectionAndProject result = get(fileName); if (result == null) { Project project = new Project(); SortedBugCollection bugCollection = readCollection(fileName, project); result = new BugCollectionAndProject(bugCollection, project); put(fileName, result); } return result; } } /** * A set operation between two bug collections. */ public interface SetOperation { /** * Perform the set operation. * * @param result Set to put the resulting BugInstances in * @param origCollection original BugCollection * @param newCollection new BugCollection * @return the input bug collection the results are taken from */ public SortedBugCollection perform(Set<BugInstance> result, SortedBugCollection origCollection, SortedBugCollection newCollection); } /** * Get the warnings which were <em>added</em>, * meaning that they were not part of the original BugCollection. * The BugInstances returned are from the new BugCollection. */ public static final SetOperation ADDED_WARNINGS = new SetOperation(){ public SortedBugCollection perform(Set<BugInstance> result, SortedBugCollection origCollection, SortedBugCollection newCollection) { result.addAll(newCollection.getCollection()); // Get shared instances List<BugInstance> inBoth = getSharedInstances(result, origCollection); // Remove the shared instances from the result removeBugInstances(result, inBoth); return newCollection; } }; /** * Get the warnings which were <em>retained</em>, * meaning that they occur in both the original and new BugCollections. * The BugInstances returned are from the new BugCollection. */ public static final SetOperation RETAINED_WARNINGS = new SetOperation(){ public SortedBugCollection perform(Set<BugInstance> result, SortedBugCollection origCollection, SortedBugCollection newCollection) { result.addAll(newCollection.getCollection()); if (DEBUG) System.out.println(result.size() + " instances initially"); // Get shared instances List<BugInstance> inBoth = getSharedInstances(result, origCollection); // Replace instances with only those shared replaceBugInstances(result, inBoth); if (DEBUG) System.out.println(result.size() + " after retaining new instances"); return newCollection; } }; /** * Get the warnings which were <em>removed</em>, * meaning that they occur in the original BugCollection but not in * the new BugCollection. * The BugInstances returned are from the original BugCollection. */ public static final SetOperation REMOVED_WARNINGS = new SetOperation(){ public SortedBugCollection perform(Set<BugInstance> result, SortedBugCollection origCollection, SortedBugCollection newCollection) { result.addAll(origCollection.getCollection()); // Get shared instances List<BugInstance> inBoth = getSharedInstances(result, newCollection); // Remove shared instances removeBugInstances(result, inBoth); return origCollection; } }; private SortedBugCollection origCollection, newCollection; private SortedBugCollection resultCollection; private SortedBugCollection originator; private WarningComparator comparator; /** * Contructor. * * @param origCollection the original BugCollection * @param newCollection the new BugCollection */ public BugHistory(SortedBugCollection origCollection, SortedBugCollection newCollection) { this.origCollection = origCollection; this.newCollection = newCollection; } /** * Get the Comparator used to compare BugInstances from different BugCollections. */ public WarningComparator getComparator() { return comparator; } /** * @param comparator The comparator to set. */ public void setComparator(WarningComparator comparator) { this.comparator = comparator; } /** * Perform a SetOperation. * * @param operation the SetOperation * @return the BugCollection resulting from performing the SetOperation */ public SortedBugCollection performSetOperation(SetOperation operation) { // Create a result set which uses the version-insensitive/fuzzy bug comparator. // This will help figure out which bug instances are the "same" // between versions. TreeSet<BugInstance> result = new TreeSet<BugInstance>(getComparator()); // Perform the operation, keeping track of which input BugCollection // should be cloned for metadata. originator = operation.perform(result, origCollection, newCollection); // Clone the actual BugInstances selected by the set operation. Collection<BugInstance> selected = new LinkedList<BugInstance>(); SortedBugCollection.cloneAll(selected, result); // Duplicate the collection from which the results came, // in order to copy all metadata, such as analysis errors, // class/method hashes, etc. SortedBugCollection resultCollection = originator.duplicate(); // Replace with just the cloned instances of the subset selected by the set operation. resultCollection.clearBugInstances(); resultCollection.addAll(selected); this.resultCollection = resultCollection; return resultCollection; } /** * @return Returns the originator. */ public SortedBugCollection getOriginator() { return originator; } /** * @return Returns the origCollection. */ public SortedBugCollection getOrigCollection() { return origCollection; } /** * @return Returns the newCollection. */ public SortedBugCollection getNewCollection() { return newCollection; } /** * @return Returns the result. */ public SortedBugCollection getResultCollection() { return resultCollection; } public void writeResultCollection(Project origProject, Project newProject, OutputStream outputStream) throws IOException { getResultCollection().writeXML( outputStream, getOriginator() == getOrigCollection() ? origProject : newProject); } /** * Get instances shared between given Set and BugCollection. * The Set is queried for membership, because it has a special Comparator * which can match BugInstances from different versions. * * @param result the Set * @param collection the BugCollection * @return List of shared instances */ private static List<BugInstance> getSharedInstances(Set<BugInstance> result, SortedBugCollection collection) { List<BugInstance> inBoth = new LinkedList<BugInstance>(); for (Iterator<BugInstance> i = collection.iterator(); i.hasNext();) { BugInstance origBugInstance = i.next(); if (result.contains(origBugInstance)) { inBoth.add(origBugInstance); } } return inBoth; } /** * Replace all of the BugInstances in given Set with the given Collection. * * @param dest the Set to replace the instances of * @param source the Collection containing the instances to put in the Set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -