Skip to content

Instantly share code, notes, and snippets.

@andrewrlee
Last active December 5, 2022 10:19
Show Gist options
  • Save andrewrlee/dee004278d2266b9c3f6aa4a50f0033b to your computer and use it in GitHub Desktop.
Save andrewrlee/dee004278d2266b9c3f6aa4a50f0033b to your computer and use it in GitHub Desktop.
Transform json file into the kotlin code that defines the same data structure
package uk.gov.justice.digital.hmpps.createandvaryalicenceapi.service
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import uk.gov.justice.digital.hmpps.createandvaryalicenceapi.model.policy.LicencePolicy
import java.io.File
import java.nio.charset.StandardCharsets.UTF_8
import kotlin.reflect.full.memberProperties
val seenTypes = mutableSetOf<Class<*>>()
val policyMap = mapOf(
"policyV2_1" to "src/main/resources/policy_conditions/policyV2.1.json",
"policyV2" to "src/main/resources/policy_conditions/policyV2.json",
"policyV1" to "src/main/resources/policy_conditions/policyV1.json",
)
fun main() {
policyMap.forEach { (k, v) ->
writePolicyFile(k, v)
}
}
fun writePolicyFile(name: String, location: String) {
val policyObj = getLicencePolicy(location)
val policy = printValue(policyObj)
var text = "package uk.gov.justice.digital.hmpps.createandvaryalicenceapi.service\n\n"
seenTypes.forEach {
text += "import ${it.canonicalName}\n"
}
text += "\n\nval $name = $policy"
println(text)
File("src/main/kotlin/uk/gov/justice/digital/hmpps/createandvaryalicenceapi/service/${name}.kt").writeText(
text, UTF_8
)
}
private fun getLicencePolicy(location: String): LicencePolicy {
val stream = File(location).inputStream()
return jacksonObjectMapper().readValue(stream)
}
private fun printValue(value: Any?, depth: Int = 0): String? = when {
value == null -> null
String::class.isInstance(value) -> if (value.toString().contains("\"")) "\"\"\"$value\"\"\"" else "\"$value\""
Int::class.isInstance(value) -> value.toString()
Boolean::class.isInstance(value) -> value.toString()
java.util.List::class.java.isInstance(value) -> {
var result = ""
result += "listOf("
(value as List<*>?)?.forEach {
result += "${printValue(it!!, depth + 2)},\n"
}
result += depth.pad(")")
result
}
value::class.java.packageName.startsWith("uk.gov") -> {
seenTypes.add(value::class.java)
val members = value::class.memberProperties
var result = depth.pad("${value::class.simpleName!!}(\n")
members.forEach {
val fieldValue = it.call(value)
val formattedValue = printValue(fieldValue, depth + 2)
result += (depth + 2).pad("${it.name} = $formattedValue,\n")
}
result += depth.pad(")")
result
}
else -> throw RuntimeException("${value::class} = unknown -> ${value::class.javaObjectType}\n")
}
fun Int.pad(v: String) = "${" ".repeat(this)} $v"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment