ScalaBot/scalabot-app/src/main/kotlin/util/Utils.kt
LamGC 7b985ce325
refactor: 将十六进制转换代码迁移到 Kotlin.
将 ByteUtils 的实现改用 Kotlin 代码做, 移除 ByteUtils.
另外, 本次修改同时修正了方法名错误的问题(hax 改成 hex), 并补充了单元测试.
2022-05-04 00:38:30 +08:00

106 lines
3.4 KiB
Kotlin

package net.lamgc.scalabot.util
import mu.KotlinLogging
import net.lamgc.scalabot.ExtensionPackageFinder
import net.lamgc.scalabot.FinderRules
import org.eclipse.aether.artifact.Artifact
import java.io.File
import java.io.FileFilter
import java.io.FilenameFilter
import java.net.URL
internal fun ByteArray.toHexString(): String = joinToString("") { it.toString(16) }
internal fun Artifact.equalsArtifact(that: Artifact): Boolean =
this.groupId.equals(that.groupId) &&
this.artifactId.equals(that.artifactId) &&
this.version.equals(that.version) &&
this.baseVersion.equals(that.baseVersion) &&
this.isSnapshot == that.isSnapshot &&
this.classifier.equals(that.classifier) &&
this.extension.equals(that.extension) &&
(if (this.file == null) that.file == null else this.file.equals(that.file)) &&
this.properties.equals(that.properties)
internal fun File.deepListFiles(
addSelf: Boolean = false,
onlyFile: Boolean = false,
fileFilter: FileFilter? = null,
filenameFilter: FilenameFilter? = null
): Array<File>? {
val files = if (fileFilter != null) {
this.listFiles(fileFilter)
} else if (filenameFilter != null) {
this.listFiles(filenameFilter)
} else {
this.listFiles()
} ?: return null
val result = if (addSelf) mutableSetOf(this) else mutableSetOf()
for (file in files) {
if (file.isFile) {
result.add(file)
} else {
if (!onlyFile) {
result.add(file)
}
val subFiles = file.deepListFiles(false, onlyFile, fileFilter, filenameFilter) ?: continue
result.addAll(subFiles)
}
}
return result.toTypedArray()
}
/**
* 从 Finder 的 [FinderRules] 注解中获取优先级.
* @return 获取 Finder 的优先级.
* @throws NoSuchFieldException 如果 Finder 没有添加 [FinderRules] 注解时抛出该异常.
*/
internal fun ExtensionPackageFinder.getPriority() =
this::class.java.getDeclaredAnnotation(FinderRules::class.java)?.priority
?: throw NoSuchFieldException("Finder did not add `FinderRules` annotation")
/**
* 为 [AutoCloseable] 对象注册 Jvm Shutdown 钩子.
* @return 返回对象本身, 方便进行链式调用.
*/
fun <T : AutoCloseable> T.registerShutdownHook(): T {
UtilsInternal.autoCloseableSet.add(this)
return this
}
private val log = KotlinLogging.logger { }
private object UtilsInternal {
val autoCloseableSet = mutableSetOf<AutoCloseable>()
init {
Runtime.getRuntime().addShutdownHook(Thread({
log.debug { "Closing registered hook resources..." }
autoCloseableSet.forEach {
try {
it.close()
} catch (e: Exception) {
log.error(e) { "An exception occurred while closing the resource. (Resource: `$it`)" }
}
}
log.debug { "All registered hook resources have been closed." }
}, "Shutdown-AutoCloseable"))
}
}
fun URL.resolveToFile(canonical: Boolean = true): File {
if ("file" != protocol) {
throw ClassCastException("Only the URL of the `file` protocol can be converted into a File object.")
}
val urlString = toString().substringAfter(':')
val file = File(urlString)
return if (canonical) {
file.canonicalFile
} else {
file
}
}