Refactor context factories
This commit is contained in:
parent
027d5ed923
commit
030f3ed6fe
@ -17,6 +17,7 @@
|
|||||||
- \[Major breaking change\] Schemes and configurables us `MutableItemProvider` instead of `Config`
|
- \[Major breaking change\] Schemes and configurables us `MutableItemProvider` instead of `Config`
|
||||||
- \[Major breaking change\] `MetaItem` renamed to `TypedMetaItem` and `MetaItem` is now an alias for `TypedMetaItem<*>`
|
- \[Major breaking change\] `MetaItem` renamed to `TypedMetaItem` and `MetaItem` is now an alias for `TypedMetaItem<*>`
|
||||||
- \[Major breaking change\] Moved `NodeItem` and `ValueItem` to a top level
|
- \[Major breaking change\] Moved `NodeItem` and `ValueItem` to a top level
|
||||||
|
- Plugins are removed from Context constructor and added lazily in ContextBuilder
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
@ -38,8 +38,7 @@ public final class hep/dataforge/context/ClassLoaderPluginKt {
|
|||||||
public class hep/dataforge/context/Context : hep/dataforge/context/Named, hep/dataforge/meta/MetaRepr, hep/dataforge/provider/Provider, kotlinx/coroutines/CoroutineScope {
|
public class hep/dataforge/context/Context : hep/dataforge/context/Named, hep/dataforge/meta/MetaRepr, hep/dataforge/provider/Provider, kotlinx/coroutines/CoroutineScope {
|
||||||
public static final field Companion Lhep/dataforge/context/Context$Companion;
|
public static final field Companion Lhep/dataforge/context/Context$Companion;
|
||||||
public static final field PROPERTY_TARGET Ljava/lang/String;
|
public static final field PROPERTY_TARGET Ljava/lang/String;
|
||||||
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/context/Context;Lhep/dataforge/meta/Meta;Ljava/util/Set;)V
|
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/context/Context;Lhep/dataforge/meta/Meta;)V
|
||||||
public synthetic fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/context/Context;Lhep/dataforge/meta/Meta;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
|
||||||
public fun close ()V
|
public fun close ()V
|
||||||
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
||||||
public final fun content (Ljava/lang/String;Z)Ljava/util/Map;
|
public final fun content (Ljava/lang/String;Z)Ljava/util/Map;
|
||||||
@ -65,7 +64,6 @@ public final class hep/dataforge/context/ContextBuilder {
|
|||||||
public synthetic fun <init> (Lhep/dataforge/context/Context;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Lhep/dataforge/context/Context;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun build ()Lhep/dataforge/context/Context;
|
public final fun build ()Lhep/dataforge/context/Context;
|
||||||
public final fun getName ()Ljava/lang/String;
|
public final fun getName ()Ljava/lang/String;
|
||||||
public final fun plugin (Lhep/dataforge/context/Plugin;)V
|
|
||||||
public final fun plugin (Lhep/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)V
|
public final fun plugin (Lhep/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)V
|
||||||
public final fun plugin (Lhep/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;)V
|
public final fun plugin (Lhep/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;)V
|
||||||
public final fun plugin (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
|
public final fun plugin (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
|
||||||
@ -147,7 +145,7 @@ public final class hep/dataforge/context/PluginFactory$Companion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class hep/dataforge/context/PluginManager : hep/dataforge/context/ContextAware, java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker {
|
public final class hep/dataforge/context/PluginManager : hep/dataforge/context/ContextAware, java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker {
|
||||||
public fun <init> (Lhep/dataforge/context/Context;Ljava/util/Set;)V
|
public fun <init> (Lhep/dataforge/context/Context;)V
|
||||||
public final fun fetch (Lhep/dataforge/context/PluginFactory;ZLhep/dataforge/meta/Meta;)Lhep/dataforge/context/Plugin;
|
public final fun fetch (Lhep/dataforge/context/PluginFactory;ZLhep/dataforge/meta/Meta;)Lhep/dataforge/context/Plugin;
|
||||||
public final fun fetch (Lhep/dataforge/context/PluginFactory;ZLkotlin/jvm/functions/Function1;)Lhep/dataforge/context/Plugin;
|
public final fun fetch (Lhep/dataforge/context/PluginFactory;ZLkotlin/jvm/functions/Function1;)Lhep/dataforge/context/Plugin;
|
||||||
public static synthetic fun fetch$default (Lhep/dataforge/context/PluginManager;Lhep/dataforge/context/PluginFactory;ZLhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/context/Plugin;
|
public static synthetic fun fetch$default (Lhep/dataforge/context/PluginManager;Lhep/dataforge/context/PluginFactory;ZLhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/context/Plugin;
|
||||||
|
@ -25,7 +25,6 @@ public open class Context(
|
|||||||
final override val name: Name,
|
final override val name: Name,
|
||||||
public val parent: Context?,
|
public val parent: Context?,
|
||||||
meta: Meta,
|
meta: Meta,
|
||||||
plugins: Set<Plugin> = emptySet(),
|
|
||||||
) : Named, MetaRepr, Provider, CoroutineScope {
|
) : Named, MetaRepr, Provider, CoroutineScope {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +39,7 @@ public open class Context(
|
|||||||
/**
|
/**
|
||||||
* A [PluginManager] for current context
|
* A [PluginManager] for current context
|
||||||
*/
|
*/
|
||||||
public val plugins: PluginManager by lazy { PluginManager(this, plugins)}
|
public val plugins: PluginManager by lazy { PluginManager(this)}
|
||||||
|
|
||||||
override val defaultTarget: String get() = Plugin.TARGET
|
override val defaultTarget: String get() = Plugin.TARGET
|
||||||
|
|
||||||
|
@ -8,17 +8,13 @@ import hep.dataforge.names.toName
|
|||||||
*/
|
*/
|
||||||
@DFBuilder
|
@DFBuilder
|
||||||
public class ContextBuilder(private val parent: Context = Global, public var name: String = "@anonymous") {
|
public class ContextBuilder(private val parent: Context = Global, public var name: String = "@anonymous") {
|
||||||
private val plugins = HashSet<Plugin>()
|
private val factories = HashMap<PluginFactory<*>, Meta>()
|
||||||
private var meta = MetaBuilder()
|
private var meta = MetaBuilder()
|
||||||
|
|
||||||
public fun properties(action: MetaBuilder.() -> Unit) {
|
public fun properties(action: MetaBuilder.() -> Unit) {
|
||||||
meta.action()
|
meta.action()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun plugin(plugin: Plugin) {
|
|
||||||
plugins.add(plugin)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(DFExperimental::class)
|
@OptIn(DFExperimental::class)
|
||||||
private fun findPluginFactory(tag: PluginTag): PluginFactory<*> =
|
private fun findPluginFactory(tag: PluginTag): PluginFactory<*> =
|
||||||
parent.gatherInSequence<PluginFactory<*>>(PluginFactory.TYPE).values
|
parent.gatherInSequence<PluginFactory<*>>(PluginFactory.TYPE).values
|
||||||
@ -26,12 +22,11 @@ public class ContextBuilder(private val parent: Context = Global, public var nam
|
|||||||
|
|
||||||
public fun plugin(tag: PluginTag, metaBuilder: MetaBuilder.() -> Unit = {}) {
|
public fun plugin(tag: PluginTag, metaBuilder: MetaBuilder.() -> Unit = {}) {
|
||||||
val factory = findPluginFactory(tag)
|
val factory = findPluginFactory(tag)
|
||||||
val plugin = factory.invoke(Meta(metaBuilder), parent)
|
factories[factory] = Meta(metaBuilder)
|
||||||
plugins.add(plugin)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun plugin(builder: PluginFactory<*>, action: MetaBuilder.() -> Unit = {}) {
|
public fun plugin(factory: PluginFactory<*>, metaBuilder: MetaBuilder.() -> Unit = {}) {
|
||||||
plugins.add(builder.invoke(Meta(action)))
|
factories[factory] = Meta(metaBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun plugin(name: String, group: String = "", version: String = "", action: MetaBuilder.() -> Unit = {}) {
|
public fun plugin(name: String, group: String = "", version: String = "", action: MetaBuilder.() -> Unit = {}) {
|
||||||
@ -39,6 +34,10 @@ public class ContextBuilder(private val parent: Context = Global, public var nam
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun build(): Context {
|
public fun build(): Context {
|
||||||
return Context(name.toName(), parent, meta.seal(), plugins)
|
return Context(name.toName(), parent, meta.seal()).apply {
|
||||||
|
factories.forEach { (factory, meta) ->
|
||||||
|
plugins.load(factory, meta)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package hep.dataforge.context
|
||||||
|
|
||||||
|
import hep.dataforge.provider.Type
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@Type(PluginFactory.TYPE)
|
||||||
|
public interface PluginFactory<T : Plugin> : Factory<T> {
|
||||||
|
public val tag: PluginTag
|
||||||
|
public val type: KClass<out T>
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
public const val TYPE: String = "pluginFactory"
|
||||||
|
}
|
||||||
|
}
|
@ -2,34 +2,23 @@ package hep.dataforge.context
|
|||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.MetaBuilder
|
import hep.dataforge.meta.MetaBuilder
|
||||||
import hep.dataforge.provider.Type
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
@Type(PluginFactory.TYPE)
|
|
||||||
public interface PluginFactory<T : Plugin> : Factory<T> {
|
|
||||||
public val tag: PluginTag
|
|
||||||
public val type: KClass<out T>
|
|
||||||
|
|
||||||
public companion object {
|
|
||||||
public const val TYPE: String = "pluginFactory"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The manager for plugin system. Should monitor plugin dependencies and locks.
|
* The manager for plugin system. Should monitor plugin dependencies and locks.
|
||||||
*
|
*
|
||||||
* @property context A context for this plugin manager
|
* @property context A context for this plugin manager
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
public class PluginManager(override val context: Context, plugins: Set<Plugin>) : ContextAware, Iterable<Plugin> {
|
public class PluginManager(override val context: Context) : ContextAware, Iterable<Plugin> {
|
||||||
|
|
||||||
//TODO refactor to read-only container
|
//TODO refactor to read-only container
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of loaded plugins
|
* A set of loaded plugins
|
||||||
*/
|
*/
|
||||||
private val plugins: HashSet<Plugin> = HashSet(plugins)
|
private val plugins: HashSet<Plugin> = HashSet()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
plugins.forEach { it.attach(context) }
|
plugins.forEach { it.attach(context) }
|
||||||
|
@ -17,13 +17,13 @@ class ContextTest {
|
|||||||
else -> emptyMap()
|
else -> emptyMap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPluginManager() {
|
fun testPluginManager() {
|
||||||
val context = Global.context("test"){
|
val context = Global.context("test")
|
||||||
plugin(DummyPlugin())
|
context.plugins.load(DummyPlugin())
|
||||||
}
|
|
||||||
//Global.plugins.load(DummyPlugin())
|
//Global.plugins.load(DummyPlugin())
|
||||||
val members = context.gather<Name>("test")
|
val members = context.gather<Name>("test")
|
||||||
assertEquals(3, members.count())
|
assertEquals(3, members.count())
|
||||||
|
@ -299,18 +299,6 @@ public final class hep/dataforge/meta/MetaSerializer : kotlinx/serialization/KSe
|
|||||||
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class hep/dataforge/meta/MetaWithDefault : hep/dataforge/meta/MetaBase {
|
|
||||||
public fun <init> (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)V
|
|
||||||
public final fun getDefault ()Lhep/dataforge/meta/ItemProvider;
|
|
||||||
public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/TypedMetaItem;
|
|
||||||
public fun getItems ()Ljava/util/Map;
|
|
||||||
public final fun getMeta ()Lhep/dataforge/meta/Meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class hep/dataforge/meta/MetaWithDefaultKt {
|
|
||||||
public static final fun withDefault (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MetaWithDefault;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class hep/dataforge/meta/MutableItemDelegateKt {
|
public final class hep/dataforge/meta/MutableItemDelegateKt {
|
||||||
public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty;
|
public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty;
|
||||||
public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty;
|
public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty;
|
||||||
|
@ -39,9 +39,13 @@ public operator fun ItemProvider?.get(key: String): MetaItem? = this?.get(key.to
|
|||||||
/**
|
/**
|
||||||
* Create a provider that uses given provider for default values if those are not found in this provider
|
* Create a provider that uses given provider for default values if those are not found in this provider
|
||||||
*/
|
*/
|
||||||
public fun ItemProvider.withDefault(default: ItemProvider): ItemProvider = ItemProvider {
|
public fun ItemProvider.withDefault(default: ItemProvider?): ItemProvider = if (default == null) {
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
ItemProvider {
|
||||||
this[it] ?: default[it]
|
this[it] ?: default[it]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all items matching given name. The index of the last element, if present is used as a [Regex],
|
* Get all items matching given name. The index of the last element, if present is used as a [Regex],
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
package hep.dataforge.meta
|
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
|
||||||
import hep.dataforge.names.NameToken
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Meta object with default provider for items not present in the initial meta.
|
|
||||||
*/
|
|
||||||
public class MetaWithDefault(public val meta: Meta, public val default: ItemProvider) : MetaBase() {
|
|
||||||
override val items: Map<NameToken, MetaItem>
|
|
||||||
get() = meta.items
|
|
||||||
|
|
||||||
override fun getItem(name: Name): MetaItem? {
|
|
||||||
return meta[name] ?: default[name]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun Meta.withDefault(default: ItemProvider): MetaWithDefault = MetaWithDefault(this, default)
|
|
@ -56,8 +56,7 @@ class DataPropagationTestPlugin : WorkspacePlugin() {
|
|||||||
|
|
||||||
override val type: KClass<out DataPropagationTestPlugin> = DataPropagationTestPlugin::class
|
override val type: KClass<out DataPropagationTestPlugin> = DataPropagationTestPlugin::class
|
||||||
|
|
||||||
override fun invoke(meta: Meta, context: Context): DataPropagationTestPlugin =
|
override fun invoke(meta: Meta, context: Context): DataPropagationTestPlugin = DataPropagationTestPlugin()
|
||||||
DataPropagationTestPlugin(meta)
|
|
||||||
|
|
||||||
override val tag: PluginTag = PluginTag("Test")
|
override val tag: PluginTag = PluginTag("Test")
|
||||||
}
|
}
|
||||||
@ -66,7 +65,7 @@ class DataPropagationTestPlugin : WorkspacePlugin() {
|
|||||||
class DataPropagationTest {
|
class DataPropagationTest {
|
||||||
val testWorkspace = Workspace {
|
val testWorkspace = Workspace {
|
||||||
context {
|
context {
|
||||||
plugin(DataPropagationTestPlugin())
|
plugin(DataPropagationTestPlugin)
|
||||||
}
|
}
|
||||||
data {
|
data {
|
||||||
repeat(100) {
|
repeat(100) {
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
package hep.dataforge.workspace
|
package hep.dataforge.workspace
|
||||||
|
|
||||||
import hep.dataforge.context.PluginTag
|
import hep.dataforge.context.*
|
||||||
import hep.dataforge.context.logger
|
|
||||||
import hep.dataforge.data.*
|
import hep.dataforge.data.*
|
||||||
import hep.dataforge.meta.boolean
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.builder
|
|
||||||
import hep.dataforge.meta.get
|
|
||||||
import hep.dataforge.meta.int
|
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
|
import kotlin.reflect.KClass
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a fake-factory for a one single plugin. Useful for unique or test plugins
|
||||||
|
*/
|
||||||
|
public inline fun <reified P: Plugin> P.toFactory(): PluginFactory<P> = object : PluginFactory<P> {
|
||||||
|
override fun invoke(meta: Meta, context: Context): P = this@toFactory
|
||||||
|
|
||||||
|
override val tag: PluginTag = this@toFactory.tag
|
||||||
|
override val type: KClass<out P> = P::class
|
||||||
|
}
|
||||||
|
|
||||||
class SimpleWorkspaceTest {
|
class SimpleWorkspaceTest {
|
||||||
val testPlugin = object : WorkspacePlugin() {
|
val testPlugin = object : WorkspacePlugin() {
|
||||||
@ -23,11 +29,12 @@ class SimpleWorkspaceTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val testPluginFactory = testPlugin.toFactory()
|
||||||
|
|
||||||
val workspace = Workspace {
|
val workspace = Workspace {
|
||||||
|
|
||||||
context {
|
context {
|
||||||
plugin(testPlugin)
|
plugin(testPluginFactory)
|
||||||
}
|
}
|
||||||
|
|
||||||
data {
|
data {
|
||||||
|
Loading…
Reference in New Issue
Block a user