package org.nocket.page;
import java.util.ArrayList;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import org.apache.commons.lang.ClassUtils;
import org.nocket.rtcompile.CharSequenceJavaFileObject;
import org.nocket.rtcompile.ClassFileManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class allows two create generic Page classes at runtime using the
* in-memory runtime compiler from package org.nocket.rtcompile. The structure of a
* fully generic page class is absolutely canonic and therefore can completely
* be derived from the domain class to display.
*
* @author less02
*/
abstract public class InMemoryClassBuilder {
private static final Logger log = LoggerFactory.getLogger(InMemoryClassBuilder.class);
protected final String packageName;
protected final Class<?> domainClass;
public InMemoryClassBuilder(Class<?> domainClass) {
//TODO JL: Konfiguration aus gengui lesen:
// - Soll die dynamische Erzeugung überhaupt passieren?
// - Soll sie auch passieren, wenn noch nicht mal das HTML existiert?
//TODO L: Prüfung auf Serializable der domainClass
this.domainClass = domainClass;
this.packageName = ClassUtils.getPackageName(domainClass);
}
public Class<?> buildClassInMemory() throws ClassNotFoundException {
String fullyQualifiedClassName = fullyQualifiedClassName();
String sourcecode = constructSourceCode();
log.debug("Compiling source code in memory: " + sourcecode);
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileManager fileManager =
new ClassFileManager(compiler.getStandardFileManager(null, null, null));
List<JavaFileObject> jfiles = new ArrayList<JavaFileObject>();
jfiles.add(new CharSequenceJavaFileObject(fullyQualifiedClassName, new StringBuilder(sourcecode)));
compiler.getTask(null, fileManager, null, null, null, jfiles).call();
Class<?> clazz = fileManager.getClassLoader(null).loadClass(fullyQualifiedClassName);
log.debug("Compilation successful: " + clazz);
return clazz;
}
protected abstract String fullyQualifiedClassName();
protected abstract String constructSourceCode();
}