com.alibaba.bytekit.asm.meta.ClassMeta Maven / Gradle / Ivy
package com.alibaba.bytekit.asm.meta;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.alibaba.bytekit.utils.ClassLoaderUtils;
import com.alibaba.deps.org.objectweb.asm.ClassReader;
import com.alibaba.deps.org.objectweb.asm.Opcodes;
/**
* 从字节码 byte[] 中提取类的元信息
*
* @author hengyunabc 2020-11-20
*
*/
public class ClassMeta {
/**
* internal name 是 java/lang/String 的形式
*/
private String internalClassName;
/**
* internal name 是 java/lang/String 的形式
*/
private String internalSuperName;
private Set interfaces = new HashSet();
private ClassMeta superClassMeta;
private List interfaceClassMetas = null;
private int access;
private ClassLoader classLoader;
public ClassMeta() {
}
public ClassMeta(byte[] classfileBuffer, ClassLoader classLoader) {
ClassReader reader = new ClassReader(classfileBuffer);
this.internalClassName = reader.getClassName();
this.internalSuperName = reader.getSuperName();
String[] interfacesArray = reader.getInterfaces();
if (interfacesArray != null) {
for (String i : interfacesArray) {
this.interfaces.add(i);
}
}
this.access = reader.getAccess();
this.classLoader = ClassLoaderUtils.wrap(classLoader);
}
public static ClassMeta fromByteCode(byte[] classfileBuffer, ClassLoader classLoader) {
if (classfileBuffer == null) {
return null;
}
return new ClassMeta(classfileBuffer, classLoader);
}
public boolean isInterface() {
return (access & Opcodes.ACC_INTERFACE) > 0;
}
public ClassMeta getSuperclass() {
if (this.internalSuperName == null) {
return null;
}
if (superClassMeta == null) {
byte[] classBytes = ClassLoaderUtils.readBytecodeByName(classLoader, internalSuperName);
if (classBytes == null) {
// TODO 打印error?
return null;
}
superClassMeta = new ClassMeta(classBytes, classLoader);
}
return superClassMeta;
}
private boolean isSubclassOf(ClassMeta other) {
for (ClassMeta c = this; c != null; c = c.getSuperclass()) {
ClassMeta sc = c.getSuperclass();
if (sc != null && sc.internalClassName.equals(other.internalClassName)) {
return true;
}
}
return false;
}
List interfaceMetas() {
if (this.interfaceClassMetas == null) {
interfaceClassMetas = new ArrayList();
for (String interfaceName : interfaces) {
byte[] classBytes = ClassLoaderUtils.readBytecodeByName(classLoader, interfaceName);
if (classBytes == null) {
continue;
}
ClassMeta meta = new ClassMeta(classBytes, classLoader);
interfaceClassMetas.add(meta);
}
}
return interfaceClassMetas;
}
private boolean implementsInterface(ClassMeta other) {
if (this.equals(other)) {
return true;
}
for (ClassMeta c = this; c != null; c = c.getSuperclass()) {
for (ClassMeta in : c.interfaceMetas()) {
if (in.internalClassName.equals(other.internalClassName) || in.implementsInterface(other)) {
return true;
}
}
}
return false;
}
public boolean isAssignableFrom(ClassMeta other) {
return this.equals(other) || other.implementsInterface(this) || other.isSubclassOf(this)
|| (other.isInterface() && this.internalClassName.equals("Ljava/lang/Object;"));
}
/**
* 查找所有的 interface ,包含多重继承的
*
* @param classMetaCache
* @return
*/
public Set allInterfaces(ClassMetaCache classMetaCache) {
// TODO 每次都要向上多次查询,需要缓存一次结果不?
Set result = new HashSet(interfaces);
// 从 super 类里查找
if (internalSuperName != null) {
ClassMeta classMeta = classMetaCache.findClassMeta(internalSuperName);
if (classMeta != null) {
result.addAll(classMeta.allInterfaces(classMetaCache));
}
}
// 从实现的 interface里查找
for (String interfaceName : interfaces) {
ClassMeta classMeta = classMetaCache.findClassMeta(interfaceName);
if (classMeta != null) {
result.addAll(classMeta.allInterfaces(classMetaCache));
}
}
return result;
}
public List allSuperNames(ClassMetaCache classMetaCache) {
List result = new ArrayList();
String superName = internalSuperName;
for (; superName != null;) {
result.add(superName);
ClassMeta classMeta = classMetaCache.findClassMeta(superName);
if (classMeta == null) {
break;
} else {
superName = classMeta.getInternalSuperName();
}
}
return result;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((internalClassName == null) ? 0 : internalClassName.hashCode());
result = prime * result + ((internalSuperName == null) ? 0 : internalSuperName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
// TODO 是否要比较 classLoader?
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ClassMeta other = (ClassMeta) obj;
if (internalClassName == null) {
if (other.internalClassName != null)
return false;
} else if (!internalClassName.equals(other.internalClassName))
return false;
if (internalSuperName == null) {
if (other.internalSuperName != null)
return false;
} else if (!internalSuperName.equals(other.internalSuperName))
return false;
return true;
}
public String getInternalClassName() {
return internalClassName;
}
public void setInternalClassName(String internalClassName) {
this.internalClassName = internalClassName;
}
public String getInternalSuperName() {
return internalSuperName;
}
public void setInternalSuperName(String internalSuperName) {
this.internalSuperName = internalSuperName;
}
public Set getInterfaces() {
return interfaces;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy