51414bde创建于 2025年10月9日历史提交
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
 */
package appauth

import stdx.encoding.json.JsonObject
import stdx.encoding.json.JsonValue
import stdx.encoding.json.JsonException
import std.collection.Map
import stdx.encoding.json.JsonArray
import std.collection.ArrayList
import std.collection.TreeMap
import std.collection.HashMap
import ohos.hilog.Hilog
import stdx.encoding.json.JsonString
import stdx.encoding.json.JsonInt

class JsonUtil {

    /**
     * 将指定的Int64值放入JsonObject中
     * 
     * @param json 要放入值的JsonObject对象
     * @param field 字段名
     * @param value 要放入的Int64值
     */
    public static func put(json: JsonObject, field: String, value: Int64): Unit {
        try {
            json.put(field, JsonInt(value))
        } catch (ex: JsonException) {
            throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
        }
    }

    /**
     * 将指定的String值放入JsonObject中
     * 
     * @param json 要放入值的JsonObject对象
     * @param field 字段名
     * @param value 要放入的String值
     */
    public static func put(json: JsonObject, field: String, value: String): Unit {
        try {
            json.put(field, JsonString(value))
        } catch (ex: JsonException) {
            throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
        }
    }

    /**
     * 将指定的JsonValue放入JsonObject中
     * 
     * @param json 要放入值的JsonObject对象
     * @param field 字段名
     * @param value 要放入的JsonValue
     */
    public static func put(json: JsonObject, field: String, value: JsonValue): Unit {
        try {
            json.put(field, value)
        } catch (ex: JsonException) {
            throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
        }
    }

    /**
     * 将指定的JsonObject放入另一个JsonObject中
     * 
     * @param json 要放入值的JsonObject对象
     * @param field 字段名
     * @param value 要放入的JsonObject
     */
    public static func put(json: JsonObject, field: String, value: JsonObject): Unit {
        try {
            json.put(field, value)
        } catch (ex: JsonException) {
            throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
        }
    }

    /**
     * 如果值不为null,则将指定的Int64值放入JsonObject中
     * 
     * @param json 要放入值的JsonObject对象
     * @param field 字段名
     * @param value 可空的Int64值
     */
    public static func putIfNotNull(json: JsonObject, field: String, value: ?Int64): Unit {
        if (let Some(v) <- value) {
        	try {
                json.put(field, JsonString(v.toString()))
            } catch (ex: JsonException) {
                throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
            }
        }
    }

    /**
     * 如果值不为null,则将指定的String值放入JsonObject中
     * 
     * @param json 要放入值的JsonObject对象
     * @param field 字段名
     * @param value 可空的String值
     */
    public static func putIfNotNull(json: JsonObject, field: String, value: ?String): Unit {
        if (value.isNone() || value.getOrThrow().size == 0) {
            return
        }
        if (let Some(v) <- value) {
            	try {
                    json.put(field, JsonString(value.getOrThrow().toString()))
                } catch (ex: JsonException) {
                    throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
                }
        }
    }

    /**
     * 如果值不为null,则将指定的Uri值放入JsonObject中
     * 
     * @param json 要放入值的JsonObject对象
     * @param field 字段名
     * @param value 可空的Uri值
     */
    public static func putIfNotNull(json: JsonObject, field: String, value: ?AuthUri): Unit {
        if (value.isNone() || (value.getOrThrow().toString().size == 2 && value.getOrThrow().toString().endsWith("?#"))) {
            return
        }
        if (let Some(v) <- value) {
            try {
                var val = v.toString()
                if (!val.startsWith("\"")) {
                	val = "\"" + val
                }
                if (!val.endsWith("\"")) {
                	val = val + "\""
                }
                json.put(field, JsonValue.fromStr(val))
            } catch (ex: JsonException) {
                throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
            }
        }
    }

    /**
     * 如果值不为null,则将指定的JsonObject放入另一个JsonObject中
     * 
     * @param json 要放入值的JsonObject对象
     * @param field 字段名
     * @param value 可空的JsonObject值
     */
    public static func putIfNotNull(json: JsonObject, field: String, value: ?JsonObject): Unit {
        if (let Some(v) <- value) {
            try {
                json.put(field, v)
            } catch (ex: JsonException) {
                throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
            }
        }
    }

    static func putIfNotNull(json: JsonObject, field: String, value: ?Array<String>): Unit {
        if (let Some(v) <- value) {
            try {
                var jsonArray = ArrayList<JsonValue>()
                for (item in v) {
                	jsonArray.add(JsonString(item))
                }
                json.put(field, JsonArray(jsonArray))
            } catch (ex: JsonException) {
                throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
            }
        }
    }

    static func putIfNotNull(json: JsonObject, field: String, value: ?Map<String, String>): Unit {
        if (let Some(v) <- value) {
            try {
                var valueObj: JsonObject = JsonObject()
                for (key in v.keys()) {
                	putIfNotNull(valueObj, key, v.get(key).getOrThrow())
                }
                json.put(field, valueObj)
            } catch (ex: JsonException) {
                throw IllegalStateException("JSONException thrown in violation of contract, ${ex}")
            }
        }
    }

