package play.core.server
import akka.actor.ActorSystem
import play.api.{ Application, Configuration }
import play.core.ApplicationProvider
import scala.concurrent.Future
trait ServerProvider {
def createServer(context: ServerProvider.Context): Server
final def createServer(config: ServerConfig, app: Application): Server =
createServer(ServerProvider.Context(config, ApplicationProvider(app), app.actorSystem, () => Future.successful(())))
}
object ServerProvider {
final case class Context(
config: ServerConfig,
appProvider: ApplicationProvider,
actorSystem: ActorSystem,
stopHook: () => Future[Unit])
def fromConfiguration(classLoader: ClassLoader, configuration: Configuration): ServerProvider = {
val ClassNameConfigKey = "play.server.provider"
val className: String = configuration.getString(ClassNameConfigKey).getOrElse(throw new ServerStartException(s"No ServerProvider configured with key '$ClassNameConfigKey'"))
val clazz = try classLoader.loadClass(className) catch {
case _: ClassNotFoundException => throw ServerStartException(s"Couldn't find ServerProvider class '$className'")
}
if (!classOf[ServerProvider].isAssignableFrom(clazz)) throw ServerStartException(s"Class ${clazz.getName} must implement ServerProvider interface")
val ctor = try clazz.getConstructor() catch {
case _: NoSuchMethodException => throw ServerStartException(s"ServerProvider class ${clazz.getName} must have a public default constructor")
}
ctor.newInstance().asInstanceOf[ServerProvider]
}
implicit lazy val defaultServerProvider: ServerProvider = {
val classLoader = this.getClass.getClassLoader
val config = Configuration.load(classLoader, System.getProperties, Map.empty, true)
fromConfiguration(classLoader, config)
}
}