001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2003-2007 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.ba.ch;
021:
022: import edu.umd.cs.findbugs.annotations.CheckForNull;
023: import edu.umd.cs.findbugs.annotations.Nullable;
024: import edu.umd.cs.findbugs.ba.XClass;
025: import edu.umd.cs.findbugs.classfile.ClassDescriptor;
026: import edu.umd.cs.findbugs.graph.AbstractVertex;
027:
028: /**
029: * Vertex class - represents a class or interface in the InheritanceGraph.
030: * Edges connect subtypes to supertypes.
031: *
032: * @author David Hovemeyer
033: */
034: class ClassVertex extends AbstractVertex<InheritanceEdge, ClassVertex> {
035: private static final int FINISHED = 1;
036: private static final int APPLICATION_CLASS = 2;
037: private static final int INTERFACE = 4;
038:
039: private final ClassDescriptor classDescriptor;
040: private final @CheckForNull
041: XClass xclass;
042: private int flags;
043: private ClassVertex directSuperclass;
044:
045: @Override
046: public String toString() {
047: return classDescriptor.toString();
048: }
049:
050: @Override
051: public boolean equals(Object o) {
052: if (!(o instanceof ClassVertex))
053: return false;
054: return classDescriptor
055: .equals(((ClassVertex) o).classDescriptor);
056: }
057:
058: @Override
059: public int hashCode() {
060: return classDescriptor.hashCode();
061: }
062:
063: private ClassVertex(ClassDescriptor classDescriptor, XClass xclass) {
064: this .classDescriptor = classDescriptor;
065: this .xclass = xclass;
066: this .flags = 0;
067: if (xclass.isInterface()) {
068: setInterface();
069: }
070: }
071:
072: private ClassVertex(ClassDescriptor classDescriptor,
073: boolean isInterfaceEdge) {
074: this .classDescriptor = classDescriptor;
075: this .xclass = null;
076: this .flags = 0;
077: if (isInterfaceEdge) {
078: setInterface();
079: }
080: }
081:
082: /**
083: * Factory method for resolved ClassVertex objects.
084: *
085: * @param classDescriptor ClassDescriptor naming the class or interface
086: * @param xclass object containing information about a class or interface
087: * @return ClassVertex
088: */
089: public static ClassVertex createResolvedClassVertex(
090: ClassDescriptor classDescriptor, XClass xclass) {
091: return new ClassVertex(classDescriptor, xclass);
092: }
093:
094: /**
095: * Factory method for ClassVertex objects representing missing classes.
096: *
097: * @param classDescriptor ClassDescriptor naming the missing class or interface
098: * @param isInterface true if missing class is an interface, false otherwise
099: * @return ClassVertex
100: */
101: public static ClassVertex createMissingClassVertex(
102: ClassDescriptor classDescriptor, boolean isInterface) {
103: return new ClassVertex(classDescriptor, isInterface);
104: }
105:
106: /**
107: * @return Returns the classDescriptor.
108: */
109: public ClassDescriptor getClassDescriptor() {
110: return classDescriptor;
111: }
112:
113: /**
114: * @return Returns the xClass.
115: */
116: public @Nullable
117: XClass getXClass() {
118: return xclass;
119: }
120:
121: /**
122: * Return true if this ClassVertex corresponds to a resolved
123: * class, or false if the class could not be found.
124: */
125: public boolean isResolved() {
126: return xclass != null;
127: }
128:
129: /**
130: * @param finished The finished to set.
131: */
132: public void setFinished(boolean finished) {
133: setFlag(FINISHED, finished);
134: }
135:
136: /**
137: * @return Returns the finished.
138: */
139: public boolean isFinished() {
140: return isFlagSet(FINISHED);
141: }
142:
143: /**
144: * Mark this ClassVertex as representing an application class.
145: */
146: public void markAsApplicationClass() {
147: setFlag(APPLICATION_CLASS, true);
148: }
149:
150: /**
151: * @return true if this ClassVertex represents an application class,
152: * false otherwise
153: */
154: public boolean isApplicationClass() {
155: return isFlagSet(APPLICATION_CLASS);
156: }
157:
158: /**
159: * Mark this ClassVertex as representing an interface.
160: */
161: private void setInterface() {
162: setFlag(INTERFACE, true);
163: }
164:
165: /**
166: * @return true if this ClassVertex represents an interface,
167: * false otherwise
168: */
169: public boolean isInterface() {
170: return isFlagSet(INTERFACE);
171: }
172:
173: /**
174: * Set the ClassVertex representing the direct superclass.
175: *
176: * @param target ClassVertex representing the direct superclass.
177: */
178: public void setDirectSuperclass(ClassVertex target) {
179: this .directSuperclass = target;
180: }
181:
182: /**
183: * @return Returns the directSuperclass.
184: */
185: public ClassVertex getDirectSuperclass() {
186: return directSuperclass;
187: }
188:
189: private void setFlag(int flag, boolean enable) {
190: if (enable) {
191: flags |= flag;
192: } else {
193: flags &= ~flag;
194: }
195: }
196:
197: private boolean isFlagSet(int flag) {
198: return (flags & flag) != 0;
199: }
200: }
|