
org.test4j.mock.faking.util.ClassFile Maven / Gradle / Ivy
package org.test4j.mock.faking.util;
import g_asm.org.objectweb.asm.ClassReader;
import java.io.*;
import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import static org.test4j.mock.faking.util.ReflectUtility.doThrow;
/**
* class 文件读取
*
* @author darui.wu
*/
public final class ClassFile {
private ClassFile() {
}
/**
* class 是Object.class 或 Proxy.class
*
* @param aClass
* @return
*/
public static boolean notObjectOrProxy(Class aClass) {
return aClass != null && !Objects.equals(aClass, Object.class) && !Objects.equals(aClass, Proxy.class);
}
private static byte[] readBytesFromClassFile(String classDesc) {
return readBytes(classDesc);
}
public static byte[] readBytesFromClassFile(Class aClass) {
String classDesc = TypeUtility.classPath(aClass);
return readBytesFromClassFile(classDesc);
}
public static ClassReader getClassReader(Class clazz) {
byte[] bytes = ClassFile.readBytes(TypeUtility.classPath(clazz));
return new ClassReader(bytes);
}
public static byte[] readBytes(String classDesc) {
try (InputStream is = getClassInputStream(classDesc)) {
byte[] bytecode = new byte[is.available()];
int len = 0;
while (true) {
int n = is.read(bytecode, len, bytecode.length - len);
if (n == -1) {
if (len < bytecode.length) {
byte[] truncatedCopy = new byte[len];
System.arraycopy(bytecode, 0, truncatedCopy, 0, len);
bytecode = truncatedCopy;
}
return bytecode;
}
len += n;
if (len == bytecode.length) {
int last = is.read();
if (last < 0) {
return bytecode;
}
byte[] lengthenedCopy = new byte[bytecode.length + 1000];
System.arraycopy(bytecode, 0, lengthenedCopy, 0, len);
lengthenedCopy[len++] = (byte) last;
bytecode = lengthenedCopy;
}
}
} catch (IOException e) {
throw new RuntimeException("Failed to read class file for " + classDesc.replace('/', '.'), e);
}
}
/**
* 返回Class文件流
*
* @param classDesc
* @return
*/
private static InputStream getClassInputStream(String classDesc) {
String classFileName = classDesc + ".class";
InputStream inputStream = ClassLoad.CLASS_LOADER.getResourceAsStream(classFileName);
if (inputStream != null) {
return inputStream;
} else {
throw new NotFoundException(classDesc);
}
}
public static final class NotFoundException extends RuntimeException {
private NotFoundException(String classNameOrDesc) {
super("Unable to find class file for " + classNameOrDesc.replace('/', '.'));
}
}
private final static Set Print_Fakes = new HashSet<>();
/**
* 设置需要输出asm文件的类
*/
public static void initPrintFakes() {
String fakes = System.getProperty("PrintFake");
if (fakes == null || fakes.trim().isEmpty()) {
return;
}
String[] items = fakes.split("[,;]");
for (String item : items) {
if (item == null || item.trim().isEmpty()) {
continue;
}
Print_Fakes.add(item.trim());
}
}
/**
* 写字节码到文件中, 供测试查看
*
* @param fakeClass
* @param bytes
*/
public static void writeBytes4Debug(String fakeClass, byte[] bytes) {
if (!needPrintFakeFile(fakeClass)) {
return;
}
String fileName = System.getProperty("user.dir")
+ "/target/mock/"
+ fakeClass.replace('.', '/').replace('$', '.')
+ ".class";
File file = new File(fileName);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try (OutputStream out = new FileOutputStream(file);
InputStream is = new ByteArrayInputStream(bytes)) {
byte[] buff = new byte[1024];
int len = 0;
while ((len = is.read(buff)) != -1) {
out.write(buff, 0, len);
}
} catch (Exception e) {
doThrow(e);
}
}
private static boolean needPrintFakeFile(String fakeClass) {
if (Print_Fakes.isEmpty()) {
return false;
}
for (String namePart : Print_Fakes) {
if (fakeClass.contains(namePart)) {
return true;
}
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy