简化Yaml.toYaml方法实现

This commit is contained in:
tursom 2020-03-08 02:26:56 +08:00
parent 654d721428
commit 9669ea20fe
3 changed files with 45 additions and 24 deletions

View File

@ -4,8 +4,12 @@ import java.lang.reflect.Array
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import java.lang.reflect.ParameterizedType
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashSet
object Parser {
private val simpleDateFormat = ThreadLocalSimpleDateFormat()
private val Field.actualTypeArguments get() = (genericType as ParameterizedType).actualTypeArguments[0] as Class<*>
fun <T> parse(yaml: Any, clazz: Class<T>): T? {
@ -26,6 +30,7 @@ object Parser {
Float::class.java -> yaml.toFloat()
Double::class.java -> yaml.toDouble()
Boolean::class.java -> yaml.toBoolean()
Date::class.java -> yaml.toDate()
getClazz<Int>() -> yaml.toInt()
getClazz<Long>() -> yaml.toLong()
@ -174,4 +179,23 @@ object Parser {
is Map<*, *> -> null
else -> toString().toBoolean()
}
private fun Any.toDate(): Date? = when (this) {
is Number -> Date(toLong())
is Boolean -> null
is String -> when (val time = toLongOrNull()) {
null -> simpleDateFormat.get().parse(this)
else -> Date(time)
}
is Iterable<*> -> null
is Iterator<*> -> null
is Map<*, *> -> null
else -> {
val str = toString()
when (val time = str.toLongOrNull()) {
null -> simpleDateFormat.get().parse(str)
else -> Date(time)
}
}
}
}

View File

@ -2,6 +2,6 @@ package cn.tursom.core
import java.text.SimpleDateFormat
class ThreadLocalSimpleDateFormat(val format: String) : SimpThreadLocal<SimpleDateFormat>({
class ThreadLocalSimpleDateFormat(val format: String = "YYYY-MM-dd'T'HH:mm:ssZZ") : SimpThreadLocal<SimpleDateFormat>({
SimpleDateFormat(format)
})

View File

@ -1,13 +1,16 @@
package cn.tursom.yaml
import cn.tursom.core.Parser
import cn.tursom.core.ThreadLocalSimpleDateFormat
import cn.tursom.core.getClazz
import org.yaml.snakeyaml.Yaml
import java.lang.reflect.Modifier
import java.util.*
@Suppress("MemberVisibilityCanBePrivate", "unused")
object Yaml {
private val simpleDateFormat = ThreadLocalSimpleDateFormat()
private val yaml = Yaml()
fun toYaml(obj: Any): String {
@ -25,7 +28,19 @@ object Yaml {
is Long -> stringBuilder.append(obj)
is Float -> stringBuilder.append(obj)
is Double -> stringBuilder.append(obj)
is String -> stringBuilder.append(obj)
is Date -> stringBuilder.append(simpleDateFormat.get().format(obj))
is String -> when {
obj.contains('\n') -> {
stringBuilder.append("|${if (obj.endsWith('\n')) '+' else '-'}")
obj.split('\n').forEach {
stringBuilder.append("$indentation$it")
}
}
obj.startsWith('|') -> stringBuilder.append("\"$obj\"")
else -> {
stringBuilder.append(obj)
}
}
is Map<*, *> -> {
var first = true
obj.forEach { (any, u) ->
@ -67,28 +82,10 @@ object Yaml {
if ((it.modifiers and (Modifier.STATIC or Modifier.TRANSIENT)) != 0) return@forEach
it.isAccessible = true
val value = it.get(obj)
when (it.type) {
Byte::class.java -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
Char::class.java -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
Short::class.java -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
Int::class.java -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
Long::class.java -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
Float::class.java -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
Double::class.java -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
getClazz<Byte>() -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
getClazz<Char>() -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
getClazz<Short>() -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
getClazz<Int>() -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
getClazz<Long>() -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
getClazz<Float>() -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
getClazz<Double>() -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
String::class.java -> stringBuilder.append("${getIndentation()}${it.name}: $value\n")
else -> {
stringBuilder.append("${getIndentation()}${it.name}: ")
toYaml(value, stringBuilder, "${getIndentation()} ")
}
stringBuilder.append("${getIndentation()}${it.name}: ")
toYaml(value, stringBuilder, "${getIndentation()} ")
if (!stringBuilder.endsWith('\n')) {
stringBuilder.append("\n")
}
}
}