Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,35 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou
return result
}

@OptIn(ExperimentalResourceApi::class)
override fun getUri(path: String): String {
val classLoader = getClassLoader()
val resource = classLoader.getResource(path) ?: run {
//try to find a font in the android assets
if (File(path).isFontResource()) {
classLoader.getResource("assets/$path")
} else null
} ?: throw MissingResourceException(path)
return resource.toURI().toString()
}

@OptIn(ExperimentalResourceApi::class)
private fun getResourceAsStream(path: String): InputStream {
val classLoader = Thread.currentThread().contextClassLoader ?: this.javaClass.classLoader
val classLoader = getClassLoader()
val resource = classLoader.getResourceAsStream(path) ?: run {
//try to find a font in the android assets
if (File(path).parentFile?.name.orEmpty().startsWith("font")) {
if (File(path).isFontResource()) {
classLoader.getResourceAsStream("assets/$path")
} else null
} ?: throw MissingResourceException(path)
return resource
}

private fun File.isFontResource(): Boolean {
return this.parentFile?.name.orEmpty().startsWith("font")
}

private fun getClassLoader(): ClassLoader {
return Thread.currentThread().contextClassLoader ?: this.javaClass.classLoader!!
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,19 @@ class MissingResourceException(path: String) : Exception("Missing resource with
@InternalResourceApi
suspend fun readResourceBytes(path: String): ByteArray = DefaultResourceReader.read(path)

/**
* Provides the platform dependent URI for a given resource path.
*
* @param path The path to the file in the resource's directory.
* @return The URI string of the specified resource.
*/
@InternalResourceApi
fun getResourceUri(path: String): String = DefaultResourceReader.getUri(path)

internal interface ResourceReader {
suspend fun read(path: String): ByteArray
suspend fun readPart(path: String, offset: Long, size: Long): ByteArray
fun getUri(path: String): String
}

internal expect fun getPlatformResourceReader(): ResourceReader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.runComposeUiTest
import kotlinx.coroutines.test.runTest
import org.jetbrains.skiko.URIManager
import kotlin.test.*

@OptIn(ExperimentalTestApi::class, ExperimentalResourceApi::class, InternalResourceApi::class)
Expand Down Expand Up @@ -286,4 +287,21 @@ class ComposeResourceTest {
bytes.decodeToString()
)
}

@Test
fun testGetResourceUri() = runComposeUiTest {
var uri1 = ""
var uri2 = ""
setContent {
CompositionLocalProvider(LocalComposeEnvironment provides TestComposeEnvironment) {
val resourceReader = LocalResourceReader.current
uri1 = resourceReader.getUri("1.png")
uri2 = resourceReader.getUri("2.png")
}
}
waitForIdle()

assertTrue(uri1.endsWith("/1.png"))
assertTrue(uri2.endsWith("/2.png"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ internal class TestResourceReader : ResourceReader {
readPathsList.add("$path/$offset-$size")
return DefaultResourceReader.readPart(path, offset, size)
}

override fun getUri(path: String): String {
return DefaultResourceReader.getUri(path)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,20 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou
return result
}

@OptIn(ExperimentalResourceApi::class)
override fun getUri(path: String): String {
val classLoader = getClassLoader()
val resource = classLoader.getResource(path) ?: throw MissingResourceException(path)
return resource.toURI().toString()
}

@OptIn(ExperimentalResourceApi::class)
private fun getResourceAsStream(path: String): InputStream {
val classLoader = Thread.currentThread().contextClassLoader ?: this.javaClass.classLoader
val classLoader = getClassLoader()
return classLoader.getResourceAsStream(path) ?: throw MissingResourceException(path)
}

private fun getClassLoader(): ClassLoader {
return Thread.currentThread().contextClassLoader ?: this.javaClass.classLoader!!
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou
}
}

override fun getUri(path: String): String {
return NSURL.fileURLWithPath(getPathInBundle(path)).toString()
}

private fun readData(path: String): NSData {
return NSFileManager.defaultManager().contentsAtPath(path) ?: throw MissingResourceException(path)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou
return part.asByteArray()
}

override fun getUri(path: String): String {
val location = window.location
return getResourceUrl(location.origin, location.pathname, path)
}

private suspend fun readAsBlob(path: String): Blob {
val resPath = WebResourcesConfiguration.getResourcePath(path)
val response = window.fetch(resPath).await()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou
}
}

override fun getUri(path: String): String {
return NSURL.fileURLWithPath(getPathOnDisk(path)).toString()
}

private fun readData(path: String): NSData {
return NSFileManager.defaultManager().contentsAtPath(path) ?: throw MissingResourceException(path)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou
return part.asByteArray()
}

override fun getUri(path: String): String {
val location = window.location
return getResourceUrl(location.origin, location.pathname, path)
}

private suspend fun readAsBlob(path: String): Blob {
val resPath = WebResourcesConfiguration.getResourcePath(path)
val response = window.fetch(resPath).await<Response>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,14 @@ object WebResourcesConfiguration {
@ExperimentalResourceApi
fun configureWebResources(configure: WebResourcesConfiguration.() -> Unit) {
WebResourcesConfiguration.configure()
}

@OptIn(ExperimentalResourceApi::class)
internal fun getResourceUrl(windowOrigin: String, windowPathname: String, resourcePath: String): String {
val path = WebResourcesConfiguration.getResourcePath(resourcePath)
return when {
path.startsWith("/") -> windowOrigin + path
path.startsWith("http://") || path.startsWith("https://") -> path
else -> windowOrigin + windowPathname + path
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,27 @@ internal fun getResFileSpecs(
.addStatement("""return %M("$moduleDir" + path)""", readResourceBytes)
.build()
)

//getUri
val getResourceUri = MemberName("org.jetbrains.compose.resources", "getResourceUri")
resObject.addFunction(
FunSpec.builder("getUri")
.addKdoc(
"""
Returns the URI string of the resource file at the specified path.

Example: `val uri = Res.getUri("files/key.bin")`

@param path The path of the file in the compose resource's directory.
@return The URI string of the file.
""".trimIndent()
)
.addParameter("path", String::class)
.returns(String::class)
.addStatement("""return %M("$moduleDir" + path)""", getResourceUri)
.build()
)

ResourceType.values().forEach { type ->
resObject.addType(TypeSpec.objectBuilder(type.accessorName).build())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlin.ByteArray
import kotlin.OptIn
import kotlin.String
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.getResourceUri
import org.jetbrains.compose.resources.readResourceBytes

@ExperimentalResourceApi
Expand All @@ -23,6 +24,16 @@ public object Res {
*/
public suspend fun readBytes(path: String): ByteArray = readResourceBytes("" + path)

/**
* Returns the URI string of the resource file at the specified path.
*
* Example: `val uri = Res.getUri("files/key.bin")`
*
* @param path The path of the file in the compose resource's directory.
* @return The URI string of the file.
*/
public fun getUri(path: String): String = getResourceUri("" + path)

public object drawable

public object string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlin.ByteArray
import kotlin.OptIn
import kotlin.String
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.getResourceUri
import org.jetbrains.compose.resources.readResourceBytes

@ExperimentalResourceApi
Expand All @@ -23,6 +24,16 @@ internal object Res {
*/
public suspend fun readBytes(path: String): ByteArray = readResourceBytes("" + path)

/**
* Returns the URI string of the resource file at the specified path.
*
* Example: `val uri = Res.getUri("files/key.bin")`
*
* @param path The path of the file in the compose resource's directory.
* @return The URI string of the file.
*/
public fun getUri(path: String): String = getResourceUri("" + path)

public object drawable

public object string
Expand All @@ -32,4 +43,4 @@ internal object Res {
public object plurals

public object font
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
org.jetbrains.compose.resources.ExperimentalResourceApi::class,
)

package app.group.empty_res.generated.resources
package app.group.resources_test.generated.resources

import kotlin.ByteArray
import kotlin.OptIn
import kotlin.String
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.getResourceUri
import org.jetbrains.compose.resources.readResourceBytes

@ExperimentalResourceApi
Expand All @@ -23,6 +24,16 @@ internal object Res {
*/
public suspend fun readBytes(path: String): ByteArray = readResourceBytes("" + path)

/**
* Returns the URI string of the resource file at the specified path.
*
* Example: `val uri = Res.getUri("files/key.bin")`
*
* @param path The path of the file in the compose resource's directory.
* @return The URI string of the file.
*/
public fun getUri(path: String): String = getResourceUri("" + path)

public object drawable

public object string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
org.jetbrains.compose.resources.ExperimentalResourceApi::class,
)

package me.app.jvmonlyresources.generated.resources
package app.group.resources_test.generated.resources

import kotlin.ByteArray
import kotlin.OptIn
import kotlin.String
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.getResourceUri
import org.jetbrains.compose.resources.readResourceBytes

@ExperimentalResourceApi
Expand All @@ -23,6 +24,16 @@ internal object Res {
*/
public suspend fun readBytes(path: String): ByteArray = readResourceBytes("" + path)

/**
* Returns the URI string of the resource file at the specified path.
*
* Example: `val uri = Res.getUri("files/key.bin")`
*
* @param path The path of the file in the compose resource's directory.
* @return The URI string of the file.
*/
public fun getUri(path: String): String = getResourceUri("" + path)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not we add test that calls getUri (we may check that resulting URI contains original path)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

original path depends on a platform. so we need to call the same logic in the test, it means the test will do nothing


public object drawable

public object string
Expand All @@ -32,4 +43,4 @@ internal object Res {
public object plurals

public object font
}
}