001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2006, University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA
018: */
019:
020: package edu.umd.cs.findbugs.gui2;
021:
022: import java.sql.Timestamp;
023: import java.util.Arrays;
024: import java.util.Comparator;
025: import java.util.List;
026:
027: import edu.umd.cs.findbugs.AppVersion;
028: import edu.umd.cs.findbugs.BugCollection;
029: import edu.umd.cs.findbugs.BugInstance;
030: import edu.umd.cs.findbugs.BugPattern;
031: import edu.umd.cs.findbugs.Detector;
032: import edu.umd.cs.findbugs.I18N;
033: import edu.umd.cs.findbugs.gui2.BugAspects.SortableValue;
034:
035: /**
036: * A useful enum for dealing with all the types of filterable and sortable data in BugInstances
037: * This is the preferred way for getting the information out of a BugInstance and formatting it for display
038: * It also has the comparators for the different types of data
039: *
040: * @author Reuven
041: */
042:
043: public enum Sortables implements Comparator<SortableValue> {
044:
045: FIRSTVERSION(edu.umd.cs.findbugs.L10N.getLocalString(
046: "sort.first_version", "First Version")) {
047: @Override
048: public String getFrom(BugInstance bug) {
049: return Long.toString(bug.getFirstVersion());
050: }
051:
052: @Override
053: public String formatValue(String value) {
054: int seqNum = Integer.parseInt(value);
055: BugCollection bugCollection = MainFrame.getInstance().bugCollection;
056: if (bugCollection == null)
057: return "--";
058: AppVersion appVersion = bugCollection
059: .getAppVersionFromSequenceNumber(seqNum);
060: String appendItem = "";
061: if (appVersion != null) {
062: String timestamp = new Timestamp(appVersion
063: .getTimestamp()).toString();
064: appendItem = appVersion.getReleaseName()
065: + " ("
066: + timestamp
067: .substring(0, timestamp.indexOf(' '))
068: + ")";
069: }
070: if (appendItem == "")
071: appendItem = "#" + seqNum;
072: return appendItem;
073: }
074:
075: @Override
076: public int compare(SortableValue one, SortableValue two) {
077: // Numerical (zero is first)
078: return Integer.valueOf(one.value).compareTo(
079: Integer.valueOf(two.value));
080: }
081: },
082:
083: LASTVERSION(edu.umd.cs.findbugs.L10N.getLocalString(
084: "sort.last_version", "Last Version")) {
085: @Override
086: public String getFrom(BugInstance bug) {
087: return Long.toString(bug.getLastVersion());
088: }
089:
090: @Override
091: public String formatValue(String value) {
092: //System.out.println("Formatting last version value");
093: if (value.equals("-1"))
094: return "";
095: int seqNum = Integer.parseInt(value);
096: BugCollection bugCollection = MainFrame.getInstance().bugCollection;
097: if (bugCollection == null)
098: return "--";
099: AppVersion appVersion = bugCollection
100: .getAppVersionFromSequenceNumber(seqNum);
101: String appendItem = "";
102: if (appVersion != null) {
103: String timestamp = new Timestamp(appVersion
104: .getTimestamp()).toString();
105: appendItem = appVersion.getReleaseName()
106: + " ("
107: + timestamp
108: .substring(0, timestamp.indexOf(' '))
109: + ")";
110: }
111: if (appendItem == "")
112: appendItem = "#" + seqNum;
113: return appendItem;
114: }
115:
116: @Override
117: public int compare(SortableValue one, SortableValue two) {
118: if (one.value.equals(two.value))
119: return 0;
120:
121: // Numerical (except that -1 is last)
122: int first = Integer.valueOf(one.value);
123: int second = Integer.valueOf(two.value);
124: if (first == second)
125: return 0;
126: if (first < 0)
127: return 1;
128: if (second < 0)
129: return -1;
130: if (first < second)
131: return -1;
132: return 1;
133: }
134: },
135:
136: PRIORITY(edu.umd.cs.findbugs.L10N.getLocalString("sort.priority",
137: "Priority")) {
138: @Override
139: public String getFrom(BugInstance bug) {
140: return String.valueOf(bug.getPriority());
141: }
142:
143: @Override
144: public String formatValue(String value) {
145: if (value.equals(String.valueOf(Detector.HIGH_PRIORITY)))
146: return edu.umd.cs.findbugs.L10N.getLocalString(
147: "sort.priority_high", "High");
148: if (value.equals(String.valueOf(Detector.NORMAL_PRIORITY)))
149: return edu.umd.cs.findbugs.L10N.getLocalString(
150: "sort.priority_normal", "Normal");
151: if (value.equals(String.valueOf(Detector.LOW_PRIORITY)))
152: return edu.umd.cs.findbugs.L10N.getLocalString(
153: "sort.priority_low", "Low");
154: if (value.equals(String.valueOf(Detector.EXP_PRIORITY)))
155: return edu.umd.cs.findbugs.L10N.getLocalString(
156: "sort.priority_experimental", "Experimental");
157: return edu.umd.cs.findbugs.L10N.getLocalString(
158: "sort.priority_ignore", "Ignore"); // This probably shouldn't ever happen, but what the hell, let's be complete
159:
160: }
161:
162: @Override
163: public int compare(SortableValue one, SortableValue two) {
164: // Numerical
165: return Integer.valueOf(one.value).compareTo(
166: Integer.valueOf(two.value));
167: }
168: },
169: CLASS(edu.umd.cs.findbugs.L10N
170: .getLocalString("sort.class", "Class")) {
171: @Override
172: public String getFrom(BugInstance bug) {
173: return bug.getPrimarySourceLineAnnotation().getClassName();
174: }
175:
176: @Override
177: public int compare(SortableValue one, SortableValue two) {
178: // If both have dollar signs and are of the same outer class, compare the numbers after the dollar signs.
179: try {
180: if (one.value.contains("$")
181: && two.value.contains("$")
182: && one.value.substring(0,
183: one.value.lastIndexOf("$")).equals(
184: two.value.substring(0, two.value
185: .lastIndexOf("$"))))
186: return Integer.valueOf(
187: one.value.substring(one.value
188: .lastIndexOf("$"))).compareTo(
189: Integer.valueOf(two.value
190: .substring(two.value
191: .lastIndexOf("$"))));
192: } catch (NumberFormatException e) {
193: } // Somebody's playing silly buggers with dollar signs, just do it lexicographically
194:
195: // Otherwise, lexicographicalify it
196: return one.value.compareTo(two.value);
197: }
198: },
199: PACKAGE(edu.umd.cs.findbugs.L10N.getLocalString("sort.package",
200: "Package")) {
201: @Override
202: public String getFrom(BugInstance bug) {
203: return bug.getPrimarySourceLineAnnotation()
204: .getPackageName();
205: }
206:
207: @Override
208: public String formatValue(String value) {
209: if (value.equals(""))
210: return "(Default)";
211: return value;
212: }
213: },
214: CATEGORY(edu.umd.cs.findbugs.L10N.getLocalString("sort.category",
215: "Category")) {
216: @Override
217: public String getFrom(BugInstance bug) {
218:
219: BugPattern bugPattern = bug.getBugPattern();
220: if (bugPattern == null) {
221: return "?";
222: }
223: return bugPattern.getCategory();
224: }
225:
226: @Override
227: public String formatValue(String value) {
228: return I18N.instance().getBugCategoryDescription(value);
229: }
230: },
231: DESIGNATION(edu.umd.cs.findbugs.L10N.getLocalString(
232: "sort.designation", "Designation")) {
233: @Override
234: public String getFrom(BugInstance bug) {
235: return bug.getUserDesignationKey();
236: }
237:
238: /**
239: * value is the key of the designations.
240: * @param value
241: * @return
242: */
243: @Override
244: public String formatValue(String value) {
245: return I18N.instance().getUserDesignation(value);
246: }
247:
248: @Override
249: public String[] getAllSorted() {//FIXME I think we always want user to see all possible designations, not just the ones he has set in his project, Agreement? -Dan
250: List<String> sortedDesignations = I18N.instance()
251: .getUserDesignationKeys(true);
252: return sortedDesignations
253: .toArray(new String[sortedDesignations.size()]);
254: }
255: },
256: BUGCODE(edu.umd.cs.findbugs.L10N.getLocalString("sort.bug_kind",
257: "Bug Kind")) {
258: @Override
259: public String getFrom(BugInstance bug) {
260: BugPattern bugPattern = bug.getBugPattern();
261: if (bugPattern == null)
262: return null;
263: return bugPattern.getAbbrev();
264: }
265:
266: @Override
267: public String formatValue(String value) {
268: return I18N.instance().getBugTypeDescription(value);
269: }
270:
271: @Override
272: public int compare(SortableValue one, SortableValue two) {
273: return formatValue(one.value).compareTo(
274: formatValue(two.value));
275: }
276: },
277: TYPE(edu.umd.cs.findbugs.L10N.getLocalString("sort.bug_pattern",
278: "Bug Pattern")) {
279: @Override
280: public String getFrom(BugInstance bug) {
281: if ((bug.getBugPattern()) == null)
282: return "?";
283: else
284: return bug.getBugPattern().getType();
285: }
286:
287: @Override
288: public String formatValue(String value) {
289: return I18N.instance().getShortMessageWithoutCode(value);
290: }
291: },
292: DIVIDER(" ") {
293: @Override
294: public String getFrom(BugInstance bug) {
295: throw new UnsupportedOperationException();
296: }
297:
298: @Override
299: public String[] getAll() {
300: throw new UnsupportedOperationException();
301: }
302:
303: @Override
304: public String formatValue(String value) {
305: throw new UnsupportedOperationException();
306: }
307:
308: @Override
309: public int compare(SortableValue one, SortableValue two) {
310: throw new UnsupportedOperationException();
311: }
312: };
313:
314: String prettyName;
315:
316: Sortables(String prettyName) {
317: this .prettyName = prettyName;
318: }
319:
320: @Override
321: public String toString() {
322: return prettyName;
323: }
324:
325: public abstract String getFrom(BugInstance bug);
326:
327: public String[] getAll() {
328: return getAll(BugSet.getMainBugSet());
329: }
330:
331: public String[] getAll(BugSet set) {
332: return set.getAll(this );
333: }
334:
335: public String formatValue(String value) {
336: return value;
337: }
338:
339: public int compare(SortableValue one, SortableValue two) {
340: // Lexicographical by default
341: return one.value.compareTo(two.value);
342: }
343:
344: public String[] getAllSorted() {
345: return getAllSorted(BugSet.getMainBugSet());
346: }
347:
348: public String[] getAllSorted(BugSet set) {
349: String[] values = getAll(set);
350: SortableValue[] pairs = new SortableValue[values.length];
351: for (int i = 0; i < values.length; i++)
352: pairs[i] = new SortableValue(this , values[i]);
353: Arrays.sort(pairs, this );
354: for (int i = 0; i < values.length; i++)
355: values[i] = pairs[i].value;
356: return values;
357: }
358:
359: public Comparator<BugLeafNode> getBugLeafNodeComparator() {
360: final Sortables key = this ;
361: return new Comparator<BugLeafNode>() {
362: public int compare(BugLeafNode one, BugLeafNode two) {
363: return key.compare(new SortableValue(key, key
364: .getFrom(one.getBug())), new SortableValue(key,
365: key.getFrom(two.getBug())));
366: }
367: };
368: }
369:
370: public static Sortables getSortableByPrettyName(String name) {
371: for (Sortables s : Sortables.values()) {
372: if (s.prettyName.equals(name))
373: return s;
374: }
375: return null;
376: }
377: }
|