use of cn.bran.japid.rendererloader.TemplateClassLoader in project Japid by branaway.
the class JapidRenderer method loadRendererClass.
private static Class<? extends JapidTemplateBaseWithoutPlay> loadRendererClass(RendererClass rc) {
// the template may refer to model classes etc available only from the
// parent class loader
ClassLoader cl = _parentClassLoader == null ? JapidRenderer.class.getClassLoader() : _parentClassLoader;
// do I need to new instance of TemplateClassLoader for each invocation?
// likely...
TemplateClassLoader classReloader = new TemplateClassLoader(cl);
try {
Class<JapidTemplateBaseWithoutPlay> loadClass = (Class<JapidTemplateBaseWithoutPlay>) classReloader.loadClass(rc.getClassName());
rc.setClz(loadClass);
return loadClass;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
use of cn.bran.japid.rendererloader.TemplateClassLoader in project japid42 by branaway.
the class JapidRenderer method registerTemplate.
/**
* To register a template in the Japid engine. Once a template is
* registered, the template class can be retrieved with the name by invoking
* {@link #getClass(String)} or {@link #getRendererClass(String)}.
*
* This method can be used at runtime to compile a Japid script and later
* use it to render data by invoking
* JapidController.renderJapidWith(className, args...);
*
* @author Bing Ran (bing.ran@gmail.com)
* @param mimeType
* the MIME type of content generated by this template.
* @param source
* the script source of the Japid template
* @param key
* the key that the source script is registered under. must be in
* the form of a valid Java class name
* @return returns the key, which is prefixed with "japidviews." if it was
* not so
*/
public static String registerTemplate(MimeTypeEnum mimeType, String source, String key) {
refreshClasses();
if (!key.startsWith(JAPIDVIEWS)) {
key = JAPIDVIEWS + "." + key.replace('-', '_').replace(' ', '_');
}
RendererClass cl = dynamicClasses.get(key);
if (cl != null) {
if (source.equals(cl.getJapidSourceCode())) {
return key;
}
}
try {
String javaCode = JapidTemplateTransformer.generateInMemory(source, key, mimeType, usePlay);
JapidFlags.log("converted: " + key);
// System.out.println(javaCode);
RendererClass rc = newRendererClass(key);
rc.setJapidSourceCode(source);
rc.setJavaSourceCode(javaCode);
removeInnerClasses(key);
cleanByteCode(rc);
// remember the current impl of class
japidClasses.put(key, rc);
// refresh will erase dynamic template
// class from this container.
compiler.compile(new String[] { key });
dynamicClasses.put(key, rc);
TemplateClassLoader loader = getClassLoader();
loader.loadClass(key);
} catch (Exception e) {
if (e instanceof JapidTemplateException)
throw (JapidTemplateException) e;
throw new RuntimeException(e);
}
return key;
}
use of cn.bran.japid.rendererloader.TemplateClassLoader in project japid42 by branaway.
the class JapidRenderer method refreshClasses.
static synchronized void refreshClasses() {
if (!classesInited) {
classesInited = true;
} else {
if (!timeToRefresh())
return;
}
if (templateRoots == null)
return;
if (!JapidRenderer.keepJavaFiles) {
refreshClassesInMemory();
return;
}
try {
// there are two passes of directory scanning. XXX
String[] allTemps = DirUtil.getAllTemplateFileNames(templateRoots);
Set<String> currentClassesOnDir = createClassNameSet(allTemps);
Set<String> allScriptNames = new HashSet<String>(currentClassesOnDir);
Set<String> keySet = japidClasses.keySet();
if (!keySet.equals(currentClassesOnDir)) {
Set<String> classNamesRegistered = new HashSet<String>(keySet);
Set<String> classNamesDir = new HashSet<String>(currentClassesOnDir);
if (classNamesRegistered.containsAll(classNamesDir)) {
classNamesRegistered.removeAll(classNamesDir);
if (!classNamesRegistered.isEmpty()) {
for (String n : classNamesRegistered) {
if (!n.contains("$")) {
// if (!japidClasses.get(n).fromJar()) {
if (!specialClasses.contains(n)) {
touch();
break;
}
}
}
}
} else {
touch();
}
} else {
// no name changes
}
// got new templates
allScriptNames.removeAll(keySet);
removeRemoved(currentClassesOnDir, keySet);
for (String c : allScriptNames) {
RendererClass rc = newRendererClass(c);
japidClasses.put(c, rc);
}
// now all the class set size is up to date
// now update any Java source code
// second disk scanning.
List<File> gen = gen(templateRoots);
// this would include both new and updated java
Set<String> updatedClasses = new HashSet<String>();
if (gen.size() > 0) {
for (File f : gen) {
String className = getClassName(f);
updatedClasses.add(className);
RendererClass rendererClass = japidClasses.get(className);
if (rendererClass == null) {
// this should not happen, since
throw new RuntimeException("any new class names should have been in the classes container: " + className);
// rendererClass = newRendererClass(className);
// japidClasses.put(className, rendererClass);
}
setSources(rendererClass, f);
removeInnerClasses(className);
cleanByteCode(rendererClass);
}
}
// find all render class without bytecode
for (Iterator<String> i = japidClasses.keySet().iterator(); i.hasNext(); ) {
String k = i.next();
RendererClass rc = japidClasses.get(k);
if (rc.getJavaSourceCode() == null) {
if (!rc.getClassName().contains("$")) {
try {
setSources(rc, k);
} catch (Exception e) {
JapidFlags.log("Cannot find the source Java file for " + rc.getClassName() + ". Dropped.");
i.remove();
continue;
}
cleanByteCode(rc);
updatedClasses.add(k);
} else {
rc.setLastUpdated(0);
}
} else {
if (rc.getBytecode() == null) {
cleanByteCode(rc);
updatedClasses.add(k);
}
}
}
// compile all
if (updatedClasses.size() > 0) {
dynamicClasses.clear();
String[] names = new String[updatedClasses.size()];
int i = 0;
for (String s : updatedClasses) {
names[i++] = s;
}
long t = System.currentTimeMillis();
// newly compiled class bytecode bodies are set in the global
// classes set ready for defining
compiler.compile(names);
howlong("compile time for " + names.length + " classes", t);
for (String k : japidClasses.keySet()) {
japidClasses.get(k).setClz(null);
}
TemplateClassLoader loader = getClassLoader();
for (String cname : updatedClasses) {
loader.loadClass(cname);
}
}
} catch (Exception e) {
if (e instanceof JapidTemplateException)
throw (JapidTemplateException) e;
throw new RuntimeException(e);
}
}
Aggregations