All Downloads are FREE. Search and download functionalities are using the official Maven repository.

skinny.micro.rl.UriPath.scala Maven / Gradle / Ivy

The newest version!
// The MIT License (MIT) Copyright (c) 2011 Mojolly Ltd.
package skinny.micro.rl

import scala.collection.Seq
import scala.collection.immutable.Vector

trait UriPath extends UriNode {

  def segments: Seq[String]
  def isRelative: Boolean
  def isAbsolute: Boolean

  def collapseDots(): Seq[String] = {
    segments.foldLeft(Vector.empty[String]) { (lb, seg) =>
      seg match {
        case "." => lb
        case "src/main" => if (!lb.isEmpty) lb.dropRight(1) else lb
        case a => lb :+ a
      }
    }
  }

  def normalize: UriPath

  def apply() = uriPart

  protected[this] def startSeparator = UriPath.unixSeparator

  protected[this] def toUriPart(endSeparator: String = UriPath.unixSeparator) = {
    val l = segments.size
    if (l == 0) ""
    else {
      val sb = new StringBuilder
      var i = 0
      while (i < l) {
        if (i > 0) sb.append(UriPath.unixSeparator)
        else sb.append(startSeparator)
        sb.append(segments(i))
        i += 1
      }
      sb.append(endSeparator)
      sb.toString()
    }
  }

  def uriPartWithoutTrailingSlash = toUriPart("")

}

trait EmptyUriPath extends UriPath {

  val segments = Nil

  def normalize = this

}

case object EmptyPath extends EmptyUriPath {

  val isAbsolute: Boolean = false

  val isRelative: Boolean = true

  val uriPart = "/"

}

case class RelativePath(segments: Seq[String]) extends UriPath {

  val isAbsolute: Boolean = false

  val isRelative: Boolean = true

  override protected[this] def startSeparator: String = ""

  val uriPart = toUriPart()

  def normalize = RelativePath(collapseDots())

}

case class AbsolutePath(segments: Seq[String]) extends UriPath {

  val isAbsolute: Boolean = true

  val isRelative: Boolean = false

  val uriPart = toUriPart()

  def normalize = AbsolutePath(collapseDots())

}

trait PathOps {

  private val wlpExpr = """^[A-Za-z]:\\""".r
  private val wuncpExpr = """^\\\\""".r

  val windowsSeparator = "\\"
  val unixSeparator = "/"

  def windowsToUnixPath(path: String) = {
    if (wlpExpr.findFirstIn(path).isDefined) {
      "file:///" + convertWindowsToUnixPath(path)
    } else if (wuncpExpr.findFirstIn(path).isDefined) {
      "file:" + convertWindowsToUnixPath(path)
    } else convertWindowsToUnixPath(path)
  }

  private def convertWindowsToUnixPath(path: String) = {
    path.replace(windowsSeparator, unixSeparator).replace(" ", "%20")
  }

  def parsePath(text: Option[String]): UriPath = {
    text match {
      case None => EmptyPath
      case Some(pt) if pt.trim == "/" => EmptyPath
      case Some(pt) if pt.startsWith("/") => AbsolutePath(pt.split("/").drop(1).toList)
      case Some(pt) => RelativePath(pt.split("/"))
    }
  }

}

object UriPath extends PathOps




© 2015 - 2024 Weber Informatics LLC | Privacy Policy