Cleanup Input/Output/CacheStore

This commit is contained in:
Dale Wijnand 2016-11-30 16:21:37 +00:00
parent c6e793b03c
commit 1368f5f9db
No known key found for this signature in database
GPG Key ID: 4F256E3D151DF5EF
3 changed files with 36 additions and 104 deletions

View File

@ -1,23 +1,17 @@
package sbt.internal.util
import java.io.{ File, InputStream, OutputStream }
import sbt.io.syntax.fileToRichFile
import sbt.io.{ IO, Using }
import sjsonnew.{ IsoString, JsonReader, JsonWriter, SupportConverter }
import java.io.{ File, InputStream, OutputStream }
import sbt.io.{ IO, Using }
import sbt.io.syntax.fileToRichFile
/**
* A `CacheStore` is used by the caching infrastructure to persist cached information.
*/
/** A `CacheStore` is used by the caching infrastructure to persist cached information. */
trait CacheStore extends Input with Output {
/** Delete the persisted information. */
def delete(): Unit
}
/**
* Factory that can derive new stores.
*/
/** Factory that can derive new stores. */
trait CacheStoreFactory {
/** Create a new store. */
def derive(identifier: String): CacheStore
@ -26,74 +20,32 @@ trait CacheStoreFactory {
def sub(identifier: String): CacheStoreFactory
}
/**
* A factory that creates new stores persisted in `base`.
*/
/** A factory that creates new stores persisted in `base`. */
class DirectoryStoreFactory[J: IsoString](base: File, converter: SupportConverter[J]) extends CacheStoreFactory {
IO.createDirectory(base)
override def derive(identifier: String): CacheStore =
new FileBasedStore(base / identifier, converter)
def derive(identifier: String): CacheStore = new FileBasedStore(base / identifier, converter)
override def sub(identifier: String): CacheStoreFactory =
new DirectoryStoreFactory(base / identifier, converter)
def sub(identifier: String): CacheStoreFactory = new DirectoryStoreFactory(base / identifier, converter)
}
/**
* A `CacheStore` that persists information in `file`.
*/
/** A `CacheStore` that persists information in `file`. */
class FileBasedStore[J: IsoString](file: File, converter: SupportConverter[J]) extends CacheStore {
IO.touch(file, setModified = false)
override def delete(): Unit =
IO.delete(file)
def read[T: JsonReader]() = Using.fileInputStream(file)(stream => new PlainInput(stream, converter).read())
override def read[T: JsonReader](): T =
Using.fileInputStream(file) { stream =>
val input = new PlainInput(stream, converter)
input.read()
}
override def read[T: JsonReader](default: => T): T =
try read[T]()
catch { case _: Exception => default }
override def write[T: JsonWriter](value: T): Unit =
Using.fileOutputStream(append = false)(file) { stream =>
val output = new PlainOutput(stream, converter)
output.write(value)
}
override def close(): Unit = ()
def write[T: JsonWriter](value: T) =
Using.fileOutputStream(append = false)(file)(stream => new PlainOutput(stream, converter).write(value))
def delete() = IO.delete(file)
def close() = ()
}
/**
* A store that reads from `inputStream` and writes to `outputStream
*/
/** A store that reads from `inputStream` and writes to `outputStream`. */
class StreamBasedStore[J: IsoString](inputStream: InputStream, outputStream: OutputStream, converter: SupportConverter[J]) extends CacheStore {
override def delete(): Unit = ()
override def read[T: JsonReader](): T = {
val input = new PlainInput(inputStream, converter)
input.read()
}
override def read[T: JsonReader](default: => T): T =
try read[T]()
catch { case _: Exception => default }
override def write[T: JsonWriter](value: T): Unit = {
val output = new PlainOutput(outputStream, converter)
output.write(value)
}
override def close(): Unit = {
inputStream.close()
outputStream.close()
}
}
def read[T: JsonReader]() = new PlainInput(inputStream, converter).read()
def write[T: JsonWriter](value: T) = new PlainOutput(outputStream, converter).write(value)
def delete() = ()
def close() = { inputStream.close(); outputStream.close() }
}

View File

@ -1,20 +1,18 @@
package sbt.internal.util
import sbt.io.{ IO, Using }
import java.io.{ Closeable, InputStream }
import scala.util.{ Failure, Success }
import scala.util.control.NonFatal
import sjsonnew.{ IsoString, JsonReader, SupportConverter }
import sbt.io.{ IO, Using }
trait Input extends Closeable {
def read[T: JsonReader](): T
def read[T: JsonReader](default: => T): T
def read[T: JsonReader](default: => T): T = try read[T]() catch { case NonFatal(_) => default }
}
class PlainInput[J: IsoString](input: InputStream, converter: SupportConverter[J]) extends Input {
val isoFormat: IsoString[J] = implicitly
private def readFully(): String = {
Using.streamReader(input, IO.utf8) { reader =>
val builder = new StringBuilder()
@ -28,18 +26,7 @@ class PlainInput[J: IsoString](input: InputStream, converter: SupportConverter[J
}
}
override def read[T: JsonReader](): T = {
val string = readFully()
val json = isoFormat.from(string)
converter.fromJson(json) match {
case Success(value) => value
case Failure(ex) => throw ex
}
}
def read[T: JsonReader]() = converter.fromJson(isoFormat.from(readFully())).get
override def read[T: JsonReader](default: => T): T =
try read[T]()
catch { case _: Exception => default }
override def close(): Unit = input.close()
def close() = input.close()
}

View File

@ -1,12 +1,8 @@
package sbt.internal.util
import sbt.io.Using
import java.io.{ Closeable, OutputStream }
import scala.util.{ Failure, Success }
import sjsonnew.{ IsoString, JsonWriter, SupportConverter }
import sbt.io.Using
trait Output extends Closeable {
def write[T: JsonWriter](value: T): Unit
@ -14,19 +10,16 @@ trait Output extends Closeable {
class PlainOutput[J: IsoString](output: OutputStream, converter: SupportConverter[J]) extends Output {
val isoFormat: IsoString[J] = implicitly
override def write[T: JsonWriter](value: T): Unit = {
converter.toJson(value) match {
case Success(js) =>
val asString = isoFormat.to(js)
Using.bufferedOutputStream(output) { writer =>
val out = new java.io.PrintWriter(writer)
out.print(asString)
out.flush()
}
case Failure(ex) =>
throw ex
def write[T: JsonWriter](value: T) = {
val js = converter.toJson(value).get
val asString = isoFormat.to(js)
Using.bufferedOutputStream(output) { writer =>
val out = new java.io.PrintWriter(writer)
out.print(asString)
out.flush()
}
}
override def close(): Unit = output.close()
def close() = output.close()
}