mirror of https://github.com/sbt/sbt.git
95 lines
4.2 KiB
Scala
95 lines
4.2 KiB
Scala
/* sbt -- Simple Build Tool
|
|
* Copyright 2008, 2009 Mark Harrah
|
|
*/
|
|
package sbt
|
|
|
|
import java.io.{Closeable, File, FileInputStream, FileOutputStream, InputStream, OutputStream}
|
|
import java.io.{BufferedInputStream, BufferedOutputStream, ByteArrayOutputStream, InputStreamReader, OutputStreamWriter}
|
|
import java.io.{BufferedReader, BufferedWriter, FileReader, FileWriter, Reader, Writer}
|
|
import java.util.zip.{GZIPInputStream, GZIPOutputStream}
|
|
import java.net.{URL, URISyntaxException}
|
|
import java.nio.charset.{Charset, CharsetDecoder, CharsetEncoder}
|
|
import java.nio.channels.FileChannel
|
|
import java.util.jar.{Attributes, JarEntry, JarFile, JarInputStream, JarOutputStream, Manifest}
|
|
import java.util.zip.{GZIPOutputStream, ZipEntry, ZipFile, ZipInputStream, ZipOutputStream}
|
|
|
|
import ErrorHandling.translate
|
|
import Using._
|
|
|
|
abstract class Using[Source, T] extends NotNull
|
|
{
|
|
protected def open(src: Source): T
|
|
def apply[R](src: Source)(f: T => R): R =
|
|
{
|
|
val resource = open(src)
|
|
try { f(resource) }
|
|
finally { close(resource) }
|
|
}
|
|
protected def close(out: T): Unit
|
|
}
|
|
import scala.reflect.{Manifest => SManifest}
|
|
abstract class WrapUsing[Source, T](implicit srcMf: SManifest[Source], targetMf: SManifest[T]) extends Using[Source, T]
|
|
{
|
|
protected def label[S](m: SManifest[S]) = m.erasure.getSimpleName
|
|
protected def openImpl(source: Source): T
|
|
protected final def open(source: Source): T =
|
|
translate("Error wrapping " + label(srcMf) + " in " + label(targetMf) + ": ") { openImpl(source) }
|
|
}
|
|
trait OpenFile[T] extends Using[File, T]
|
|
{
|
|
protected def openImpl(file: File): T
|
|
protected final def open(file: File): T =
|
|
{
|
|
val parent = file.getParentFile
|
|
if(parent != null)
|
|
IO.createDirectory(parent)
|
|
openImpl(file)
|
|
}
|
|
}
|
|
object Using
|
|
{
|
|
def wrap[Source, T<: Closeable](openF: Source => T)(implicit srcMf: SManifest[Source], targetMf: SManifest[T]): Using[Source,T] =
|
|
wrap(openF, closeCloseable)
|
|
def wrap[Source, T](openF: Source => T, closeF: T => Unit)(implicit srcMf: SManifest[Source], targetMf: SManifest[T]): Using[Source,T] =
|
|
new WrapUsing[Source, T]
|
|
{
|
|
def openImpl(source: Source) = openF(source)
|
|
def close(t: T) = closeF(t)
|
|
}
|
|
|
|
def resource[Source, T <: Closeable](openF: Source => T): Using[Source,T] =
|
|
resource(openF, closeCloseable)
|
|
def resource[Source, T](openF: Source => T, closeF: T => Unit): Using[Source,T] =
|
|
new Using[Source,T]
|
|
{
|
|
def open(s: Source) = openF(s)
|
|
def close(s: T) = closeF(s)
|
|
}
|
|
def file[T <: Closeable](openF: File => T): OpenFile[T] = file(openF, closeCloseable)
|
|
def file[T](openF: File => T, closeF: T => Unit): OpenFile[T] =
|
|
new OpenFile[T]
|
|
{
|
|
def openImpl(file: File) = openF(file)
|
|
def close(t: T) = closeF(t)
|
|
}
|
|
private def closeCloseable[T <: Closeable]: T => Unit = _.close()
|
|
|
|
def fileOutputStream(append: Boolean = false) = file(f => new BufferedOutputStream(new FileOutputStream(f, append)))
|
|
def fileInputStream = file(f => new BufferedInputStream(new FileInputStream(f)))
|
|
def urlInputStream = resource( (u: URL) => translate("Error opening " + u + ": ")(u.openStream))
|
|
def fileOutputChannel = file(f => new FileOutputStream(f).getChannel)
|
|
def fileInputChannel = file(f => new FileInputStream(f).getChannel)
|
|
def fileWriter(charset: Charset = IO.utf8, append: Boolean = false) =
|
|
file(f => new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, append), charset)) )
|
|
def fileReader(charset: Charset) = file(f => new BufferedReader(new InputStreamReader(new FileInputStream(f), charset)) )
|
|
def jarFile(verify: Boolean) = file(f => new JarFile(f, verify), (_: JarFile).close())
|
|
def zipFile = file(f => new ZipFile(f), (_: ZipFile).close())
|
|
def streamReader = wrap{ (_: (InputStream, Charset)) match { case (in, charset) => new InputStreamReader(in, charset) } }
|
|
def gzipInputStream = wrap( (in: InputStream) => new GZIPInputStream(in) )
|
|
def zipInputStream = wrap( (in: InputStream) => new ZipInputStream(in))
|
|
def gzipOutputStream = wrap((out: OutputStream) => new GZIPOutputStream(out), (_: GZIPOutputStream).finish())
|
|
def jarOutputStream = wrap( (out: OutputStream) => new JarOutputStream(out))
|
|
def jarInputStream = wrap( (in: InputStream) => new JarInputStream(in))
|
|
def zipEntry(zip: ZipFile) = resource( (entry: ZipEntry) =>
|
|
translate("Error opening " + entry.getName + " in " + zip + ": ") { zip.getInputStream(entry) } )
|
|
} |