Skip to content

Instantly share code, notes, and snippets.

@paulp
Created July 7, 2016 16:16
Show Gist options
  • Save paulp/d9092b24071d3154db8038db0a3becc7 to your computer and use it in GitHub Desktop.
Save paulp/d9092b24071d3154db8038db0a3becc7 to your computer and use it in GitHub Desktop.
package psp
package jio
import MetaPath._
final case class SinglePath(path: Path) extends AnyVal {
def entries = path.entries
def deepEntries = path.deepEntries
def deepDirClasses = path.deepClasses map (path relativize _)
def deepClasses = if (path.isDirectory() && !path.isAbsolute) deepDirClasses else path.deepClasses
override def toString = path.toString
}
final case class SinglePaths(singles: IndexedSeq[SinglePath]) extends IndexedSeq[SinglePath] {
def apply(idx: Int) = singles(idx)
def length = singles.length
def paths = singles map (_.path)
def entries = paths flatMap (_.entries)
// def deepEntries = paths flatMap (_.deepEntries)
// def packageNames = deepFiles flatMap packagesIn dsort
val pathToPackage = paths mapOnto (_.deepPackageNames)
val packageToPath = pathToPackage.values.flatten.distinct mapOnto (pkg => paths filter (p => pathToPackage(p) contains pkg))
}
/** A MetaPath encapsulates the character content of a classpath string as
* well as its contextual semantics. Resolving a metapath involves first
* flattening it, which means splitting on the classpath separator so that
* there are no composite paths, and then expanding each one, which means
* replacing *-paths and extdir paths with the contents of those directories
* where appropriate.
*/
case class MetaPath(path: Path, style: MetaStyle) {
private def sep = java.io.File.pathSeparatorChar
private def newPath(s: String) = path.getFileSystem getPath s
private def chars = path.toString
private def singles = (chars split sep).toList map single
private def hasStar(p: Path) = p.filename == "*"
private def single(s: String): MetaPath = copy(path = newPath(s))
def isComposite = chars contains sep
def flatten: MetaPaths = if (isComposite) singles else this :: Nil
def expanded: SinglePaths = MetaPath expansion this
def entries: Paths = expanded flatMap (_.entries)
override def toString = s"meta[$path]"
}
object MetaPath {
def expansion(mp: MetaPath): SinglePaths = SinglePaths(
if (mp.isComposite)
(mp.flatten flatMap expansion).toIndexedSeq
else mp.style match {
case Expand => mp.path.entries.toIndexedSeq map SinglePath
case ExpandStar => mp.path.parent.entries.toIndexedSeq map SinglePath
case Literal => SinglePath(mp.path) :: Nil toIndexedSeq
}
)
sealed trait MetaStyle
case object Literal extends MetaStyle
case object Expand extends MetaStyle
case object ExpandStar extends MetaStyle
def literal(uri: URI): MetaPath = literal(uri.fs)
def literal(chars: String): MetaPath = literal(newPath(chars))
def literal(path: Path): MetaPath = MetaPath(path, Literal)
def expand(chars: String) = MetaPath(newPath(chars), Expand)
def expandStar(chars: String) = MetaPath(newPath(chars), ExpandStar)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment