Skip to content

Commit

Permalink
add zip protocol to isDirectory
Browse files Browse the repository at this point in the history
when a play app is deployed as a war on weblogic, it fails as the classpath
contains zip archives and isDirectory throws an Exception, rendering the
usage of I18n unusable.

Based on 422ca97.
  • Loading branch information
Sarunas Valaskevicius committed Feb 29, 2016
1 parent e920c5c commit 0b5fe10
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
14 changes: 10 additions & 4 deletions framework/src/play/src/main/scala/play/utils/Resources.scala
Expand Up @@ -16,7 +16,8 @@ object Resources {

def isDirectory(classLoader: ClassLoader, url: URL) = url.getProtocol match {
case "file" => new File(url.toURI).isDirectory
case "jar" => isJarResourceDirectory(url)
case "jar" => isZipResourceDirectory(url)
case "zip" => isZipResourceDirectory(url)
case "bundle" => isBundleResourceDirectory(classLoader, url)
case _ => throw new IllegalArgumentException(s"Cannot check isDirectory for a URL with protocol='${url.getProtocol}'")
}
Expand Down Expand Up @@ -75,13 +76,18 @@ object Resources {
classLoader.getResource(path) != null && classLoader.getResource(pathSlash) != null
}

private def isJarResourceDirectory(url: URL): Boolean = {
private def isZipResourceDirectory(url: URL): Boolean = {
val path = url.getPath
val bangIndex = url.getFile.indexOf("!")

val jarFile: File = new File(URI.create(path.substring(0, bangIndex)))
val startIndex = if (path.startsWith("zip:")) 4 else 0
val fileUri = path.substring(startIndex, bangIndex)
val fileProtocol = if (fileUri.startsWith("/")) "file://" else ""
val absoluteFileUri = fileProtocol + fileUri

val zipFile: File = new File(URI.create(absoluteFileUri))
val resourcePath = URI.create(path.substring(bangIndex + 1)).getPath.drop(1)
val zip = new ZipFile(jarFile)
val zip = new ZipFile(zipFile)

try {
val entry = zip.getEntry(resourcePath)
Expand Down
32 changes: 31 additions & 1 deletion framework/src/play/src/test/scala/play/utils/ResourcesSpec.scala
Expand Up @@ -114,7 +114,27 @@ object ResourcesSpec extends Specification {
isDirectory(osgiClassloader, url) must beFalse
}

"throw an exception for a URL with a protocol other than 'file'/'jar'/'bundle'" in {
"return true for a directory resource URL with the 'zip' protocol" in {
val url = new URL("zip", "", 0, createZipUrl(jar, dirRes), EmptyURLStreamHandler)
isDirectory(classloader, url) must beTrue
}

"return true for a directory resource URL that contains spaces in the zip path with the 'zip' protocol" in {
val url = new URL("zip", "", 0, createZipUrl(spacesJar, dirRes), EmptyURLStreamHandler)
isDirectory(classloader, url) must beTrue
}

"return true for a directory resource URL that contains spaces in the file path with the 'zip' protocol" in {
val url = new URL("zip", "", 0, createZipUrl(jar, dirSpacesRes), EmptyURLStreamHandler)
isDirectory(classloader, url) must beTrue
}

"return false for a file resource URL with the 'zip' protocol" in {
val url = new URL("zip", "", 0, createZipUrl(jar, fileRes), EmptyURLStreamHandler)
isDirectory(classloader, url) must beFalse
}

"throw an exception for a URL with a protocol other than 'file'/'jar'/'zip'/'bundle'" in {
val url = new URL("ftp", "", "/some/path")
isDirectory(classloader, url) must throwAn[IllegalArgumentException]
}
Expand All @@ -129,10 +149,20 @@ object ResourcesSpec extends Specification {
}
}

object EmptyURLStreamHandler extends URLStreamHandler {
def openConnection(u: URL) = new URLConnection(u) {
def connect() {}
}
}

private def createJarUrl(jarFile: File, file: File) = {
s"${jarFile.toURI.toURL}!/${UriEncoding.encodePathSegment(file.getName, "utf-8")}"
}

private def createZipUrl(zipFile: File, file: File) = {
s"zip:${zipFile.toURI.toURL}!/${UriEncoding.encodePathSegment(file.getName, "utf-8")}"
}

private def createTempDir(prefix: String, suffix: String, parent: File = null) = {
val f = File.createTempFile(prefix, suffix, parent)
f.delete()
Expand Down

0 comments on commit 0b5fe10

Please sign in to comment.