Simplified Provider API
This commit is contained in:
parent
5b053d60a2
commit
da4a9ebe9d
@ -3,7 +3,7 @@ plugins {
|
||||
id("scientifik.publish") apply false
|
||||
}
|
||||
|
||||
val dataforgeVersion by extra("0.1.3-dev-8")
|
||||
val dataforgeVersion by extra("0.1.3-dev-9")
|
||||
|
||||
val bintrayRepo by extra("dataforge")
|
||||
val vcs by extra("https://github.com/mipt-npm/dataforge-core")
|
||||
|
@ -18,7 +18,5 @@ abstract class AbstractPlugin(override val meta: Meta = EmptyMeta) : Plugin {
|
||||
this._context = null
|
||||
}
|
||||
|
||||
override fun provideTop(target: String, name: Name): Any? = null
|
||||
|
||||
override fun listNames(target: String): Sequence<Name> = emptySequence()
|
||||
override fun provideTop(target: String): Map<Name, Any> = emptyMap()
|
||||
}
|
@ -59,19 +59,11 @@ open class Context(final override val name: String, val parent: Context? = Globa
|
||||
|
||||
override val defaultTarget: String get() = Plugin.PLUGIN_TARGET
|
||||
|
||||
override fun provideTop(target: String, name: Name): Any? {
|
||||
return when (target) {
|
||||
Plugin.PLUGIN_TARGET -> plugins[PluginTag.fromString(name.toString())]
|
||||
Value.TYPE -> properties[name]?.value
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override fun listNames(target: String): Sequence<Name> {
|
||||
return when (target) {
|
||||
Plugin.PLUGIN_TARGET -> plugins.asSequence().map { it.name.toName() }
|
||||
Value.TYPE -> properties.values().map { it.first }
|
||||
else -> emptySequence()
|
||||
override fun provideTop(target: String): Map<Name, Any> {
|
||||
return when(target){
|
||||
Value.TYPE -> properties.sequence().toMap()
|
||||
Plugin.PLUGIN_TARGET -> plugins.sequence(true).associateBy { it.name.toName() }
|
||||
else-> emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ package hep.dataforge.provider
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* A marker utility interface for providers.
|
||||
@ -42,29 +41,21 @@ interface Provider {
|
||||
|
||||
|
||||
/**
|
||||
* Provide a top level element for this [Provider] or return null if element is not present
|
||||
* A map of direct children for specific target
|
||||
*/
|
||||
fun provideTop(target: String, name: Name): Any?
|
||||
|
||||
/**
|
||||
* [Sequence] of available names with given target. Only top level names are listed, no chain path.
|
||||
*
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
fun listNames(target: String): Sequence<Name>
|
||||
fun provideTop(target: String): Map<Name, Any>
|
||||
}
|
||||
|
||||
fun Provider.provide(path: Path, targetOverride: String? = null): Any? {
|
||||
if (path.length == 0) throw IllegalArgumentException("Can't provide by empty path")
|
||||
val first = path.first()
|
||||
val top = provideTop(targetOverride ?: first.target ?: defaultTarget, first.name)
|
||||
val target = targetOverride ?: first.target ?: defaultTarget
|
||||
val res = provideTop(target)[first.name] ?: return null
|
||||
return when (path.length) {
|
||||
1 -> top
|
||||
1 -> res
|
||||
else -> {
|
||||
when (top) {
|
||||
null -> null
|
||||
is Provider -> top.provide(path.tail!!, targetOverride = defaultChainTarget)
|
||||
when (res) {
|
||||
is Provider -> res.provide(path.tail!!, targetOverride = defaultChainTarget)
|
||||
else -> throw IllegalStateException("Chain path not supported: child is not a provider")
|
||||
}
|
||||
}
|
||||
@ -85,16 +76,12 @@ inline fun <reified T : Any> Provider.provide(target: String, name: Name): T? {
|
||||
inline fun <reified T : Any> Provider.provide(target: String, name: String): T? =
|
||||
provide(target, name.toName())
|
||||
|
||||
|
||||
fun Provider.top(target: String): Map<Name, Any> = top<Any>(target)
|
||||
|
||||
/**
|
||||
* A top level content with names
|
||||
* Typed top level content
|
||||
*/
|
||||
@JvmName("typedTop")
|
||||
inline fun <reified T : Any> Provider.top(target: String): Map<Name, T> {
|
||||
return listNames(target).associate {
|
||||
it to (provideTop(target, it) as? T ?: error("The element $it is declared but not provided"))
|
||||
return provideTop(target).mapValues {
|
||||
it.value as? T ?: error("The type of element $it is ${it::class} but ${T::class} is expected")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,17 +12,10 @@ class ContextTest {
|
||||
class DummyPlugin : AbstractPlugin() {
|
||||
override val tag get() = PluginTag("test")
|
||||
|
||||
override fun provideTop(target: String, name: Name): Any? {
|
||||
return when (target) {
|
||||
"test" -> return name
|
||||
else -> super.provideTop(target, name)
|
||||
}
|
||||
}
|
||||
|
||||
override fun listNames(target: String): Sequence<Name> {
|
||||
return when (target) {
|
||||
"test" -> sequenceOf("a", "b", "c.d").map { it.toName() }
|
||||
else -> super.listNames(target)
|
||||
override fun provideTop(target: String): Map<Name, Any> {
|
||||
return when(target){
|
||||
"test" -> listOf("a", "b", "c.d").associate { it.toName() to it.toName() }
|
||||
else -> emptyMap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,9 +34,7 @@ inline fun <reified T : Any> Provider.provideByType(name: Name): T? {
|
||||
|
||||
inline fun <reified T : Any> Provider.top(): Map<Name, T> {
|
||||
val target = Types[T::class]
|
||||
return listNames(target).associate { name ->
|
||||
name to (provideByType<T>(name) ?: error("The element $name is declared but not provided"))
|
||||
}
|
||||
return top(target)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,6 @@ import hep.dataforge.data.DataNode
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.provider.top
|
||||
|
||||
|
||||
/**
|
||||
|
@ -29,27 +29,16 @@ interface Workspace : ContextAware, Provider {
|
||||
*/
|
||||
val tasks: Map<Name, Task<*>>
|
||||
|
||||
override fun provideTop(target: String, name: Name): Any? {
|
||||
override fun provideTop(target: String): Map<Name, Any> {
|
||||
return when (target) {
|
||||
"target", Meta.TYPE -> targets[name.toString()]
|
||||
Task.TYPE -> tasks[name]
|
||||
Data.TYPE -> data[name]
|
||||
DataNode.TYPE -> data.getNode(name)
|
||||
else -> null
|
||||
"target", Meta.TYPE -> targets.mapKeys { it.key.toName() }
|
||||
Task.TYPE -> tasks
|
||||
Data.TYPE -> data.data().toMap()
|
||||
DataNode.TYPE -> data.nodes().toMap()
|
||||
else -> emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
override fun listNames(target: String): Sequence<Name> {
|
||||
return when (target) {
|
||||
"target", Meta.TYPE -> targets.keys.asSequence().map { it.toName() }
|
||||
Task.TYPE -> tasks.keys.asSequence().map { it }
|
||||
Data.TYPE -> data.data().map { it.first }
|
||||
DataNode.TYPE -> data.nodes().map { it.first }
|
||||
else -> emptySequence()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invoke a task in the workspace utilizing caching if possible
|
||||
*/
|
||||
@ -64,15 +53,6 @@ interface Workspace : ContextAware, Provider {
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Invoke a task in the workspace utilizing caching if possible
|
||||
// */
|
||||
// operator fun <R : Any> Task<R>.invoke(targetName: String): DataNode<R> {
|
||||
// val target = targets[targetName] ?: error("A target with name $targetName not found in ${this@Workspace}")
|
||||
// context.logger.info { "Running ${this.name} on $target" }
|
||||
// return invoke(target)
|
||||
// }
|
||||
|
||||
companion object {
|
||||
const val TYPE = "workspace"
|
||||
}
|
||||
|
@ -10,19 +10,10 @@ import hep.dataforge.names.toName
|
||||
abstract class WorkspacePlugin : AbstractPlugin() {
|
||||
abstract val tasks: Collection<Task<*>>
|
||||
|
||||
override fun provideTop(target: String, name: Name): Any? {
|
||||
return if (target == Task.TYPE) {
|
||||
tasks.find { it.name == name.toString() }
|
||||
} else {
|
||||
super.provideTop(target, name)
|
||||
}
|
||||
}
|
||||
|
||||
override fun listNames(target: String): Sequence<Name> {
|
||||
return if (target == Task.TYPE) {
|
||||
tasks.asSequence().map { it.name.toName() }
|
||||
} else {
|
||||
return super.listNames(target)
|
||||
override fun provideTop(target: String): Map<Name, Any> {
|
||||
return when(target){
|
||||
Task.TYPE -> tasks.associateBy { it.name.toName() }
|
||||
else -> emptyMap()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user