Skip to content

Commit

Permalink
Added a test for S3. Also fixed a bug where you couldn't use get with…
Browse files Browse the repository at this point in the history
… a List that was ROOT list.
  • Loading branch information
jdiazcano committed Aug 6, 2018
1 parent 8040839 commit 0548240
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 21 deletions.
Expand Up @@ -144,7 +144,7 @@ class ConfigurationHandler {
val targetType = TargetType(returnType)
val rawType = targetType.rawTargetType()
val collection = createCollection(rawType)
toMutableCollection(configObject, returnType, collection, name, provider, prefix)
toMutableCollection(configObject, targetType, collection, name, provider, prefix)
returning = collection
} else if (configObject.isString()) {
val targetType = TargetType(returnType)
Expand Down
Expand Up @@ -67,15 +67,13 @@ class BindingInvocationHandler(
}
}
} else {
val targetType = TargetType(type)
val rawType = targetType.rawTargetType()
if (configObject.isList()) {
val targetType = TargetType(type)
val rawType = targetType.rawTargetType()
val collection = createCollection(rawType)
toMutableCollection(configObject, type, collection, name, provider, prefix)
toMutableCollection(configObject, targetType, collection, name, provider, prefix)
return collection
} else if (configObject.isString()) {
val targetType = TargetType(type)
val rawType = targetType.rawTargetType()
val superType = targetType.getParameterizedClassArguments().firstOrNull()
val classType = superType ?: rawType
return classType.findParser().parse(configObject, classType, superType?.findParser())
Expand Down Expand Up @@ -104,14 +102,12 @@ fun createCollection(rawType: Class<*>): MutableCollection<Any?> {
}
}

fun toMutableCollection(configObject: ConfigObject, type: Type, list: MutableCollection<Any?>, name: String, provider: ConfigProvider, prefix: String) {
fun toMutableCollection(configObject: ConfigObject, targetType: TargetType, list: MutableCollection<Any?>, name: String, provider: ConfigProvider, prefix: String) {
configObject.asList().forEachIndexed { index, innerObject ->
if (innerObject.isObject()) {
val targetType = TargetType(type)
val superType = targetType.getParameterizedClassArguments().firstOrNull()
list.add(provider.bind(concatPrefix(prefix, "$name[$index]"), superType as Class<Any>))
} else if (innerObject.isString()) {
val targetType = TargetType(type)
val rawType = targetType.rawTargetType()
val superType = targetType.getParameterizedClassArguments().firstOrNull()
val classType = superType ?: rawType
Expand All @@ -121,7 +117,7 @@ fun toMutableCollection(configObject: ConfigObject, type: Type, list: MutableCol
}

fun KClass<*>.getDefaultMethod(methodName: String): Method? {
return Class.forName(jvmName + "\$DefaultImpls").methods.firstOrNull { it.name == methodName }
return Class.forName("$jvmName\$DefaultImpls").methods.firstOrNull { it.name == methodName }
}

fun KClass<*>.isMethodNullable(method: Method, propertyName: String = ""): Boolean {
Expand Down
Expand Up @@ -12,10 +12,13 @@ interface ConfigObject {
fun child(key: String): ConfigObject? {
val (number, cleanKey) = findNumbers(key)

return if (number == null) {
asObject()[cleanKey]
} else {
asObject()[cleanKey]?.asList()?.get(number)
return when {
// We're in a normal object
number == null -> asObject()[cleanKey]
// We're in a list that is ROOT
cleanKey.isEmpty() -> asList()[number]
// When we are in a list that is inside our object
else -> asObject()[cleanKey]?.asList()?.get(number)
}
}

Expand Down
Expand Up @@ -42,12 +42,12 @@ open class DefaultConfigLoader(protected var root: ConfigObject = "".toConfig())

}

internal val numberRegex = "([^\\[]+)(?:\\[(\\d+)])".toRegex()
internal val numberRegex = "([^\\[]+)?(?:\\[(\\d+)])".toRegex()

internal fun findNumbers(key: String): Pair<Int?, String> {
val result = numberRegex.find(key)
return if (result != null) {
result.groups[2]?.value?.toInt() to result.groups[1]?.value!!
result.groups[2]?.value?.toInt() to (result.groups[1]?.value ?: "")
} else {
null to key
}
Expand Down
Expand Up @@ -71,10 +71,8 @@ open class DefaultConfigProvider(
val classType = superType ?: rawType
return rawType.findParser().parse(value, classType, superType?.findParser()) as T
} else if (value.isList()) {
val superType = targetType.getParameterizedClassArguments().firstOrNull()
val classType = superType ?: rawType
val collection = createCollection(rawType)
toMutableCollection(value, classType, collection, name, this, name)
toMutableCollection(value, targetType, collection, name, this, name)
return collection as T
}
throw ParserClassNotFound("Parser for class $type was not found")
Expand Down
1 change: 1 addition & 0 deletions cfg4k-s3/build.gradle
Expand Up @@ -5,6 +5,7 @@ dependencies {
compile libraries.jetbrains.kotlin.stdlib
compile libraries.aws.s3

testCompile project(":cfg4k-json")
testCompile libraries.jetbrains.spek.api
testCompile libraries.junitrunner
testCompile libraries.expekt
Expand Down
@@ -1,6 +1,6 @@
package com.jdiazcano.cfg4k.s3

import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.AmazonS3
import com.jdiazcano.cfg4k.sources.ConfigSource
import java.io.InputStream

Expand All @@ -10,7 +10,7 @@ import java.io.InputStream
* @since 0.8.6
*/
class S3ConfigSource(
private val client: AmazonS3Client,
private val client: AmazonS3,
private val bucket: String,
private val objectName: String
) : ConfigSource {
Expand Down
@@ -0,0 +1,32 @@
package com.jdiazcano.cfg4k.s3

import com.amazonaws.regions.Regions
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import com.jdiazcano.cfg4k.json.JsonConfigLoader
import com.jdiazcano.cfg4k.providers.DefaultConfigProvider
import com.jdiazcano.cfg4k.providers.cache
import com.jdiazcano.cfg4k.providers.get
import com.winterbe.expekt.should
import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.dsl.describe

class S3ConfigSourceTest : Spek({
describe("a config source that can fetch data") {
val client = AmazonS3ClientBuilder.standard().withRegion(Regions.US_EAST_1).build()
val source = S3ConfigSource(client, "mtln-public-data", "Samples/airports.json")
val loader = JsonConfigLoader(source)
val provider = DefaultConfigProvider(loader).cache()
val airports = provider.get<List<Airport>>()
airports.should.not.be.empty
}
})

private interface Airport {
val iata: String
val airport: String
val city: String
val state: String
val country: String
val lat: Double
val long: Double
}

0 comments on commit 0548240

Please sign in to comment.