330 lines
9.4 KiB
Kotlin
330 lines
9.4 KiB
Kotlin
package cc.maxmc.servux.util
|
|
|
|
import com.google.gson.*
|
|
import org.bukkit.util.Vector
|
|
import taboolib.common.platform.function.info
|
|
import taboolib.common.platform.function.warning
|
|
import taboolib.platform.BukkitPlugin
|
|
import java.io.File
|
|
import java.io.FileReader
|
|
import java.io.FileWriter
|
|
import java.io.IOException
|
|
|
|
object JsonUtils {
|
|
val GSON = GsonBuilder().setPrettyPrinting().create()
|
|
fun getNestedObject(parent: JsonObject, key: String?, create: Boolean): JsonObject? {
|
|
return if (!parent.has(key) || !parent[key].isJsonObject) {
|
|
if (!create) {
|
|
return null
|
|
}
|
|
val obj = JsonObject()
|
|
parent.add(key, obj)
|
|
obj
|
|
} else {
|
|
parent[key].asJsonObject
|
|
}
|
|
}
|
|
|
|
fun hasBoolean(obj: JsonObject, name: String?): Boolean {
|
|
val el = obj[name]
|
|
if (el != null && el.isJsonPrimitive) {
|
|
try {
|
|
el.asBoolean
|
|
return true
|
|
} catch (_: Exception) { }
|
|
}
|
|
return false
|
|
}
|
|
|
|
fun hasInteger(obj: JsonObject, name: String?): Boolean {
|
|
val el = obj[name]
|
|
if (el != null && el.isJsonPrimitive) {
|
|
try {
|
|
el.asInt
|
|
return true
|
|
} catch (e: Exception) {
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
fun hasLong(obj: JsonObject, name: String?): Boolean {
|
|
val el = obj[name]
|
|
if (el != null && el.isJsonPrimitive) {
|
|
try {
|
|
el.asLong
|
|
return true
|
|
} catch (_: Exception) {
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
fun hasFloat(obj: JsonObject, name: String?): Boolean {
|
|
val el = obj[name]
|
|
if (el != null && el.isJsonPrimitive) {
|
|
try {
|
|
el.asFloat
|
|
return true
|
|
} catch (_: Exception) {
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
fun hasDouble(obj: JsonObject, name: String?): Boolean {
|
|
val el = obj[name]
|
|
if (el != null && el.isJsonPrimitive) {
|
|
try {
|
|
el.asDouble
|
|
return true
|
|
} catch (_: Exception) { }
|
|
}
|
|
return false
|
|
}
|
|
|
|
fun hasString(obj: JsonObject, name: String?): Boolean {
|
|
val el = obj[name]
|
|
if (el != null && el.isJsonPrimitive) {
|
|
try {
|
|
el.asString
|
|
return true
|
|
} catch (_: Exception) { }
|
|
}
|
|
return false
|
|
}
|
|
|
|
fun hasObject(obj: JsonObject, name: String?): Boolean {
|
|
val el = obj[name]
|
|
return el != null && el.isJsonObject
|
|
}
|
|
|
|
fun hasArray(obj: JsonObject, name: String?): Boolean {
|
|
val el = obj[name]
|
|
return el != null && el.isJsonArray
|
|
}
|
|
|
|
fun getBooleanOrDefault(obj: JsonObject, name: String?, defaultValue: Boolean): Boolean {
|
|
if (obj.has(name) && obj[name].isJsonPrimitive) {
|
|
try {
|
|
return obj[name].asBoolean
|
|
} catch (e: Exception) {
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
fun getIntegerOrDefault(obj: JsonObject, name: String?, defaultValue: Int): Int {
|
|
if (obj.has(name) && obj[name].isJsonPrimitive) {
|
|
try {
|
|
return obj[name].asInt
|
|
} catch (e: Exception) {
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
fun getLongOrDefault(obj: JsonObject, name: String?, defaultValue: Long): Long {
|
|
if (obj.has(name) && obj[name].isJsonPrimitive) {
|
|
try {
|
|
return obj[name].asLong
|
|
} catch (e: Exception) {
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
fun getFloatOrDefault(obj: JsonObject, name: String?, defaultValue: Float): Float {
|
|
if (obj.has(name) && obj[name].isJsonPrimitive) {
|
|
try {
|
|
return obj[name].asFloat
|
|
} catch (e: Exception) {
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
fun getDoubleOrDefault(obj: JsonObject, name: String?, defaultValue: Double): Double {
|
|
if (obj.has(name) && obj[name].isJsonPrimitive) {
|
|
try {
|
|
return obj[name].asDouble
|
|
} catch (e: Exception) {
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
fun getStringOrDefault(obj: JsonObject, name: String?, defaultValue: String?): String? {
|
|
if (obj.has(name) && obj[name].isJsonPrimitive) {
|
|
try {
|
|
return obj[name].asString
|
|
} catch (e: Exception) {
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
fun getBoolean(obj: JsonObject, name: String?): Boolean {
|
|
return getBooleanOrDefault(obj, name, false)
|
|
}
|
|
|
|
fun getInteger(obj: JsonObject, name: String?): Int {
|
|
return getIntegerOrDefault(obj, name, 0)
|
|
}
|
|
|
|
fun getLong(obj: JsonObject, name: String?): Long {
|
|
return getLongOrDefault(obj, name, 0)
|
|
}
|
|
|
|
fun getFloat(obj: JsonObject, name: String?): Float {
|
|
return getFloatOrDefault(obj, name, 0f)
|
|
}
|
|
|
|
fun getDouble(obj: JsonObject, name: String?): Double {
|
|
return getDoubleOrDefault(obj, name, 0.0)
|
|
}
|
|
|
|
fun getString(obj: JsonObject, name: String?): String? {
|
|
return getStringOrDefault(obj, name, null)
|
|
}
|
|
|
|
fun hasBlockPos(obj: JsonObject, name: String?): Boolean {
|
|
return blockPosFromJson(obj, name) != null
|
|
}
|
|
|
|
fun blockPosToJson(pos: Vector): JsonArray {
|
|
val arr = JsonArray()
|
|
arr.add(pos.x)
|
|
arr.add(pos.y)
|
|
arr.add(pos.z)
|
|
return arr
|
|
}
|
|
|
|
fun blockPosFromJson(obj: JsonObject, name: String?): Vector? {
|
|
if (hasArray(obj, name)) {
|
|
val arr = obj.getAsJsonArray(name)
|
|
if (arr.size() == 3) {
|
|
try {
|
|
return Vector(arr[0].asInt, arr[1].asInt, arr[2].asInt)
|
|
} catch (ignored: Exception) {
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
fun hasVec3d(obj: JsonObject, name: String?): Boolean {
|
|
return vec3dFromJson(obj, name) != null
|
|
}
|
|
|
|
fun vec3dToJson(vec: Vector): JsonArray {
|
|
val arr = JsonArray()
|
|
arr.add(vec.x)
|
|
arr.add(vec.y)
|
|
arr.add(vec.z)
|
|
return arr
|
|
}
|
|
|
|
fun vec3dFromJson(obj: JsonObject, name: String?): Vector? {
|
|
if (hasArray(obj, name)) {
|
|
val arr = obj.getAsJsonArray(name)
|
|
if (arr.size() == 3) {
|
|
try {
|
|
return Vector(arr[0].asDouble, arr[1].asDouble, arr[2].asDouble)
|
|
} catch (e: Exception) {
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
// https://stackoverflow.com/questions/29786197/gson-jsonobject-copy-value-affected-others-jsonobject-instance
|
|
fun deepCopy(jsonObject: JsonObject): JsonObject {
|
|
val result = JsonObject()
|
|
for ((key, value) in jsonObject.entrySet()) {
|
|
result.add(key, deepCopy(value))
|
|
}
|
|
return result
|
|
}
|
|
|
|
fun deepCopy(jsonArray: JsonArray): JsonArray {
|
|
val result = JsonArray()
|
|
for (e in jsonArray) {
|
|
result.add(deepCopy(e))
|
|
}
|
|
return result
|
|
}
|
|
|
|
fun deepCopy(jsonElement: JsonElement): JsonElement {
|
|
return if (jsonElement.isJsonPrimitive || jsonElement.isJsonNull) {
|
|
jsonElement // these are immutable anyway
|
|
} else if (jsonElement.isJsonObject) {
|
|
deepCopy(jsonElement.asJsonObject)
|
|
} else if (jsonElement.isJsonArray) {
|
|
deepCopy(jsonElement.asJsonArray)
|
|
} else {
|
|
throw UnsupportedOperationException("Unsupported element: $jsonElement")
|
|
}
|
|
}
|
|
|
|
fun parseJsonFromString(str: String?): JsonElement? {
|
|
try {
|
|
val parser = JsonParser()
|
|
return parser.parse(str)
|
|
} catch (e: Exception) {
|
|
}
|
|
return null
|
|
}
|
|
|
|
fun parseJsonFile(file: File?): JsonElement? {
|
|
if (file != null && file.exists() && file.isFile && file.canRead()) {
|
|
val fileName = file.absolutePath
|
|
try {
|
|
val parser = JsonParser()
|
|
val reader = FileReader(file)
|
|
val element = parser.parse(reader)
|
|
reader.close()
|
|
return element
|
|
} catch (e: Exception) {
|
|
warning("Failed to parse the JSON file '" + fileName + "'" + e.message)
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Converts the given JsonElement tree into its string representation.
|
|
* If **compact** is true, then it's written in one line without spaces or line breaks.
|
|
*
|
|
* @param element
|
|
* @param compact
|
|
* @return
|
|
*/
|
|
fun jsonToString(element: JsonElement?, compact: Boolean): String {
|
|
val gson = if (compact) Gson() else GSON
|
|
return gson.toJson(element)
|
|
}
|
|
|
|
fun writeJsonToFile(root: JsonElement?, file: File): Boolean {
|
|
return writeJsonToFile(GSON, root, file)
|
|
}
|
|
|
|
fun writeJsonToFile(gson: Gson, root: JsonElement?, file: File): Boolean {
|
|
var writer: FileWriter? = null
|
|
try {
|
|
writer = FileWriter(file)
|
|
writer.write(gson.toJson(root))
|
|
writer.close()
|
|
return true
|
|
} catch (e: IOException) {
|
|
warning("Failed to write JSON data to file '" + file.absolutePath + "'" + e.message)
|
|
} finally {
|
|
try {
|
|
writer?.close()
|
|
} catch (e: Exception) {
|
|
warning("Failed to close JSON file" + e.message)
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
} |