KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > FieldAnnotation


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2003-2005, 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;
21
22 import java.io.IOException JavaDoc;
23
24 import org.apache.bcel.classfile.Field;
25 import org.apache.bcel.generic.ConstantPoolGen;
26 import org.apache.bcel.generic.FieldInstruction;
27 import org.apache.bcel.generic.GETFIELD;
28 import org.apache.bcel.generic.GETSTATIC;
29 import org.apache.bcel.generic.Instruction;
30 import org.apache.bcel.generic.PUTFIELD;
31 import org.apache.bcel.generic.PUTSTATIC;
32
33 import edu.umd.cs.findbugs.ba.AnalysisContext;
34 import edu.umd.cs.findbugs.ba.SignatureConverter;
35 import edu.umd.cs.findbugs.ba.SourceInfoMap;
36 import edu.umd.cs.findbugs.ba.XField;
37 import edu.umd.cs.findbugs.classfile.FieldDescriptor;
38 import edu.umd.cs.findbugs.visitclass.DismantleBytecode;
39 import edu.umd.cs.findbugs.visitclass.PreorderVisitor;
40 import edu.umd.cs.findbugs.xml.XMLAttributeList;
41 import edu.umd.cs.findbugs.xml.XMLOutput;
42
43 /**
44  * A BugAnnotation specifying a particular field in particular class.
45  *
46  * @author David Hovemeyer
47  * @see BugAnnotation
48  */

