- /*
 - * 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();
 - }
 - }