Skip to content

Instantly share code, notes, and snippets.

@eatkins
Created January 17, 2019 22:54
Show Gist options
  • Save eatkins/b8f7e7ece77cba120830c1ce65b9e240 to your computer and use it in GitHub Desktop.
Save eatkins/b8f7e7ece77cba120830c1ce65b9e240 to your computer and use it in GitHub Desktop.
Implement a PathWatcher that handles relative paths
package com.swoval
package files
import java.io.IOException
import java.nio.file.Path
import java.util.concurrent.ConcurrentHashMap
import com.swoval.files.FileTreeViews.Observer
import com.swoval.files.PathWatchers.Event
import scala.collection.JavaConverters._
class RelativePathWatcher extends PathWatcher[(Path, Path)] {
private type JBool = java.lang.Boolean
private val underlying = PathWatchers.get(true)
private val registered = new ConcurrentHashMap[Path, (Path, Int)].asScala
private def convertEvent(event: Event): Option[(Path, Path)] = {
val eventPath: Path = event.getTypedPath.getPath
val sorted = registered.toSeq.sorted.reverse
sorted.collectFirst {
case (abs, (p, d))
if eventPath.startsWith(abs) && (eventPath == abs || (abs
.relativize(eventPath)
.getNameCount - 1 <= d)) =>
(p, abs.relativize(eventPath))
}
}
override def register(path: Path, maxDepth: Int): functional.Either[IOException, JBool] = {
val abs = if (path.isAbsolute) path else path.toAbsolutePath
registered.get(abs) match {
case Some((_, d)) if d >= maxDepth => functional.Either.right(false: JBool)
case _ =>
val res = underlying.register(abs, maxDepth)
if (res.isRight && res.get) registered.put(abs, (path, maxDepth))
res
}
}
override def unregister(path: Path): Unit = {
registered.remove(path)
underlying.unregister(path)
}
override def close(): Unit = {
underlying.close()
}
override def addObserver(observer: Observer[_ >: (Path, Path)]): Int = {
underlying.addObserver(new Observer[Event] {
override def onError(t: Throwable): Unit = observer.onError(t)
override def onNext(t: Event): Unit = convertEvent(t).foreach(e => observer.onNext(e))
})
}
override def removeObserver(handle: Int): Unit = underlying.removeObserver(handle)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment