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

co.paralleluniverse.common.reflection.ASMUtil Maven / Gradle / Ivy

Go to download

The core library for Fibers on Java, compatible with Java 11-16. Forked from puniverse/quasar

There is a newer version: 10.0.6
Show newest version
/*
 * Quasar: lightweight threads and actors for the JVM.
 * Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved.
 * 
 * This program and the accompanying materials are dual-licensed under
 * either the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation
 *  
 *   or (per the licensee's choosing)
 *  
 * under the terms of the GNU Lesser General Public License version 3.0
 * as published by the Free Software Foundation.
 */
package co.paralleluniverse.common.reflection;

import static co.paralleluniverse.common.reflection.ClassLoaderUtil.classToResource;
import static co.paralleluniverse.common.reflection.ClassLoaderUtil.classToSlashed;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;

/**
 *
 * @author pron
 */
public final class ASMUtil {
    public static InputStream getClassInputStream(String className, ClassLoader cl) {
        final String resource = classToResource(className);
        return cl != null ? cl.getResourceAsStream(resource) : ClassLoader.getSystemResourceAsStream(resource);
    }

    public static InputStream getClassInputStream(Class clazz) {
        final InputStream is = getClassInputStream(clazz.getName(), clazz.getClassLoader());
        if (is == null)
            throw new UnsupportedOperationException("Class file " + clazz.getName() + " could not be loaded by the class's classloader " + clazz.getClassLoader());
        return is;
    }

    public static byte[] getClass(String className, ClassLoader cl) throws IOException {
        try (InputStream is = getClassInputStream(className, cl)) {
            return ByteStreams.toByteArray(is);
        }
    }

    public static byte[] getClass(Class klass) throws IOException {
        try (InputStream is = getClassInputStream(klass)) {
            return ByteStreams.toByteArray(is);
        }
    }

    public static  T accept(InputStream is, int flags, T visitor) throws IOException {
        if (is == null)
            return null;
        try (InputStream is1 = is) {
            new ClassReader(is1).accept(visitor, flags);
            return visitor;
        }
    }

    public static  T accept(byte[] buffer, int flags, T visitor) throws IOException {
        if (buffer == null)
            throw new NullPointerException("Buffer is null");
        new ClassReader(buffer).accept(visitor, flags);
        return visitor;
    }

    public static  T accept(String className, ClassLoader cl, int flags, T visitor) throws IOException {
        return accept(getClassInputStream(className, cl), flags, visitor);
    }

    public static  T accept(Class clazz, int flags, T visitor) throws IOException {
        return accept(getClassInputStream(clazz), flags, visitor);
    }

    public static ClassNode getClassNode(InputStream is, boolean skipCode) throws IOException {
        return accept(is,
                ClassReader.SKIP_DEBUG | (skipCode ? 0 : ClassReader.SKIP_CODE),
                new ClassNode());
    }

    public static ClassNode getClassNode(String className, ClassLoader cl, boolean skipCode) throws IOException {
        final ClassNode cn = getClassNode(getClassInputStream(className, cl), skipCode);
        if (cn == null)
            throw new IOException("Resource " + classToResource(className) + " not found.");
        return cn;
    }

    public static ClassNode getClassNode(Class clazz, boolean skipCode) throws IOException {
        return getClassNode(getClassInputStream(clazz), skipCode);
    }

    public static boolean hasAnnotation(String annDesc, List anns) {
        if (anns == null)
            return false;
        for (AnnotationNode ann : anns) {
            if (ann.desc.equals(annDesc))
                return true;
        }
        return false;
    }

    public static boolean hasAnnotation(Class ann, List anns) {
        return hasAnnotation(Type.getDescriptor(ann), anns);
    }

    public static boolean hasAnnotation(String annDesc, ClassNode c) {
        return hasAnnotation(annDesc, c.visibleAnnotations);
    }

    public static boolean hasAnnotation(Class ann, ClassNode c) {
        return hasAnnotation(ann, c.visibleAnnotations);
    }

    public static boolean hasAnnotation(String annDesc, MethodNode m) {
        return hasAnnotation(annDesc, m.visibleAnnotations);
    }

    public static boolean hasAnnotation(Class ann, MethodNode m) {
        return hasAnnotation(ann, m.visibleAnnotations);
    }

    public static boolean hasAnnotation(String annDesc, FieldNode f) {
        return hasAnnotation(annDesc, f.visibleAnnotations);
    }

    public static boolean hasAnnotation(Class ann, FieldNode f) {
        return hasAnnotation(ann, f.visibleAnnotations);
    }

    public static MethodNode getMethod(MethodNode method, List ms) {
        if (ms == null)
            return null;
        for (MethodNode m : ms) {
            if (equals(method, m))
                return m;
        }
        return null;
    }

    public static MethodNode getMethod(MethodNode method, ClassNode c) {
        return getMethod(method, c.methods);
    }

    public static boolean hasMethod(MethodNode method, List ms) {
        return getMethod(method, ms) != null;
    }

    public static boolean hasMethod(MethodNode method, ClassNode c) {
        return hasMethod(method, c.methods);
    }

    public static boolean equals(MethodNode m1, MethodNode m2) {
//        if (Objects.equals(m1.name, m2.name) && m1.signature != null && Objects.equals(m1.signature, m2.signature) != Objects.equals(m1.desc, m2.desc))
//            System.err.println("XXXXX WARN desc and signtures not equal " + m1.name + ":" + m1.desc + ":" + m1.signature + " vs " + m2.desc + ":" + m2.signature);
        return Objects.equals(m1.name, m2.name) && Objects.equals(m1.desc, m2.desc);
    }

    public static boolean equals(ClassNode c1, ClassNode c2) {
        return Objects.equals(c1.name, c2.name);
    }

    public static boolean isAssignableFrom(Class supertype, String className, ClassLoader cl) {
        return isAssignableFrom0(classToSlashed(supertype), classToSlashed(className), cl);
    }

    public static boolean isAssignableFrom(String supertypeName, String className, ClassLoader cl) {
        return isAssignableFrom0(classToSlashed(supertypeName), classToSlashed(className), cl);
    }

    private static boolean isAssignableFrom0(String supertypeName, String className, ClassLoader cl) {
        try {
            if (className == null)
                return false;
            if (supertypeName.equals(className))
                return true;
            ClassNode cn = getClassNode(className, cl, true);

            if (supertypeName.equals(cn.superName))
                return true;
            if (isAssignableFrom0(supertypeName, cn.superName, cl))
                return true;

            if (cn.interfaces != null) {
                for (String iface : (List) cn.interfaces) {
                    if (supertypeName.equals(iface))
                        return true;
                    if (isAssignableFrom0(supertypeName, iface, cl))
                        return true;
                }
            }
            return false;
        } catch (IOException e) {
            // e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    
    public static String getDescriptor(Member m) {
        if (m instanceof Method)
            return Type.getMethodDescriptor((Method) m);
        if (m instanceof Constructor)
            return Type.getConstructorDescriptor((Constructor) m);
        throw new IllegalArgumentException("Not an executable: " + m);
    }
    
    public static String getReadableDescriptor(String descriptor) {
        Type[] types = Type.getArgumentTypes(descriptor);
        StringBuilder sb = new StringBuilder();
        sb.append("(");
        for (int i = 0; i < types.length; i++) {
            if (i > 0)
                sb.append(", ");
            sb.append(types[i].getClassName());
        }
        sb.append(")");
        return sb.toString();
    }
    
    private ASMUtil() {
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy