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

net.amygdalum.testrecorder.ClassNodeManager Maven / Gradle / Ivy

package net.amygdalum.testrecorder;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;

import net.amygdalum.testrecorder.util.IdentityWorkSet;

public class ClassNodeManager {

	private Map cache;

	public ClassNodeManager() {
		cache = new HashMap<>();
	}

	public ClassNode fetch(String className, ClassLoader loader) throws IOException {
		ClassNode classNode = cache.get(className);
		if (classNode == null) {
			ClassReader cr = readerFor(className, loader);
			classNode = new ClassNode();

			cr.accept(classNode, 0);
			cache.put(className, classNode);
		}
		return classNode;
	}

	private ClassReader readerFor(String className, ClassLoader loader) throws IOException {
		if (loader == null) {
			return new ClassReader(className);
		}
		InputStream stream = loader.getResourceAsStream(className.replace('.', '/') + ".class");
		if (stream == null) {
			return new ClassReader(className);
		}
		return new ClassReader(stream);
	}

	public ClassNode register(byte[] buffer) {
		ClassReader cr = new ClassReader(buffer);
		ClassNode classNode = new ClassNode();

		cr.accept(classNode, 0);
		cache.put(classNode.name, classNode);
		return classNode;
	}

	public MethodNode fetch(ClassNode classNode, String methodName, String methodDesc, ClassLoader loader) throws IOException, NoSuchMethodException {
		ClassNode currentClassNode = classNode;
		IdentityWorkSet interfaces = new IdentityWorkSet<>();
		while (currentClassNode != null) {
			for (MethodNode method : currentClassNode.methods) {
				if (method.name.equals(methodName) && method.desc.equals(methodDesc)) {
					return method;
				}
			}
			interfaces.addAll(currentClassNode.interfaces);
			currentClassNode = currentClassNode.superName == null ? null : fetch(currentClassNode.superName, loader);
		}

		while (interfaces.hasMoreElements()) {
			String interfaceName = interfaces.remove();
			currentClassNode = fetch(interfaceName, loader);
			for (MethodNode method : currentClassNode.methods) {
				if (method.name.equals(methodName) && method.desc.equals(methodDesc)) {
					return method;
				}
			}
			interfaces.addAll(currentClassNode.interfaces);
		}
		throw new NoSuchMethodException(methodName + methodDesc);
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy