All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hfg.util.BasicClassFileInfo Maven / Gradle / Ivy

There is a newer version: 20240423
Show newest version
package com.hfg.util;


import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

//------------------------------------------------------------------------------
/**
 Currently this is just a simple helper class used by ClassExplorer to extract
 information from Java class files about the superclass and interfaces implemented.
 
@author J. Alex Taylor, hairyfatguy.com
*/ //------------------------------------------------------------------------------ // com.hfg XML/HTML Coding Library // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com // [email protected] //------------------------------------------------------------------------------ // See: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html public class BasicClassFileInfo { private int mMajorVersion; private int mMinorVersion; private int mConstantPoolCount; private int mInterfacesCount; private String mClassname; private String mSuperclassname; private String[] mInterfaces; // Constant Pool tag values private enum ConstantPoolTag { CONSTANT_Utf8(1), CONSTANT_Integer(3), CONSTANT_Float(4), CONSTANT_Long(5), CONSTANT_Double(6), CONSTANT_Class(7), CONSTANT_String(8), CONSTANT_Fieldref(9), CONSTANT_Methodref(10), CONSTANT_InterfaceMethodref(11), CONSTANT_NameAndType(12), CONSTANT_MethodHandle(15), CONSTANT_MethodType(16), CONSTANT_InvokeDynamic(18); private int mValue; private ConstantPoolTag(int inValue) { mValue = inValue; } public int getValue() { return mValue; } public static ConstantPoolTag valueOf(int inValue) { ConstantPoolTag tag = null; for (ConstantPoolTag poolTag : values()) { if (poolTag.getValue() == inValue) { tag = poolTag; break; } } return tag; } } //-------------------------------------------------------------------------- public BasicClassFileInfo(DataInputStream inStream) throws IOException { int magic = inStream.readInt(); if (magic != 0xCAFEBABE) { throw new IOException("Bad magic number: " + Integer.toHexString(magic)); } mMinorVersion = inStream.readUnsignedShort(); mMajorVersion = inStream.readUnsignedShort(); mConstantPoolCount = inStream.readUnsignedShort(); List entries = new ArrayList<>(mConstantPoolCount); for (int idx = 1; idx < mConstantPoolCount; idx++) { ConstantPoolTag tag = ConstantPoolTag.valueOf(inStream.readUnsignedByte()); switch (tag) { case CONSTANT_Utf8: entries.add(new Utf8Entry(inStream)); break; case CONSTANT_Integer: entries.add(new IntegerEntry(inStream)); break; case CONSTANT_Float: entries.add(new FloatEntry(inStream)); break; case CONSTANT_Long: entries.add(new LongEntry(inStream)); break; case CONSTANT_Double: entries.add(new DoubleEntry(inStream)); break; case CONSTANT_Class: entries.add(new ClassEntry(inStream)); break; case CONSTANT_String: entries.add(new StringEntry(inStream)); break; case CONSTANT_Fieldref: entries.add(new FieldrefEntry(inStream)); break; case CONSTANT_Methodref: entries.add(new MethodrefEntry(inStream)); break; case CONSTANT_InterfaceMethodref: entries.add(new InterfaceMethodrefEntry(inStream)); break; case CONSTANT_NameAndType: entries.add(new NameAndTypeEntry(inStream)); break; case CONSTANT_MethodHandle: entries.add(new MethodHandleEntry(inStream)); break; case CONSTANT_MethodType: entries.add(new MethodTypeEntry(inStream)); break; case CONSTANT_InvokeDynamic: entries.add(new InvokeDynamicEntry(inStream)); break; } } // Access flags inStream.readUnsignedShort(); // Class name int classIdx = inStream.readUnsignedShort(); ClassEntry classEntry = (ClassEntry) entries.get(classIdx - 1); mClassname = ((Utf8Entry) entries.get(classEntry.getNameIndex() - 1)).getString().replace(File.separator, "."); // Super class int superclassIdx = inStream.readUnsignedShort(); ClassEntry superclassEntry = (ClassEntry) entries.get(superclassIdx - 1); mSuperclassname = ((Utf8Entry) entries.get(superclassEntry.getNameIndex() - 1)).getString().replace(File.separator, "."); mInterfacesCount = inStream.readUnsignedShort(); if (mInterfacesCount > 0) { mInterfaces = new String[mInterfacesCount]; for (int i = 0; i < mInterfacesCount; i++) { int index = inStream.readUnsignedShort(); ClassEntry interfaceEntry = (ClassEntry) entries.get(index - 1); mInterfaces[i] = ((Utf8Entry) entries.get(interfaceEntry.getNameIndex() - 1)).getString().replace(File.separator, "."); } } } //-------------------------------------------------------------------------- public String getClassname() { return mClassname; } //-------------------------------------------------------------------------- public String getSuperClassname() { return mSuperclassname; } //-------------------------------------------------------------------------- public String[] getInterfaceClassnames() { return mInterfaces; } abstract class ConstantPoolEntry { } private class Utf8Entry extends ConstantPoolEntry { private String mString; //----------------------------------------------------------------------- public Utf8Entry(DataInputStream inStream) throws IOException { mString = inStream.readUTF(); } //----------------------------------------------------------------------- public String getString() { return mString; } } private class IntegerEntry extends ConstantPoolEntry { private int mValue; //----------------------------------------------------------------------- public IntegerEntry(DataInputStream inStream) throws IOException { mValue = inStream.readInt(); } //----------------------------------------------------------------------- public int getValue() { return mValue; } } private class FloatEntry extends ConstantPoolEntry { private float mValue; //----------------------------------------------------------------------- public FloatEntry(DataInputStream inStream) throws IOException { mValue = inStream.readFloat(); } //----------------------------------------------------------------------- public float getValue() { return mValue; } } private class LongEntry extends ConstantPoolEntry { private long mValue; //----------------------------------------------------------------------- public LongEntry(DataInputStream inStream) throws IOException { mValue = inStream.readLong(); } //----------------------------------------------------------------------- public long getValue() { return mValue; } } private class DoubleEntry extends ConstantPoolEntry { private double mValue; //----------------------------------------------------------------------- public DoubleEntry(DataInputStream inStream) throws IOException { mValue = inStream.readDouble(); } //----------------------------------------------------------------------- public double getValue() { return mValue; } } private class StringEntry extends ConstantPoolEntry { private int mIndex; //----------------------------------------------------------------------- public StringEntry(DataInputStream inStream) throws IOException { mIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getIndex() { return mIndex; } } private class ClassEntry extends ConstantPoolEntry { private int mNameIndex; //----------------------------------------------------------------------- public ClassEntry(DataInputStream inStream) throws IOException { mNameIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getNameIndex() { return mNameIndex; } } private class NameAndTypeEntry extends ConstantPoolEntry { private int mMemberNameIndex; private int mTypeDescriptorIndex; //----------------------------------------------------------------------- public NameAndTypeEntry(DataInputStream inStream) throws IOException { mMemberNameIndex = inStream.readUnsignedShort(); mTypeDescriptorIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getMemberNameIndex() { return mMemberNameIndex; } //----------------------------------------------------------------------- public int getTypeDescriptorIndex() { return mTypeDescriptorIndex; } } private class InterfaceMethodrefEntry extends ConstantPoolEntry { private int mClassIndex; private int mNameAndTypeIndex; //----------------------------------------------------------------------- public InterfaceMethodrefEntry(DataInputStream inStream) throws IOException { mClassIndex = inStream.readUnsignedShort(); mNameAndTypeIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getClassIndex() { return mClassIndex; } //----------------------------------------------------------------------- public int getNameAndTypeIndex() { return mNameAndTypeIndex; } } private class MethodrefEntry extends ConstantPoolEntry { private int mClassIndex; private int mNameAndTypeIndex; //----------------------------------------------------------------------- public MethodrefEntry(DataInputStream inStream) throws IOException { mClassIndex = inStream.readUnsignedShort(); mNameAndTypeIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getClassIndex() { return mClassIndex; } //----------------------------------------------------------------------- public int getNameAndTypeIndex() { return mNameAndTypeIndex; } } private class FieldrefEntry extends ConstantPoolEntry { private int mClassIndex; private int mNameAndTypeIndex; //----------------------------------------------------------------------- public FieldrefEntry(DataInputStream inStream) throws IOException { mClassIndex = inStream.readUnsignedShort(); mNameAndTypeIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getClassIndex() { return mClassIndex; } //----------------------------------------------------------------------- public int getNameAndTypeIndex() { return mNameAndTypeIndex; } } private class MethodHandleEntry extends ConstantPoolEntry { private int mKind; private int mIndex; //----------------------------------------------------------------------- public MethodHandleEntry(DataInputStream inStream) throws IOException { mKind = inStream.readUnsignedByte(); mIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getKind() { return mKind; } //----------------------------------------------------------------------- public int getIndex() { return mIndex; } } private class MethodTypeEntry extends ConstantPoolEntry { private int mDescriptorIndex; //----------------------------------------------------------------------- public MethodTypeEntry(DataInputStream inStream) throws IOException { mDescriptorIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getDescriptorIndex() { return mDescriptorIndex; } } private class InvokeDynamicEntry extends ConstantPoolEntry { private int mBootstrapMethodAttrIndex; private int mNameAndTypeIndex; //----------------------------------------------------------------------- public InvokeDynamicEntry(DataInputStream inStream) throws IOException { mBootstrapMethodAttrIndex = inStream.readUnsignedShort(); mNameAndTypeIndex = inStream.readUnsignedShort(); } //----------------------------------------------------------------------- public int getBootstrapMethodAttrIndex() { return mBootstrapMethodAttrIndex; } //----------------------------------------------------------------------- public int getNameAndTypeIndex() { return mNameAndTypeIndex; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy