This repository has been archived by the owner on Jul 13, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from kohesive/develop
Develop to mater for 1.3.0 release
- Loading branch information
Showing
17 changed files
with
404 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
dependencies { | ||
compile relativeProject(":injekt-api") | ||
runtime relativeProject(":injekt-core") | ||
compile "uy.klutter:klutter-config-typesafe-jdk6:$version_klutter" | ||
compile "uy.klutter:klutter-json-jackson-jdk6:$version_klutter" | ||
} |
94 changes: 94 additions & 0 deletions
94
...pesafe-jdk6/src/main/kotlin/uy/kohesive/injekt/config/typesafe/TypesafeConfigInjection.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package uy.kohesive.injekt.config.typesafe | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper | ||
import com.typesafe.config.Config | ||
import com.typesafe.config.ConfigFactory | ||
import com.typesafe.config.ConfigRenderOptions | ||
import com.typesafe.config.ConfigResolveOptions | ||
import uy.kohesive.injekt.Injekt | ||
import uy.kohesive.injekt.api.InjektModule | ||
import uy.kohesive.injekt.api.InjektRegistrar | ||
import uy.kohesive.injekt.api.InjektScope | ||
import java.net.URI | ||
|
||
/** | ||
* A class that startups up an system using Injekt + TypesafeConfig, using the default global scope, and default object binder | ||
*/ | ||
public abstract class KonfigAndInjektMain(): KonfigAndInjektScopedMain(Injekt) | ||
|
||
/** | ||
* A startup module that registers and uses singletons/object factories from a specific scope, | ||
* and an ObjectMapper to bind configuration properties into class instances. | ||
*/ | ||
public abstract class KonfigAndInjektScopedMain(public val scope: InjektScope, public val mapper: ObjectMapper = jacksonObjectMapper()) : InjektModule, KonfigModule { | ||
private val ADDON_ID = "Konfigure" | ||
|
||
abstract fun configFactory(): Config | ||
|
||
private data class KonfigureClassAtPath(val path: String, val klass: Class<*>) | ||
|
||
private inner class ScopedKonfigRegistrar(val path: List<String>, val scope: InjektScope, val itemsToConfigure: MutableList<KonfigureClassAtPath>): KonfigRegistrar { | ||
override fun importModule(atPath: String, module: KonfigModule) { | ||
module.registerWith(ScopedKonfigRegistrar(path + atPath.split('.'), scope, itemsToConfigure)) | ||
} | ||
|
||
override fun bindClassAtConfigRoot(klass: Class<*>) { | ||
val fullpath = path.filter { it.isNotBlank() }.map { it.removePrefix(".").removeSuffix(".") }.joinToString(".") | ||
itemsToConfigure.add(KonfigureClassAtPath(fullpath, klass)) | ||
} | ||
|
||
override fun bindClassAtConfigPath(configPath: String, klass: Class<*>) { | ||
val fullpath = (path + configPath.split('.')).filter { it.isNotBlank() }.map { it.removePrefix(".").removeSuffix(".") }.joinToString(".") | ||
itemsToConfigure.add(KonfigureClassAtPath(fullpath, klass)) | ||
} | ||
|
||
@suppress("UNCHECKED_CAST") | ||
fun loadAndInject(config: Config) { | ||
itemsToConfigure.forEach { | ||
val configAtPath = config.getConfig(it.path) | ||
// TODO: handle a class that wants to be constructed with a configuration object instead of binding | ||
val asJson = configAtPath.root().render(ConfigRenderOptions.concise().setJson(true)) | ||
val instance: Any = mapper.readValue(asJson, it.klass)!! | ||
scope.registrar.addSingleton(it.klass as Class<Any>, instance) | ||
} | ||
} | ||
} | ||
|
||
init { | ||
val itemsToConfigure: MutableList<KonfigureClassAtPath> = scope.getAddonMetadata(ADDON_ID) ?: scope.setAddonMetadata(ADDON_ID, linkedListOf<KonfigureClassAtPath>()) | ||
val registrar = ScopedKonfigRegistrar(emptyList(), scope, itemsToConfigure) | ||
registrar.registerConfigurables() | ||
val config = configFactory() | ||
registrar.loadAndInject(config) | ||
scope.registrar.registerInjectables() | ||
} | ||
} | ||
|
||
public interface KonfigRegistrar { | ||
fun importModule(atPath: String, module: KonfigModule) | ||
|
||
final inline fun <reified T> bindClassAtConfigPath(configPath: String) { | ||
bindClassAtConfigPath(configPath, javaClass<T>()) | ||
} | ||
|
||
fun bindClassAtConfigPath(configPath: String, klass: Class<*>) | ||
|
||
final inline fun <reified T> bindClassAtConfigRoot() { | ||
bindClassAtConfigRoot(javaClass<T>()) | ||
} | ||
|
||
fun bindClassAtConfigRoot(klass: Class<*>) | ||
} | ||
|
||
/** | ||
* A package of configuration bound items that can be included into a scope of someone else | ||
*/ | ||
public interface KonfigModule { | ||
final internal fun registerWith(intoModule: KonfigRegistrar) { | ||
intoModule.registerConfigurables() | ||
} | ||
|
||
fun KonfigRegistrar.registerConfigurables() | ||
} | ||
|
78 changes: 78 additions & 0 deletions
78
...fe-jdk6/src/test/kotlin/uy/kohesive/injekt/config/typesafe/TestTypesafeConfigInjection.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package uy.kohesive.injekt.config.typesafe | ||
|
||
import com.typesafe.config.Config | ||
import org.junit.Test | ||
import uy.klutter.config.typesafe.MapAsConfig | ||
import uy.klutter.config.typesafe.loadConfig | ||
import uy.kohesive.injekt.Injekt | ||
import uy.kohesive.injekt.api.InjektModule | ||
import uy.kohesive.injekt.api.InjektRegistrar | ||
import kotlin.test.assertEquals | ||
|
||
class TestTypesafeConfigInjection { | ||
companion object : KonfigAndInjektMain() { | ||
override fun configFactory(): Config { | ||
return loadConfig(MapAsConfig(kotlin.mapOf( | ||
"http" to kotlin.mapOf("httpPort" to 8080, "workerThreads" to 16), | ||
"data" to kotlin.mapOf("bucket" to "com.test.bucket", "region" to "us-east"), | ||
"other" to kotlin.mapOf("name" to "frisbee")))) | ||
} | ||
|
||
override fun KonfigRegistrar.registerConfigurables() { | ||
bindClassAtConfigPath<HttpConfig>("http") | ||
bindClassAtConfigPath<DataConfig>("data") | ||
importModule("other", OtherModule) | ||
} | ||
|
||
override fun InjektRegistrar.registerInjectables() { | ||
addFactory { ConfiguredThing() } | ||
importModule(OtherModule) | ||
} | ||
|
||
} | ||
|
||
@Test public fun testConfigSingletonsExist() { | ||
val matchHttp = HttpConfig(8080,16) | ||
val matchData = DataConfig("com.test.bucket", "us-east") | ||
|
||
assertEquals(matchHttp, Injekt.get<HttpConfig>()) | ||
assertEquals(matchData, Injekt.get<DataConfig>()) | ||
} | ||
|
||
@Test public fun testFactoryUsingConfigWorks() { | ||
val matchHttp = HttpConfig(8080,16) | ||
val matchData = DataConfig("com.test.bucket", "us-east") | ||
|
||
val thing = Injekt.get<ConfiguredThing>() | ||
assertEquals(matchHttp, thing.httpCfg) | ||
assertEquals(matchData, thing.dataCfg) | ||
} | ||
|
||
@Test public fun testWithModules() { | ||
val thing = Injekt.get<OtherThingWantingConfig>() | ||
assertEquals("frisbee", thing.cfg.name) | ||
} | ||
|
||
|
||
data class HttpConfig(val httpPort: Int, val workerThreads: Int) | ||
data class DataConfig(val bucket: String, val region: String) | ||
data class ConfiguredThing(val httpCfg: HttpConfig = Injekt.get(), val dataCfg: DataConfig = Injekt.get()) | ||
} | ||
|
||
|
||
data class OtherConfig(val name: String) | ||
data class OtherThingWantingConfig(val cfg: OtherConfig = Injekt.get()) | ||
|
||
public object OtherModule : KonfigModule, InjektModule { | ||
override fun KonfigRegistrar.registerConfigurables() { | ||
bindClassAtConfigRoot<OtherConfig>() | ||
} | ||
|
||
override fun InjektRegistrar.registerInjectables() { | ||
addFactory { OtherThingWantingConfig() } | ||
} | ||
} | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
dependencies { | ||
compile relativeProject(":injekt-api") | ||
runtime relativeProject(":injekt-core") | ||
compile relativeProject(":injekt-config-typesafe-jdk6") | ||
compile "uy.klutter:klutter-config-typesafe-jdk7:$version_klutter" | ||
compile "uy.klutter:klutter-json-jackson-jdk6:$version_klutter" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
dependencies { | ||
compile relativeProject(":injekt-api") | ||
runtime relativeProject(":injekt-core") | ||
compile relativeProject(":injekt-config-typesafe-jdk6") // TODO: exclude uy.klutter:klutter-json-jackson-jdk6 | ||
compile relativeProject(":injekt-config-typesafe-jdk7") // TODO: exclude uy.klutter:klutter-json-jackson-jdk6 | ||
compile "uy.klutter:klutter-config-typesafe-jdk8:$version_klutter" | ||
compile "uy.klutter:klutter-json-jackson-jdk8:$version_klutter" | ||
} |
Oops, something went wrong.