All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.harmonysoft.oss.common.string.util.ToStringUtil.kt Maven / Gradle / Ivy

package tech.harmonysoft.oss.common.string.util

import tech.harmonysoft.oss.common.reflection.TypeUtil
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.KVisibility
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.memberProperties

@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class HideValueInToString

object ToStringUtil {

    const val HIDDEN_VALUE_PLACEHOLDER = "***"

    /**
     * Convenient way to build object's string representation where some fields should be excluded (e.g. a field
     * which holds sensitive data like password)
     */
    fun build(o: Any?): String {
        o ?: return "null"
        if (TypeUtil.PRIMITIVES.contains(o::class)) {
            return o.toString()
        }
        when (o) {
            is Class<*> -> return "class ${o.name}"
            is KClass<*> -> return "class ${o.simpleName}"
            is KFunction<*> -> return "fun ${o.name}()"
            is Collection<*> -> return o.joinToString(prefix = "[", postfix = "]") {
                build(it)
            }
            is Array<*> -> return o.joinToString(prefix = "[", postfix = "]") {
                build(it)
            }
            is Map<*, *> -> return o.entries.joinToString(prefix = "{", postfix = "}") {
                "${build(it.key)}: ${build(it.value)}"
            }
        }
        val memberProperties = o::class.memberProperties.sortedBy { it.name }
        if (memberProperties.isEmpty()) {
            return o::class.simpleName ?: throw IllegalArgumentException("can't build string representation for $o")
        }
        val values = memberProperties.mapNotNull { property ->
            if (property.visibility != KVisibility.PUBLIC) {
                null
            } else {
                val value = if (property.findAnnotation() != null) {
                    HIDDEN_VALUE_PLACEHOLDER
                } else {
                    property.call(o)
                }
                "${property.name}=${build(value)}"
            }
        }
        return values.joinToString(prefix = "(", postfix = ")")
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy