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

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