diff options
author | Paul Phillips <paulp@improving.org> | 2011-03-16 07:49:16 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-03-16 07:49:16 +0000 |
commit | eb0b73b1160c7e62e2ae0e338a9664b8b53ddbde (patch) | |
tree | d1836661a909a33fc805d302183741868582876f /src/compiler/scala/tools/nsc/io/Jar.scala | |
parent | f80801c67545a28f61abd1a36a5ef8b5bc337d87 (diff) | |
download | scala-eb0b73b1160c7e62e2ae0e338a9664b8b53ddbde.tar.gz scala-eb0b73b1160c7e62e2ae0e338a9664b8b53ddbde.tar.bz2 scala-eb0b73b1160c7e62e2ae0e338a9664b8b53ddbde.zip |
Undoing some much too hacky code to implement a...
Undoing some much too hacky code to implement a -jar option and then
following wherever that led me. Tangible results include:
* much beautified scala -help, including documenting some things
never before documented in this plane of existence
* an improved Jar abstraction
* further systemization of system properties
In addition, the jars created by -savecompiled are given the right
manifest so the jar is runnable. That means you can:
scala -savecompiled bippy.scala arg1 arg2
scala -jar bippy.scala.jar arg1 arg2
And both lines should yield the same result. No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/io/Jar.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/io/Jar.scala | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/io/Jar.scala b/src/compiler/scala/tools/nsc/io/Jar.scala new file mode 100644 index 0000000000..0796742fb6 --- /dev/null +++ b/src/compiler/scala/tools/nsc/io/Jar.scala @@ -0,0 +1,77 @@ +package scala.tools.nsc +package io + +import java.io.{ InputStream, OutputStream, IOException, FileNotFoundException, FileInputStream } +import java.util.jar._ +import collection.JavaConverters._ +import Attributes.Name + +class Jar(file: File) extends Iterable[JarEntry] { + def this(path: String) = this(File(path)) + protected def errorFn(msg: String): Unit = Console println msg + + lazy val jarFile = new JarFile(file.jfile) + lazy val manifest = withJarInput(s => Option(s.getManifest)) + def mainClass = manifest map (f => f(Name.MAIN_CLASS)) + + def withJarInput[T](f: JarInputStream => T): T = { + val in = new JarInputStream(file.inputStream()) + try f(in) + finally in.close() + } + def jarWriter() = new JarWriter(file) + + override def foreach[U](f: JarEntry => U): Unit = withJarInput { in => + Iterator continually in.getNextJarEntry() takeWhile (_ != null) foreach f + } + override def iterator: Iterator[JarEntry] = this.toList.iterator + def fileishIterator: Iterator[Fileish] = jarFile.entries.asScala map (x => Fileish(x, () => getEntryStream(x))) + + private def getEntryStream(entry: JarEntry) = jarFile getInputStream entry match { + case null => errorFn("No such entry: " + entry) ; null + case x => x + } + override def toString = "" + file +} + +class JarWriter(file: File, val manifest: Manifest = new Manifest()) { + private lazy val out = new JarOutputStream(file.outputStream(), manifest) + def writeAllFrom(dir: Directory) = { + try dir.list foreach (x => addEntry(x, "")) + finally out.close() + + file + } + private def addFile(entry: File, prefix: String) { + out putNextEntry new JarEntry(prefix + entry.name) + try transfer(entry.inputStream(), out) + finally out.closeEntry() + } + private def addEntry(entry: Path, prefix: String) { + if (entry.isFile) addFile(entry.toFile, prefix) + else addDirectory(entry.toDirectory, prefix + entry.name + "/") + } + private def addDirectory(entry: Directory, prefix: String) { + entry.list foreach (p => addEntry(p, prefix)) + } + private def transfer(in: InputStream, out: OutputStream) = { + val buf = new Array[Byte](10240) + def loop: Unit = in.read(buf, 0, buf.length) match { + case -1 => in.close() + case n => out.write(buf, 0, n) ; loop + } + loop + } +} + +object Jar { + // CLASS_PATH + // CONTENT_TYPE + + def create(file: File, sourceDir: Directory, mainClass: String): File = { + val writer = new Jar(file).jarWriter() + writer.manifest(Name.MANIFEST_VERSION) = "1.0" + writer.manifest(Name.MAIN_CLASS) = mainClass + writer writeAllFrom sourceDir + } +} |