Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 151 lines (137 sloc) 4.695 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
/* sbt -- Simple Build Tool
* Copyright 2008, 2009, 2010 Mark Harrah
*/
package sbt

import java.io.File
import java.net.{URL, URLClassLoader}
import scala.xml.NodeSeq

object JettyRunner
{
val DefaultPort = 8080
val DefaultScanInterval = 3
}
class JettyRunner(configuration: JettyConfiguration) extends ExitHook
{
ExitHooks.register(this)

def name = "jetty-shutdown"
def runBeforeExiting() { stop() }
private var running: Option[Stoppable] = None
private def started(s: Stoppable) { running = Some(s) }
def stop()
{
running.foreach(_.stop())
running = None
}
def reload() = running.foreach(_.reload())
def apply(): Option[String] =
{
import configuration._
def runJetty() =
{
val baseLoader = this.getClass.getClassLoader
val jettyParentLoader = configuration match { case d: DefaultJettyConfiguration => d.parentLoader; case _ => ClassLoader.getSystemClassLoader }
val jettyLoader: ClassLoader = ClasspathUtilities.toLoader(jettyClasspath, jettyParentLoader)

val jettyFilter = (name: String) => name.startsWith("org.mortbay.") || name.startsWith("org.eclipse.jetty.")
val notJettyFilter = (name: String) => !jettyFilter(name)

val dual = new xsbt.DualLoader(baseLoader, notJettyFilter, x => true, jettyLoader, jettyFilter, x => false)

def createRunner(implClassName: String) =
{
val lazyLoader = new LazyFrameworkLoader(implClassName, Array(FileUtilities.classLocation[Stoppable].toURI.toURL), dual, baseLoader)
ModuleUtilities.getObject(implClassName, lazyLoader).asInstanceOf[JettyRun]
}
val runner = try { createRunner(implClassName6) } catch { case e: NoClassDefFoundError => createRunner(implClassName7) }
runner(configuration, jettyLoader)
}

if(running.isDefined)
Some("This instance of Jetty is already running.")
else
{
try
{
started(runJetty())
None
}
catch
{
case e: NoClassDefFoundError => runError(e, "Jetty and its dependencies must be on the " + classpathName + " classpath: ", log)
case e => runError(e, "Error running Jetty: ", log)
}
}
}
private val implClassName6 = "sbt.jetty.LazyJettyRun6"
private val implClassName7 = "sbt.jetty.LazyJettyRun7"

private def runError(e: Throwable, messageBase: String, log: Logger) =
{
log.trace(e)
Some(messageBase + e.toString)
}
}

private trait Stoppable
{
def stop(): Unit
def reload(): Unit
}
private trait JettyRun
{
def apply(configuration: JettyConfiguration, jettyLoader: ClassLoader): Stoppable
}
sealed trait JettyConfiguration extends NotNull
{
/** The classpath to get Jetty from. */
def jettyClasspath: PathFinder
def classpathName: String
def log: Logger
}
trait DefaultJettyConfiguration extends JettyConfiguration
{
def war: Path
def scanDirectories: Seq[File]
def scanInterval: Int


def contextPath: String
def port: Int
/** The classpath containing the classes, jars, and resources for the web application. */
def classpath: PathFinder
def parentLoader: ClassLoader
def jettyEnv: Option[File]
}
abstract class CustomJettyConfiguration extends JettyConfiguration
{
def jettyConfigurationFiles: Seq[File] = Nil
def jettyConfigurationXML: NodeSeq = NodeSeq.Empty
}

private class JettyLoggerBase(delegate: Logger)
{
def getName = "JettyLogger"
def isDebugEnabled = delegate.atLevel(Level.Debug)
def setDebugEnabled(enabled: Boolean) = delegate.setLevel(if(enabled) Level.Debug else Level.Info)

def info(msg: String) { delegate.info(msg) }
def debug(msg: String) { delegate.warn(msg) }
def warn(msg: String) { delegate.warn(msg) }
def info(msg: String, arg0: AnyRef, arg1: AnyRef) { delegate.info(format(msg, arg0, arg1)) }
def debug(msg: String, arg0: AnyRef, arg1: AnyRef) { delegate.debug(format(msg, arg0, arg1)) }
def warn(msg: String, arg0: AnyRef, arg1: AnyRef) { delegate.warn(format(msg, arg0, arg1)) }
def info(msg: String, args: Array[AnyRef]) { delegate.info(format(msg, args: _*)) }
def debug(msg: String, args: Array[AnyRef]) { delegate.debug(format(msg, args: _*)) }
def warn(msg: String, args: Array[AnyRef]) { delegate.warn(format(msg, args: _*)) }
def warn(msg: String, th: Throwable)
{
delegate.warn(msg)
delegate.trace(th)
}
def debug(msg: String, th: Throwable)
{
delegate.debug(msg)
delegate.trace(th)
}
private def format(msg: String, args: AnyRef*) =
{
def toString(arg: AnyRef) = if(arg == null) "" else arg.toString
val pieces = msg.split("""\{\}""", args.length + 1).toList
val argStrs = args.map(toString).toList ::: List("")
pieces.zip(argStrs).foldLeft(new StringBuilder) { (sb, pair) =>
val (piece, argStr) = pair
if (piece.isEmpty) sb
else sb.append(piece).append(argStr)
}.toString
}
}
Something went wrong with that request. Please try again.