Skip to content

Instantly share code, notes, and snippets.

@int128
Last active January 3, 2016 16:49
Show Gist options
  • Save int128/8491710 to your computer and use it in GitHub Desktop.
Save int128/8491710 to your computer and use it in GitHub Desktop.
Servlet filter for compiling Scala with Zinc (these attempts did not work due to sandbox of App Engine dev server)
package zinc
import javax.servlet.ServletContext
import java.util.logging.Logger
import com.typesafe.zinc.ZincClient
import java.io._
case class Processor(context: ServletContext) {
private val logger = Logger.getLogger(Processor.getClass.getName)
private val zinc = new ZincClient()
def process = {
zinc.serverAvailable() match {
case true =>
context.log("Using Zinc server")
zinc.run(
Seq(
"-scala-compiler", lib(_.getName.startsWith("scala-compiler-")),
"-scala-library", lib(_.getName.startsWith("scala-library-")),
"-scala-extra", lib(_.getName.startsWith("scala-reflect-")),
"-d", contextPath("/WEB-INF/classes"),
"-classpath", lib(_.getName.endsWith(".jar"))
) ++ sources(_.getName.endsWith(".scala")),
projectDir,
System.out,
System.err)
case false =>
logger.warning("Zinc server not available")
}
}
private def contextPath = context.getRealPath _
private def projectDir = new File(context.getRealPath("/")).getParentFile.getParentFile.getParentFile
private def libDir = new File(context.getRealPath("/WEB-INF/lib/"))
private def srcDir = new File(projectDir, "src/main/scala")
private def lib(f: (File) => Boolean) = libDir.listFiles().filter(f).map(_.getPath).mkString(":")
private def sources(f: (File) => Boolean) = srcDir.listFiles().filter(f).map(_.getPath)
}
class Filter extends javax.servlet.Filter {
import javax.servlet._
private var processor: Processor = _
def init(config: FilterConfig) = {
processor = Processor(config.getServletContext)
}
def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) = {
processor.process
chain.doFilter(request, response)
}
def destroy() = {}
}
import com.typesafe.zinc.Setup
import java.io.File
import javax.servlet._
import xsbti.F0
class ZincFilter extends Filter {
private var configVar: FilterConfig = _
def config = configVar
class ServletLogger(context: ServletContext) extends xsbti.Logger {
def error(p1: F0[String]) = context.log(p1())
def warn(p1: F0[String]) = context.log(p1())
def info(p1: F0[String]) = context.log(p1())
def debug(p1: F0[String]) = context.log(p1())
def trace(p1: F0[Throwable]) = context.log(p1().toString)
}
lazy val logger = new ServletLogger(config.getServletContext)
lazy val compiler = {
def lib(name: String) = new File(config.getServletContext.getRealPath(s"/WEB-INF/lib/$name"))
val setup = Setup.setup(
lib("scala-compiler-2.10.3.jar"),
lib("scala-library-2.10.3.jar"),
Seq(lib("scala-reflect-2.10.3.jar")),
lib("sbt-interface-0.13.0.jar"),
lib("compiler-interface-0.13.0-sources.jar"),
None,
forkJava = false)
com.typesafe.zinc.Compiler(setup, logger)
}
def init(givenConfig: FilterConfig) {
configVar = givenConfig
compiler
}
def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) = {
// TODO
chain.doFilter(request, response)
}
def destroy() = {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment