summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/io/ZipArchive.scala
diff options
context:
space:
mode:
authorRaphael Jolly <rjolly@users.sourceforge.net>2013-03-09 21:54:22 +0100
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-03-11 22:35:54 -0700
commit3e8f8ddb2ac057ad82e1a7e37f59baff1c0e15ac (patch)
tree5b510ff5f73e1c645da400ca759bc9d1a0f34fd8 /src/reflect/scala/reflect/io/ZipArchive.scala
parent9eb21e54bdb1ea23b4215c641c98bd90a8b859cf (diff)
downloadscala-3e8f8ddb2ac057ad82e1a7e37f59baff1c0e15ac.tar.gz
scala-3e8f8ddb2ac057ad82e1a7e37f59baff1c0e15ac.tar.bz2
scala-3e8f8ddb2ac057ad82e1a7e37f59baff1c0e15ac.zip
SI-874 reflect.io improvements
Diffstat (limited to 'src/reflect/scala/reflect/io/ZipArchive.scala')
-rw-r--r--src/reflect/scala/reflect/io/ZipArchive.scala62
1 files changed, 61 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/io/ZipArchive.scala b/src/reflect/scala/reflect/io/ZipArchive.scala
index 5414441e00..1342fde3c5 100644
--- a/src/reflect/scala/reflect/io/ZipArchive.scala
+++ b/src/reflect/scala/reflect/io/ZipArchive.scala
@@ -7,10 +7,12 @@ package scala.reflect
package io
import java.net.URL
-import java.io.{ IOException, InputStream, ByteArrayInputStream }
+import java.io.{ IOException, InputStream, ByteArrayInputStream, FilterInputStream }
import java.io.{ File => JFile }
import java.util.zip.{ ZipEntry, ZipFile, ZipInputStream }
+import java.util.jar.Manifest
import scala.collection.{ immutable, mutable }
+import scala.collection.convert.WrapAsScala.asScalaIterator
import scala.annotation.tailrec
/** An abstraction for zip files and streams. Everything is written the way
@@ -39,6 +41,8 @@ object ZipArchive {
*/
def fromURL(url: URL): URLZipArchive = new URLZipArchive(url)
+ def fromManifestURL(url: URL): AbstractFile = new ManifestResources(url)
+
private def dirName(path: String) = splitPath(path, front = true)
private def baseName(path: String) = splitPath(path, front = false)
private def splitPath(path0: String, front: Boolean): String = {
@@ -227,3 +231,59 @@ final class URLZipArchive(val url: URL) extends ZipArchive(null) {
case _ => false
}
}
+
+final class ManifestResources(val url: URL) extends ZipArchive(null) {
+ def iterator = {
+ val root = new DirEntry("/")
+ val dirs = mutable.HashMap[String, DirEntry]("/" -> root)
+ val manifest = new Manifest(input)
+ val iter = manifest.getEntries().keySet().iterator().filter(_.endsWith(".class")).map(new ZipEntry(_))
+
+ while (iter.hasNext) {
+ val zipEntry = iter.next()
+ val dir = getDir(dirs, zipEntry)
+ if (zipEntry.isDirectory) dir
+ else {
+ class FileEntry() extends Entry(zipEntry.getName) {
+ override def lastModified = zipEntry.getTime()
+ override def input = resourceInputStream(path)
+ override def sizeOption = None
+ }
+ val f = new FileEntry()
+ dir.entries(f.name) = f
+ }
+ }
+
+ try root.iterator
+ finally dirs.clear()
+ }
+
+ def name = path
+ def path: String = url.getPath() match { case s => s.substring(0, s.lastIndexOf('!')) }
+ def input = url.openStream()
+ def lastModified =
+ try url.openConnection().getLastModified()
+ catch { case _: IOException => 0 }
+
+ override def canEqual(other: Any) = other.isInstanceOf[ManifestResources]
+ override def hashCode() = url.hashCode
+ override def equals(that: Any) = that match {
+ case x: ManifestResources => url == x.url
+ case _ => false
+ }
+
+ private def resourceInputStream(path: String): InputStream = {
+ new FilterInputStream(null) {
+ override def read(): Int = {
+ if(in == null) in = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
+ if(in == null) throw new RuntimeException(path + " not found")
+ super.read();
+ }
+
+ override def close(): Unit = {
+ super.close();
+ in = null;
+ }
+ }
+ }
+}