aboutsummaryrefslogtreecommitdiff
path: root/plugins/all-modules-page/src/main/kotlin/templates/TemplateProcessor.kt
blob: 18d63df023efc402cd04468473dc60ba0bc45eb7 (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
60
package org.jetbrains.dokka.allModulesPage.templates

import kotlinx.coroutines.*
import org.jetbrains.dokka.allModulesPage.AllModulesPagePlugin
import org.jetbrains.dokka.base.templating.Command
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
import org.jetbrains.dokka.plugability.query
import org.jsoup.nodes.Element
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import kotlin.coroutines.coroutineContext

interface TemplateProcessor {
    fun process()
}

interface TemplateProcessingStrategy {
    suspend fun process(input: File, output: File): Boolean
    suspend fun finish(output: File) {}
}

class DefaultTemplateProcessor(
    private val context: DokkaContext,
): TemplateProcessor {

    private val strategies: List<TemplateProcessingStrategy> = context.plugin<AllModulesPagePlugin>().query { templateProcessingStrategy }

    override fun process() = runBlocking(Dispatchers.Default) {
        coroutineScope {
            context.configuration.modules.forEach {
                launch {
                    it.sourceOutputDirectory.visit(context.configuration.outputDir.resolve(it.relativePathToOutputDirectory))
                }
            }
        }
        strategies.map { it.finish(context.configuration.outputDir) }
        Unit
    }

    private suspend fun File.visit(target: File): Unit = coroutineScope {
        val source = this@visit
        if (source.isDirectory) {
           target.mkdir()
           source.list()?.forEach {
               launch { source.resolve(it).visit(target.resolve(it)) }
           }
        } else {
            strategies.asSequence().first { it.process(source, target) }
        }
    }
}

data class TemplatingContext<out T: Command>(
    val input: File,
    val output: File,
    val element: Element,
    val command: T,
)