001: /*
002: * FindBugs - Find bugs in Java programs
003: * Copyright (C) 2003-2005, 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: import java.io.IOException;
023:
024: import edu.umd.cs.findbugs.xml.XMLAttributeList;
025: import edu.umd.cs.findbugs.xml.XMLOutput;
026:
027: /**
028: * Bug annotation class for integer values.
029: *
030: * @author William Pugh
031: * @see BugAnnotation
032: */
033: public class StringAnnotation implements BugAnnotation {
034: private static final long serialVersionUID = 1L;
035:
036: private static final String DEFAULT_ROLE = "STRING_DEFAULT";
037:
038: final private String value;
039: private String description;
040:
041: /**
042: * Constructor.
043: *
044: * @param value the String value
045: */
046: public StringAnnotation(String value) {
047: this .value = quoteCharacters(value);
048: this .description = DEFAULT_ROLE;
049: }
050:
051: @Override
052: public Object clone() {
053: try {
054: return super .clone();
055: } catch (CloneNotSupportedException e) {
056: throw new AssertionError(e);
057: }
058: }
059:
060: private static String quoteCharacters(String s) {
061: StringBuffer result = null;
062: for (int i = 0, max = s.length(), delta = 0; i < max; i++) {
063: char c = s.charAt(i);
064: String replacement = null;
065:
066: if (c == '&') {
067: replacement = "&";
068: } else if (c == '<') {
069: replacement = "<";
070: } else if (c == '\r') {
071: replacement = " ";
072: } else if (c == '>') {
073: replacement = ">";
074: } else if (c == '"') {
075: replacement = """;
076: } else if (c == '\'') {
077: replacement = "'";
078: }
079:
080: if (replacement != null) {
081: if (result == null) {
082: result = new StringBuffer(s);
083: }
084: result.replace(i + delta, i + delta + 1, replacement);
085: delta += (replacement.length() - 1);
086: }
087: }
088: if (result == null) {
089: return s;
090: }
091: return result.toString();
092: }
093:
094: /**
095: * Get the String value.
096: *
097: * @return the String value
098: */
099: public String getValue() {
100: return value;
101: }
102:
103: public void accept(BugAnnotationVisitor visitor) {
104: visitor.visitStringAnnotation(this );
105: }
106:
107: public String format(String key, ClassAnnotation primaryClass) {
108: return value;
109: }
110:
111: public void setDescription(String description) {
112: this .description = description;
113: }
114:
115: public String getDescription() {
116: return description;
117: }
118:
119: @Override
120: public int hashCode() {
121: return value.hashCode();
122: }
123:
124: @Override
125: public boolean equals(Object o) {
126: if (!(o instanceof StringAnnotation))
127: return false;
128: return value.equals(((StringAnnotation) o).value);
129: }
130:
131: public int compareTo(BugAnnotation o) {
132: if (!(o instanceof StringAnnotation)) // BugAnnotations must be Comparable with any type of BugAnnotation
133: return this .getClass().getName().compareTo(
134: o.getClass().getName());
135: return value.compareTo(((StringAnnotation) o).value);
136: }
137:
138: @Override
139: public String toString() {
140: String pattern = I18N.instance().getAnnotationDescription(
141: description);
142: FindBugsMessageFormat format = new FindBugsMessageFormat(
143: pattern);
144: return format.format(new BugAnnotation[] { this }, null);
145: }
146:
147: /* ----------------------------------------------------------------------
148: * XML Conversion support
149: * ---------------------------------------------------------------------- */
150:
151: private static final String ELEMENT_NAME = "String";
152:
153: public void writeXML(XMLOutput xmlOutput) throws IOException {
154: writeXML(xmlOutput, false);
155: }
156:
157: public void writeXML(XMLOutput xmlOutput, boolean addMessages)
158: throws IOException {
159: XMLAttributeList attributeList = new XMLAttributeList()
160: .addAttribute("value", value);
161:
162: String role = getDescription();
163: if (!role.equals(DEFAULT_ROLE))
164: attributeList.addAttribute("role", role);
165:
166: BugAnnotationUtil.writeXML(xmlOutput, ELEMENT_NAME, this ,
167: attributeList, addMessages);
168: }
169:
170: public boolean isSignificant() {
171: return true;
172: }
173: }
174:
175: // vim:ts=4
|