001: /*
002: * FindBugs - Find bugs in Java programs
003: * Copyright (C) 2003,2004 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;
021:
022: /**
023: * Format the message for a BugInstance.
024: * This class works in much the same way as <code>java.text.MessageFormat</code>;
025: * however, each placeholder may have an optional "key" which specifies
026: * how the object at that position should be formatted.
027: * <p/>
028: * <p> Example:
029: * <pre>
030: * new FindBugsMessageFormat("BUG: {1} does something bad to field {2.fullField}")
031: * </pre>
032: * In this example, the method annotation at position 1 is formatted using
033: * the empty (default) key. The field annotation at position 2 is formatted
034: * using the "fullField" key, which uses the long format for the field rather
035: * than the usual "class.fieldname" format.
036: *
037: * @author David Hovemeyer
038: * @see BugInstance
039: */
040: public class FindBugsMessageFormat {
041: private String pattern;
042:
043: /**
044: * Constructor.
045: *
046: * @param pattern the pattern for the message
047: */
048: public FindBugsMessageFormat(String pattern) {
049: this .pattern = pattern;
050: }
051:
052: /**
053: * Format the message using the given array of BugAnnotations as arguments
054: * to bind to the placeholders in the pattern string.
055: *
056: * @param args the BugAnnotations used as arguments
057: * @param primaryClass TODO
058: * @return the formatted message
059: */
060: public String format(BugAnnotation[] args,
061: ClassAnnotation primaryClass) {
062: String pat = pattern;
063: StringBuffer result = new StringBuffer();
064:
065: while (pat.length() > 0) {
066: int subst = pat.indexOf('{');
067: if (subst < 0) {
068: result.append(pat);
069: break;
070: }
071:
072: result.append(pat.substring(0, subst));
073: pat = pat.substring(subst + 1);
074:
075: int end = pat.indexOf('}');
076: if (end < 0)
077: throw new IllegalStateException("bad pattern "
078: + pattern);
079:
080: String substPat = pat.substring(0, end);
081:
082: int dot = substPat.indexOf('.');
083: String key = "";
084: if (dot >= 0) {
085: key = substPat.substring(dot + 1);
086: substPat = substPat.substring(0, dot);
087: }
088:
089: int fieldNum;
090: try {
091: fieldNum = Integer.parseInt(substPat);
092: } catch (NumberFormatException e) {
093: throw new IllegalArgumentException("bad pattern "
094: + pattern);
095: }
096:
097: // System.out.println("fn: " + fieldNum);
098: if (fieldNum < 0) {
099: result.append("?<?" + fieldNum + "/" + args.length
100: + "???");
101: } else if (fieldNum >= args.length) {
102: result.append("?>?" + fieldNum + "/" + args.length
103: + "???");
104: } else {
105: BugAnnotation field = args[fieldNum];
106: String formatted = "";
107: try {
108: formatted = field.format(key, primaryClass);
109: } catch (IllegalArgumentException iae) {
110: // unknown key -- not unprecedented when reading xml generated by older versions of findbugs
111: formatted = "\u00BF" + fieldNum + ".(key=" + key
112: + ")?"; // "\u00BF" is inverted question mark
113: // System.err.println(iae.getMessage()+" in FindBugsMessageFormat"); // FIXME: log this error better
114: }
115: result.append(formatted);
116: }
117:
118: pat = pat.substring(end + 1);
119: }
120:
121: return result.toString();
122: }
123: }
124:
125: // vim:ts=4
|