KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > config > ProjectFilterSettings


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2004, 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.config;
21
22 import java.util.HashMap JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.Set JavaDoc;
27 import java.util.StringTokenizer JavaDoc;
28
29 import edu.umd.cs.findbugs.BugInstance;
30 import edu.umd.cs.findbugs.BugPattern;
31 import edu.umd.cs.findbugs.BugProperty;
32 import edu.umd.cs.findbugs.Detector;
33 import edu.umd.cs.findbugs.DetectorFactoryCollection;
34 import edu.umd.cs.findbugs.I18N;
35
36 /**
37  * Settings for user filtering of warnings for a project.
38  * This includes selecting particular bug categories
39  * to view, as well as a minimum warning priority.
40  * Includes support for encoding these settings as a String,
41  * which can easily be stored as a persistent project property
42  * in Eclipse.
43  *
44  * @see BugInstance
45  * @author David Hovemeyer
46  */

47 public class ProjectFilterSettings implements Cloneable JavaDoc {
48     /** Text string for high priority. */
49     public static final String JavaDoc HIGH_PRIORITY = "High";
50
51     /** Text string for medium priority. */
52     public static final String JavaDoc MEDIUM_PRIORITY = "Medium";
53
54     /** Text string for low priority. */
55     public static final String JavaDoc LOW_PRIORITY = "Low";
56     
57     /** Text string for experimental priority. */
58     public static final String JavaDoc EXPERIMENTAL_PRIORITY = "Experimental";
59
60     /** Default warning threshold priority. */
61     public static final String JavaDoc DEFAULT_PRIORITY = MEDIUM_PRIORITY;
62
63     /** Map of priority level names to their numeric values. */
64     private static Map JavaDoc<String JavaDoc, Integer JavaDoc> priorityNameToValueMap = new HashMap JavaDoc<String JavaDoc, Integer JavaDoc>();
65     static {
66         priorityNameToValueMap.put(HIGH_PRIORITY, (Integer JavaDoc)(Detector.HIGH_PRIORITY));
67         priorityNameToValueMap.put(MEDIUM_PRIORITY, (Integer JavaDoc)(Detector.NORMAL_PRIORITY));
68         priorityNameToValueMap.put(LOW_PRIORITY, (Integer JavaDoc)(Detector.LOW_PRIORITY));
69         priorityNameToValueMap.put(EXPERIMENTAL_PRIORITY, (Integer JavaDoc)(Detector.EXP_PRIORITY));
70     }
71     
72     /**
73      * The character used for delimiting whole fields in filter settings encoded as strings
74      */

75     private static String JavaDoc FIELD_DELIMITER="|";
76     /**
77      * The character used for delimiting list items in filter settings encoded as strings
78      */

79     private static String JavaDoc LISTITEM_DELIMITER=",";
80
81     // Fields
82
private Set JavaDoc<String JavaDoc> activeBugCategorySet; // not used for much: hiddenBugCategorySet has priority.
83
private Set JavaDoc<String JavaDoc> hiddenBugCategorySet;
84     private String JavaDoc minPriority;
85     private int minPriorityAsInt;
86     private boolean displayFalseWarnings;
87     
88     /**
89      * Constructor.
90      * This is not meant to be called directly; use one of the factory methods instead.
91      */

92     private ProjectFilterSettings() {
93         DetectorFactoryCollection.instance(); // ensure detectors loaded
94

95         // initially all known bug categories are active
96
this.activeBugCategorySet = new HashSet JavaDoc<String JavaDoc>( I18N.instance().getBugCategories() );
97         this.hiddenBugCategorySet = new HashSet JavaDoc<String JavaDoc>();
98         setMinPriority(DEFAULT_PRIORITY);
99         this.displayFalseWarnings = false;
100     }
101     
102     /**
103      * Factory method to create a default ProjectFilterSettings object.
104      * Uses the default warning priority threshold, and enables
105      * all bug categories.
106      *
107      * @return a default ProjectFilterSettings object
108      */

109     public static ProjectFilterSettings createDefault() {
110         ProjectFilterSettings result = new ProjectFilterSettings();
111         
112         // Set default priority threshold
113
result.setMinPriority(DEFAULT_PRIORITY);
114         
115         return result;
116     }
117
118     /**
119      * Create ProjectFilterSettings from an encoded string.
120      *
121      * @param s the encoded string
122      * @return the ProjectFilterSettings
123      */

124     public static ProjectFilterSettings fromEncodedString(String JavaDoc s) {
125         ProjectFilterSettings result = new ProjectFilterSettings();
126
127         if (s.length() > 0) {
128             int bar = s.indexOf(FIELD_DELIMITER);
129             String JavaDoc minPriority;
130             if (bar >= 0) {
131                 minPriority = s.substring(0, bar);
132                 s = s.substring(bar+1);
133             } else {
134                 minPriority = s;
135                 s = "";
136             }
137             if (priorityNameToValueMap.get(minPriority) == null)
138                 minPriority = DEFAULT_PRIORITY;
139             result.setMinPriority(minPriority);
140         }
141
142         if (s.length() > 0) {
143             int bar = s.indexOf(FIELD_DELIMITER);
144             String JavaDoc categories;
145             if (bar >= 0) {
146                 categories = s.substring(0, bar);
147                 s = s.substring(bar+1);
148             } else {
149                 categories = s;
150                 s = "";
151             }
152             StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(categories, LISTITEM_DELIMITER);
153             while (t.hasMoreTokens()) {
154                 String JavaDoc category = t.nextToken();
155                 // 'result' probably already contains 'category', since
156
// it contains all known bug category keys by default.
157
// But add it to the set anyway in case it is an unknown key.
158
result.addCategory(category);
159             }
160         }
161
162         if (s.length() > 0) {
163             int bar = s.indexOf(FIELD_DELIMITER);
164             String JavaDoc displayFalseWarnings;
165             if (bar >= 0) {
166                 displayFalseWarnings = s.substring(0, bar);
167                 s = s.substring(bar+1);
168             } else {
169                 displayFalseWarnings = s;
170                 s = "";
171             }
172             result.setDisplayFalseWarnings(Boolean.valueOf(displayFalseWarnings).booleanValue());
173         }
174         
175         if (s.length() > 0) {
176             // Can add other fields here...
177
assert true;
178         }
179     
180     
181         
182         return result;
183             
184     }
185     
186
187     /**
188      * set the hidden bug categories on the specifed ProjectFilterSettings
189      * from an encoded string
190      *
191      * @param result the ProjectFilterSettings from which to remove bug categories
192      * @param s the encoded string
193      * @see ProjectFilterSettings#hiddenFromEncodedString(ProjectFilterSettings, String)
194      */

195     public static void hiddenFromEncodedString(ProjectFilterSettings result, String JavaDoc s) {
196         
197         if (s.length() > 0) {
198             int bar = s.indexOf(FIELD_DELIMITER);
199             String JavaDoc categories;
200             if (bar >= 0) {
201                 categories = s.substring(0, bar);
202             } else {
203                 categories = s;
204             }
205             StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(categories, LISTITEM_DELIMITER);
206             while (t.hasMoreTokens()) {
207                 String JavaDoc category = t.nextToken();
208                 result.removeCategory(category);
209             }
210         }
211
212     }
213     
214
215     /**
216      * Return whether or not a warning should be displayed,
217      * according to the project filter settings.
218      *
219      * @param bugInstance the warning
220      * @return true if the warning should be displayed, false if not
221      */

222     public boolean displayWarning(BugInstance bugInstance) {
223         
224         int priority = bugInstance.getPriority();
225         if (priority > getMinPriorityAsInt())
226             return false;
227         
228         BugPattern bugPattern = bugInstance.getBugPattern();
229
230         // HACK: it is conceivable that the detector plugin which generated
231
// this warning is not available any more, in which case we can't
232
// find out the category. Let the warning be visible in this case.
233
if (bugPattern != null && !containsCategory(bugPattern.getCategory()))
234             return false;
235         
236         if (!displayFalseWarnings) {
237             boolean isFalseWarning =
238                 !Boolean.valueOf(bugInstance.getProperty(BugProperty.IS_BUG, "true")).booleanValue();
239             if (isFalseWarning)
240                 return false;
241         }
242         
243         return true;
244     }
245     
246     /**
247      * Set minimum warning priority threshold.
248      *
249      * @param minPriority the priority threshold: one of "High", "Medium", or "Low"
250      */

251     public void setMinPriority(String JavaDoc minPriority) {
252         this.minPriority = minPriority;
253         
254         Integer JavaDoc value = priorityNameToValueMap.get(minPriority);
255         if (value == null) {
256             value = priorityNameToValueMap.get(DEFAULT_PRIORITY);
257             if (value == null)
258                 throw new IllegalStateException JavaDoc();
259         }
260         
261         this.minPriorityAsInt = value.intValue();
262
263     }
264     
265     /**
266      * Get the minimum warning priority threshold.
267      *
268      * @return minimum warning priority threshold: one of "High", "Medium", or "Low"
269      */

270     public String JavaDoc getMinPriority() {
271         return this.minPriority;
272     }
273     
274     /**
275      * Return the minimum warning priority threshold as an integer.
276      *
277      * @return the minimum warning priority threshold as an integer
278      */

279     public int getMinPriorityAsInt() {
280         return minPriorityAsInt;
281     }
282
283     /**
284      * Add a bug category to the set of categories to be displayed.
285      *
286      * @param category the bug category: e.g., "CORRECTNESS"
287      */

288     public void addCategory(String JavaDoc category) {
289         this.hiddenBugCategorySet.remove(category);
290         this.activeBugCategorySet.add(category);
291     }
292
293     /**
294      * Remove a bug category from the set of categories to be displayed.
295      *
296      * @param category the bug category: e.g., "CORRECTNESS"
297      */

298     public void removeCategory(String JavaDoc category) {
299         this.hiddenBugCategorySet.add(category);
300         this.activeBugCategorySet.remove(category);
301     }
302
303     /**
304      * Clear all bug categories from the hidden list.
305      * So the effect is to enable all bug categories.
306      */

307     public void clearAllCategories() {
308         this.activeBugCategorySet.addAll(hiddenBugCategorySet);
309         this.hiddenBugCategorySet.clear();
310     }
311     
312     /**
313      * Returns false if the given category is hidden
314      * in the project filter settings.
315      *
316      * @param category the category
317      * @return false if the category is hidden, true if not
318      */

319     public boolean containsCategory(String JavaDoc category) {
320         // do _not_ consult the activeBugCategorySet: if not hidden return true.
321
return !hiddenBugCategorySet.contains(category);
322     }
323     
324     /**
325      * Return set of active (enabled) bug categories.
326      *
327      * Note that bug categories that are not explicity
328      * hidden will appear active even if they are not
329      * members of this set.
330      *
331      * @return the set of active categories
332      */

333     public Set JavaDoc<String JavaDoc> getActiveCategorySet() {
334         Set JavaDoc<String JavaDoc> result = new HashSet JavaDoc<String JavaDoc>();
335         result.addAll(this.activeBugCategorySet);
336         return result;
337     }
338
339     /**
340      * Set whether or not false warnings should be displayed.
341      *
342      * @param displayFalseWarnings true if false warnings should be displayed,
343      * false if not
344      */

345     public void setDisplayFalseWarnings(boolean displayFalseWarnings) {
346         this.displayFalseWarnings = displayFalseWarnings;
347     }
348     
349     /**
350      * Get whether or not false warnings should be displayed.
351      *
352      * @return true if false warnings should be displayed, false if not
353      */

354     public boolean displayFalseWarnings() {
355         return displayFalseWarnings;
356     }
357
358     /**
359      * Create a string containing the encoded form of the hidden bug categories
360      *
361      * @return an encoded string
362      */

363     public String JavaDoc hiddenToEncodedString() {
364         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
365         // Encode hidden bug categories
366
for (Iterator JavaDoc<String JavaDoc> i = hiddenBugCategorySet.iterator(); i.hasNext(); ) {
367             buf.append(i.next());
368             if (i.hasNext())
369                 buf.append(LISTITEM_DELIMITER);
370         }
371         buf.append(FIELD_DELIMITER);
372         
373         return buf.toString();
374     }
375
376     /**
377      * Create a string containing the encoded form of the ProjectFilterSettings.
378      *
379      * @return an encoded string
380      */

381     public String JavaDoc toEncodedString() {
382         // Priority threshold
383
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
384         buf.append(getMinPriority());
385         
386         // Encode enabled bug categories. Note that these aren't really used for much.
387
// They only come in to play when parsed by a version of FindBugs older than 1.1.
388
buf.append(FIELD_DELIMITER);
389         for (Iterator JavaDoc<String JavaDoc> i = activeBugCategorySet.iterator(); i.hasNext(); ) {
390             buf.append(i.next());
391             if (i.hasNext())
392                 buf.append(LISTITEM_DELIMITER);
393             
394         }
395         
396         // Whether to display false warnings
397
buf.append(FIELD_DELIMITER);
398         buf.append(displayFalseWarnings ? "true" : "false");
399         
400         return buf.toString();
401     }
402
403     @Override JavaDoc
404          public String JavaDoc toString() {
405         return toEncodedString();
406     }
407     
408     /* (non-Javadoc)
409      * @see java.lang.Object#equals(java.lang.Object)
410      */

411     @Override JavaDoc
412          public boolean equals(Object JavaDoc obj) {
413         if (obj == null || obj.getClass() != this.getClass())
414             return false;
415         ProjectFilterSettings other = (ProjectFilterSettings) obj;
416         
417         if (!this.getMinPriority().equals(other.getMinPriority()))
418             return false;
419
420         // don't compare the activeBugCategorySet. compare the hiddenBugCategorySet only
421
if (!this.hiddenBugCategorySet.equals(other.hiddenBugCategorySet))
422             return false;
423         
424         if (this.displayFalseWarnings != other.displayFalseWarnings)
425             return false;
426         
427         return true;
428     }
429     
430     
431     /* (non-Javadoc)
432      * @see java.lang.Object#clone()
433      */

434     @Override JavaDoc
435          public Object JavaDoc clone() {
436         try {
437             // Create shallow copy
438
ProjectFilterSettings clone = (ProjectFilterSettings) super.clone();
439             
440             // Copy field contents
441
clone.hiddenBugCategorySet = new HashSet JavaDoc<String JavaDoc>();
442             clone.hiddenBugCategorySet.addAll(this.hiddenBugCategorySet);
443             clone.activeBugCategorySet = new HashSet JavaDoc<String JavaDoc>();
444             clone.activeBugCategorySet.addAll(this.activeBugCategorySet);
445             clone.setMinPriority(this.getMinPriority());
446             clone.displayFalseWarnings = this.displayFalseWarnings;
447             
448             return clone;
449         } catch (CloneNotSupportedException JavaDoc e) {
450             // Should not happen!
451
throw new AssertionError JavaDoc(e);
452         }
453         
454     }
455     
456     /* (non-Javadoc)
457      * @see java.lang.Object#hashCode()
458      */

459     @Override JavaDoc
460          public int hashCode() {
461         return minPriority.hashCode()
462             + 1009 * hiddenBugCategorySet.hashCode()
463             + (displayFalseWarnings ? 7919 : 0);
464     }
465     
466     /**
467      * Convert an integer warning priority threshold value to
468      * a String.
469      */

470     public static String JavaDoc getIntPriorityAsString(int prio) {
471         String JavaDoc minPriority;
472         switch (prio) {
473             case Detector.EXP_PRIORITY:
474                 minPriority = ProjectFilterSettings.EXPERIMENTAL_PRIORITY;
475                 break;
476             case Detector.LOW_PRIORITY:
477                 minPriority = ProjectFilterSettings.LOW_PRIORITY;
478                 break;
479             case Detector.NORMAL_PRIORITY:
480                 minPriority = ProjectFilterSettings.MEDIUM_PRIORITY;
481                 break;
482             case Detector.HIGH_PRIORITY:
483                 minPriority = ProjectFilterSettings.HIGH_PRIORITY;
484                 break;
485             default:
486                 minPriority = ProjectFilterSettings.DEFAULT_PRIORITY;
487                 break;
488         }
489         return minPriority;
490     }
491 }
492
493 // vim:ts=4
494
Popular Tags