/* * FindBugs - Find Bugs in Java programs * Copyright (C) 2003-2007 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.ba.ch; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import edu.umd.cs.findbugs.ba.XClass; import edu.umd.cs.findbugs.classfile.ClassDescriptor; import edu.umd.cs.findbugs.graph.AbstractVertex; /** * Vertex class - represents a class or interface in the InheritanceGraph. Edges * connect subtypes to supertypes. * * @author David Hovemeyer */ class ClassVertex extends AbstractVertex<InheritanceEdge, ClassVertex> { private static final int FINISHED = 1; private static final int APPLICATION_CLASS = 2; private static final int INTERFACE = 4; private final ClassDescriptor classDescriptor; private final @CheckForNull XClass xclass; private int flags; private ClassVertex directSuperclass; @Override public String toString() { return classDescriptor.toString(); } @Override public boolean equals(Object o) { if (!(o instanceof ClassVertex)) return false; return classDescriptor.equals(((ClassVertex) o).classDescriptor); } @Override public int hashCode() { return classDescriptor.hashCode(); } private ClassVertex(ClassDescriptor classDescriptor, XClass xclass) { this.classDescriptor = classDescriptor; this.xclass = xclass; this.flags = 0; if (xclass.isInterface()) { setInterface(); } } private ClassVertex(ClassDescriptor classDescriptor, boolean isInterfaceEdge) { this.classDescriptor = classDescriptor; this.xclass = null; this.flags = 0; if (isInterfaceEdge) { setInterface(); } } /** * Factory method for resolved ClassVertex objects. * * @param classDescriptor * ClassDescriptor naming the class or interface * @param xclass * object containing information about a class or interface * @return ClassVertex */ public static ClassVertex createResolvedClassVertex(ClassDescriptor classDescriptor, XClass xclass) { return new ClassVertex(classDescriptor, xclass); } /** * Factory method for ClassVertex objects representing missing classes. * * @param classDescriptor * ClassDescriptor naming the missing class or interface * @param isInterface * true if missing class is an interface, false otherwise * @return ClassVertex */ public static ClassVertex createMissingClassVertex(ClassDescriptor classDescriptor, boolean isInterface) { return new ClassVertex(classDescriptor, isInterface); } /** * @return Returns the classDescriptor. */ public ClassDescriptor getClassDescriptor() { return classDescriptor; } /** * @return Returns the xClass. */ public @Nullable XClass getXClass() { return xclass; } /** * Return true if this ClassVertex corresponds to a resolved class, or false * if the class could not be found. */ public boolean isResolved() { return xclass != null; } /** * @param finished * The finished to set. */ public void setFinished(boolean finished) { setFlag(FINISHED, finished); } /** * @return Returns the finished. */ public boolean isFinished() { return isFlagSet(FINISHED); } /** * Mark this ClassVertex as representing an application class. */ public void markAsApplicationClass() { setFlag(APPLICATION_CLASS, true); } /** * @return true if this ClassVertex represents an application class, false * otherwise */ public boolean isApplicationClass() { return isFlagSet(APPLICATION_CLASS); } /** * Mark this ClassVertex as representing an interface. */ private void setInterface() { setFlag(INTERFACE, true); } /** * @return true if this ClassVertex represents an interface, false otherwise */ public boolean isInterface() { return isFlagSet(INTERFACE); } /** * Set the ClassVertex representing the direct superclass. * * @param target * ClassVertex representing the direct superclass. */ public void setDirectSuperclass(ClassVertex target) { this.directSuperclass = target; } /** * @return Returns the directSuperclass. */ public ClassVertex getDirectSuperclass() { return directSuperclass; } private void setFlag(int flag, boolean enable) { if (enable) { flags |= flag; } else { flags &= ~flag; } } private boolean isFlagSet(int flag) { return (flags & flag) != 0; } }