main.app.cash.backfila.client.stat.internal.StaticDatasourceBackend.kt Maven / Gradle / Ivy
package app.cash.backfila.client.stat.internal
import app.cash.backfila.client.DeleteBy
import app.cash.backfila.client.Description
import app.cash.backfila.client.parseDeleteByDate
import app.cash.backfila.client.spi.BackfilaParametersOperator
import app.cash.backfila.client.spi.BackfillBackend
import app.cash.backfila.client.spi.BackfillOperator
import app.cash.backfila.client.spi.BackfillRegistration
import app.cash.backfila.client.stat.ForStaticBackend
import app.cash.backfila.client.stat.StaticDatasourceBackfillBase
import com.google.inject.Injector
import com.google.inject.TypeLiteral
import com.squareup.moshi.Types
import java.lang.reflect.ParameterizedType
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.reflect.KClass
import kotlin.reflect.full.findAnnotation
@Singleton
class StaticDatasourceBackend @Inject constructor(
private val injector: Injector,
@ForStaticBackend private val backfills: MutableMap>>,
) : BackfillBackend {
/** Creates Backfill instances. Each backfill ID gets a new Backfill instance. */
private fun getBackfill(name: String): StaticDatasourceBackfillBase<*, *>? {
val backfillClass = backfills[name]
return if (backfillClass != null) {
injector.getInstance(backfillClass.java) as StaticDatasourceBackfillBase<*, *>
} else {
null
}
}
private fun createStaticDatasourceOperator(
backfill: StaticDatasourceBackfillBase,
) = StaticDatasourceBackfillOperator(
backfill,
BackfilaParametersOperator(parametersClass(backfill::class)),
)
override fun create(backfillName: String): BackfillOperator? {
val backfill = getBackfill(backfillName)
if (backfill != null) {
@Suppress("UNCHECKED_CAST") // We don't know the types statically, so fake them.
return createStaticDatasourceOperator(backfill as StaticDatasourceBackfillBase)
}
return null
}
override fun backfills(): Set {
return backfills.map {
BackfillRegistration(
name = it.key,
description = it.value.findAnnotation()?.text,
parametersClass = parametersClass(it.value as KClass>),
deleteBy = it.value.findAnnotation()?.parseDeleteByDate(),
)
}.toSet()
}
private fun parametersClass(backfillClass: KClass>): KClass {
// Like MyBackfill.
val thisType = TypeLiteral.get(backfillClass.java)
// Like StaticDatasourceBackfillBase.
val supertype = thisType.getSupertype(StaticDatasourceBackfillBase::class.java).type as ParameterizedType
// Like MyParameterClass
return (Types.getRawType(supertype.actualTypeArguments[1]) as Class).kotlin
}
}