001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.harmony.pack200.bytecode;
018:
019: import java.io.DataOutputStream;
020: import java.io.IOException;
021:
022: public abstract class CPRef extends ConstantPoolEntry {
023:
024: CPClass className;
025: transient int classNameIndex;
026:
027: protected CPNameAndType nameAndType;
028: transient int nameAndTypeIndex;
029:
030: public CPRef(byte type, String className, String descriptor) {
031: super (type);
032: this .className = new CPClass(className);
033: this .nameAndType = new CPNameAndType(descriptor);
034: }
035:
036: public boolean equals(Object obj) {
037: if (this == obj)
038: return true;
039: if (obj == null)
040: return false;
041: if (getClass() != obj.getClass())
042: return false;
043: final CPRef other = (CPRef) obj;
044: if (className == null) {
045: if (other.className != null)
046: return false;
047: } else if (!className.equals(other.className))
048: return false;
049: if (nameAndType == null) {
050: if (other.nameAndType != null)
051: return false;
052: } else if (!nameAndType.equals(other.nameAndType))
053: return false;
054: return true;
055: }
056:
057: protected ClassFileEntry[] getNestedClassFileEntries() {
058: ClassFileEntry[] entries = new ClassFileEntry[2];
059: entries[0] = className;
060: entries[1] = nameAndType;
061: return entries;
062: }
063:
064: public int hashCode() {
065: final int PRIME = 31;
066: int result = 1;
067: result = PRIME * result
068: + ((className == null) ? 0 : className.hashCode());
069: result = PRIME * result
070: + ((nameAndType == null) ? 0 : nameAndType.hashCode());
071: return result;
072: }
073:
074: protected void resolve(ClassConstantPool pool) {
075: super .resolve(pool);
076: nameAndTypeIndex = pool.indexOf(nameAndType);
077: classNameIndex = pool.indexOf(className);
078: }
079:
080: public String comparisonString() {
081: // This one is tricky. The sorting appears to be
082: // done based on the indices of the method descriptor
083: // and class name in the classpool *after* sorting them.
084:
085: // If we haven't yet been resolved, just do a normal
086: // compare (so things like .contains() work).
087: if (!isResolved()) {
088: return super .comparisonString();
089: }
090:
091: // If we get here, the receiver has been resolved; there
092: // is a different sort order.
093: StringBuffer result = new StringBuffer();
094: // Pad all numbers to 6 digits so they sort correctly.
095: int padLength = 6;
096: int classIndexLength = ("" + classNameIndex).length();
097: int nameAndTypeIndexLength = ("" + nameAndTypeIndex).length();
098:
099: for (int index = 0; index < (padLength - classIndexLength); index++) {
100: result.append('0');
101: }
102: result.append("" + classNameIndex);
103: result.append(":");
104: for (int index = 0; index < (padLength - nameAndTypeIndexLength); index++) {
105: result.append('0');
106: }
107: result.append("" + nameAndTypeIndex);
108: return result.toString();
109: }
110:
111: public String toString() {
112: String type;
113: if (getTag() == ConstantPoolEntry.CP_Fieldref) {
114: type = "FieldRef"; //$NON-NLS-1$
115: } else if (getTag() == ConstantPoolEntry.CP_Methodref) {
116: type = "MethoddRef"; //$NON-NLS-1$
117: } else if (getTag() == ConstantPoolEntry.CP_InterfaceMethodref) {
118: type = "InterfaceMethodRef"; //$NON-NLS-1$
119: } else {
120: type = "unknown"; //$NON-NLS-1$
121: }
122: return type + ": " + className + "#" + nameAndType; //$NON-NLS-1$ //$NON-NLS-2$
123: }
124:
125: protected void writeBody(DataOutputStream dos) throws IOException {
126: dos.writeShort(classNameIndex);
127: dos.writeShort(nameAndTypeIndex);
128: }
129:
130: }
|