sbt/util/classpath/ClassLoaderCache.scala

37 lines
1.3 KiB
Scala

package sbt.classpath
import java.lang.ref.{Reference, SoftReference}
import java.io.File
import java.net.URLClassLoader
import java.util.HashMap
private[sbt] final class ClassLoaderCache(val commonParent: ClassLoader)
{
private[this] val delegate = new HashMap[List[File],Reference[CachedClassLoader]]
def apply(files: List[File]): ClassLoader =
{
val tstamps = files.map(_.lastModified)
getFromReference(files, tstamps, delegate.get(files))
}
private[this] def getFromReference(files: List[File], stamps: List[Long], existingRef: Reference[CachedClassLoader]) =
if(existingRef eq null)
newEntry(files, stamps)
else
get(files, stamps, existingRef.get)
private[this] def get(files: List[File], stamps: List[Long], existing: CachedClassLoader): ClassLoader =
if(existing == null || stamps != existing.timestamps)
newEntry(files, stamps)
else
existing.loader
private[this] def newEntry(files: List[File], stamps: List[Long]): ClassLoader =
{
val loader = new URLClassLoader(files.map(_.toURI.toURL).toArray, commonParent)
delegate.put(files, new SoftReference(new CachedClassLoader(loader, files, stamps)))
loader
}
}
private[sbt] final class CachedClassLoader(val loader: ClassLoader, val files: List[File], val timestamps: List[Long])