Skip to content

Commit

Permalink
fix: Load resources from jar correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
0ffz committed Oct 27, 2024
1 parent e46fa21 commit 1100511
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import kotlinx.io.buffered
import kotlinx.io.files.Path
import java.io.File
import java.io.InputStream
import java.util.jar.JarFile
import kotlin.io.path.*
import kotlin.reflect.KClass

Expand Down Expand Up @@ -47,20 +48,57 @@ object PrefabsDSLExtensions {
fun walkJarResources(
classLoader: ClassLoader,
directory: String,
): Sequence<java.nio.file.Path> {
val directoryPath = File(classLoader.getResource(directory)?.toURI() ?: return emptySequence()).toPath()
return directoryPath.walk().filter { it.isRegularFile() }
): Sequence<JarResource> = sequence {
val resources = classLoader.getResources(directory)
while (resources.hasMoreElements()) {
val resource = resources.nextElement()
val protocol = resource.protocol
if (protocol == "jar") {
val jarPath = resource.path.substringBefore("!").removePrefix("file:")
val jarFile = JarFile(jarPath)
val entries = jarFile.entries()
while (entries.hasMoreElements()) {
val entry = entries.nextElement()
if (entry.name.startsWith(directory) && !entry.isDirectory) {
yield(JarResource(
nameWithoutExt = entry.name.substringAfterLast("/").substringBeforeLast("."),
ext = entry.name.substringAfterLast("."),
stream = jarFile.getInputStream(entry)
))
}
}
} else if (protocol == "file") {
val directoryPath = File(classLoader.getResource(directory)?.toURI() ?: return@sequence).toPath()
yieldAll(directoryPath.walk().filter { it.isRegularFile() }.map {
JarResource(
nameWithoutExt = it.nameWithoutExtension,
ext = it.extension,
stream = it.inputStream()
)
})
}
}
}

fun getResource(classLoader: ClassLoader, path: String): java.nio.file.Path? {
return File(classLoader.getResource(path)?.toURI() ?: return null).toPath()
fun getResource(classLoader: ClassLoader, path: String): JarResource? {
return classLoader.getResourceAsStream(path)?.let { stream ->
JarResource(
nameWithoutExt = path.substringAfterLast("/").substringBeforeLast("."),
ext = path.substringAfterLast("."),
stream = stream
)
}
}

private fun java.nio.file.Path.asPrefabSource(namespace: String) = PrefabSource(
source = inputStream().asSource().buffered(),
key = PrefabKey.of(namespace, nameWithoutExtension),
formatExt = extension
private fun JarResource.asPrefabSource(namespace: String) = PrefabSource(
source = stream.asSource().buffered(),
key = PrefabKey.of(namespace, nameWithoutExt),
formatExt = ext
)

data class NameToStream(val name: String, val stream: InputStream)
data class JarResource(
val nameWithoutExt: String,
val ext: String,
val stream: InputStream,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.mineinabyss.geary.prefabs

import com.mineinabyss.geary.modules.TestEngineModule
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.geary.prefabs.PrefabsDSLExtensions.fromFiles
import com.mineinabyss.geary.prefabs.PrefabsDSLExtensions.fromJarResourceDirectory
import com.mineinabyss.geary.prefabs.PrefabsDSLExtensions.fromJarResources
import com.mineinabyss.geary.serialization.formats.YamlFormat
Expand Down Expand Up @@ -48,23 +47,4 @@ class PrefabFromResourcesTest {
entityOfOrNull(PrefabKey.of("test:prefabB")) shouldNotBe null
}
}

@Test
fun `should load prefabs from path source`() {
val world = world().configure {
namespace("test") {
prefabs {
fromFiles(
PrefabsDSLExtensions.getResource(
PrefabFromResourcesTest::class.java.classLoader,
"prefabs/prefabA.yml"
)!!
)
}
}
}.start()
with(world) {
entityOfOrNull(PrefabKey.of("test:prefabA")) shouldNotBe null
}
}
}

0 comments on commit 1100511

Please sign in to comment.