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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
@file:OptIn(ExperimentalSerializationApi::class)
package moe.nea.firmament.gui.config.storage
import java.nio.file.Path
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream
import kotlin.io.path.createDirectories
import kotlin.io.path.deleteExisting
import kotlin.io.path.exists
import kotlin.io.path.inputStream
import kotlin.io.path.listDirectoryEntries
import kotlin.io.path.nameWithoutExtension
import kotlin.io.path.outputStream
import moe.nea.firmament.Firmament
class FirstLevelSplitJsonFolder(
val context: ConfigLoadContext,
val folder: Path
) {
var hasCreatedBackup = false
fun backup(cause: String) {
if (hasCreatedBackup) return
hasCreatedBackup = true
context.createBackup(folder, cause)
}
fun load(): JsonObject {
context.logInfo("Loading FLSJF from $folder")
if (!folder.exists())
return JsonObject(mapOf())
return try {
folder.listDirectoryEntries("*.json")
.mapNotNull(::loadIndividualFile)
.toMap()
.let(::JsonObject)
.also { context.logInfo("FLSJF from $folder - Voller Erfolg!") }
} catch (ex: Exception) {
context.logError("Could not load files from $folder", ex)
backup("failed-load")
JsonObject(mapOf())
}
}
fun loadIndividualFile(path: Path): Pair<String, JsonElement>? {
context.logDebug("Loading partial file from $path")
return try {
path.inputStream().use {
path.nameWithoutExtension to Firmament.json.decodeFromStream(JsonElement.serializer(), it)
}
} catch (ex: Exception) {
context.logError("Could not load file from $path", ex)
backup("failed-load")
null
}
}
fun save(value: JsonObject) {
context.logInfo("Saving FLSJF to $folder")
context.logDebug("Current value:\n$value")
if (!folder.exists()) {
context.logInfo("Creating folder $folder")
folder.createDirectories()
}
val entries = folder.listDirectoryEntries("*.json")
.toMutableList()
for ((name, element) in value) {
val path = saveIndividualFile(name, element)
if (path != null) {
entries.remove(path)
}
}
if (entries.isNotEmpty()) {
context.logInfo("Deleting additional files.")
for (path in entries) {
context.logInfo("Deleting $path")
backup("save-deletion")
try {
path.deleteExisting()
} catch (ex: Exception) {
context.logError("Could not delete $path", ex)
}
}
}
context.logInfo("FLSJF to $folder - Voller Erfolg!")
}
fun saveIndividualFile(name: String, element: JsonElement): Path? {
try {
context.logDebug("Saving partial file with name $name")
val path = folder.resolve("$name.json")
context.ensureWritable(path)
path.outputStream().use {
Firmament.json.encodeToStream(JsonElement.serializer(), element, it)
}
return path
} catch (ex: Exception) {
context.logError("Could not save $name with value $element", ex)
backup("failed-save")
return null
}
}
}
|