/*
 * FindBugs - Find bugs in Java programs
 * Copyright (C) 2003-2005, University of Maryland
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

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;

A BugAnnotation object specifying a Java class involved in the bug.
Author:David Hovemeyer
See Also:
/** * A BugAnnotation object specifying a Java class involved in the bug. * * @author David Hovemeyer * @see BugAnnotation * @see BugInstance */
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";
Constructor.
Params:
  • className – the name of the class
/** * Constructor. * * @param className * the name of the class */
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); }
Factory method to create a ClassAnnotation from a ClassDescriptor.
Params:
  • classDescriptor – the ClassDescriptor
Returns:the ClassAnnotation
/** * Factory method to create a ClassAnnotation from a ClassDescriptor. * * @param classDescriptor * the ClassDescriptor * @return the ClassAnnotation */
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)) { // Comparable with any type of // BugAnnotation return this.getClass().getName().compareTo(o.getClass().getName()); } ClassAnnotation other = (ClassAnnotation) o; return className.compareTo(other.className); } /* * (non-Javadoc) * * @see edu.umd.cs.findbugs.PackageMemberAnnotation#getSourceLines() */ @Override public SourceLineAnnotation getSourceLines() { if (sourceLines == null) { this.sourceLines = getSourceLinesForClass(className, sourceFileName); } return sourceLines; } public static SourceLineAnnotation getSourceLinesForClass(@DottedClassName String className, String sourceFileName) { // Create source line annotation for class on demand 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); } } /* * ---------------------------------------------------------------------- * XML Conversion support * ---------------------------------------------------------------------- */ 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); } }