Skip to content

Commit

Permalink
Now the OverrideConfigProvider takes a vararg of config providers ins…
Browse files Browse the repository at this point in the history
…tead of loaders.

This makes the binding and reloadstrategy be separated in each provider so you can have a different streategy for each one. The problem was that you only had one reload strategy and for example a classpath resource file won't change so there is no need to reload them!

Now the provider has a new method of "contains" to check if there is instead of checking null later on
  • Loading branch information
jdiazcano committed Feb 6, 2017
1 parent 4dd1b49 commit 62853b9
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ interface ConfigProvider {
*/
fun addReloadListener(listener: () -> Unit)

/**
* Checks if a property exists in the provider.
*/
fun contains(name: String): Boolean

/**
* Binds an interface
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ open class DefaultConfigProvider(
throw SettingNotFound("Setting $name was not found")
}
}


}

override fun contains(name: String) = configLoader.get(name) != null

override fun cancelReload() = reloadStrategy?.deregister(this)

override fun reload() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,104 +18,80 @@

package com.jdiazcano.konfig.providers

import com.jdiazcano.konfig.binders.Binder
import com.jdiazcano.konfig.loaders.ConfigLoader
import com.jdiazcano.konfig.binders.ProxyBinder
import com.jdiazcano.konfig.parsers.Parser
import com.jdiazcano.konfig.parsers.Parsers
import com.jdiazcano.konfig.reloadstrategies.ReloadStrategy
import com.jdiazcano.konfig.utils.ParserClassNotFound
import com.jdiazcano.konfig.utils.SettingNotFound
import com.jdiazcano.konfig.utils.TargetType
import com.jdiazcano.konfig.utils.Typable
import java.lang.reflect.Type

class OverrideConfigProvider(
private val loaders: Array<ConfigLoader>,
private val reloadStrategy: ReloadStrategy? = null,
override val binder: Binder = ProxyBinder()
vararg private val providers: ConfigProvider,
private val reloadStrategy: ReloadStrategy? = null
) : ConfigProvider {

override val binder = ProxyBinder()
private val listeners = mutableListOf<() -> Unit>()
private val cachedLoaders = mutableMapOf<String, ConfigLoader>()
private val cachedProviders = mutableMapOf<String, ConfigProvider>()

init {
reloadStrategy?.register(this)

addReloadListener { cachedLoaders.clear() }
addReloadListener { cachedProviders.clear() }
}

override fun <T : Any> getProperty(name: String, type: Class<T>, default: T?): T {
val value = getValueAndCacheLoader(name)

// There is no way that this has a generic parsers because the class actually removes that possibility
if (value != null) {
if (Parsers.isParser(type)) {
return Parsers.getParser(type).parse(value)
} else {
throw ParserClassNotFound("Parser for class ${type.name} was not found")
}
if (name in cachedProviders) {
return cachedProviders[name]!!.getProperty(name, type, default)
} else {
if (default != null) {
return default
} else {
throw SettingNotFound("Setting $name was not found")
for (provider in providers) {
if (provider.contains(name)) {
cachedProviders[name] = provider
return provider.getProperty(name, type, default)
}
}
}
}

private fun getValueAndCacheLoader(name: String): String? {
var value: String? = null
if (name in cachedLoaders) {
value = cachedLoaders[name]!!.get(name)
if (default != null) {
return default
} else {
for (loader in loaders) {
val internalValue = loader.get(name)
if (internalValue != null) {
value = internalValue
cachedLoaders[name] = loader
break
}
}
throw SettingNotFound("Setting $name was not found")
}
return value
}

override fun <T : Any> getProperty(name: String, type: Typable, default: T?): T {
return getProperty(name, type.getType())
}

override fun <T : Any> getProperty(name: String, type: Type, default: T?): T {
var value: String = ""
if (name in cachedLoaders) {
value = cachedLoaders[name]!!.get(name)!!
if (name in cachedProviders) {
return cachedProviders[name]!!.getProperty(name, type, default)
} else {
for (loader in loaders) {
val internalValue = loader.get(name)
if (internalValue != null) {
value = internalValue
cachedLoaders[name] = loader
break
for (provider in providers) {
if (provider.contains(name)) {
cachedProviders[name] = provider
return provider.getProperty(name, type, default)
}
}
}

val rawType = TargetType(type).rawTargetType()
if (Parsers.isParseredParser(rawType)) {
val parser = Parsers.getParseredParser(rawType) as Parser<T>
val superType = TargetType(type).getParameterizedClassArguments()[0]
return parser.parse(value, superType, Parsers.findParser(superType) as Parser<T>)
} else if (Parsers.isClassedParser(rawType.superclass)) {
val parser = Parsers.getClassedParser(rawType.superclass!!) as Parser<T>
return parser.parse(value, rawType as Class<T>)
} else if (Parsers.isParser(rawType)) {
return Parsers.getParser(rawType).parse(value) as T
if (default != null) {
return default
} else {
throw SettingNotFound("Setting $name was not found")
}
}

override fun contains(name: String): Boolean {
providers.forEach {
if (it.contains(name)) {
return true
}
}
throw ParserClassNotFound("Parser for class $type was not found")
return false
}

override fun reload() {
loaders.forEach { it.reload() }
providers.forEach { it.reload() }
listeners.forEach { it() }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.jdiazcano.konfig.providers

import com.jdiazcano.konfig.loaders.ConfigLoader
import com.jdiazcano.konfig.providers.ConfigProvider
import com.jdiazcano.konfig.reloadstrategies.ReloadStrategy

object Providers {
fun cached(provider: ConfigProvider) = CachedConfigProvider(provider)

fun overriden(loaders: Array<ConfigLoader>, reloadStrategy: ReloadStrategy? = null) = OverrideConfigProvider(loaders, reloadStrategy)
fun overriden(vararg providers: ConfigProvider) = OverrideConfigProvider(*providers)

fun proxy(configLoader: ConfigLoader, reloadStrategy: ReloadStrategy? = null) = ProxyConfigProvider(configLoader, reloadStrategy)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.jdiazcano.konfig

import com.jdiazcano.konfig.loaders.PropertyConfigLoader
import com.jdiazcano.konfig.providers.DefaultConfigProvider
import com.jdiazcano.konfig.providers.Providers.overriden
import com.jdiazcano.konfig.providers.bind
import com.jdiazcano.konfig.providers.getProperty
Expand All @@ -27,8 +28,10 @@ import org.jetbrains.spek.api.dsl.it

class OverrideConfigProviderTest : Spek({
val provider = overriden(
arrayOf(
PropertyConfigLoader(javaClass.classLoader.getResource("overridetest.properties")),
DefaultConfigProvider(
PropertyConfigLoader(javaClass.classLoader.getResource("overridetest.properties"))
),
DefaultConfigProvider(
PropertyConfigLoader(javaClass.classLoader.getResource("test.properties"))
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ class TimedReloadStrategyTest : Spek({
normalFile.createNewFile()
normalFile.writeText(text.replace("%reload1", "b").replace("%reload2", "d"))
val provider = OverrideConfigProvider(
arrayOf(
DefaultConfigProvider(
JsonConfigLoader(overrideFile.toURI().toURL()),
JsonConfigLoader(normalFile.toURI().toURL())
TimedReloadStrategy(1, TimeUnit.SECONDS)
),
TimedReloadStrategy(1, TimeUnit.SECONDS)
DefaultConfigProvider(
JsonConfigLoader(normalFile.toURI().toURL()),
TimedReloadStrategy(1, TimeUnit.SECONDS)
)
)
checkProvider(overrideFile, provider, text, true)
normalFile.delete()
Expand Down

0 comments on commit 62853b9

Please sign in to comment.