blob: 8f1783f81e981ba79fd1783fa198c5c5d69fad87 [file] [log] [blame] [raw]
package li.cil.oc.server.fs
import java.io.FileNotFoundException
import java.util.concurrent.Callable
import li.cil.oc.api
import li.cil.oc.api.fs.Mode
import li.cil.oc.util.ExtendedNBT._
import net.minecraft.nbt.NBTTagCompound
import scala.collection.mutable
class CompositeReadOnlyFileSystem(factories: mutable.LinkedHashMap[String, Callable[api.fs.FileSystem]]) extends api.fs.FileSystem {
var parts = mutable.LinkedHashMap.empty[String, api.fs.FileSystem]
for ((name, factory) <- factories) {
val fs = factory.call()
if (fs != null) {
parts += name -> fs
}
}
// ----------------------------------------------------------------------- //
override def isReadOnly = true
override def spaceTotal = parts.values.map(_.spaceTotal).sum
override def spaceUsed = parts.values.map(_.spaceUsed).sum
// ----------------------------------------------------------------------- //
override def exists(path: String) = findFileSystem(path).isDefined
override def size(path: String) = findFileSystem(path).fold(0L)(_.size(path))
override def isDirectory(path: String) = findFileSystem(path).fold(false)(_.isDirectory(path))
override def lastModified(path: String) = findFileSystem(path).fold(0L)(_.lastModified(path))
override def list(path: String) = parts.values.foldLeft(Array.empty[String])((acc, fs) => {
if (fs.exists(path)) try {
val l = fs.list(path)
if (l != null) acc ++ l else acc
}
catch {
case _: Throwable => acc
}
else acc
})
// ----------------------------------------------------------------------- //
override def delete(path: String) = false
override def makeDirectory(path: String) = false
override def rename(from: String, to: String) = false
override def setLastModified(path: String, time: Long) = false
// ----------------------------------------------------------------------- //
override def open(path: String, mode: Mode) = findFileSystem(path) match {
case Some(fs) => fs.open(path, mode)
case _ => throw new FileNotFoundException()
}
override def getHandle(handle: Int) = parts.valuesIterator.map(_.getHandle(handle)).find(_ != null).orNull
override def close() = parts.values.foreach(_.close())
// ----------------------------------------------------------------------- //
override def load(nbt: NBTTagCompound) {
for ((name, fs) <- parts) {
fs.load(nbt.getCompoundTag(name))
}
}
override def save(nbt: NBTTagCompound) {
for ((name, fs) <- parts) {
nbt.setNewCompoundTag(name, fs.save)
}
}
// ----------------------------------------------------------------------- //
protected def findFileSystem(path: String): Option[api.fs.FileSystem] = parts.valuesIterator.toSeq.reverse.find(_.exists(path))
}