Created
November 28, 2012 18:34
-
-
Save adamrabung/4163100 to your computer and use it in GitHub Desktop.
Implementation of James Roper's Play 2 versioned assets w/o scala 2.10 dependency
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package controllers | |
import play.api.mvc.PathBindable | |
import play.api.Play | |
import java.net.JarURLConnection | |
import Play.current | |
import java.io.File | |
import com.google.common.cache.CacheBuilder | |
import com.google.common.cache.CacheLoader | |
import java.net.URL | |
//modified to use guava Cache instead of 2.10 TrieMap | |
//original: https://github.com/jroper/play-versioned-assets-example/blob/master/app/controllers/VersionedAssets.scala | |
class AccessTimeCacheLoader extends CacheLoader[URL, Option[Long]] { | |
@Override | |
override def load(resource: URL) = resource.getProtocol match { | |
case "jar" => { | |
resource.getPath.split('!').drop(1).headOption.flatMap { fileNameInJar => | |
Option(resource.openConnection) | |
.collect { case c: JarURLConnection => c } | |
.flatMap(c => Option(c.getJarFile.getJarEntry(fileNameInJar.drop(1)))) | |
.map(_.getTime) | |
.filterNot(_ == 0) | |
} | |
} | |
case _ => None | |
} | |
} | |
object VersionedAssets { | |
def at(file: VersionedAsset) = Assets.at(file.path, file.file) | |
} | |
case class VersionedAsset(file: String, path: String = "/public", versionParam: String = "v") | |
object VersionedAsset { | |
private val lastModifieds = CacheBuilder.newBuilder().maximumSize(10000).build(new AccessTimeCacheLoader()); | |
private def lastModifiedFor(resource: java.net.URL): Option[Long] = lastModifieds.get(resource) | |
implicit def pathBinder = new PathBindable[VersionedAsset] { | |
def bind(key: String, value: String) = Right(VersionedAsset(value)) | |
def unbind(key: String, value: VersionedAsset) = { | |
val resourceName = Option(value.path + "/" + value.file).map(name => if (name.startsWith("/")) name else ("/" + name)).get | |
val modified = Play.resource(resourceName).flatMap { resource => | |
resource.getProtocol match { | |
case file if file == "file" => Some(new File(resource.toURI).lastModified()) | |
case jar if jar == "jar" => lastModifiedFor(resource) | |
case _ => None | |
} | |
} | |
modified.map(value.file + "?" + value.versionParam + "=" + _).getOrElse(value.file) | |
} | |
} | |
implicit def toVersionedAsset(path: String): VersionedAsset = VersionedAsset(path) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment