summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/io/Path.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/io/Path.scala')
-rw-r--r--src/compiler/scala/tools/nsc/io/Path.scala289
1 files changed, 0 insertions, 289 deletions
diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala
deleted file mode 100644
index 1db015e2f5..0000000000
--- a/src/compiler/scala/tools/nsc/io/Path.scala
+++ /dev/null
@@ -1,289 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2011 LAMP/EPFL
- * @author Paul Phillips
- */
-
-package scala.tools.nsc
-package io
-
-import java.io.{
- FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
- BufferedInputStream, BufferedOutputStream, RandomAccessFile }
-// [scala-reflect.jar migration note] uncomment when creating scala-reflect.jar
-// import java.io.{ File => JFile }
-import java.net.{ URI, URL }
-import scala.util.Random.alphanumeric
-import language.implicitConversions
-
-/** An abstraction for filesystem paths. The differences between
- * Path, File, and Directory are primarily to communicate intent.
- * Since the filesystem can change at any time, there is no way to
- * reliably associate Files only with files and so on. Any Path
- * can be converted to a File or Directory (and thus gain access to
- * the additional entity specific methods) by calling toFile or
- * toDirectory, which has no effect on the filesystem.
- *
- * Also available are createFile and createDirectory, which attempt
- * to create the path in question.
- *
- * @author Paul Phillips
- * @since 2.8
- */
-
-object Path {
- def isExtensionJarOrZip(jfile: JFile): Boolean = isExtensionJarOrZip(jfile.getName)
- def isExtensionJarOrZip(name: String): Boolean = {
- val ext = extension(name)
- ext == "jar" || ext == "zip"
- }
- def extension(name: String): String = {
- var i = name.length - 1
- while (i >= 0 && name.charAt(i) != '.')
- i -= 1
-
- if (i < 0) ""
- else name.substring(i + 1).toLowerCase
- }
- // [Eugene++] I hope that noone relied on this method
-// def isJarOrZip(f: Path, examineFile: Boolean = true) = Jar.isJarOrZip(f, examineFile)
-
- // not certain these won't be problematic, but looks good so far
- implicit def string2path(s: String): Path = apply(s)
- implicit def jfile2path(jfile: JFile): Path = apply(jfile)
-
- // java 7 style, we don't use it yet
- // object AccessMode extends Enumeration {
- // val EXECUTE, READ, WRITE = Value
- // }
- // def checkAccess(modes: AccessMode*): Boolean = {
- // modes foreach {
- // case EXECUTE => throw new Exception("Unsupported") // can't check in java 5
- // case READ => if (!jfile.canRead()) return false
- // case WRITE => if (!jfile.canWrite()) return false
- // }
- // true
- // }
-
- def onlyDirs(xs: Iterator[Path]): Iterator[Directory] = xs filter (_.isDirectory) map (_.toDirectory)
- def onlyDirs(xs: List[Path]): List[Directory] = xs filter (_.isDirectory) map (_.toDirectory)
- def onlyFiles(xs: Iterator[Path]): Iterator[File] = xs filter (_.isFile) map (_.toFile)
- def onlyFiles(xs: List[Path]): List[File] = xs filter (_.isFile) map (_.toFile)
-
- def roots: List[Path] = java.io.File.listRoots().toList map Path.apply
-
- def apply(segments: Seq[String]): Path = apply(segments mkString java.io.File.separator)
- def apply(path: String): Path = apply(new JFile(path))
- def apply(jfile: JFile): Path =
- if (jfile.isFile) new File(jfile)
- else if (jfile.isDirectory) new Directory(jfile)
- else new Path(jfile)
-
- /** Avoiding any shell/path issues by only using alphanumerics. */
- private[io] def randomPrefix = alphanumeric take 6 mkString
- private[io] def fail(msg: String) = throw FileOperationException(msg)
-}
-import Path._
-
-/** The Path constructor is private so we can enforce some
- * semantics regarding how a Path might relate to the world.
- */
-class Path private[io] (val jfile: JFile) {
- val separator = java.io.File.separatorChar
- val separatorStr = java.io.File.separator
-
- // Validation: this verifies that the type of this object and the
- // contents of the filesystem are in agreement. All objects are
- // valid except File objects whose path points to a directory and
- // Directory objects whose path points to a file.
- def isValid: Boolean = true
-
- // conversions
- def toFile: File = new File(jfile)
- def toDirectory: Directory = new Directory(jfile)
- def toAbsolute: Path = if (isAbsolute) this else Path(jfile.getAbsolutePath())
- def toCanonical: Path = Path(jfile.getCanonicalPath())
- def toURI: URI = jfile.toURI()
- def toURL: URL = toURI.toURL()
- /** If this path is absolute, returns it: otherwise, returns an absolute
- * path made up of root / this.
- */
- def toAbsoluteWithRoot(root: Path) = if (isAbsolute) this else root.toAbsolute / this
-
- /** Creates a new Path with the specified path appended. Assumes
- * the type of the new component implies the type of the result.
- */
- def /(child: Path): Path = if (isEmpty) child else new Path(new JFile(jfile, child.path))
- def /(child: Directory): Directory = /(child: Path).toDirectory
- def /(child: File): File = /(child: Path).toFile
-
- /** If this path is a container, recursively iterate over its contents.
- * The supplied condition is a filter which is applied to each element,
- * with that branch of the tree being closed off if it is true. So for
- * example if the condition is true for some subdirectory, nothing
- * under that directory will be in the Iterator; but otherwise each
- * file and subdirectory underneath it will appear.
- */
- def walkFilter(cond: Path => Boolean): Iterator[Path] =
- if (isFile) toFile walkFilter cond
- else if (isDirectory) toDirectory walkFilter cond
- else Iterator.empty
-
- /** Equivalent to walkFilter(_ => false).
- */
- def walk: Iterator[Path] = walkFilter(_ => true)
-
- // identity
- def name: String = jfile.getName()
- def path: String = jfile.getPath()
- def normalize: Path = Path(jfile.getAbsolutePath())
- def isRootPath: Boolean = roots exists (_ isSame this)
-
- def resolve(other: Path) = if (other.isAbsolute || isEmpty) other else /(other)
- def relativize(other: Path) = {
- assert(isAbsolute == other.isAbsolute, "Paths not of same type: "+this+", "+other)
-
- def createRelativePath(baseSegs: List[String], otherSegs: List[String]) : String = {
- (baseSegs, otherSegs) match {
- case (b :: bs, o :: os) if b == o => createRelativePath(bs, os)
- case (bs, os) => ((".."+separator)*bs.length)+os.mkString(separatorStr)
- }
- }
-
- Path(createRelativePath(segments, other.segments))
- }
-
- // derived from identity
- def root: Option[Path] = roots find (this startsWith _)
- def segments: List[String] = (path split separator).toList filterNot (_.length == 0)
- /**
- * @return The path of the parent directory, or root if path is already root
- */
- def parent: Directory = path match {
- case "" | "." => Directory("..")
- case _ =>
- // the only solution <-- a comment which could have used elaboration
- if (segments.nonEmpty && segments.last == "..")
- (path / "..").toDirectory
- else jfile.getParent match {
- case null =>
- if (isAbsolute) toDirectory // it should be a root. BTW, don't need to worry about relative pathed root
- else Directory(".") // a dir under pwd
- case x =>
- Directory(x)
- }
- }
- def parents: List[Directory] = {
- val p = parent
- if (p isSame this) Nil else p :: p.parents
- }
- // if name ends with an extension (e.g. "foo.jpg") returns the extension ("jpg"), otherwise ""
- def extension: String = {
- var i = name.length - 1
- while (i >= 0 && name.charAt(i) != '.')
- i -= 1
-
- if (i < 0) ""
- else name.substring(i + 1)
- }
- // def extension: String = (name lastIndexOf '.') match {
- // case -1 => ""
- // case idx => name drop (idx + 1)
- // }
- // compares against extensions in a CASE INSENSITIVE way.
- def hasExtension(ext: String, exts: String*) = {
- val lower = extension.toLowerCase
- ext.toLowerCase == lower || exts.exists(_.toLowerCase == lower)
- }
- // returns the filename without the extension.
- def stripExtension: String = name stripSuffix ("." + extension)
- // returns the Path with the extension.
- def addExtension(ext: String): Path = Path(path + "." + ext)
- // changes the existing extension out for a new one, or adds it
- // if the current path has none.
- def changeExtension(ext: String): Path = (
- if (extension == "") addExtension(ext)
- else Path(path.stripSuffix(extension) + ext)
- )
-
- // conditionally execute
- def ifFile[T](f: File => T): Option[T] = if (isFile) Some(f(toFile)) else None
- def ifDirectory[T](f: Directory => T): Option[T] = if (isDirectory) Some(f(toDirectory)) else None
-
- // Boolean tests
- def canRead = jfile.canRead()
- def canWrite = jfile.canWrite()
- def exists = jfile.exists()
- def notExists = try !jfile.exists() catch { case ex: SecurityException => false }
-
- def isFile = jfile.isFile()
- def isDirectory = jfile.isDirectory()
- def isAbsolute = jfile.isAbsolute()
- def isHidden = jfile.isHidden()
- def isEmpty = path.length == 0
-
- // Information
- def lastModified = jfile.lastModified()
- def lastModified_=(time: Long) = jfile setLastModified time // should use setXXX function?
- def length = jfile.length()
-
- // Boolean path comparisons
- def endsWith(other: Path) = segments endsWith other.segments
- def startsWith(other: Path) = segments startsWith other.segments
- def isSame(other: Path) = toCanonical == other.toCanonical
- def isFresher(other: Path) = lastModified > other.lastModified
-
- // creations
- def createDirectory(force: Boolean = true, failIfExists: Boolean = false): Directory = {
- val res = if (force) jfile.mkdirs() else jfile.mkdir()
- if (!res && failIfExists && exists) fail("Directory '%s' already exists." format name)
- else if (isDirectory) toDirectory
- else new Directory(jfile)
- }
- def createFile(failIfExists: Boolean = false): File = {
- val res = jfile.createNewFile()
- if (!res && failIfExists && exists) fail("File '%s' already exists." format name)
- else if (isFile) toFile
- else new File(jfile)
- }
-
- // deletions
- def delete() = jfile.delete()
- def deleteIfExists() = if (jfile.exists()) delete() else false
-
- /** Deletes the path recursively. Returns false on failure.
- * Use with caution!
- */
- def deleteRecursively(): Boolean = deleteRecursively(jfile)
- private def deleteRecursively(f: JFile): Boolean = {
- if (f.isDirectory) f.listFiles match {
- case null =>
- case xs => xs foreach deleteRecursively
- }
- f.delete()
- }
-
- def truncate() =
- isFile && {
- val raf = new RandomAccessFile(jfile, "rw")
- raf setLength 0
- raf.close()
- length == 0
- }
-
- def touch(modTime: Long = System.currentTimeMillis) = {
- createFile()
- if (isFile)
- lastModified = modTime
- }
-
- // todo
- // def copyTo(target: Path, options ...): Boolean
- // def moveTo(target: Path, options ...): Boolean
-
- override def toString() = path
- override def equals(other: Any) = other match {
- case x: Path => path == x.path
- case _ => false
- }
- override def hashCode() = path.hashCode()
-}