package org.webpieces.compiler.impl;
import org.webpieces.util.logging.Logger;
import org.webpieces.util.logging.LoggerFactory;
import org.webpieces.compiler.api.CompileConfig;
import org.webpieces.compiler.api.CompileOnDemand;
public class CompileOnDemandImpl implements CompileOnDemand {
private static final Logger log = LoggerFactory.getLogger(CompileOnDemandImpl.class);
private final CompileConfig config;
private final CompileMetaMgr appClassMgr;
private final FileLookup fileLookup;
private final CompilerWrapper compiler;
public CompilingClassloader classloader;
public CompileOnDemandImpl(CompileConfig config) {
this(config, "");
}
public CompileOnDemandImpl(CompileConfig config, String basePackage) {
this.config = config;
appClassMgr = new CompileMetaMgr(config);
fileLookup = new FileLookup(appClassMgr, config.getJavaPath());
compiler = new CompilerWrapper(appClassMgr, fileLookup, config);
classloader = new CompilingClassloader(config, compiler, fileLookup);
fileLookup.scanFilesWithFilter(basePackage);
log.info("using bytecode cache directory="+config.getByteCodeCacheDir());
log.info("using src directories to compile from="+config.getJavaPath());
}
@Override
public Class<?> loadClass(String name) {
if(classloader.isNeedToReloadJavaFiles()) {
classloader = new CompilingClassloader(config, compiler, fileLookup);
}
Class<?> clazz = classloader.loadApplicationClass(name);
if(clazz == null) {
clazz = loadClassFromDefaultClassloader(name);
}
if(clazz == null)
throw new IllegalArgumentException("class name="+name+" is not found in the source directories="+config.getJavaPath()+" nor on the classpath");
return clazz;
}
private Class<?> loadClassFromDefaultClassloader(String name) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
return cl.loadClass(name);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("class name="+name+" is not found in the source directories="+config.getJavaPath()+" nor on the classpath");
}
}
@Override
public Class<?> loadClass(String name, boolean forceReload) {
if(forceReload) {
classloader = new CompilingClassloader(config, compiler, fileLookup);
}
return loadClass(name);
}
}