mirror of https://github.com/sbt/sbt.git
37 lines
1.3 KiB
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])
|