PageRenderTime 39ms CodeModel.GetById 32ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/scalate-core/src/main/scala/org/fusesource/scalate/support/Precompiler.scala

http://github.com/scalate/scalate
Scala | 117 lines | 74 code | 18 blank | 25 comment | 24 complexity | 530053c8997b7f94021f7a829dde09d8 MD5 | raw file
  1/**
  2 * Copyright (C) 2009-2011 the original author or authors.
  3 * See the notice.md file distributed with this work for additional
  4 * information regarding copyright ownership.
  5 *
  6 * Licensed under the Apache License, Version 2.0 (the "License");
  7 * you may not use this file except in compliance with the License.
  8 * You may obtain a copy of the License at
  9 *
 10 *     http://www.apache.org/licenses/LICENSE-2.0
 11 *
 12 * Unless required by applicable law or agreed to in writing, software
 13 * distributed under the License is distributed on an "AS IS" BASIS,
 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18package org.fusesource.scalate.support
 19
 20import java.io.File
 21
 22import org.fusesource.scalate.servlet.ServletRenderContext
 23import org.fusesource.scalate.{ Binding, TemplateEngine }
 24
 25import scala.language.reflectiveCalls
 26
 27/**
 28 * This class can precompile Scalate templates into JVM
 29 * classes.
 30 *
 31 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
 32 */
 33class Precompiler {
 34
 35  var sources = Array[File]()
 36  var workingDirectory: File = _
 37  var targetDirectory: File = _
 38  var templates = Array[String]()
 39  var info: { def apply(v1: String): Unit } = (value: String) => println(value)
 40  var contextClass: String = _
 41  var bootClassName: String = _
 42
 43  def execute() = {
 44
 45    if (sources == null || sources.isEmpty) {
 46      throw new IllegalArgumentException("The sources property not properly set")
 47    }
 48
 49    val engine = new TemplateEngine(sources) {
 50      // lets output generated bytecode to the classes directory.
 51      override def bytecodeDirectory = {
 52        if (targetDirectory != null) {
 53          targetDirectory
 54        } else {
 55          super.bytecodeDirectory
 56        }
 57      }
 58    }
 59
 60    engine.classLoader = Thread.currentThread.getContextClassLoader
 61
 62    if (contextClass != null) {
 63      engine.bindings = List(Binding("context", contextClass, true, isImplicit = true))
 64    } else {
 65      engine.bindings = List(Binding("context", "_root_." + classOf[ServletRenderContext].getName, true, isImplicit = true))
 66    }
 67
 68    if (workingDirectory != null) {
 69      engine.workingDirectory = workingDirectory
 70      workingDirectory.mkdirs()
 71    }
 72    if (bootClassName != null) {
 73      engine.bootClassName = bootClassName
 74    }
 75    engine.boot
 76
 77    var paths = List[String]()
 78    for (extension <- engine.codeGenerators.keysIterator; sd <- sources if sd.exists) {
 79      paths = collectUrisWithExtension(sd, "", "." + extension) ::: paths
 80    }
 81
 82    templates.foreach { x =>
 83      paths ::= x
 84    }
 85
 86    info("Precompiling Scalate Templates into Scala classes...")
 87    for (uri <- paths) {
 88
 89      // TODO it would be easier to just generate Source + URI pairs maybe rather than searching again for the source file???
 90      val file = sources.map(new File(_, uri)).find(_.exists).getOrElse(uri)
 91      info("    processing " + file)
 92      engine.load(uri)
 93    }
 94  }
 95
 96  protected def collectUrisWithExtension(basedir: File, baseuri: String, extension: String): List[String] = {
 97    var collected = List[String]()
 98    if (basedir.isDirectory()) {
 99      val files = basedir.listFiles()
100      if (files != null) {
101        for (file <- files) {
102          if (file.isDirectory()) {
103            collected = collectUrisWithExtension(file, baseuri + "/" + file.getName(), extension) ::: collected
104          } else {
105            if (file.getName().endsWith(extension)) {
106              collected = baseuri + "/" + file.getName() :: collected
107            } else {
108            }
109
110          }
111        }
112      }
113    }
114    collected
115  }
116
117}