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

os.browse.internal.Resource.scala Maven / Gradle / Ivy

The newest version!
// Copyright 2014,2015 ~ Optersoft SL

package os.browse.internal

import scala.reflect.api.Universe
import os.io.Path
import scala.reflect.macros.blackbox.Context
import os.io.File
import java.util.zip.CRC32

object Resource {

  def apply(c: Context)(name: c.Expr[String]): c.Expr[String] = {

    import c.universe._

    val Literal(Constant(n: String)) = name.tree

    // TODO test extension (has and ok)

    val owner = c.internal.enclosingOwner

    val path = getPackagePath(c.universe)(owner) / n
    val file = (c.internal.enclosingOwner.pos.source.path: File).parent + n

    if (!file.exists())
      c.abort(c.enclosingPosition, s"Resource not found: $path")

    val x = toURI(path.toString(), hash(file))

    c.Expr[String](q"$x")

  }

  def getPackagePath(u: Universe)(s: u.Symbol): Path = {

    var parts: List[String] = Nil
    var symbol = s.owner

    while (!symbol.isPackage)
      symbol = symbol.owner

    while (symbol.owner != u.NoSymbol) {
      parts = symbol.name.toString() :: parts
      symbol = symbol.owner
    }

    parts match {
      case Nil => Path.Empty
      case x :: Nil => Path(x)
      case x :: xs => Path(x, xs: _*)
    }

  }

  def isResource(path: String): Boolean = {

    var i = path.length() - 1
    while (i >= 0) {
      val char = path.charAt(i)
      if (char == '.') return true
      else if (char == '/') return false
      i -= 1
    }

    false
  }

  def toURI(path: String, version: String) = {

    val index = path.lastIndexOf('.')

    "/R/" + path.substring(0, index) + "." + version + path.substring(index)

  }

  def removeVersion(path: String) = {

    var begin: Int = -1; var end: Int = -1

    var i = path.length() - 1
    while (i >= 0) {
      val char = path.charAt(i)
      if (char == '.') {
        if (end < 0) end = i else {
          begin = i; i = -1
        }
      } else if (char == '/')
        i = -1
      i -= 1
    }

    if (end == -1 || begin == -1) path.substring(0)
    else
      path.substring(0, begin) + path.substring(end, path.length())

  }

  private def hash(file: File) = {

    val inputStream = file.inputStream

    try {

      val crc32 = new CRC32()

      val buffer = new Array[Byte](512)
      Stream.continually(inputStream.read(buffer)).
        takeWhile(_ != -1).
        foreach(crc32.update(buffer, 0, _))

      crc32.getValue().toHexString

    } finally {
      inputStream.close()
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy