All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jetbrains.plugin.structure.classes.resolvers.CompositeResolver.kt Maven / Gradle / Ivy

Go to download

Base library for resolving class files and resources. Used by other JetBrains Plugins Structure Classes libraries.

There is a newer version: 3.289
Show newest version
/*
 * 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.closeAll
import org.objectweb.asm.tree.ClassNode
import java.util.*

/**
 * [Resolver] that combines several [resolvers] with the Java classpath search strategy.
 */
class CompositeResolver private constructor(
  private val resolvers: List,
  override val readMode: ReadMode
) : Resolver() {

  private val packageToResolvers: MutableMap> = hashMapOf()

  private val fullBundleNames = hashMapOf>()

  private val baseBundleNameToResolvers: MutableMap> = hashMapOf()

  init {
    buildIndex()
  }

  private fun buildIndex() {
    for (resolver in resolvers) {
      for (packageName in resolver.allPackages) {
        packageToResolvers.getOrPut(packageName) { arrayListOf() } += resolver
      }

      val bundleNameSet = resolver.allBundleNameSet
      for (baseBundleName in bundleNameSet.baseBundleNames) {
        baseBundleNameToResolvers.getOrPut(baseBundleName) { arrayListOf() } += resolver

        val resolverAllNames = bundleNameSet[baseBundleName]
        if (resolverAllNames.isNotEmpty()) {
          fullBundleNames.getOrPut(baseBundleName) { hashSetOf() } += resolverAllNames
        }
      }
    }
  }

  override val allClasses
    get() = resolvers.flatMapTo(hashSetOf()) { it.allClasses }

  override val allBundleNameSet: ResourceBundleNameSet
    get() = ResourceBundleNameSet(fullBundleNames)

  override val allPackages
    get() = packageToResolvers.keys

  override fun processAllClasses(processor: (ResolutionResult) -> Boolean) =
    resolvers.all { it.processAllClasses(processor) }

  private fun getPackageName(className: String) = className.substringBeforeLast('/', "")

  override fun containsClass(className: String): Boolean {
    val packageName = getPackageName(className)
    val resolvers = packageToResolvers[packageName] ?: emptyList()
    return resolvers.any { it.containsClass(className) }
  }

  override fun containsPackage(packageName: String) = packageName in packageToResolvers

  override fun resolveClass(className: String): ResolutionResult {
    val packageName = getPackageName(className)
    val resolvers = packageToResolvers[packageName] ?: emptyList()
    for (resolver in resolvers) {
      val resolutionResult = resolver.resolveClass(className)
      if (resolutionResult !is ResolutionResult.NotFound) {
        return resolutionResult
      }
    }
    return ResolutionResult.NotFound
  }

  override fun resolveExactPropertyResourceBundle(baseName: String, locale: Locale): ResolutionResult {
    val resolvers = baseBundleNameToResolvers[baseName] ?: emptyList()
    for (resolver in resolvers) {
      val resolutionResult = resolver.resolveExactPropertyResourceBundle(baseName, locale)
      if (resolutionResult !is ResolutionResult.NotFound) {
        return resolutionResult
      }
    }
    return ResolutionResult.NotFound
  }

  override fun close() {
    resolvers.closeAll()
  }

  override fun toString() = "Union of ${resolvers.size} resolver" + (if (resolvers.size != 1) "s" else "")

  companion object {

    @JvmStatic
    fun create(vararg resolvers: Resolver): Resolver = create(resolvers.asIterable())

    @JvmStatic
    fun create(resolvers: Iterable): Resolver {
      val list = resolvers.toList()
      return when(list.size) {
        0 -> EmptyResolver
        1 -> list.first()
        else -> {
          val readMode = if (list.all { it.readMode == ReadMode.FULL }) {
            ReadMode.FULL
          } else {
            ReadMode.SIGNATURES
          }
          CompositeResolver(list, readMode)
        }
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy