Created
January 17, 2019 22:54
-
-
Save eatkins/b8f7e7ece77cba120830c1ce65b9e240 to your computer and use it in GitHub Desktop.
Implement a PathWatcher that handles relative paths
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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