/**
* jetbrick-template
* http://subchen.github.io/jetbrick-template/
*
* Copyright 2010-2014 Guoqiang Chen. All rights reserved.
* Email: subchen@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrick.template.compiler;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import jetbrick.template.JetConfig;
import jetbrick.template.JetConfig.CompileStrategy;
import jetbrick.template.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JetTemplateClassLoader {
private final Logger log = LoggerFactory.getLogger(JetTemplateClassLoader.class);
private final File outputdir;
private final URL[] urls;
private final ClassLoader classloader;
private final boolean reloadable;
public JetTemplateClassLoader(JetConfig config) {
this.outputdir = getCanonicalClasspath(config.getCompilePath());
this.urls = new URL[] { URLUtils.fromFile(this.outputdir) };
this.classloader = createClassLoader();
this.reloadable = config.isTemplateReloadable() && config.getCompileStrategy() != CompileStrategy.none;
log.info("Will compile template into " + this.outputdir);
}
public Class<?> loadClass(String qualifiedClassName) throws ClassNotFoundException {
if (reloadable) {
// 为了可以动态卸载 Class,需要每次重新 new 一个 URLClassLoader
ClassLoader classloader = createClassLoader();
return classloader.loadClass(qualifiedClassName);
} else {
return classloader.loadClass(qualifiedClassName);
}
}
// 编译的目标路径
public File getOutputdir() {
return outputdir;
}
// 返回生成的 .java 文件对象
public File getGeneratedJavaSourceFile(String qualifiedClassName) {
String fileName = qualifiedClassName.replace('.', '/');
return new File(outputdir, fileName + ".java");
}
// 返回生成的 .class 文件对象
public File getGeneratedJavaClassFile(String qualifiedClassName) {
String fileName = qualifiedClassName.replace('.', '/');
return new File(outputdir, fileName + ".class");
}
private ClassLoader createClassLoader() {
return new URLClassLoader(urls, ClassLoaderUtils.getContextClassLoader());
}
private static File getCanonicalClasspath(String outputdir) {
File dir = new File(outputdir);
// 必须先建立目录,否则 URLClassLoader 会失败
if (!dir.mkdirs() && !dir.exists()) {
throw new IllegalStateException("Can't create a directory in " + dir.getAbsolutePath());
}
return PathUtils.getCanonicalFile(dir);
}
}