summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/io
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-03-12 10:15:43 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-03-12 10:15:43 -0700
commit5262cd5422a49336a546b2ac08c307f2a0a9c606 (patch)
tree811bd3d2d36461dc9d4d9a31cab8f8e936a28346 /src/reflect/scala/reflect/io
parenta41c79bb5b2f16d8f37e253737f67171e5764bb9 (diff)
parent3a30af154e62f5b8a569486b09788c42db2103a6 (diff)
downloadscala-5262cd5422a49336a546b2ac08c307f2a0a9c606.tar.gz
scala-5262cd5422a49336a546b2ac08c307f2a0a9c606.tar.bz2
scala-5262cd5422a49336a546b2ac08c307f2a0a9c606.zip
Merge pull request #2238 from adriaanm/pr-2206-rebased
[rebase of #2206] l JSR-223 compliance for the interpreter
Diffstat (limited to 'src/reflect/scala/reflect/io')
-rw-r--r--src/reflect/scala/reflect/io/AbstractFile.scala34
-rw-r--r--src/reflect/scala/reflect/io/Path.scala9
-rw-r--r--src/reflect/scala/reflect/io/ZipArchive.scala62
3 files changed, 90 insertions, 15 deletions
diff --git a/src/reflect/scala/reflect/io/AbstractFile.scala b/src/reflect/scala/reflect/io/AbstractFile.scala
index 4d6f14c71d..8b69efc749 100644
--- a/src/reflect/scala/reflect/io/AbstractFile.scala
+++ b/src/reflect/scala/reflect/io/AbstractFile.scala
@@ -7,7 +7,7 @@
package scala.reflect
package io
-import java.io.{ FileOutputStream, IOException, InputStream, OutputStream, BufferedOutputStream }
+import java.io.{ FileOutputStream, IOException, InputStream, OutputStream, BufferedOutputStream, ByteArrayOutputStream }
import java.io.{ File => JFile }
import java.net.URL
import scala.collection.mutable.ArrayBuffer
@@ -54,6 +54,8 @@ object AbstractFile {
if (url == null || !Path.isExtensionJarOrZip(url.getPath)) null
else ZipArchive fromURL url
}
+
+ def getResources(url: URL): AbstractFile = ZipArchive fromManifestURL url
}
/**
@@ -156,16 +158,28 @@ abstract class AbstractFile extends Iterable[AbstractFile] {
@throws(classOf[IOException])
def toByteArray: Array[Byte] = {
val in = input
- var rest = sizeOption.getOrElse(0)
- val arr = new Array[Byte](rest)
- while (rest > 0) {
- val res = in.read(arr, arr.length - rest, rest)
- if (res == -1)
- throw new IOException("read error")
- rest -= res
+ sizeOption match {
+ case Some(size) =>
+ var rest = size
+ val arr = new Array[Byte](rest)
+ while (rest > 0) {
+ val res = in.read(arr, arr.length - rest, rest)
+ if (res == -1)
+ throw new IOException("read error")
+ rest -= res
+ }
+ in.close()
+ arr
+ case None =>
+ val out = new ByteArrayOutputStream()
+ var c = in.read()
+ while(c != -1) {
+ out.write(c)
+ c = in.read()
+ }
+ in.close()
+ out.toByteArray()
}
- in.close()
- arr
}
/** Returns all abstract subfiles of this abstract directory. */
diff --git a/src/reflect/scala/reflect/io/Path.scala b/src/reflect/scala/reflect/io/Path.scala
index 3b5d3079cd..44fb41a1cd 100644
--- a/src/reflect/scala/reflect/io/Path.scala
+++ b/src/reflect/scala/reflect/io/Path.scala
@@ -56,10 +56,11 @@ object Path {
def roots: List[Path] = java.io.File.listRoots().toList map Path.apply
def apply(path: String): Path = apply(new JFile(path))
- def apply(jfile: JFile): Path =
+ def apply(jfile: JFile): Path = try {
if (jfile.isFile) new File(jfile)
else if (jfile.isDirectory) new Directory(jfile)
else new Path(jfile)
+ } catch { case ex: SecurityException => new Path(jfile) }
/** Avoiding any shell/path issues by only using alphanumerics. */
private[io] def randomPrefix = alphanumeric take 6 mkString ""
@@ -186,10 +187,10 @@ class Path private[io] (val jfile: JFile) {
// Boolean tests
def canRead = jfile.canRead()
def canWrite = jfile.canWrite()
- def exists = jfile.exists()
+ def exists = try jfile.exists() catch { case ex: SecurityException => false }
- def isFile = jfile.isFile()
- def isDirectory = jfile.isDirectory()
+ def isFile = try jfile.isFile() catch { case ex: SecurityException => false }
+ def isDirectory = try jfile.isDirectory() catch { case ex: SecurityException => false }
def isAbsolute = jfile.isAbsolute()
def isEmpty = path.length == 0
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;
+ }
+ }
+ }
+}