49 public class FieldAnnotation extends PackageMemberAnnotation {
50     private static final long serialVersionUID = 1L;
51
52     private static final String JavaDoc DEFAULT_ROLE = "FIELD_DEFAULT";
53
54     private String JavaDoc fieldName;
55     private String JavaDoc fieldSig;
56     private boolean isStatic;
57
58     /**
59      * Constructor.
60      *
61      * @param className the name of the class containing the field
62      * @param fieldName the name of the field
63      * @param fieldSig the type signature of the field
64      */

65     public FieldAnnotation(String JavaDoc className, String JavaDoc fieldName, String JavaDoc fieldSig, boolean isStatic) {
66         super(className, DEFAULT_ROLE);
67         if (fieldSig.indexOf(".") >= 0) {
68             assert false : "signatures should not be dotted: " + fieldSig;
69             fieldSig = fieldSig.replace('.','/');
70         }
71         this.fieldName = fieldName;
72         this.fieldSig = fieldSig;
73         this.isStatic = isStatic;
74     }
75
76     /**
77      * Factory method. Class name, field name, and field signatures are taken from
78      * the given visitor, which is visiting the field.
79      *
80      * @param visitor the visitor which is visiting the field
81      * @return the FieldAnnotation object
82      */

83     public static FieldAnnotation fromVisitedField(PreorderVisitor visitor) {
84         return new FieldAnnotation(visitor.getDottedClassName(),
85                 visitor.getFieldName(), visitor.getFieldSig(),
86                 visitor.getFieldIsStatic());
87     }
88
89     /**
90      * Factory method. Class name, field name, and field signatures are taken from
91      * the given visitor, which is visiting a reference to the field
92      * (i.e., a getfield or getstatic instruction).
93      *
94      * @param visitor the visitor which is visiting the field reference
95      * @return the FieldAnnotation object
96      */

97     public static FieldAnnotation fromReferencedField(DismantleBytecode visitor) {
98         String JavaDoc className = visitor.getDottedClassConstantOperand();
99         return new FieldAnnotation(className,
100                 visitor.getNameConstantOperand(),
101                 visitor.getSigConstantOperand(), visitor.getRefFieldIsStatic());
102     }
103
104     /**
105      * Factory method. Construct from class name and BCEL Field object.
106      *
107      * @param className the name of the class which defines the field
108      * @param field the BCEL Field object
109      * @return the FieldAnnotation
110      */

111     public static FieldAnnotation fromBCELField(String JavaDoc className, Field field) {
112         return new FieldAnnotation(className, field.getName(), field.getSignature(), field.isStatic());
113     }
114
115     /**
116      * Factory method. Construct from a FieldDescriptor.
117      *
118      * @param fieldDescriptor the FieldDescriptor
119      * @return the FieldAnnotation
120      */

121     public static FieldAnnotation fromFieldDescriptor(FieldDescriptor fieldDescriptor) {
122         return new FieldAnnotation(
123                 fieldDescriptor.getClassName(),
124                 fieldDescriptor.getName(),
125                 fieldDescriptor.getSignature(),
126                 fieldDescriptor.isStatic());
127     }
128
129     public static FieldAnnotation fromXField(XField fieldDescriptor) {
130         return new FieldAnnotation(
131                 fieldDescriptor.getClassName(),
132                 fieldDescriptor.getName(),
133                 fieldDescriptor.getSignature(),
134                 fieldDescriptor.isStatic());
135     }
136     /**
137      * Get the field name.
138      */

139     public String JavaDoc getFieldName() {
140         return fieldName;
141     }
142
143     /**
144      * Get the type signature of the field.
145      */

146     public String JavaDoc getFieldSignature() {
147         return fieldSig;
148     }
149
150     /**
151      * Return whether or not the field is static.
152      */

153     public boolean isStatic() {
154         return isStatic;
155     }
156
157     /**
158      * Is the given instruction a read of a field?
159      *
160      * @param ins the Instruction to check
161      * @param cpg ConstantPoolGen of the method containing the instruction
162      * @return the Field if the instruction is a read of a field, null otherwise
163      */

164     public static FieldAnnotation isRead(Instruction ins, ConstantPoolGen cpg) {
165         if (ins instanceof GETFIELD || ins instanceof GETSTATIC) {
166             FieldInstruction fins = (FieldInstruction) ins;
167             String JavaDoc className = fins.getClassName(cpg);
168             return new FieldAnnotation(className, fins.getName(cpg), fins.getSignature(cpg), fins instanceof GETSTATIC);
169         } else
170             return null;
171     }
172
173     /**
174      * Is the instruction a write of a field?
175      *
176      * @param ins the Instruction to check
177      * @param cpg ConstantPoolGen of the method containing the instruction
178      * @return the Field if instruction is a write of a field, null otherwise
179      */

180     public static FieldAnnotation isWrite(Instruction ins, ConstantPoolGen cpg) {
181         if (ins instanceof PUTFIELD || ins instanceof PUTSTATIC) {
182             FieldInstruction fins = (FieldInstruction) ins;
183             String JavaDoc className = fins.getClassName(cpg);
184             return new FieldAnnotation(className, fins.getName(cpg), fins.getSignature(cpg), fins instanceof PUTSTATIC);
185         } else
186             return null;
187     }
188
189     public void accept(BugAnnotationVisitor visitor) {
190         visitor.visitFieldAnnotation(this);
191     }
192
193     @Override JavaDoc
194     protected String JavaDoc formatPackageMember(String JavaDoc key, ClassAnnotation primaryClass) {
195         if (key.equals("") || key.equals("hash"))
196             return className + "." + fieldName;
197         else if (key.equals("name"))
198             return fieldName;
199         else if (key.equals("fullField")) {
200             SignatureConverter converter = new SignatureConverter(fieldSig);
201             StringBuffer JavaDoc result = new StringBuffer JavaDoc();
202             if (isStatic)
203                 result.append("static ");
204             result.append(converter.parseNext());
205             result.append(' ');
206             result.append(className);
207             result.append('.');
208             result.append(fieldName);
209             return result.toString();
210         } else
211             throw new IllegalArgumentException JavaDoc("unknown key " + key);
212     }
213
214     @Override JavaDoc
215     public int hashCode() {
216         return className.hashCode() + fieldName.hashCode() + fieldSig.hashCode();
217     }
218
219     @Override JavaDoc
220     public boolean equals(Object JavaDoc o) {
221         if (!(o instanceof FieldAnnotation))
222             return false;
223         FieldAnnotation other = (FieldAnnotation) o;
224         return className.equals(other.className)
225                 && fieldName.equals(other.fieldName)
226                 && fieldSig.equals(other.fieldSig)
227                 && isStatic == other.isStatic;
228     }
229
230     public int compareTo(BugAnnotation o) {
231         if (!(o instanceof FieldAnnotation)) // BugAnnotations must be Comparable with any type of BugAnnotation
232
return this.getClass().getName().compareTo(o.getClass().getName());
233         FieldAnnotation other = (FieldAnnotation) o;
234         int cmp;
235         cmp = className.compareTo(other.className);
236         if (cmp != 0)
237             return cmp;
238         cmp = fieldName.compareTo(other.fieldName);
239         if (cmp != 0)
240             return cmp;
241         return fieldSig.compareTo(other.fieldSig);
242     }
243     
244     /* (non-Javadoc)
245      * @see edu.umd.cs.findbugs.PackageMemberAnnotation#getSourceLines()
246      */

247     @Override JavaDoc
248     public SourceLineAnnotation getSourceLines() {
249         if (sourceLines == null) {
250             // Create source line annotation for field on demand
251
AnalysisContext currentAnalysisContext = AnalysisContext.currentAnalysisContext();
252             if (currentAnalysisContext == null)
253                 sourceLines = new SourceLineAnnotation(className, sourceFileName, -1, -1, -1, -1);
254             else {
255             SourceInfoMap.SourceLineRange fieldLine = currentAnalysisContext
256                 .getSourceInfoMap()
257                 .getFieldLine(className, fieldName);
258             if (fieldLine == null) sourceLines = new SourceLineAnnotation(
259                     className, sourceFileName, -1, -1, -1, -1);
260             else sourceLines = new SourceLineAnnotation(
261                     className, sourceFileName, fieldLine.getStart(), fieldLine.getEnd(), -1, -1);
262             }
263         }
264         return sourceLines;
265     }
266
267     /* ----------------------------------------------------------------------
268      * XML Conversion support
269      * ---------------------------------------------------------------------- */

270
271     private static final String JavaDoc ELEMENT_NAME = "Field";
272
273     public void writeXML(XMLOutput xmlOutput) throws IOException JavaDoc {
274         writeXML(xmlOutput, false);
275     }
276
277     public void writeXML(XMLOutput xmlOutput, boolean addMessages) throws IOException JavaDoc {
278         XMLAttributeList attributeList = new XMLAttributeList()
279             .addAttribute("classname", getClassName())
280             .addAttribute("name", getFieldName())
281             .addAttribute("signature", getFieldSignature())
282             .addAttribute("isStatic", String.valueOf(isStatic()));
283         
284         String JavaDoc role = getDescription();
285         if (!role.equals(DEFAULT_ROLE))
286             attributeList.addAttribute("role", role);
287         
288         xmlOutput.openTag(ELEMENT_NAME, attributeList);
289         getSourceLines().writeXML(xmlOutput, addMessages);
290         if (addMessages) {
291             xmlOutput.openTag(BugAnnotation.MESSAGE_TAG);
292             xmlOutput.writeText(this.toString());
293             xmlOutput.closeTag(BugAnnotation.MESSAGE_TAG);
294         }
295         xmlOutput.closeTag(ELEMENT_NAME);
296     }
297 }
298
299 // vim:ts=4
300
Popular Tags