    /**
     * 从JsonObject中获取指定字段的字符串值
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return 指定字段的字符串值
     * @throws JsonException 当字段不存在时抛出异常
     */
    public static func getString(json: JsonObject, field: String): String {
        if (!json.containsKey(field)) {
        	throw JsonException("field: ${field} not found in json object")
        }

        var value: String = json.get(field).getOrThrow().asString().getValue()
        return value
    }

    /**
     * 从JsonObject中获取指定字段的字符串值,如果字段不存在则返回空字符串
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return 指定字段的字符串值或空字符串
     */
    public static func getStringIfDefined(json: JsonObject, field: String): String {
        if (!json.containsKey(field)) {
        	return ""
        }

        var value: String = json.get(field).getOrThrow().asString().getValue()
        return value
    }

    /**
     * 从JsonObject中获取指定字段的字符串列表
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return 字符串列表
     */
    public static func getStringListIfDefined(json: JsonObject, field: String): ArrayList<String> {
        if (!json.containsKey(field)) {
        	return ArrayList<String>()
        }

        var value: JsonArray = json.get(field).getOrThrow().asArray()
        return toStringList(value)
    }

    /**
     * 从JsonObject中获取指定字段的Uri值
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return Uri值
     */
    public static func getUri(json: JsonObject, field: String): AuthUri {
        var value: String = json.get(field).getOrThrow().asString().getValue()
        return AuthUri.parse(value)
    }

    /**
     * 从JsonObject中获取指定字段的Uri值,如果字段不存在则返回空值
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return 可选的Uri值
     */
    public static func getUriIfDefined(json: JsonObject, field: String): Option<AuthUri> {
        if (!json.containsKey(field)) {
        	return Option<AuthUri>.None
        }
        var value: String = json.get(field).getOrThrow().asString().getValue()
        return AuthUri.parse(value)
    }

    /**
     * 从JsonObject中获取指定字段的Int64值,如果字段不存在则返回-1
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return Int64值或-1
     */
    public static func getInt64IfDefined(json: JsonObject, field: String): Int64 {
        if (!json.containsKey(field)) {
        	return -1
        }
        var value: JsonValue = json.get(field).getOrThrow()
        try {
        	return value.asInt().getValue()
        } catch (ex: JsonException) {
        	return -1
        }
    }

    /**
     * 从JsonObject中获取指定字段的字符串列表
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return 字符串列表
     * @throws JsonException 当字段不存在时抛出异常
     */
    public static func getStringList(json: JsonObject, field: String): ArrayList<String> {
        if (!json.containsKey(field)) {
        	throw JsonException("field: ${field} not found in json object")
        }
        var value: JsonArray = json.get(field).getOrThrow().asArray()
        return toStringList(value)
    }

    /**
     * 从JsonObject中获取指定字段的Uri列表
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return Uri列表
     * @throws JsonException 当字段不存在时抛出异常
     */
    public static func getUriList(json: JsonObject, field: String): ArrayList<AuthUri> {
        if (!json.containsKey(field)) {
        	throw JsonException("field: ${field} not found in json object")
        }
        var value: JsonArray = json.get(field).getOrThrow().asArray()
        return toUriList(value)
    }

    /**
     * 从JsonObject中获取指定字段的键值对映射
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return 字符串键值对映射
     */
    public static func getStringMap(json: JsonObject, field: String): Map<String, String> {
        var stringMap: TreeMap<String, String> = TreeMap<String, String>()
        if (!json.containsKey(field)) {
        	return stringMap
        }

        var mapJson: JsonObject = json.get(field).getOrThrow().asObject()
        var keys = mapJson.getFields().keys()
        for (key in keys) {
        	var value = mapJson.get(key).getOrThrow().asString().getValue()
            stringMap.add(key, value)
        }
        return stringMap
    }

    /**
     * 从JsonObject中获取指定字段的JsonObject值,如果字段不存在则返回空的JsonObject
     * 
     * @param json JsonObject对象
     * @param field 字段名
     * @return JsonObject值
     */
    public static func getJsonObjectIfDefined(json: JsonObject, field: String): JsonObject {
        if (!json.containsKey(field)) {
        	return JsonObject()
        }
        var value: JsonObject = json.get(field).getOrThrow().asObject()
        return value
    }

    /**
     * 将JsonArray转换为字符串列表
     * 
     * @param jsonArray JsonArray对象
     * @return 字符串列表
     */
    public static func toStringList(jsonArray: JsonArray): ArrayList<String> {
        var arrayList: ArrayList<String> = ArrayList<String>()
        var tmpArray = jsonArray.getItems()
        for (item in tmpArray) {
        	arrayList.add(item.asString().toString())
        }
        return arrayList
    }

