aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/resolvers/local/DefaultLocationProvider.kt
blob: c956b308f204d8298ddf943dfadfadbdb30b5aaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package org.jetbrains.dokka.base.resolvers.local

import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.resolvers.external.ExternalLocationProvider
import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation
import org.jetbrains.dokka.base.resolvers.shared.PackageList
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.DisplaySourceSet
import org.jetbrains.dokka.pages.RootPageNode
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.query

abstract class DefaultLocationProvider(
    protected val pageGraphRoot: RootPageNode,
    protected val dokkaContext: DokkaContext
) : LocationProvider {
    protected val externalLocationProviderFactories =
        dokkaContext.plugin<DokkaBase>().query { externalLocationProviderFactory }

    protected val externalLocationProviders: Map<ExternalDocumentation, ExternalLocationProvider?> = dokkaContext
        .configuration
        .sourceSets
        .flatMap { sourceSet ->
            sourceSet.externalDocumentationLinks.map {
                PackageList.load(it.packageListUrl, sourceSet.jdkVersion, dokkaContext.configuration.offlineMode)
                    ?.let { packageList -> ExternalDocumentation(it.url, packageList) }
            }
        }
        .filterNotNull()
        .map { extDocInfo ->
            val externalLocationProvider = (externalLocationProviderFactories.asSequence()
                .mapNotNull { it.getExternalLocationProvider(extDocInfo) }.firstOrNull()
                ?: run { dokkaContext.logger.error("No ExternalLocationProvider for '${extDocInfo.packageList.url}' found"); null })
            extDocInfo to externalLocationProvider
        }
        .toMap()

    protected val packagesIndex: Map<String, ExternalLocationProvider?> = externalLocationProviders
        .flatMap { (extDocInfo, externalLocationProvider) ->
            extDocInfo.packageList.packages.map { packageName -> packageName to externalLocationProvider }
        }
        .toMap()
        .filterKeys(String::isNotBlank)


    protected val locationsIndex: Map<String, ExternalLocationProvider?> = externalLocationProviders
        .flatMap { (extDocInfo, externalLocationProvider) ->
            extDocInfo.packageList.locations.keys.map { relocatedDri -> relocatedDri to externalLocationProvider }
        }
        .toMap()
        .filterKeys(String::isNotBlank)

    protected open fun getExternalLocation(dri: DRI, sourceSets: Set<DisplaySourceSet>): String? =
        packagesIndex[dri.packageName]?.resolve(dri)
            ?: locationsIndex[dri.toString()]?.resolve(dri)
            ?: externalLocationProviders.values.mapNotNull { it?.resolve(dri) }.firstOrNull()

}