package jadx.tests.api.compiler;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import java.io.IOException;
import java.security.SecureClassLoader;
import java.util.HashMap;
import java.util.Map;
import static javax.tools.JavaFileObject.Kind;
public class ClassFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
private DynamicClassLoader classLoader;
public ClassFileManager(StandardJavaFileManager standardManager) {
super(standardManager);
classLoader = new DynamicClassLoader();
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className,
Kind kind, FileObject sibling) throws IOException {
JavaClassObject clsObject = new JavaClassObject(className, kind);
classLoader.getClsMap().put(className, clsObject);
return clsObject;
}
@Override
public ClassLoader getClassLoader(Location location) {
return classLoader;
}
private class DynamicClassLoader extends SecureClassLoader {
private final Map<String, JavaClassObject> clsMap = new HashMap<String, JavaClassObject>();
private final Map<String, Class<?>> clsCache = new HashMap<String, Class<?>>();
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> cls = replaceClass(name);
if (cls != null) {
return cls;
}
return super.findClass(name);
}
public Class<?> loadClass(String name) throws ClassNotFoundException {
Class<?> cls = replaceClass(name);
if (cls != null) {
return cls;
}
return super.loadClass(name);
}
public Class<?> replaceClass(String name) throws ClassNotFoundException {
Class<?> cacheCls = clsCache.get(name);
if (cacheCls != null) {
return cacheCls;
}
JavaClassObject clsObject = clsMap.get(name);
if (clsObject == null) {
return null;
}
byte[] clsBytes = clsObject.getBytes();
Class<?> cls = super.defineClass(name, clsBytes, 0, clsBytes.length);
clsCache.put(name, cls);
return cls;
}
public Map<String, JavaClassObject> getClsMap() {
return clsMap;
}
}
}