![JAR search and dependency download from the Maven repository](/logo.png)
com.jetbrains.plugin.structure.classes.resolvers.DirectoryResolver.kt Maven / Gradle / Ivy
/*
* Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package com.jetbrains.plugin.structure.classes.resolvers
import com.jetbrains.plugin.structure.base.utils.*
import com.jetbrains.plugin.structure.classes.utils.AsmUtil
import com.jetbrains.plugin.structure.classes.utils.getBundleBaseName
import com.jetbrains.plugin.structure.classes.utils.getBundleNameByBundlePath
import org.objectweb.asm.tree.ClassNode
import java.nio.file.Files
import java.nio.file.Path
import java.util.*
class DirectoryResolver(
private val root: Path,
private val fileOrigin: FileOrigin,
override val readMode: ReadMode = ReadMode.FULL
) : Resolver() {
private val classNameToFile = hashMapOf()
private val bundlePathToFile = hashMapOf()
private val bundleNames = hashMapOf>()
private val packageSet = PackageSet()
init {
Files.walk(root).use { fileStream ->
fileStream.forEach { file ->
if (file.extension == "class") {
val className = AsmUtil.readClassName(file)
val classRoot = getClassRoot(file, className)
if (classRoot != null) {
classNameToFile[className] = file
packageSet.addPackagesOfClass(className)
}
}
if (file.extension == "properties") {
val bundlePath = root.relativize(file).toString().toSystemIndependentName()
bundlePathToFile[bundlePath] = file
val fullBundleName = getBundleNameByBundlePath(bundlePath)
bundleNames.getOrPut(getBundleBaseName(fullBundleName)) { hashSetOf() } += fullBundleName
}
}
}
}
private fun getClassRoot(classFile: Path, className: String): Path? {
val levelsUp = className.count { it == '/' }
var root: Path? = classFile
for (i in 0 until levelsUp + 1) {
root = root?.parent
}
return root
}
override fun resolveClass(className: String): ResolutionResult {
val classFile = classNameToFile[className] ?: return ResolutionResult.NotFound
return readClass(className, classFile)
}
private fun readClass(className: String, classFile: Path): ResolutionResult =
try {
val classNode = AsmUtil.readClassFromFile(className, classFile, readMode == ReadMode.FULL)
ResolutionResult.Found(classNode, fileOrigin)
} catch (e: InvalidClassFileException) {
ResolutionResult.Invalid(e.message)
} catch (e: Exception) {
e.rethrowIfInterrupted()
ResolutionResult.FailedToRead(e.message ?: e.javaClass.name)
}
override fun resolveExactPropertyResourceBundle(baseName: String, locale: Locale): ResolutionResult {
val control = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_PROPERTIES)
val bundleName = control.toBundleName(baseName, locale)
val bundlePath = control.toResourceName(bundleName, "properties")
val bundleFile = bundlePathToFile[bundlePath]
if (bundleFile != null) {
val propertyResourceBundle: PropertyResourceBundle = try {
PropertyResourceBundle(Files.newInputStream(bundleFile).bufferedReader())
} catch (e: IllegalArgumentException) {
return ResolutionResult.Invalid(e.message ?: e.javaClass.name)
} catch (e: Exception) {
return ResolutionResult.FailedToRead(e.message ?: e.javaClass.name)
}
return ResolutionResult.Found(propertyResourceBundle, fileOrigin)
}
return ResolutionResult.NotFound
}
override val allPackages
get() = packageSet.getAllPackages()
override val allBundleNameSet: ResourceBundleNameSet
get() = ResourceBundleNameSet(bundleNames)
override val allClasses
get() = classNameToFile.keys
override fun containsClass(className: String) = className in classNameToFile
override fun containsPackage(packageName: String) = packageSet.containsPackage(packageName)
override fun close() = Unit
override fun processAllClasses(processor: (ResolutionResult) -> Boolean): Boolean {
for ((className, classFile) in classNameToFile) {
val result = readClass(className, classFile)
if (!processor(result)) {
return false
}
}
return true
}
override fun toString() = root.toAbsolutePath().toString()
}
fun buildDirectoriesResolvers(
directories: Iterable,
readMode: Resolver.ReadMode,
parentOrigin: FileOrigin
): List {
val resolvers = arrayListOf()
resolvers.closeOnException {
directories.mapTo(resolvers) { directory ->
val fileOrigin = DirectoryFileOrigin(directory.simpleName, parentOrigin)
DirectoryResolver(directory, fileOrigin, readMode)
}
}
return resolvers
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy