- /*
- * Copyright 2000-2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
-
- import java.io.DataInputStream;
- import java.io.IOException;
- import java.util.Enumeration;
- import java.util.Hashtable;
- import java.util.Vector;
-
- /**
- * The constant pool of a Java class. The constant pool is a collection of
- * constants used in a Java class file. It stores strings, constant values,
- * class names, method names, field names etc.
- *
- * @see <a href="http://java.sun.com/docs/books/vmspec/">The Java Virtual
- * Machine Specification</a>
- */
- public class ConstantPool {
-
- /** The entries in the constant pool. */
- private Vector entries;
-
- /**
- * A Hashtable of UTF8 entries - used to get constant pool indexes of
- * the UTF8 values quickly
- */
- private Hashtable utf8Indexes;
-
- /** Initialise the constant pool. */
- public ConstantPool() {
- entries = new Vector();
-
- // The zero index is never present in the constant pool itself so
- // we add a null entry for it
- entries.addElement(null);
-
- utf8Indexes = new Hashtable();
- }
-
- /**
- * Read the constant pool from a class input stream.
- *
- * @param classStream the DataInputStream of a class file.
- * @exception IOException if there is a problem reading the constant pool
- * from the stream
- */
- public void read(DataInputStream classStream) throws IOException {
- int numEntries = classStream.readUnsignedShort();
-
- for (int i = 1; i < numEntries;) {
- ConstantPoolEntry nextEntry
- = ConstantPoolEntry.readEntry(classStream);
-
- i += nextEntry.getNumEntries();
-
- addEntry(nextEntry);
- }
- }
-
- /**
- * Get the size of the constant pool.
- *
- * @return the size of the constant pool
- */
- public int size() {
- return entries.size();
- }
-
- /**
- * Add an entry to the constant pool.
- *
- * @param entry the new entry to be added to the constant pool.
- * @return the index into the constant pool at which the entry is
- * stored.
- */
- public int addEntry(ConstantPoolEntry entry) {
- int index = entries.size();
-
- entries.addElement(entry);
-
- int numSlots = entry.getNumEntries();
-
- // add null entries for any additional slots required.
- for (int j = 0; j < numSlots - 1; ++j) {
- entries.addElement(null);
- }
-
- if (entry instanceof Utf8CPInfo) {
- Utf8CPInfo utf8Info = (Utf8CPInfo) entry;
-
- utf8Indexes.put(utf8Info.getValue(), new Integer(index));
- }
-
- return index;
- }
-
- /**
- * Resolve the entries in the constant pool. Resolution of the constant
- * pool involves transforming indexes to other constant pool entries
- * into the actual data for that entry.
- */
- public void resolve() {
- for (Enumeration i = entries.elements(); i.hasMoreElements();) {
- ConstantPoolEntry poolInfo = (ConstantPoolEntry) i.nextElement();
-
- if (poolInfo != null && !poolInfo.isResolved()) {
- poolInfo.resolve(this);
- }
- }
- }
-
-
- /**
- * Get an constant pool entry at a particular index.
- *
- * @param index the index into the constant pool.
- * @return the constant pool entry at that index.
- */
- public ConstantPoolEntry getEntry(int index) {
- return (ConstantPoolEntry) entries.elementAt(index);
- }
-
- /**
- * Get the index of a given UTF8 constant pool entry.
- *
- * @param value the string value of the UTF8 entry.
- * @return the index at which the given string occurs in the constant
- * pool or -1 if the value does not occur.
- */
- public int getUTF8Entry(String value) {
- int index = -1;
- Integer indexInteger = (Integer) utf8Indexes.get(value);
-
- if (indexInteger != null) {
- index = indexInteger.intValue();
- }
-
- return index;
- }
-
- /**
- * Get the index of a given CONSTANT_CLASS entry in the constant pool.
- *
- * @param className the name of the class for which the class entry
- * index is required.
- * @return the index at which the given class entry occurs in the
- * constant pool or -1 if the value does not occur.
- */
- public int getClassEntry(String className) {
- int index = -1;
-
- for (int i = 0; i < entries.size() && index == -1; ++i) {
- Object element = entries.elementAt(i);
-
- if (element instanceof ClassCPInfo) {
- ClassCPInfo classinfo = (ClassCPInfo) element;
-
- if (classinfo.getClassName().equals(className)) {
- index = i;
- }
- }
- }
-
- return index;
- }
-
- /**
- * Get the index of a given constant value entry in the constant pool.
- *
- * @param constantValue the constant value for which the index is
- * required.
- * @return the index at which the given value entry occurs in the
- * constant pool or -1 if the value does not occur.
- */
- public int getConstantEntry(Object constantValue) {
- int index = -1;
-
- for (int i = 0; i < entries.size() && index == -1; ++i) {
- Object element = entries.elementAt(i);
-
- if (element instanceof ConstantCPInfo) {
- ConstantCPInfo constantEntry = (ConstantCPInfo) element;
-
- if (constantEntry.getValue().equals(constantValue)) {
- index = i;
- }
- }
- }
-
- return index;
- }
-
- /**
- * Get the index of a given CONSTANT_METHODREF entry in the constant
- * pool.
- *
- * @param methodClassName the name of the class which contains the
- * method being referenced.
- * @param methodName the name of the method being referenced.
- * @param methodType the type descriptor of the method being referenced.
- * @return the index at which the given method ref entry occurs in the
- * constant pool or -1 if the value does not occur.
- */
- public int getMethodRefEntry(String methodClassName, String methodName,
- String methodType) {
- int index = -1;
-
- for (int i = 0; i < entries.size() && index == -1; ++i) {
- Object element = entries.elementAt(i);
-
- if (element instanceof MethodRefCPInfo) {
- MethodRefCPInfo methodRefEntry = (MethodRefCPInfo) element;
-
- if (methodRefEntry.getMethodClassName().equals(methodClassName)
- && methodRefEntry.getMethodName().equals(methodName)
- && methodRefEntry.getMethodType().equals(methodType)) {
- index = i;
- }
- }
- }
-
- return index;
- }
-
- /**
- * Get the index of a given CONSTANT_INTERFACEMETHODREF entry in the
- * constant pool.
- *
- * @param interfaceMethodClassName the name of the interface which
- * contains the method being referenced.
- * @param interfaceMethodName the name of the method being referenced.
- * @param interfaceMethodType the type descriptor of the method being
- * referenced.
- * @return the index at which the given method ref entry occurs in the
- * constant pool or -1 if the value does not occur.
- */
- public int getInterfaceMethodRefEntry(String interfaceMethodClassName,
- String interfaceMethodName,
- String interfaceMethodType) {
- int index = -1;
-
- for (int i = 0; i < entries.size() && index == -1; ++i) {
- Object element = entries.elementAt(i);
-
- if (element instanceof InterfaceMethodRefCPInfo) {
- InterfaceMethodRefCPInfo interfaceMethodRefEntry
- = (InterfaceMethodRefCPInfo) element;
-
- if (interfaceMethodRefEntry.getInterfaceMethodClassName().equals(interfaceMethodClassName)
- && interfaceMethodRefEntry.getInterfaceMethodName().equals(interfaceMethodName)
- && interfaceMethodRefEntry.getInterfaceMethodType().equals(interfaceMethodType)) {
- index = i;
- }
- }
- }
-
- return index;
- }
-
- /**
- * Get the index of a given CONSTANT_FIELDREF entry in the constant
- * pool.
- *
- * @param fieldClassName the name of the class which contains the field
- * being referenced.
- * @param fieldName the name of the field being referenced.
- * @param fieldType the type descriptor of the field being referenced.
- * @return the index at which the given field ref entry occurs in the
- * constant pool or -1 if the value does not occur.
- */
- public int getFieldRefEntry(String fieldClassName, String fieldName,
- String fieldType) {
- int index = -1;
-
- for (int i = 0; i < entries.size() && index == -1; ++i) {
- Object element = entries.elementAt(i);
-
- if (element instanceof FieldRefCPInfo) {
- FieldRefCPInfo fieldRefEntry = (FieldRefCPInfo) element;
-
- if (fieldRefEntry.getFieldClassName().equals(fieldClassName)
- && fieldRefEntry.getFieldName().equals(fieldName)
- && fieldRefEntry.getFieldType().equals(fieldType)) {
- index = i;
- }
- }
- }
-
- return index;
- }
-
- /**
- * Get the index of a given CONSTANT_NAMEANDTYPE entry in the constant
- * pool.
- *
- * @param name the name
- * @param type the type
- * @return the index at which the given NameAndType entry occurs in the
- * constant pool or -1 if the value does not occur.
- */
- public int getNameAndTypeEntry(String name, String type) {
- int index = -1;
-
- for (int i = 0; i < entries.size() && index == -1; ++i) {
- Object element = entries.elementAt(i);
-
- if (element instanceof NameAndTypeCPInfo) {
- NameAndTypeCPInfo nameAndTypeEntry
- = (NameAndTypeCPInfo) element;
-
- if (nameAndTypeEntry.getName().equals(name)
- && nameAndTypeEntry.getType().equals(type)) {
- index = i;
- }
- }
- }
-
- return index;
- }
-
- /**
- * Dump the constant pool to a string.
- *
- * @return the constant pool entries as strings
- */
- public String toString() {
- StringBuffer sb = new StringBuffer("\n");
- int size = entries.size();
-
- for (int i = 0; i < size; ++i) {
- sb.append("[" + i + "] = " + getEntry(i) + "\n");
- }
-
- return sb.toString();
- }
-
- }
-