package ro.isdc.wro.extensions.processor.support.template;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.lang3.StringUtils;
import org.mozilla.javascript.ScriptableObject;
import ro.isdc.wro.WroRuntimeException;
import ro.isdc.wro.extensions.script.RhinoScriptBuilder;
import ro.isdc.wro.util.WroUtil;
/**
* A base class for template processors like: dustJS or hoganJS.
*
* @author Eivind Barstad Waaler
* @since 1.4.7
* @created 11 May 2012
*/
public abstract class AbstractJsTemplateCompiler {
private ScriptableObject scope;
/**
* Compiles the javascript template into plain javascript.
*
* @param content
* the template to be compiled.
* @param optionalArgument
* any additional arguments used by template script.
* @return the compiled javascript.
*/
public String compile(final String content, final String optionalArgument) {
final RhinoScriptBuilder builder = initScriptBuilder();
final String argStr = createArgStr(optionalArgument) + createArgStr(getArguments());
final String compileScript =
String.format("%s(%s%s);", getCompileCommand(), WroUtil.toJSMultiLineString(content), argStr);
return (String) builder.evaluate(compileScript, getCompileCommand());
}
/**
* @return the js statement used to execute the compilation of the template.
*/
protected abstract String getCompileCommand();
/**
* @return additional arguments for the compiler.
*/
protected String getArguments() {
return null;
}
private String createArgStr(final String argument) {
return StringUtils.isNotBlank(argument) ? ", " + argument : "";
}
/**
* @return the stream of the compiler resource (javascript) used to compile templates.
* @throws IOException
* if the stream could not be located.
*/
protected abstract InputStream getCompilerAsStream() throws IOException;
private RhinoScriptBuilder initScriptBuilder() {
try {
RhinoScriptBuilder builder;
if (scope == null) {
builder = RhinoScriptBuilder.newClientSideAwareChain().evaluateChain(getCompilerAsStream(), "templateCompiler.js");
scope = builder.getScope();
} else {
builder = RhinoScriptBuilder.newChain(scope);
}
return builder;
} catch (final IOException ex) {
throw new WroRuntimeException("Failed reading init script", ex);
}
}
}