KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > gui2 > BugSet


1 /*
2  * FindBugs - Find Bugs in Java programs
3  * Copyright (C) 2006, University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA
18  */

19
20 package edu.umd.cs.findbugs.gui2;
21
22 import java.lang.management.ManagementFactory JavaDoc;
23 import java.lang.management.ThreadMXBean JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.Comparator JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32
33 import edu.umd.cs.findbugs.BugInstance;
34 import edu.umd.cs.findbugs.BugPattern;
35 import edu.umd.cs.findbugs.annotations.NonNull;
36 import edu.umd.cs.findbugs.filter.Matcher;
37 import edu.umd.cs.findbugs.gui2.BugAspects.StringPair;
38 import edu.umd.cs.findbugs.gui2.SortableStringComparator;
39
40 /**
41  * BugSet is what we use instead of SortedBugCollections. BugSet is somewhat poorly named, in that its actually a HashList of bugs,
42  * not a Set of them. (It can't be a set because we need to be able to sort it, also, HashList is great for doing contains and indexOf, its just slow for removing which we never need to do) The power of BugSet is in query. You can query a BugSet with a BugAspects, a list of StringPairs like <priority,high>, <designation,unclassified>
43  * and you will get out a new BugSet containing all of the bugs that are both high priority and unclassified. Also, after the first time a query is made, the results will come back instantly on future calls
44  * because the old queries are cached. Note that this caching can also lead to issues, problems with the BugTreeModel and the JTree getting out of sync, if there comes a time when the model and tree are out of sync
45  * but come back into sync if the tree is rebuilt, say by sorting the column headers, it probably means that resetData needs to be called on the model after doing one of its operations.
46  *
47  * @author Dan
48  *
49  */

