io.kjson.resource.Resource.kt Maven / Gradle / Ivy
The newest version!
/*
* @(#) Resource.kt
*
* resource-loader Resource loading mechanism
* Copyright (c) 2021, 2022, 2023, 2024 Peter Wall
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package io.kjson.resource
import java.io.File
import java.net.URI
import java.net.URL
import java.nio.file.Files
import java.nio.file.Path
/**
* A resource, as described by a [URL] and loaded by a [ResourceLoader].
*
* @author Peter Wall
*/
class Resource internal constructor(
internal val resourcePath: Path?,
val resourceURL: URL,
private val resourceLoader: ResourceLoader,
) {
/**
* Load the resource. This function is delegated to the [ResourceLoader], which will load a resource of the target
* type.
*/
fun load(): T = resourceLoader.load(this)
/**
* Resolve a relative URL against the current `Resource`, returning a new `Resource`.
*/
fun resolve(relativeURL: String): Resource {
val extendedURL = resourceLoader.addExtension(relativeURL)
if (URI(extendedURL).scheme == null && resourcePath != null) {
// we're navigating entirely within the file system
val resolved: Path = when {
Files.isDirectory(resourcePath) -> resourcePath.resolve(extendedURL)
else -> resourcePath.resolveSibling(extendedURL)
}
return resourceLoader.resource(resolved)
}
val resolvedURL = resourceURL.toURI().resolve(extendedURL).toURL()
return resourceLoader.resource(resolvedURL)
}
override fun equals(other: Any?): Boolean = this === other || other is Resource<*> &&
resourceLoader === other.resourceLoader && resourceURL.toString() == other.resourceURL.toString()
override fun hashCode(): Int = resourceLoader.hashCode() xor resourceURL.toString().hashCode()
/**
* Create a string form of the URL for this `Resource` suitable for use in debugging and logging messages.
*/
override fun toString(): String = if (resourceURL.protocol != "file") resourceURL.toString() else {
val path = resourceURL.path
if (path.startsWith(currentPath))
path.drop(currentPath.length)
else
path
}
companion object {
val currentPath: String = File(".").absoluteFile.toURI().path.let {
when {
it.endsWith("/./") -> it.dropLast(2)
it.endsWith("/.") -> it.dropLast(1)
it.endsWith('/') -> it
else -> "$it/"
}
}
/**
* Get a URL for a resource in the classpath (will be either a `file:` or a `jar:` URL).
*/
fun classPathURL(name: String): URL? = Resource::class.java.getResource(name)
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy