001: /*
002: * Bytecode Analysis Framework
003: * Copyright (C) 2005, 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: package edu.umd.cs.findbugs.ba;
020:
021: import org.apache.bcel.Constants;
022:
023: import edu.umd.cs.findbugs.classfile.ClassDescriptor;
024: import edu.umd.cs.findbugs.classfile.DescriptorFactory;
025: import edu.umd.cs.findbugs.internalAnnotations.DottedClassName;
026:
027: public abstract class AbstractClassMember implements ClassMember {
028: private final @DottedClassName
029: String className;
030: private final String name;
031: private final String signature;
032: private final int accessFlags;
033: private boolean resolved;
034: private int cachedHashCode = 0;
035: static int slashCountClass = 0;
036: static int dottedCountClass = 0;
037: static int slashCountSignature = 0;
038: static int dottedCountSignature = 0;
039:
040: protected AbstractClassMember(@DottedClassName
041: String className, String name, String signature, int accessFlags) {
042: if (className.indexOf('.') >= 0) {
043: // className = className.replace('.','/');
044: dottedCountClass++;
045: } else if (className.indexOf('/') >= 0) {
046: assert false;
047: slashCountClass++;
048: className = className.replace('/', '.');
049: }
050: if (signature.indexOf('.') >= 0) {
051: assert false;
052: signature = signature.replace('.', '/');
053: dottedCountSignature++;
054: } else if (signature.indexOf('/') >= 0)
055: slashCountSignature++;
056: this .className = DescriptorFactory
057: .canonicalizeString(className);
058: this .name = DescriptorFactory.canonicalizeString(name);
059: this .signature = DescriptorFactory
060: .canonicalizeString(signature);
061: this .accessFlags = accessFlags;
062: }
063:
064: public @DottedClassName
065: String getClassName() {
066: return className;
067: }
068:
069: /* (non-Javadoc)
070: * @see edu.umd.cs.findbugs.ba.AccessibleEntity#getClassDescriptor()
071: */
072: public ClassDescriptor getClassDescriptor() {
073: return DescriptorFactory.instance()
074: .getClassDescriptorForDottedClassName(className);
075: }
076:
077: public String getName() {
078: return name;
079: }
080:
081: public @DottedClassName
082: String getPackageName() {
083: int lastDot = className.lastIndexOf('.');
084: if (lastDot == -1)
085: return className;
086: return className.substring(0, lastDot);
087: }
088:
089: public String getSignature() {
090: return signature;
091: }
092:
093: public boolean isReferenceType() {
094: return signature.startsWith("L") || signature.startsWith("[");
095: }
096:
097: public int getAccessFlags() {
098: return accessFlags;
099: }
100:
101: public boolean isStatic() {
102: return (accessFlags & Constants.ACC_STATIC) != 0;
103: }
104:
105: public boolean isFinal() {
106: return (accessFlags & Constants.ACC_FINAL) != 0;
107: }
108:
109: public boolean isPublic() {
110: return (accessFlags & Constants.ACC_PUBLIC) != 0;
111: }
112:
113: public boolean isProtected() {
114: return (accessFlags & Constants.ACC_PROTECTED) != 0;
115: }
116:
117: public boolean isPrivate() {
118: return (accessFlags & Constants.ACC_PRIVATE) != 0;
119: }
120:
121: // public int compareTo(ClassMember other) {
122: // // This may be compared to any kind of PackageMember object.
123: // // If the other object is a different kind of field,
124: // // just compare class names.
125: // if (this.getClass() != other.getClass())
126: // return this.getClass().getName().compareTo(other.getClass().getName());
127: //
128: // int cmp;
129: // cmp = className.compareTo(other.getClassName());
130: // if (cmp != 0)
131: // return cmp;
132: // cmp = name.compareTo(other.getName());
133: // if (cmp != 0)
134: // return cmp;
135: // return signature.compareTo(other.getSignature());
136: // }
137:
138: // public int compareTo(FieldOrMethodName other) {
139: //
140: // int cmp = getClassDescriptor().compareTo(other.getClassDescriptor());
141: // if (cmp != 0)
142: // return cmp;
143: // cmp = name.compareTo(other.getName());
144: // if (cmp != 0)
145: // return cmp;
146: // cmp = signature.compareTo(other.getSignature());
147: // if (cmp != 0)
148: // return cmp;
149: // return (this.isStatic() ? 1 : 0) - (other.isStatic() ? 1 : 0);
150: // }
151: // public int compareTo(Object other) {
152: // return compareTo((FieldOrMethodName) other);
153: // }
154: public boolean isResolved() {
155: return resolved;
156: }
157:
158: void markAsResolved() {
159: resolved = true;
160: }
161:
162: @Override
163: public int hashCode() {
164: if (cachedHashCode == 0) {
165: cachedHashCode = className.hashCode() ^ name.hashCode()
166: ^ signature.hashCode();
167: }
168: return cachedHashCode;
169: }
170:
171: @Override
172: public boolean equals(Object o) {
173: if (o == null || this .getClass() != o.getClass())
174: return false;
175: AbstractClassMember other = (AbstractClassMember) o;
176: return className.equals(other.className)
177: && name.equals(other.name)
178: && signature.equals(other.signature);
179: }
180:
181: @Override
182: public String toString() {
183: return className + "." + name;
184: }
185:
186: }
|