50 public class BugSet implements Iterable JavaDoc<BugLeafNode>{
51     
52     private HashList<BugLeafNode> mainList;
53     private HashMap JavaDoc<StringPair,BugSet> doneMap;
54     private HashMap JavaDoc<StringPair,Boolean JavaDoc> doneContainsMap;
55     private HashMap JavaDoc<Sortables,HashList<String JavaDoc>> sortablesToStrings;
56     
57
58     private static BugSet mainBugSet=null;
59
60 // private ThreadMXBean bean = ManagementFactory.getThreadMXBean();
61
/** mainBugSet should probably always be the same as the data field in the current BugTreeModel
62      * we haven't run into any issues where it isn't, but if the two aren't equal using ==, problems might occur.
63      * If these problems do occur, See BugTreeModel.resetData() and perhaps adding a setAsRootAndCache() to it would fix the issue.
64      * This is not done right now for fear it might be slow.
65      */

66     public static BugSet getMainBugSet()
67     {
68         return mainBugSet;
69     }
70     
71     /**
72      * Gets all the string values out of the bugs in the set
73      * @param s The Sortables you want all values for
74      * @return all values of the sortable passed in that occur in this bugset, in order based on the sortable's compare method.
75      */

76     public String JavaDoc[] getAll(Sortables s)
77     {
78         HashList<String JavaDoc> list=sortablesToStrings.get(s);
79         Collections.sort(list, new SortableStringComparator(s));
80         return list.toArray(new String JavaDoc[list.size()]);
81     }
82
83     /**
84      * Creates a filterable dataset from the set passed in. The first time this is used is from outside to create the main data list
85      * After that BugSet will create new smaller filtered sets and store them using this method.
86      * @param filteredSet
87      */

88     BugSet(ArrayList JavaDoc<BugLeafNode> filteredSet)
89     {
90         this.mainList=new HashList<BugLeafNode>((ArrayList JavaDoc<BugLeafNode>)filteredSet.clone());
91         doneMap=new HashMap JavaDoc<StringPair,BugSet>();
92         doneContainsMap=new HashMap JavaDoc<StringPair,Boolean JavaDoc>();
93         cacheSortables();
94     }
95     
96     /**
97      * Sets the BugSet passed in to be the mainBugSet, this should always match up with the data set in the BugTreeModel
98      * @param bs
99      */

100     static void setAsRootAndCache(BugSet bs)
101     {
102         mainBugSet=bs;
103         bs.sortList();
104         bs.cacheSortables();
105     }
106     
107     /**
108      * we cache all values of each sortable that appear in the BugSet as we create it using cacheSortables, this makes it
109      * possible to only show branches that actually have bugs in them, and makes it faster by caching the results.
110      */

111     void cacheSortables()
112     {
113         sortablesToStrings=new HashMap JavaDoc<Sortables,HashList<String JavaDoc>>();
114         for (Sortables key: Sortables.values())
115             if (key != Sortables.DIVIDER)
116             {
117                 HashList<String JavaDoc> list=new HashList<String JavaDoc>();
118                 sortablesToStrings.put(key,list);
119             }
120         
121         ArrayList JavaDoc<BugLeafNode> bugNodes=new ArrayList JavaDoc<BugLeafNode>();
122         for(BugLeafNode p:mainList)
123         {
124             if (ProjectSettings.getInstance().getAllMatchers().match(p.getBug()))
125                 bugNodes.add(p);
126         }
127         
128         for (BugLeafNode b:bugNodes)
129         {
130             BugInstance bug=b.getBug();
131             BugPattern bugP=bug.getBugPattern();
132             
133             if (bugP==null)
134             {
135                 assert false;
136                 if (MainFrame.DEBUG) System.err.println("A bug pattern was not found for "+bug.getMessage());
137                 continue;
138             }
139
140             for (Sortables key: Sortables.values())
141                 if (key != Sortables.DIVIDER)
142                 {
143                     HashList<String JavaDoc> list=sortablesToStrings.get(key);
144                     
145                     String JavaDoc value=key.getFrom(bug);
146                     if (!list.contains(value))
147                         list.add(value);
148                     sortablesToStrings.put(key,list);
149                 }
150         }
151         
152         for (Sortables key: Sortables.values())
153             if (key != Sortables.DIVIDER)
154                 Collections.sort(sortablesToStrings.get(key));
155     }
156     
157     /** used to update the status bar in mainframe with the number of bugs that are filtered out */
158     static int countFilteredBugs()
159     {
160         CompoundMatcher cm=ProjectSettings.getInstance().getAllMatchers();
161         int result = 0;
162         for (BugLeafNode bug : mainBugSet.mainList)
163             if (!cm.match(bug.getBug()))
164                 result++;
165
166         return result;
167     }
168         
169     /**
170      * Copy constructor, also used to make sure things are recalculated
171      * @param copySet
172      */

173     //Note: THIS CLEARS THE CACHES OF DONE SETS!
174
BugSet(BugSet copySet)
175     {
176         this.mainList=copySet.mainList;
177         doneMap=new HashMap JavaDoc<StringPair,BugSet>();
178         doneContainsMap=new HashMap JavaDoc<StringPair,Boolean JavaDoc>();
179         cacheSortables();
180     }
181     
182
183     /**
184      * A String pair has a key and a value. The key is the general category ie: Type
185      * The value is the value ie: Malicious Code.
186      *
187      * Query looks through a BugLeafNode set with a keyValuePair to see which BugLeafNodes inside
188      * match the value under the category of key.
189      *
190      * passing in a key of Abbrev and a value of MS should return a new BugSet with all the Mutable Static bugs in the current set
191      * Note also: This query will only be performed once, and then stored and reused if the same query is used again.
192      * @param keyValuePair
193      * @return
194      */

195     BugSet query(StringPair keyValuePair)
196     {
197         if (doneMap.containsKey(keyValuePair))
198             return doneMap.get(keyValuePair);
199         ArrayList JavaDoc<BugLeafNode> bugs=new ArrayList JavaDoc<BugLeafNode>();
200         
201         for(BugLeafNode b:mainList)
202         {
203             if (b.matches(keyValuePair))
204                 bugs.add(b);
205         }
206         
207         BugSet temp=new BugSet(bugs);
208         doneMap.put(keyValuePair,temp);
209         return temp;
210     }
211
212     /* Sort the contents of the list by the Sortables in the order after the divider, if any. */
213     void sortList()
214     {
215         // Go backward through the sort order, sorting the entire list: that achieves the correct order
216
// But it takes waaaay too long.
217
final List JavaDoc<Sortables> order = MainFrame.getInstance().getSorter().getOrderAfterDivider();
218 // for (int i = order.size() - 1; i >= 0; i--)
219
// Collections.sort(mainList, order.get(i).getBugLeafNodeComparator());
220

221         Collections.sort(mainList, new Comparator JavaDoc<BugLeafNode>(){
222             public int compare(BugLeafNode one, BugLeafNode two)
223             {
224                 for (Sortables i : order)
225                 {
226                     int result = i.getBugLeafNodeComparator().compare(one, two);
227                     if (result != 0)
228                         return result;
229                 }
230                 // If still here, they're really equal
231
return 0;
232             }
233         });
234     }
235     
236     /**
237      *
238      * Contains takes a key/value pair
239      *
240      * @param keyValuePair
241      * @return true if a bug leaf from filterNoCache() matches the pair
242      */

243     public boolean contains(StringPair keyValuePair)
244     {
245         if (doneContainsMap.containsKey(keyValuePair))
246             return doneContainsMap.get(keyValuePair);
247         
248         for(BugLeafNode p:filterNoCache().mainList)
249         {
250             if (p.matches(keyValuePair))
251             {
252                 doneContainsMap.put(keyValuePair,true);
253                 return true;
254             }
255         }
256         doneContainsMap.put(keyValuePair,false);
257         return false;
258     }
259     
260     
261     /**
262      *Gives you back the BugSet containing all bugs that match your query
263      */

264     public BugSet query(BugAspects a)
265     {
266         BugSet result=this;
267         for (StringPair sp:a)
268         {
269             result=result.query(sp);
270         }
271
272         return result;
273     }
274     
275     public int sizeUnfiltered()
276     {
277         return mainList.size();
278     }
279 /*
280     public Iterator<BugLeafNode> iterator() {
281         return mainList.iterator();
282     }
283 */

284     public int indexOfUnfiltered(BugLeafNode p)
285     {
286         return mainList.indexOf(p);
287     }
288     
289     public BugLeafNode getUnfiltered(int index)
290     {
291         return mainList.get(index);
292     }
293     
294     public Iterator JavaDoc<BugLeafNode> iterator()
295     {
296         return mainList.iterator();
297     }
298     
299     ////////Filtered API
300

301     BugSet(ArrayList JavaDoc<BugLeafNode> filteredSet, boolean cacheSortables)
302     {
303         this.mainList=new HashList<BugLeafNode>((ArrayList JavaDoc<BugLeafNode>)filteredSet.clone());
304         doneMap=new HashMap JavaDoc<StringPair,BugSet>();
305         doneContainsMap=new HashMap JavaDoc<StringPair,Boolean JavaDoc>();
306         if (cacheSortables)
307             cacheSortables();
308     }
309     
310     public BugSet filterNoCache()
311     {
312         
313         Matcher m=ProjectSettings.getInstance().getAllMatchers();
314         ArrayList JavaDoc<BugLeafNode> people=new ArrayList JavaDoc<BugLeafNode>();
315         for(BugLeafNode p:mainList)
316         {
317             if (m.match(p.getBug()))
318                 people.add(p);
319         }
320         return new BugSet(people,false);
321     }
322     
323     public BugSet getBugsMatchingFilter(Matcher m)
324     {
325         ArrayList JavaDoc<BugLeafNode> people=new ArrayList JavaDoc<BugLeafNode>();
326         for(BugLeafNode p:mainList)
327         {
328             if(!(m.match(p.getBug())))
329                 people.add(p);
330         }
331         return new BugSet(people,false);
332     }
333     
334     public int size()
335     {
336         return filterNoCache().sizeUnfiltered();
337     }
338     
339     public int indexOf(BugLeafNode p)
340     {
341         return filterNoCache().indexOfUnfiltered(p);
342     }
343     
344     public BugLeafNode get(int index)
345     {
346         return filterNoCache().getUnfiltered(index);
347     }
348 }
Popular Tags