package edu.umd.cs.findbugs;
import java.io.IOException;
import edu.umd.cs.findbugs.ba.AnalysisContext;
import edu.umd.cs.findbugs.ba.SourceInfoMap;
import edu.umd.cs.findbugs.classfile.ClassDescriptor;
import edu.umd.cs.findbugs.internalAnnotations.DottedClassName;
import edu.umd.cs.findbugs.util.ClassName;
import edu.umd.cs.findbugs.xml.XMLAttributeList;
import edu.umd.cs.findbugs.xml.XMLOutput;
public class ClassAnnotation extends PackageMemberAnnotation {
private static final long serialVersionUID = 1L;
private static final String DEFAULT_ROLE = "CLASS_DEFAULT";
public static final String SUBCLASS_ROLE = "CLASS_SUBCLASS";
public static final String SUPERCLASS_ROLE = "CLASS_SUPERCLASS";
public static final String RECOMMENDED_SUPERCLASS_ROLE = "CLASS_RECOMMENDED_SUPERCLASS";
public static final String IMPLEMENTED_INTERFACE_ROLE = "CLASS_IMPLEMENTED_INTERFACE";
public static final String INTERFACE_ROLE = "INTERFACE_TYPE";
public static final String ANNOTATION_ROLE = "CLASS_ANNOTATION";
public static final String TYPE_QUALIFIER_ROLE = "CLASS_TYPE_QUALIFIER";
public ClassAnnotation(@DottedClassName String className) {
super(className, DEFAULT_ROLE);
}
public ClassAnnotation(@DottedClassName String className, String sourceFileName) {
super(className, DEFAULT_ROLE, sourceFileName);
}
@Override
public boolean isSignificant() {
return !SUBCLASS_ROLE.equals(description);
}
public static ClassAnnotation fromClassDescriptor(ClassDescriptor classDescriptor) {
return new ClassAnnotation(classDescriptor.toDottedClassName());
}
@Override
public void accept(BugAnnotationVisitor visitor) {
visitor.visitClassAnnotation(this);
}
@Override
protected String formatPackageMember(String key, ClassAnnotation primaryClass) {
if ("".equals(key) || "hash".equals(key)) {
return className;
} else if ("givenClass".equals(key)) {
return shorten(primaryClass.getPackageName(), className);
} else if ("excludingPackage".equals(key)) {
return shorten(getPackageName(), className);
} else if ("simpleClass".equals(key) || "simpleName".equals(key)) {
return ClassName.extractSimpleName(className);
} else {
throw new IllegalArgumentException("unknown key " + key);
}
}
@Override
public int hashCode() {
return className.hashCode();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ClassAnnotation)) {
return false;
}
ClassAnnotation other = (ClassAnnotation) o;
return className.equals(other.className);
}
public boolean contains(ClassAnnotation other) {
return other.className.startsWith(className);
}
public ClassAnnotation getTopLevelClass() {
int firstDollar = className.indexOf('$');
if (firstDollar <= 0) {
return this;
}
return new ClassAnnotation(className.substring(0, firstDollar));
}
@Override
public int compareTo(BugAnnotation o) {
if (!(o instanceof ClassAnnotation)) {
return this.getClass().getName().compareTo(o.getClass().getName());
}
ClassAnnotation other = (ClassAnnotation) o;
return className.compareTo(other.className);
}
@Override
public SourceLineAnnotation getSourceLines() {
if (sourceLines == null) {
this.sourceLines = getSourceLinesForClass(className, sourceFileName);
}
return sourceLines;
}
public static SourceLineAnnotation getSourceLinesForClass(@DottedClassName String className, String sourceFileName) {
AnalysisContext currentAnalysisContext = AnalysisContext.currentAnalysisContext();
if (currentAnalysisContext == null) {
return new SourceLineAnnotation(className, sourceFileName, -1, -1, -1, -1);
}
SourceInfoMap.SourceLineRange classLine = currentAnalysisContext.getSourceInfoMap().getClassLine(className);
if (classLine == null) {
return SourceLineAnnotation.getSourceAnnotationForClass(className, sourceFileName);
} else {
return new SourceLineAnnotation(className, sourceFileName, classLine.getStart(), classLine.getEnd(), -1, -1);
}
}
private static final String ELEMENT_NAME = "Class";
@Override
public void writeXML(XMLOutput xmlOutput) throws IOException {
writeXML(xmlOutput, false, false);
}
@Override
public void writeXML(XMLOutput xmlOutput, boolean addMessages, boolean isPrimary) throws IOException {
XMLAttributeList attributeList = new XMLAttributeList().addAttribute("classname", getClassName());
if (isPrimary) {
attributeList.addAttribute("primary", "true");
}
String role = getDescription();
if (!DEFAULT_ROLE.equals(role)) {
attributeList.addAttribute("role", role);
}
xmlOutput.openTag(ELEMENT_NAME, attributeList);
getSourceLines().writeXML(xmlOutput, addMessages, false);
if (addMessages) {
xmlOutput.openTag(BugAnnotation.MESSAGE_TAG);
xmlOutput.writeText(this.toString());
xmlOutput.closeTag(BugAnnotation.MESSAGE_TAG);
}
xmlOutput.closeTag(ELEMENT_NAME);
}
}