sbt/launch/Provider.scala

67 lines
2.2 KiB
Scala
Raw Normal View History

2009-09-26 08:18:04 +02:00
package xsbt.boot
2009-10-18 04:40:02 +02:00
import Pre._
2009-09-26 08:18:04 +02:00
import java.io.{File, FileFilter}
import java.net.{URL, URLClassLoader}
import java.util.concurrent.Callable
2009-09-26 08:18:04 +02:00
trait Provider extends NotNull
{
def configuration: UpdateConfiguration
2009-10-18 04:40:02 +02:00
def baseDirectories: List[File]
def testLoadClasses: List[String]
def target: UpdateTarget
2009-09-26 08:18:04 +02:00
def failLabel: String
def parentLoader: ClassLoader
def lockFile: File
2009-09-26 08:18:04 +02:00
def retrieveFailed: Nothing = fail("")
def retrieveCorrupt(missing: Iterable[String]): Nothing = fail(": missing " + missing.mkString(", "))
private def fail(extra: String) =
throw new xsbti.RetrieveException(versionString, "Could not retrieve " + failLabel + extra)
private def versionString: String = target match { case UpdateScala => configuration.scalaVersion; case a: UpdateApp => Version.get(a.id.version) }
val (jars, loader) = Locks(lockFile, new initialize)
private final class initialize extends Callable[(Array[File], ClassLoader)]
2009-09-26 08:18:04 +02:00
{
def call =
2009-09-26 08:18:04 +02:00
{
val (existingJars, existingLoader) = createLoader
if(Provider.getMissing(existingLoader, testLoadClasses).isEmpty)
(existingJars, existingLoader)
else
{
val retrieveSuccess = ( new Update(configuration) )(target)
if(retrieveSuccess)
{
val (newJars, newLoader) = createLoader
val missing = Provider.getMissing(newLoader, testLoadClasses)
if(missing.isEmpty) (newJars, newLoader) else retrieveCorrupt(missing)
}
else
retrieveFailed
}
}
def createLoader =
{
val jars = Provider.getJars(baseDirectories)
(jars, new URLClassLoader(jars.map(_.toURI.toURL), parentLoader) )
2009-09-26 08:18:04 +02:00
}
}
}
object Provider
2009-09-26 08:18:04 +02:00
{
def getJars(directories: List[File]): Array[File] = toArray(directories.flatMap(directory => wrapNull(directory.listFiles(JarFilter))))
2009-09-26 08:18:04 +02:00
def wrapNull(a: Array[File]): Array[File] = if(a == null) Array() else a
object JarFilter extends FileFilter
{
def accept(file: File) = !file.isDirectory && file.getName.endsWith(".jar")
}
def getMissing(loader: ClassLoader, classes: Iterable[String]): Iterable[String] =
2009-09-26 08:18:04 +02:00
{
def classMissing(c: String) = try { Class.forName(c, false, loader); false } catch { case e: ClassNotFoundException => true }
classes.toList.filter(classMissing)
2009-09-26 08:18:04 +02:00
}
}