Comments (3)
And for reference, this is the sort of thing that I'm wanting to implement. I make some very opinionated decisions in this code and wouldn't really see fit to put it into the library:
package com.example.extensibleConfig
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigValue
import io.github.config4k.ClassContainer
import io.github.config4k.CustomType
import io.github.config4k.readers.SelectReader
import io.github.config4k.toConfig
import javax.inject.Named
import kotlin.reflect.KClass
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.primaryConstructor
class SubclassingType<T: Any>(private val parentType: KClass<T>): CustomType {
private val mappedTypes: Map<String, KClass<*>>
init {
val mutableMap = mutableMapOf<String, KClass<*>>()
parentType.nestedClasses
.filter { nc -> nc.isSubclassOf(parentType) }
.forEach { nc ->
val typeName = nc.findAnnotation<Named>()?.value ?: throw IllegalStateException("Config Subtype must have @Named annotation.")
mutableMap.put(typeName, nc)
}
mappedTypes = mutableMap
}
override fun parse(clazz: ClassContainer, config: Config, name: String): Any? {
val type = config.getConfig(name).getString("type")
val kType = mappedTypes.get(type) ?: throw IllegalArgumentException("'$type' is not an allowable type for $name")
val reader = SelectReader.getReader(ClassContainer(kType)) ?: throw IllegalStateException("Could not select reader for type $kType")
return reader.invoke(config, name)
}
override fun testParse(clazz: ClassContainer): Boolean {
return clazz.mapperClass == parentType
}
private fun findMappedType(obj: Any): Pair<String, KClass<*>>? {
return mappedTypes.entries.filter { (_, v) -> v.isInstance(obj) }.singleOrNull()?.toPair()
}
override fun testToConfig(obj: Any): Boolean {
return findMappedType(obj) != null
}
override fun toConfig(obj: Any, name: String): Config {
val (typeName, cl) = findMappedType(obj) ?: throw IllegalStateException("toConfig should not be called if testToConfig is false")
return ConfigFactory.parseMap(getConfigMap(obj, typeName, cl as KClass<Any>))
}
private fun Any.toConfigValue(): ConfigValue {
val name = "dummy"
return this.toConfig(name).root()[name]!!
}
private fun getConfigMap(receiver: Any, typeName: String,
clazz: KClass<Any>): Map<String, *> =
clazz.primaryConstructor!!.parameters.mapNotNull {
val parameterName = it.name!!
clazz.memberProperties
.find { it.name == parameterName }!!
.get(receiver)
?.let {parameterValue ->
parameterName to parameterValue.toConfigValue()
}
}.toMap().plus("type" to typeName)
}
from config4k.
I agree that adding the ability to register custom types is useful. So, could you give an example(like test snippet) in order to make the design clearer?
from config4k.
I added a pull request with the idea plus a test case. It is simple static registration which I felt went with the existing pattern of the library. However things like dynamic registration or local registration might be useful as well. I'm not crazy about the "static state" thing.
from config4k.
Related Issues (20)
- `java.time.Duration` is not supported when toConfig HOT 2
- Java classes are not supported
- Unresolved class: interface java.util.Map HOT 1
- Fail "toConfig" for Map when key contains special char
- zip file closed HOT 1
- Respect Mutable* (List / Map / Set)
- toConfig does not work with private class HOT 1
- Dependency Dashboard
- Use Kotlin Explicit API Mode
- Case insensitive mapping enum values HOT 2
- Support for value classes HOT 1
- Cannot parse registered custom type from map keys HOT 1
- Extract to data class fails if default and key is kebab case HOT 1
- Extract to data class with path fails if default exists key is kebab case
- Support for `kotlin.time.Duration` HOT 1
- enum with overriden toString can't be serialized and deserialized
- 1.4.2 release was rolled back HOT 6
- Feature request: Support java.net.URL HOT 1
- Does anyone want to manage config4k repository? HOT 8
- It's not on maven HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from config4k.