    /**
     * 将JsonObject转换为HashMap
     * 
     * @param json JsonObject对象
     * @return HashMap对象
     */
    public static func toMap(json: JsonObject): HashMap<String, String> {
        var hashMap: HashMap<String, String> = HashMap<String, String>()
        var mapKeys = hashMap.keys()
        for (key in mapKeys) {
        	var mapValue: JsonValue = json.get(key).getOrThrow()
            try {
                var arrayValue = mapValue.asArray()
                var value = toList(arrayValue)
                hashMap.add(key, value.toString())
            } catch (ex: JsonException) {
                try {
                    var objValue = mapValue.asObject()
                    var value = toMap(objValue)
                    hashMap.add(key, value.toString())
                } catch (ex: JsonException) {}
            }
        }
        return hashMap
    }

    /**
     * 将JsonArray转换为字符串列表
     * 
     * @param jsonArray JsonArray对象
     * @return 字符串列表
     */
    public static func toList(jsonArray: JsonArray): ArrayList<String> {
        var arrayList: ArrayList<String> = ArrayList<String>()
        var tmpArray = jsonArray.getItems()
        for (item in tmpArray) {
            try {
                var arrayValue = item.asArray()
                var value = toList(arrayValue)
                arrayList.add(value.toString())
            } catch (ex: JsonException) {
                try {
                    var objValue = item.asObject()
                    var value = toMap(objValue)
                    arrayList.add(value.toString())
                } catch (ex: JsonException) {}
            }
        }
        return arrayList
    }

    /**
     * 将JsonArray转换为Uri列表
     * 
     * @param jsonArray JsonArray对象
     * @return Uri列表
     */
    public static func toUriList(jsonArray: JsonArray): ArrayList<AuthUri> {
        var arrayList: ArrayList<AuthUri> = ArrayList<AuthUri>()
        var tmpArray = jsonArray.getItems()
        for (item in tmpArray) {
        	arrayList.add(AuthUri.parse(item.toString()))
        }
        return arrayList
    }

    /**
     * 将字符串数组转换为JsonArray
     * 
     * @param list 字符串数组
     * @return JsonArray对象
     */
    public static func toJsonArray(list: Array<String>): JsonArray {
        var array: ArrayList<JsonValue> = ArrayList<JsonValue>()
        for (str in list) {
        	array.add(JsonString(str))
        }

        return JsonArray(array)
    }

    /**
     * 将Uri数组转换为JsonArray
     * 
     * @param list Uri数组
     * @return JsonArray对象
     */
    public static func toJsonArray(list: Array<AuthUri>): JsonArray {
        var array: ArrayList<JsonValue> = ArrayList<JsonValue>()
        for (uri in list) {
        	array.add(JsonString(uri.toString()))
        }

        return JsonArray(array)
    }

    /**
     * 将Map转换为JsonObject
     * 
     * @param map 字符串键值对映射
     * @return JsonObject对象
     */
    public static func mapToJsonObject(map: Map<String, String>): JsonObject {
        var jsonObj: JsonObject = JsonObject()
        var keys = map.keys()
        for (key in keys) {
        	put(jsonObj, key, map.get(key).getOrThrow())
        }
        return jsonObj
    }

    public static func get<T>(json: JsonObject, field: Field<T>): ?T {
        try {
            if (!json.containsKey(field.key)) {
                return field.defaultValue
            }
            return field.convert(json.get(field.key)())
        } catch (e: IllegalStateException) {
            // all appropriate steps are taken above to avoid a JSONException. If it is still
            // thrown, indicating an implementation change, throw an exception
            throw IllegalStateException("unexpected JSONException ${e.toString()}")
        }

        return field.defaultValue
    }

    public static func get<T>(json: JsonObject, field: ListField<T>): Array<T> {
        return field.defaultValue.toArray()
    }
}

open class Field<T> {
	public let key: String
    public let defaultValue: Option<T>

    public init(key: String, defaultValue: ?T) {
    	this.key = key
        this.defaultValue = defaultValue
    }

    public open func convert(value: JsonValue): T {
        return defaultValue.getOrThrow()
    }
}

class UriField <: Field<AuthUri> {

    public init(key: String, defaultValue: AuthUri) {
    	super(key, defaultValue)
    }

    public init(key: String) {
    	super(key, Option<AuthUri>.None)
    }

    public override func convert(value: JsonValue): AuthUri {
        return AuthUri.parse(value.toString())
    }
}

class StringField <: Field<String> {

    public init(key: String, defaultValue: String) {
    	super(key, defaultValue)
    }

    public init(key: String) {
    	super(key, Option<String>.None)
    }

    public override func convert(value: JsonValue): String {
        return value.asString().toString()
    }
}

class BoolField <: Field<Bool> {

    public init(key: String, defaultValue: Bool) {
    	super(key, defaultValue)
    }

    public override func convert(value: JsonValue): Bool {
        return value.asBool().getValue()
    }
}

open class ListField<T> {

	public let key: String

    public let defaultValue: ArrayList<T>

    public init(key: String, defaultValue: ArrayList<T>) {
    	this.key = key
        this.defaultValue = defaultValue
    }

    public open func convert(value: JsonValue): T {
        return defaultValue[0]
    }
}

class StringListField <: ListField<String> {

    public init(key: String, defaultValue: ArrayList<String>) {
    	super(key, defaultValue)
    }

    public init(key: String) {
    	super(key, ArrayList<String>())
    }

    public override func convert(value: JsonValue): String {
        return value.asString().toString()
    }
}