Keep the reworks coming

This commit is contained in:
Auxilor
2022-03-24 10:41:09 +00:00
parent 85303098a7
commit 77c56c46a8
5 changed files with 83 additions and 70 deletions

View File

@@ -2,13 +2,11 @@
package com.willfp.eco.internal.config
import com.google.gson.GsonBuilder
import com.willfp.eco.core.config.ConfigType
import org.bukkit.configuration.file.YamlConstructor
import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.LoaderOptions
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.representer.Representer
import java.io.BufferedReader
import java.io.Reader
@@ -18,32 +16,32 @@ fun ConfigType.toMap(input: String?): Map<String, Any?> =
fun ConfigType.toString(map: Map<String, Any?>): String =
this.handler.toString(map)
fun Any?.constrainConfigTypes(type: ConfigType): Any? = when (this) {
is Map<*, *> -> EcoConfigSection(type, this.ensureTypesForConfig(type))
is Iterable<*> -> {
if (this.firstOrNull() == null) {
mutableListOf<Any>()
} else if (this.firstOrNull() is Map<*, *>) {
this as Iterable<Map<*, *>>
this.map { map -> EcoConfigSection(type, map.ensureTypesForConfig(type)) }
} else {
this.toMutableList()
}
}
else -> this
}
fun Map<*, *>.ensureTypesForConfig(type: ConfigType): Map<String, Any?> {
val building = mutableMapOf<String, Any?>()
for (entry in this.entries) {
val value = entry.value?.let {
when (it) {
is Map<*, *> -> EcoConfigSection(type, it.ensureTypesForConfig(type))
is Collection<*> -> {
if (it.isEmpty()) {
mutableListOf<Any>()
} else if (it.first() is Map<*, *>) {
it as Collection<Map<*, *>>
it.map { map -> map.ensureTypesForConfig(type) }
} else {
it.toMutableList()
}
}
else -> it
}
}
if (entry.key == null || value == null) {
for ((key, value) in this.entries) {
if (key == null || value == null) {
continue
}
building[entry.key.toString()] = value
val constrained = value.constrainConfigTypes(type)
building[key.toString()] = constrained
}
return building
@@ -87,7 +85,7 @@ private object YamlConfigTypeHandler : ConfigTypeHandler(ConfigType.YAML) {
private fun newYaml(): Yaml {
val yamlOptions = DumperOptions()
val loaderOptions = LoaderOptions()
val representer = Representer()
val representer = EcoRepresenter()
loaderOptions.maxAliasesForCollections = 0
yamlOptions.indent = 2
@@ -112,16 +110,11 @@ private object YamlConfigTypeHandler : ConfigTypeHandler(ConfigType.YAML) {
}
private object JSONConfigTypeHandler : ConfigTypeHandler(ConfigType.JSON) {
private val gson = GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.create()
override fun parseToMap(input: String): Map<*, *> {
return gson.fromJson(input, Map::class.java)
return EcoGsonSerializer.gson.fromJson(input, Map::class.java)
}
override fun toString(map: Map<String, Any?>): String {
return gson.toJson(map)
return EcoGsonSerializer.gson.toJson(map)
}
}

View File

@@ -12,6 +12,8 @@ open class EcoConfig(
private val configType: ConfigType
) : Config {
private val values = ConcurrentHashMap<String, Any?>()
@Transient
var injections = mutableListOf<StaticPlaceholder>()
fun init(values: Map<String, Any?>) {
@@ -31,40 +33,6 @@ open class EcoConfig(
return get(path) != null
}
private fun setRecursively(
path: String,
obj: Any?
) {
this.clearCache()
val nearestPath = path.split(".")[0]
if (path.contains(".")) {
val remainingPath = path.removePrefix("${nearestPath}.")
val section = get(nearestPath)
if (section == null) {
values[nearestPath] = mutableMapOf<String, Any?>()
return setRecursively(path, obj)
} else if (section is EcoConfig) {
section.setRecursively(remainingPath, obj)
}
}
values[nearestPath] = when (obj) {
is Map<*, *> -> obj.ensureTypesForConfig(type)
is Collection<*> -> {
if (obj.isEmpty()) {
mutableListOf<Any>()
} else if (obj.first() is Map<*, *>) {
obj as Collection<Map<*, *>>
obj.map { it.ensureTypesForConfig(type) }
} else {
obj.toMutableList()
}
}
else -> obj
}
}
override fun getKeys(deep: Boolean): List<String> {
return if (deep) {
recurseKeys(mutableSetOf()).toList()
@@ -110,7 +78,21 @@ open class EcoConfig(
path: String,
obj: Any?
) {
setRecursively(path, obj)
this.clearCache()
val nearestPath = path.split(".")[0]
if (path.contains(".")) {
val remainingPath = path.removePrefix("${nearestPath}.")
val section = get(nearestPath)
if (section == null) {
values[nearestPath] = mutableMapOf<String, Any?>()
return set(path, obj)
} else if (section is Config) {
section.set(remainingPath, obj)
}
}
values[nearestPath] = obj.constrainConfigTypes(type)
}
override fun getSubsection(path: String): Config {

View File

@@ -0,0 +1,20 @@
package com.willfp.eco.internal.config
import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import com.willfp.eco.core.config.interfaces.Config
import java.lang.reflect.Type
object EcoGsonSerializer : JsonSerializer<Config> {
val gson = GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.registerTypeAdapter(Config::class.java, this)
.create()
override fun serialize(src: Config, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
return gson.toJsonTree(src.toMap())
}
}

View File

@@ -58,14 +58,14 @@ open class EcoLoadableConfig(
@Throws(IOException::class)
override fun save() {
if (!hasChanged) { // In order to preserve comments
return
//return
}
val contents = StringBuilder()
if (this.type == ConfigType.YAML) {
for (s in header) {
contents.append(s)
contents.append(s + "\n")
}
if (header.isNotEmpty()) {
@@ -86,10 +86,8 @@ open class EcoLoadableConfig(
}
private fun makeHeader(contents: String) {
val lines = contents.split("\r\n").toList()
if (this.type == ConfigType.YAML) {
for (line in lines) {
for (line in contents.lines()) {
if (!line.startsWith("#")) {
break
}

View File

@@ -0,0 +1,20 @@
package com.willfp.eco.internal.config
import com.willfp.eco.core.config.interfaces.Config
import org.yaml.snakeyaml.nodes.Node
import org.yaml.snakeyaml.representer.Represent
import org.yaml.snakeyaml.representer.Representer
class EcoRepresenter : Representer() {
init {
multiRepresenters[Config::class.java] = RepresentConfig(multiRepresenters[Map::class.java]!!)
}
private class RepresentConfig(
val handle: Represent
) : Represent {
override fun representData(data: Any): Node {
return handle.representData((data as Config).toMap())
}
}
}