calate.scalate-generator_2.11.0.5.0.source-code.Generator.scala Maven / Gradle / Ivy
The newest version!
package com.mojolly.scalate
import org.fusesource.scalate.{ TemplateEngine, TemplateSource, Binding }
import org.fusesource.scalate.util.IOUtil
import java.io.File
/**
* Uses the Scalate template engine to generate Scala source files for Scalate templates.
*/
class Generator {
var sources: File = _
var targetDirectory: File = _
var logConfig: File = _
var overwrite: Boolean = _
var scalateImports: Array[String] = Array.empty
var scalateBindings: Array[Array[AnyRef]] = Array.empty // weird structure to represent Scalate Binding
var packagePrefix: String = _
lazy val engine = {
val e = new TemplateEngine
// initialize template engine
e.importStatements = scalateImports.toList
e.bindings = (scalateBindings.toList map { b =>
Binding(
b(0).asInstanceOf[String],
b(1).asInstanceOf[String],
b(2).asInstanceOf[Boolean],
(b(3) match {
case null | "" => None
case a => Some(a.toString)
}),
b(4).asInstanceOf[String],
b(5).asInstanceOf[Boolean])
}) ::: e.bindings
e
}
def execute: Array[File] = {
System.setProperty("logback.configurationFile", logConfig.toString)
if (sources == null) {
throw new IllegalArgumentException("The sources property is not properly set")
}
if (targetDirectory == null) {
throw new IllegalArgumentException("The targetDirectory property is not properly set")
}
engine.packagePrefix = packagePrefix
targetDirectory.mkdirs
var compileTargets = List.empty[CompileTarget]
for (extension <- engine.codeGenerators.keysIterator) {
compileTargets = collectCompileTargets(sources, "", "." + extension) ::: compileTargets
}
compileTargets collect {
case NotModified(scalaFile) =>
scalaFile
case Updated(uri, templateFile, scalaFile) =>
var code:String = ""
try {
val template = TemplateSource.fromFile(templateFile, uri)
code = engine.generateScala(template).source
} catch {
case e:Exception => {
throw new Exception("Template compilation failed at file %s, Exception: %s" format (templateFile.getCanonicalPath(), e.getMessage()), e);
}
}
scalaFile.getParentFile.mkdirs
IOUtil.writeBinaryFile(scalaFile, code.getBytes("UTF-8"))
scalaFile
} toArray
}
private def collectCompileTargets(basedir: File, baseuri: String, extension: String): List[CompileTarget] = {
var collected = List.empty[CompileTarget]
if (basedir.isDirectory()) {
var files = basedir.listFiles();
if (files != null) {
for (file <- files) {
if (file.isDirectory()) {
collected = collectCompileTargets(file, baseuri + "/" + file.getName(), extension) ::: collected;
} else {
if (file.getName().endsWith(extension)) {
collected = CompileTarget(baseuri + "/" + file.getName()) :: collected
} else {
}
}
}
}
}
collected
}
/**
* A trait for representing the state of a compilation target file.
*/
private sealed trait CompileTarget
/**
* This class represents a file which is already compiled but not modified.
*/
private case class NotModified(scalaFile: File) extends CompileTarget
/**
* This class represents a file which is modified or newly created.
*/
private case class Updated(uri: String, templateFile: File, scalaFile: File) extends CompileTarget
/**
* This class represents a ignored file.
*/
private case class Ignored() extends CompileTarget
private object CompileTarget {
/**
* Returns a instance of [[CompileTarget]] depending on URI's state.
*
* @param uri the URI of maybe compiled resource
*/
def apply(uri: String): CompileTarget = {
val templateFile = new File(sources, uri)
val scalaFile = new File(targetDirectory, "/%s.scala".format(uri.replaceAll("[.]", "_")))
(overwrite, hasCompiled(scalaFile), isModified(templateFile, scalaFile)) match {
case (true, _, _) | (_, _, true) => Updated(uri, templateFile, scalaFile)
case (false, true, false) => NotModified(scalaFile)
case _ => Ignored()
}
}
/**
* Returns true if a template file is newer than a generated scala file.
*
* @param templateFile the path of a template file to be compiled
* @param scalaFile the path of a scala file to be generated by compilation
*/
private def isModified(templateFile: File, scalaFile: File): Boolean = templateFile.lastModified > scalaFile.lastModified
/**
* Returns true if a scala file is already compiled.
*
* @param scalaFile the path of a scala file to be generated by compilation
*/
private def hasCompiled(scalaFile: File): Boolean = scalaFile.exists
}
}