package php.runtime.ext.core.classes;
import php.runtime.annotation.Reflection.Name;
import php.runtime.annotation.Reflection.Signature;
import php.runtime.env.Environment;
import php.runtime.env.SplClassLoader;
import php.runtime.ext.CoreExtension;
import php.runtime.invoke.Invoker;
import php.runtime.lang.BaseObject;
import php.runtime.memory.ArrayMemory;
import php.runtime.reflection.ClassEntity;
import php.runtime.reflection.ModuleEntity;
@Name("php\\lang\\ClassLoader")
abstract public class WrapClassLoader extends BaseObject {
protected SplClassLoader splClassLoader;
public WrapClassLoader(Environment env, ClassEntity clazz) {
super(env, clazz);
}
@Signature
public void __construct() { }
@Signature
abstract public boolean loadClass(Environment env, String className) throws Throwable;
@Signature
public void register(Environment env, boolean prepend) {
if (splClassLoader == null) {
env.registerAutoloader(_getSplClassLoader(env), prepend);
} else {
env.exception("ClassLoader is already registered");
}
}
@Signature
public void unregister(Environment env) {
if (splClassLoader == null) {
env.exception("ClassLoader is not registered");
}
env.unRegisterAutoloader(splClassLoader);
splClassLoader = null;
}
synchronized protected SplClassLoader _getSplClassLoader(Environment env) {
if (splClassLoader == null) {
ArrayMemory callback = new ArrayMemory();
callback.add(this);
callback.add("loadClass");
Invoker invoker = Invoker.valueOf(env, null, callback);
splClassLoader = new SplClassLoader(invoker, callback);
}
return splClassLoader;
}
@Name(CoreExtension.NAMESPACE + "util\\LauncherClassLoader")
public static class WrapLauncherClassLoader extends WrapClassLoader {
public WrapLauncherClassLoader(Environment env, ClassEntity clazz) {
super(env, clazz);
}
@Override
@Signature
public boolean loadClass(Environment env, String className) throws Throwable {
String file = className.replace('\\', '/');
if (file.startsWith("\\") || file.startsWith("/")) {
file = file.substring(1);
}
ModuleEntity entity = fetchClass(env, file + ".phb", true);
if (entity != null) {
entity.include(env);
return true;
}
entity = fetchClass(env, file + ".php", false);
if (entity != null) {
entity.include(env);
return true;
}
return false;
}
protected ModuleEntity fetchClass(Environment env, String fileName, boolean compiled) throws Throwable {
return env.getModuleManager().fetchModule("res://" + fileName, compiled);
}
}
}