forked from detekt/detekt
/
YamlConfig.kt
74 lines (62 loc) · 2.51 KB
/
YamlConfig.kt
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package io.gitlab.arturbosch.detekt.api
import io.gitlab.arturbosch.detekt.api.internal.ValidatableConfiguration
import io.gitlab.arturbosch.detekt.api.internal.validateConfig
import org.yaml.snakeyaml.Yaml
import java.io.BufferedReader
import java.net.URL
import java.nio.file.Files
import java.nio.file.Path
/**
* Config implementation using the yaml format. SubConfigurations can return sub maps according to the
* yaml specification.
*/
@Suppress("UNCHECKED_CAST")
class YamlConfig internal constructor(
val properties: Map<String, Any>,
override val parent: HierarchicalConfig.Parent?
) : BaseConfig(), ValidatableConfiguration {
override fun subConfig(key: String): Config {
val subProperties = properties.getOrElse(key) { mapOf<String, Any>() }
return YamlConfig(subProperties as Map<String, Any>, HierarchicalConfig.Parent(this, key))
}
override fun <T : Any> valueOrDefault(key: String, default: T): T {
val result = properties[key]
return valueOrDefaultInternal(key, result, default) as T
}
override fun <T : Any> valueOrNull(key: String): T? {
return properties[key] as? T?
}
override fun toString(): String {
return "YamlConfig(properties=$properties)"
}
override fun validate(baseline: Config, excludePatterns: Set<Regex>): List<Notification> =
validateConfig(this, baseline, excludePatterns)
companion object {
private const val YAML = ".yml"
/**
* Factory method to load a yaml configuration. Given path must exist and end with "yml".
*/
fun load(path: Path): Config {
require(Files.exists(path)) { "File does not exist!" }
require(path.toString().endsWith(YAML)) { "File does not end with $YAML!" }
return load(Files.newBufferedReader(path))
}
/**
* Factory method to load a yaml configuration from a URL.
*/
fun loadResource(url: URL): Config = load(url.openStream().bufferedReader())
private fun load(reader: BufferedReader): Config = reader.use {
val yamlInput = it.lineSequence().joinToString("\n")
if (yamlInput.isEmpty()) {
Config.empty
} else {
val map: Any = Yaml().load(yamlInput)
if (map is Map<*, *>) {
YamlConfig(map as Map<String, Any>, parent = null)
} else {
throw Config.InvalidConfigurationError()
}
}
}
}
}