All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy