use of cn.bran.japid.rendererloader.TemplateClassLoader in project Japid by branaway.
the class JapidRenderer method refreshClasses.
static synchronized void refreshClasses() {
if (!timeToRefresh())
return;
try {
// find out all removed classes
List<String> allHtml = DirUtil.getAllTemplateHtmlFiles(new File(templateRoot));
Set<String> currentClassesOnDir = createNameSet(allHtml);
Set<String> tmp = new HashSet<String>(currentClassesOnDir);
Set<String> keySet = classes.keySet();
// added html
tmp.removeAll(keySet);
removeRemoved(currentClassesOnDir, keySet);
for (String c : tmp) {
RendererClass rc = newRendererClass(c);
classes.put(c, rc);
}
// now all the class set size is up to date
// now update any Java source code
List<File> gen = gen(templateRoot);
// this would include both new and updated java
Set<String> updatedClasses = new HashSet<String>();
if (gen.size() > 0) {
// int i = 0;
for (File f : gen) {
String className = getClassName(f);
updatedClasses.add(className);
RendererClass rendererClass = classes.get(className);
if (rendererClass == null) {
// this should not happen, since
throw new RuntimeException("any new key should have been in the classes container: " + className);
// rendererClass = newRendererClass(className);
// classes.put(className, rendererClass);
}
setSources(rendererClass, f);
removeInnerClasses(className);
cleanClassHolder(rendererClass);
}
}
// find all render class without bytecode
for (Iterator<String> i = classes.keySet().iterator(); i.hasNext(); ) {
String k = i.next();
RendererClass rc = classes.get(k);
if (rc.getSourceCode() == null) {
if (!rc.getClassName().contains("$")) {
setSources(rc, getJavaSrcFile(k));
cleanClassHolder(rc);
updatedClasses.add(k);
} else {
rc.setLastUpdated(0);
}
} else {
if (rc.getBytecode() == null) {
cleanClassHolder(rc);
updatedClasses.add(k);
}
}
}
// compile all
if (updatedClasses.size() > 0) {
String[] names = new String[updatedClasses.size()];
int i = 0;
for (String s : updatedClasses) {
names[i++] = s;
}
long t = System.currentTimeMillis();
compiler.compile(names);
// shall I load them right away?
// let's try
ClassLoader cl = _parentClassLoader == null ? JapidRenderer.class.getClassLoader() : _parentClassLoader;
TemplateClassLoader classReloader = new TemplateClassLoader(cl);
for (RendererClass rc : classes.values()) {
try {
if (isDevMode())
// to enable JIT loading in dev mode
rc.setClz(null);
else
rc.setClz((Class<JapidTemplateBaseWithoutPlay>) classReloader.loadClass(rc.getClassName()));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
howlong("compile/load time for " + names.length + " classes", t);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of cn.bran.japid.rendererloader.TemplateClassLoader in project japid42 by branaway.
the class JapidRenderer method refreshClassesInMemory.
/**
* all artifacts in memory
*
* @author Bing Ran (bing.ran@gmail.com)
*/
static synchronized void refreshClassesInMemory() {
if (templateRoots == null)
return;
try {
Set<File> allTemplates = DirUtil.getAllTemplateFiles(templateRoots);
Set<File> toBeUpdated = new HashSet<File>();
// find out all the classes that need to be updated
for (File tf : allTemplates) {
String cname = getClassName(tf);
RendererClass rc = japidClasses.get(cname);
if (rc == null) {
toBeUpdated.add(tf);
} else if (rc.getScriptTimestamp() < tf.lastModified()) {
toBeUpdated.add(tf);
} else if (rc.getJavaSourceCode() == null || rc.getJavaSourceCode().length() == 0) {
toBeUpdated.add(tf);
} else if (rc.getBytecode() == null || rc.getBytecode().length == 0) {
toBeUpdated.add(tf);
}
}
Set<String> currentClassesOnDir = createClassNameSet(allTemplates);
Set<String> currentClassNames = japidClasses.keySet();
if (!currentClassNames.equals(currentClassesOnDir)) {
Set<String> classNamesRegistered = new HashSet<String>(currentClassNames);
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 (!specialClasses.contains(n)) {
touch();
break;
}
}
}
}
} else {
touch();
}
} else {
// no name changes
}
// allClassNamesOnDir.removeAll(currentClassNames); // got new
// templates
removeRemoved(currentClassesOnDir, currentClassNames);
for (File tb : toBeUpdated) {
String scriptSrc = DirUtil.readFileAsString(tb);
String javaCode = JapidTemplateTransformer.generateInMemory(scriptSrc, cleanPath(tb), usePlay);
JapidFlags.log("converted: " + tb.getPath());
String className = getClassName(tb);
RendererClass rc = newRendererClass(className);
rc.setScriptFile(tb);
rc.setJapidSourceCode(scriptSrc);
rc.setJavaSourceCode(javaCode);
removeInnerClasses(className);
cleanByteCode(rc);
japidClasses.put(className, rc);
}
setupImports();
// compile all
if (toBeUpdated.size() > 0) {
// XXX why clear the dynamics?
dynamicClasses.clear();
Set<String> names = createClassNameSet(toBeUpdated);
long t = System.currentTimeMillis();
compiler.compile(names.toArray(new String[] {}));
howlong("compile time for " + names.size() + " classes", t);
TemplateClassLoader loader = getClassLoader();
for (String cname : names) {
loader.loadClass(cname);
}
}
} catch (Exception e) {
if (e instanceof JapidTemplateException)
throw (JapidTemplateException) e;
throw new RuntimeException(e);
}
}
use of cn.bran.japid.rendererloader.TemplateClassLoader in project japid42 by branaway.
the class JapidRenderer method getClassLoader.
// cache the classloader for a delay to buffer consecutive requests
// applicable to debug mode only
private static synchronized TemplateClassLoader getClassLoader() {
if (parentClassLoader == null)
throw new RuntimeException("parentClassLoader is null");
long now = System.currentTimeMillis();
if (now - newClassLoaderCreated > 2000 || lastClassLoader == null) {
newClassLoaderCreated = now;
lastClassLoader = new TemplateClassLoader(parentClassLoader);
}
return lastClassLoader;
}
use of cn.bran.japid.rendererloader.TemplateClassLoader in project japid42 by branaway.
the class JapidRenderer method init.
/**
* The <em>required</em> initialization step in using the JapidRender.
*
* @param opMode
* the operational mode of Japid. When set to OpMode.prod, it's
* assumed that all Java derivatives are already been generated
* and used directly. When set to OpMode.dev, and using
* none-static linking to using the renderer, file system changes
* are detected for every rendering request given the refresh
* interval is respected. New Java files are generated and
* compiled and new classes are loaded to serve the request.
* @param templateRoot
* the root directory to contain the "japidviews" directory tree.
* @param refreshInterval
* the minimal time, in second, that must elapse before trying to
* detect any changes in the file system.
* @param app
* the Play application instance
* @throws IOException
*/
public static void init(OpMode opMode, String[] templateRoot, int refreshInterval, Map<String, Object> app, ClassLoader clr) throws IOException {
specialClasses.clear();
showCurrentDirectory();
File cf = new File(".");
String path = cf.getAbsolutePath();
setClassCacheRoot(path);
japidResourceCompiled = false;
inited = true;
JapidRenderer.opMode = opMode == null ? OpMode.dev : opMode;
if (!rootsSet)
setTemplateRoot(templateRoot);
setRefreshInterval(refreshInterval);
boolean yesno = false;
try {
String property = (String) app.get("japid.trace.file.html");
if (property == null)
yesno = false;
else if ("on".equalsIgnoreCase(property) || "yes".equalsIgnoreCase(property))
yesno = true;
} catch (Exception e) {
}
JapidTemplateBaseWithoutPlay.globalTraceFileHtml = yesno;
try {
String property = (String) app.get("japid.trace.file.json");
if (property == null)
yesno = false;
else if ("on".equalsIgnoreCase(property) || "yes".equalsIgnoreCase(property))
yesno = true;
} catch (Exception e) {
}
JapidTemplateBaseWithoutPlay.globalTraceFileJson = yesno;
// System.out.println("parent classloader: " + clr);
parentClassLoader = clr;
TemplateClassLoader classLoader = getClassLoader();
compiler = new RendererCompiler(japidClasses, classLoader);
// if (usePlay)
// initErrorRenderer();
touch();
if (opMode == OpMode.dev)
recoverClasses();
dynamicClasses.clear();
DirUtil.curVersion = VERSION;
AbstractTemplateClassMetaData.curVersion = VERSION;
JapidFlags.debug("Before compiling Japid script from classpath. version " + VERSION);
setupImports();
compileJapidResources();
try {
refreshClasses();
} catch (Exception e) {
JapidFlags.log("There was an error in refreshing the japid classes. Will show the error in detail in processing a request: " + e);
}
System.out.println("[Japid] initialized version " + VERSION + " in " + getOpMode() + " mode");
}
use of cn.bran.japid.rendererloader.TemplateClassLoader in project Japid by branaway.
the class JapidRenderer method init.
/**
* The <em>required</em> initialization step in using the JapidRender.
*
* @param opMode
* the operational mode of Japid. When set to OpMode.prod, it's
* assumed that all Java derivatives are already been generated
* and used directly. When set to OpMode.dev, and using
* none-static linking to using the renderer, file system changes
* are detected for every rendering request given the refresh
* interval is respected. New Java files are generated and
* compiled and new classes are loaded to serve the request.
* @param templateRoot
* the root directory to contain the "japidviews" directory tree.
* @param refreshInterval
* the minimal time, in second, that must elapse before trying to
* detect any changes in the file system.
* @param usePlay
* to indicate if the generated template classes are to be used
* with play. if true, Play's implicit objects are available in
* the japid script.
*/
public static void init(OpMode opMode, String templateRoot, int refreshInterval, ClassLoader parentClassLoader, boolean usePlay) {
JapidRenderer.opMode = opMode;
setTemplateRoot(templateRoot);
setRefreshInterval(refreshInterval);
_parentClassLoader = parentClassLoader;
if (_parentClassLoader == null) {
_parentClassLoader = JapidRenderer.class.getClassLoader();
}
crlr = new TemplateClassLoader(parentClassLoader);
compiler = new RendererCompiler(classes, crlr);
JapidRenderer.usePlay = usePlay;
refreshClasses();
inited = true;
System.out.println("[Japid] initialized version " + VERSION + " in " + getOpMode() + " mode");
}
Aggregations