Isolate and deprecate Context plugin mutation logic.
This commit is contained in:
parent
9fbc482549
commit
f1f5f7a70c
@ -4,12 +4,16 @@
|
||||
### Added
|
||||
- LogManager plugin
|
||||
- dataforge-context API dependency on SLF4j
|
||||
- Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation.
|
||||
|
||||
### Changed
|
||||
- Kotlin-logging moved from common to JVM and JS. Replaced by console for native.
|
||||
- Package changed to `space.kscience`
|
||||
- Scheme made observable
|
||||
- Global context is a variable (the singleton is hidden and will be deprecated in future)
|
||||
|
||||
### Deprecated
|
||||
- Direct use of PluginManager
|
||||
|
||||
### Removed
|
||||
- Common dependency on Kotlin-logging
|
||||
|
@ -38,6 +38,7 @@ public final class space/kscience/dataforge/context/ClassLoaderPluginKt {
|
||||
public class space/kscience/dataforge/context/Context : kotlinx/coroutines/CoroutineScope, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/misc/Named, space/kscience/dataforge/provider/Provider {
|
||||
public static final field Companion Lspace/kscience/dataforge/context/Context$Companion;
|
||||
public static final field PROPERTY_TARGET Ljava/lang/String;
|
||||
public final fun buildContext (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
|
||||
public fun close ()V
|
||||
public fun content (Ljava/lang/String;)Ljava/util/Map;
|
||||
public final fun content (Ljava/lang/String;Z)Ljava/util/Map;
|
||||
@ -47,6 +48,7 @@ public class space/kscience/dataforge/context/Context : kotlinx/coroutines/Corou
|
||||
public final fun getName ()Lspace/kscience/dataforge/names/Name;
|
||||
public final fun getParent ()Lspace/kscience/dataforge/context/Context;
|
||||
public final fun getPlugins ()Lspace/kscience/dataforge/context/PluginManager;
|
||||
public final fun getProperties ()Lspace/kscience/dataforge/meta/Laminate;
|
||||
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
|
||||
}
|
||||
|
||||
@ -58,24 +60,35 @@ public abstract interface class space/kscience/dataforge/context/ContextAware {
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/context/ContextBuilder {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;)V
|
||||
public synthetic fun <init> (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun build ()Lspace/kscience/dataforge/context/Context;
|
||||
public final fun getName ()Ljava/lang/String;
|
||||
public final fun getName ()Lspace/kscience/dataforge/names/Name;
|
||||
public final fun name (Ljava/lang/String;)V
|
||||
public final fun plugin (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun plugin (Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun plugin (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)V
|
||||
public final fun plugin (Lspace/kscience/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Lspace/kscience/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public final fun properties (Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun setName (Ljava/lang/String;)V
|
||||
public final fun setName (Lspace/kscience/dataforge/names/Name;)V
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/context/ContextKt {
|
||||
public static final fun Context (Ljava/lang/String;Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
|
||||
public static synthetic fun Context$default (Ljava/lang/String;Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context;
|
||||
public final class space/kscience/dataforge/context/ContextBuilderKt {
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/context/DefaultLogManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/dataforge/context/LogManager {
|
||||
public static final field Companion Lspace/kscience/dataforge/context/DefaultLogManager$Companion;
|
||||
public fun <init> ()V
|
||||
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||
public fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/context/DefaultLogManager$Companion : space/kscience/dataforge/context/PluginFactory {
|
||||
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
|
||||
public fun getType ()Lkotlin/reflect/KClass;
|
||||
public synthetic fun invoke (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;)Ljava/lang/Object;
|
||||
public fun invoke (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/DefaultLogManager;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/dataforge/context/Factory {
|
||||
@ -88,12 +101,13 @@ public final class space/kscience/dataforge/context/Factory$DefaultImpls {
|
||||
|
||||
public final class space/kscience/dataforge/context/Global : space/kscience/dataforge/context/Context {
|
||||
public static final field INSTANCE Lspace/kscience/dataforge/context/Global;
|
||||
public fun close ()V
|
||||
public final fun context (Ljava/lang/String;Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
|
||||
public static synthetic fun context$default (Lspace/kscience/dataforge/context/Global;Ljava/lang/String;Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context;
|
||||
public final fun getContext (Ljava/lang/String;)Lspace/kscience/dataforge/context/Context;
|
||||
public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext;
|
||||
public final fun getLogger ()Lspace/kscience/dataforge/context/LogManager;
|
||||
public final fun getDefaultLogger ()Lspace/kscience/dataforge/context/LogManager;
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/context/GlobalKt {
|
||||
public static final fun Context (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
|
||||
public static synthetic fun Context$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/dataforge/context/LogManager : space/kscience/dataforge/context/Logable, space/kscience/dataforge/context/Plugin {
|
||||
@ -128,7 +142,7 @@ public final class space/kscience/dataforge/context/LogManagerKt {
|
||||
public static final fun error (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V
|
||||
public static synthetic fun error$default (Lspace/kscience/dataforge/context/Logable;Ljava/lang/Throwable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
|
||||
public static synthetic fun error$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
|
||||
public static final fun getLogger (Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/LogManager;
|
||||
public static final fun getLogger (Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/Logable;
|
||||
public static final fun getLogger (Lspace/kscience/dataforge/context/ContextAware;)Lspace/kscience/dataforge/context/Logable;
|
||||
public static final fun info (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V
|
||||
public static synthetic fun info$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
|
||||
|
@ -11,6 +11,7 @@ import space.kscience.dataforge.misc.Named
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.provider.Provider
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.jvm.Synchronized
|
||||
|
||||
/**
|
||||
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
|
||||
@ -31,12 +32,13 @@ public open class Context internal constructor(
|
||||
/**
|
||||
* Context properties. Working as substitute for environment variables
|
||||
*/
|
||||
private val properties: Laminate = if (parent == null) {
|
||||
public val properties: Laminate = if (parent == null) {
|
||||
Laminate(meta)
|
||||
} else {
|
||||
Laminate(meta, parent.properties)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A [PluginManager] for current context
|
||||
*/
|
||||
@ -68,10 +70,24 @@ public open class Context internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val childrenContexts = HashMap<Name, Context>()
|
||||
|
||||
/**
|
||||
* Detach all plugins and terminate context
|
||||
* Build and register a child context
|
||||
*/
|
||||
@Synchronized
|
||||
public fun buildContext(block: ContextBuilder.() -> Unit): Context{
|
||||
val newContext = ContextBuilder(this).apply(block).build()
|
||||
childrenContexts[newContext.name] = newContext
|
||||
return newContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach all plugins, and close child contexts
|
||||
*/
|
||||
public open fun close() {
|
||||
//recursively closed child context
|
||||
childrenContexts.forEach { it.value.close() }
|
||||
//detach all plugins
|
||||
plugins.forEach { it.detach() }
|
||||
}
|
||||
@ -87,9 +103,6 @@ public open class Context internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
public fun Context(name: String, parent: Context = Global, block: ContextBuilder.() -> Unit = {}): Context =
|
||||
Global.context(name, parent, block)
|
||||
|
||||
/**
|
||||
* The interface for something that encapsulated in context
|
||||
*
|
||||
|
@ -3,8 +3,11 @@ package space.kscience.dataforge.context
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.MetaBuilder
|
||||
import space.kscience.dataforge.meta.seal
|
||||
import space.kscience.dataforge.meta.toMutableMeta
|
||||
import space.kscience.dataforge.misc.DFBuilder
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.plus
|
||||
import space.kscience.dataforge.names.toName
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
@ -14,14 +17,22 @@ import kotlin.collections.set
|
||||
* A convenience builder for context
|
||||
*/
|
||||
@DFBuilder
|
||||
public class ContextBuilder(private val parent: Context = Global, public var name: String = "@anonymous") {
|
||||
private val factories = HashMap<PluginFactory<*>, Meta>()
|
||||
private var meta = MetaBuilder()
|
||||
public class ContextBuilder internal constructor(
|
||||
private val parent: Context,
|
||||
public var name: Name? = null,
|
||||
meta: Meta = Meta.EMPTY,
|
||||
) {
|
||||
internal val factories = HashMap<PluginFactory<*>, Meta>()
|
||||
internal var meta = meta.toMutableMeta()
|
||||
|
||||
public fun properties(action: MetaBuilder.() -> Unit) {
|
||||
meta.action()
|
||||
}
|
||||
|
||||
public fun name(string: String){
|
||||
this.name = string.toName()
|
||||
}
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
private fun findPluginFactory(tag: PluginTag): PluginFactory<*> =
|
||||
parent.gatherInSequence<PluginFactory<*>>(PluginFactory.TYPE).values
|
||||
@ -32,6 +43,10 @@ public class ContextBuilder(private val parent: Context = Global, public var nam
|
||||
factories[factory] = Meta(metaBuilder)
|
||||
}
|
||||
|
||||
public fun plugin(factory: PluginFactory<*>, meta: Meta){
|
||||
factories[factory] = meta
|
||||
}
|
||||
|
||||
public fun plugin(factory: PluginFactory<*>, metaBuilder: MetaBuilder.() -> Unit = {}) {
|
||||
factories[factory] = Meta(metaBuilder)
|
||||
}
|
||||
@ -41,10 +56,29 @@ public class ContextBuilder(private val parent: Context = Global, public var nam
|
||||
}
|
||||
|
||||
public fun build(): Context {
|
||||
return Context(name.toName(), parent, meta.seal()).apply {
|
||||
val contextName = name ?: "@auto[${hashCode().toUInt().toString(16)}]".toName()
|
||||
return Context(contextName, parent, meta.seal()).apply {
|
||||
factories.forEach { (factory, meta) ->
|
||||
plugins.load(factory, meta)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current context contains all plugins required by the builder and return it it does or forks to a new context
|
||||
* if it does not.
|
||||
*/
|
||||
public fun Context.withEnv(block: ContextBuilder.() -> Unit): Context {
|
||||
|
||||
fun Context.contains(factory: PluginFactory<*>, meta: Meta): Boolean {
|
||||
val loaded = plugins[factory.tag] ?: return false
|
||||
return loaded.meta == meta
|
||||
}
|
||||
|
||||
val builder = ContextBuilder(this, name + "env", properties).apply(block)
|
||||
val requiresFork = builder.factories.any { (factory, meta) ->
|
||||
!contains(factory, meta)
|
||||
} || ((properties as Meta) == builder.meta)
|
||||
return if (requiresFork) builder.build() else this
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package space.kscience.dataforge.context
|
||||
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.Job
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.names.asName
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
@ -13,43 +13,10 @@ internal expect val globalLoggerFactory: PluginFactory<out LogManager>
|
||||
* A global root context. Closing [Global] terminates the framework.
|
||||
*/
|
||||
@ThreadLocal
|
||||
public object Global : Context("GLOBAL".asName(), null, Meta.EMPTY) {
|
||||
private object GlobalContext : Context("GLOBAL".asName(), null, Meta.EMPTY) {
|
||||
override val coroutineContext: CoroutineContext = GlobalScope.coroutineContext + Job()
|
||||
}
|
||||
|
||||
override val coroutineContext: CoroutineContext = GlobalScope.coroutineContext + SupervisorJob()
|
||||
public val Global: Context get() = GlobalContext
|
||||
|
||||
/**
|
||||
* The default logging manager
|
||||
*/
|
||||
public val logger: LogManager by lazy { globalLoggerFactory.invoke(context = this).apply { attach(this@Global) } }
|
||||
|
||||
/**
|
||||
* Closing all contexts
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
override fun close() {
|
||||
logger.info { "Shutting down GLOBAL" }
|
||||
for (ctx in contextRegistry.values) {
|
||||
ctx.close()
|
||||
}
|
||||
super.close()
|
||||
}
|
||||
|
||||
private val contextRegistry = HashMap<String, Context>()
|
||||
|
||||
/**
|
||||
* Get previously built context
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public fun getContext(name: String): Context? {
|
||||
return contextRegistry[name]
|
||||
}
|
||||
|
||||
public fun context(name: String, parent: Context = this, block: ContextBuilder.() -> Unit = {}): Context =
|
||||
ContextBuilder(parent, name).apply(block).build().also {
|
||||
contextRegistry[name] = it
|
||||
}
|
||||
|
||||
}
|
||||
public fun Context(block: ContextBuilder.() -> Unit = {}): Context = Global.buildContext(block)
|
@ -1,15 +1,16 @@
|
||||
package space.kscience.dataforge.context
|
||||
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.misc.Named
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.plus
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public interface Logable {
|
||||
public fun interface Logable {
|
||||
public fun log(name: Name, tag: String, body: () -> String)
|
||||
}
|
||||
|
||||
public interface LogManager : Plugin, Logable {
|
||||
|
||||
public companion object {
|
||||
public const val TRACE: String = "TRACE"
|
||||
public const val INFO: String = "INFO"
|
||||
@ -41,11 +42,30 @@ public fun Logable.error(throwable: Throwable?, name: Name = Name.EMPTY, body: (
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class DefaultLogManager : AbstractPlugin(), LogManager {
|
||||
|
||||
override fun log(name: Name, tag: String, body: () -> String) {
|
||||
val message: String = body.safe
|
||||
println("[${context.name}] $name: $message")
|
||||
}
|
||||
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
public companion object : PluginFactory<DefaultLogManager> {
|
||||
override fun invoke(meta: Meta, context: Context): DefaultLogManager = DefaultLogManager()
|
||||
|
||||
override val tag: PluginTag = PluginTag(group = PluginTag.DATAFORGE_GROUP, name = "log.default")
|
||||
override val type: KClass<out DefaultLogManager> = DefaultLogManager::class
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Context log manager inherited from parent
|
||||
*/
|
||||
public val Context.logger: LogManager
|
||||
get() = plugins.find(inherit = true) { it is LogManager } as? LogManager ?: Global.logger
|
||||
public val Context.logger: Logable
|
||||
get() = plugins.find(inherit = true) { it is LogManager } as? LogManager
|
||||
?: globalLoggerFactory(context = Global).apply { attach(Global) }
|
||||
|
||||
/**
|
||||
* The named proxy logger for a context member
|
||||
|
@ -63,5 +63,4 @@ public interface Plugin : Named, ContextAware, Provider, MetaRepr {
|
||||
public companion object {
|
||||
public const val TARGET: String = "plugin"
|
||||
}
|
||||
|
||||
}
|
@ -13,8 +13,6 @@ import kotlin.reflect.KClass
|
||||
*/
|
||||
public class PluginManager(override val context: Context) : ContextAware, Iterable<Plugin> {
|
||||
|
||||
//TODO refactor to read-only container
|
||||
|
||||
/**
|
||||
* A set of loaded plugins
|
||||
*/
|
||||
@ -85,6 +83,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab
|
||||
* @param plugin
|
||||
* @return
|
||||
*/
|
||||
@Deprecated("Use immutable contexts instead")
|
||||
public fun <T : Plugin> load(plugin: T): T {
|
||||
if (get(plugin::class, plugin.tag, recursive = false) != null) {
|
||||
error("Plugin with tag ${plugin.tag} already exists in ${context.name}")
|
||||
@ -93,7 +92,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab
|
||||
fetch(factory, meta, true)
|
||||
}
|
||||
|
||||
Global.logger.info { "Loading plugin ${plugin.name} into ${context.name}" }
|
||||
logger.info { "Loading plugin ${plugin.name} into ${context.name}" }
|
||||
plugin.attach(context)
|
||||
plugins.add(plugin)
|
||||
return plugin
|
||||
@ -103,15 +102,18 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab
|
||||
/**
|
||||
* Load a plugin using its factory
|
||||
*/
|
||||
@Deprecated("Use immutable contexts instead")
|
||||
public fun <T : Plugin> load(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T =
|
||||
load(factory(meta, context))
|
||||
|
||||
@Deprecated("Use immutable contexts instead")
|
||||
public fun <T : Plugin> load(factory: PluginFactory<T>, metaBuilder: MetaBuilder.() -> Unit): T =
|
||||
load(factory, Meta(metaBuilder))
|
||||
|
||||
/**
|
||||
* Remove a plugin from [PluginManager]
|
||||
*/
|
||||
@Deprecated("Use immutable contexts instead")
|
||||
public fun remove(plugin: Plugin) {
|
||||
if (plugins.contains(plugin)) {
|
||||
Global.logger.info { "Removing plugin ${plugin.name} from ${context.name}" }
|
||||
@ -123,6 +125,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab
|
||||
/**
|
||||
* Get an existing plugin with given meta or load new one using provided factory
|
||||
*/
|
||||
@Deprecated("Use immutable contexts instead")
|
||||
public fun <T : Plugin> fetch(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY, recursive: Boolean = true): T {
|
||||
val loaded = get(factory.type, factory.tag, recursive)
|
||||
return when {
|
||||
@ -132,6 +135,7 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated("Use immutable contexts instead")
|
||||
public fun <T : Plugin> fetch(
|
||||
factory: PluginFactory<T>,
|
||||
recursive: Boolean = true,
|
||||
@ -140,4 +144,18 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab
|
||||
|
||||
override fun iterator(): Iterator<Plugin> = plugins.iterator()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a plugin with given meta from the context. If the plugin (with given meta) is already registered, it is returned.
|
||||
* Otherwise, new child context with the plugin is created. In the later case the context could be retrieved from the plugin.
|
||||
*/
|
||||
public inline fun <reified T : Plugin> Context.fetch(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T {
|
||||
val existing = plugins[factory]
|
||||
return if (existing != null && existing.meta == meta) existing
|
||||
else {
|
||||
buildContext {
|
||||
plugin(factory, meta)
|
||||
}.plugins[factory]!!
|
||||
}
|
||||
}
|
@ -22,7 +22,9 @@ class ContextTest {
|
||||
|
||||
@Test
|
||||
fun testPluginManager() {
|
||||
val context = Global.context("test")
|
||||
val context = Global.buildContext{
|
||||
name("test")
|
||||
}
|
||||
context.plugins.load(DummyPlugin())
|
||||
//Global.plugins.load(DummyPlugin())
|
||||
val members = context.gather<Name>("test")
|
||||
|
@ -1,25 +1,4 @@
|
||||
package space.kscience.dataforge.context
|
||||
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.names.Name
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
public class NativeLogManager : AbstractPlugin(), LogManager {
|
||||
|
||||
override fun log(name: Name, tag: String, body: () -> String) {
|
||||
val message: String = body.safe
|
||||
println("[${context.name}] $name: $message")
|
||||
}
|
||||
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
public companion object : PluginFactory<NativeLogManager> {
|
||||
override fun invoke(meta: Meta, context: Context): NativeLogManager = NativeLogManager()
|
||||
|
||||
override val tag: PluginTag = PluginTag(group = PluginTag.DATAFORGE_GROUP, name = "log.native")
|
||||
override val type: KClass<out NativeLogManager> = NativeLogManager::class
|
||||
}
|
||||
}
|
||||
|
||||
internal actual val globalLoggerFactory: PluginFactory<out LogManager> = NativeLogManager
|
||||
internal actual val globalLoggerFactory: PluginFactory<out LogManager> = DefaultLogManager
|
||||
|
@ -9,6 +9,7 @@ import space.kscience.dataforge.io.MetaFormatFactory.Companion.META_FORMAT_TYPE
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.toName
|
||||
import kotlin.native.concurrent.ThreadLocal
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public class IOPlugin(meta: Meta) : AbstractPlugin(meta) {
|
||||
@ -62,7 +63,8 @@ public class IOPlugin(meta: Meta) : AbstractPlugin(meta) {
|
||||
|
||||
public companion object : PluginFactory<IOPlugin> {
|
||||
public val defaultMetaFormats: List<MetaFormatFactory> = listOf(JsonMetaFormat, BinaryMetaFormat)
|
||||
public val defaultEnvelopeFormats: List<EnvelopeFormatFactory> = listOf(TaggedEnvelopeFormat, TaglessEnvelopeFormat)
|
||||
public val defaultEnvelopeFormats: List<EnvelopeFormatFactory> =
|
||||
listOf(TaggedEnvelopeFormat, TaglessEnvelopeFormat)
|
||||
|
||||
override val tag: PluginTag = PluginTag("io", group = PluginTag.DATAFORGE_GROUP)
|
||||
|
||||
@ -71,4 +73,10 @@ public class IOPlugin(meta: Meta) : AbstractPlugin(meta) {
|
||||
}
|
||||
}
|
||||
|
||||
public val Context.io: IOPlugin get() = plugins.fetch(IOPlugin)
|
||||
@ThreadLocal
|
||||
internal val ioContext = Global.withEnv {
|
||||
name("IO")
|
||||
plugin(IOPlugin)
|
||||
}
|
||||
|
||||
public val Context.io: IOPlugin get() = (if (this == Global) ioContext else this).fetch(IOPlugin)
|
@ -161,7 +161,7 @@ public class TaggedEnvelopeFormat(
|
||||
}
|
||||
}
|
||||
|
||||
private val default by lazy { invoke() }
|
||||
private val default by lazy { invoke(context = ioContext) }
|
||||
|
||||
override fun readPartial(input: Input): PartialEnvelope =
|
||||
default.run { readPartial(input) }
|
||||
|
@ -197,7 +197,7 @@ public class TaglessEnvelopeFormat(
|
||||
return TaglessEnvelopeFormat(context.io, meta)
|
||||
}
|
||||
|
||||
private val default by lazy { invoke() }
|
||||
private val default by lazy { invoke(context = ioContext) }
|
||||
|
||||
override fun readPartial(input: Input): PartialEnvelope =
|
||||
default.run { readPartial(input) }
|
||||
|
@ -193,6 +193,7 @@ public abstract interface class space/kscience/dataforge/meta/Meta : space/kscie
|
||||
public final class space/kscience/dataforge/meta/Meta$Companion {
|
||||
public static final field TYPE Ljava/lang/String;
|
||||
public static final field VALUE_KEY Ljava/lang/String;
|
||||
public final fun equals (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/meta/Meta;)Z
|
||||
public final fun getEMPTY ()Lspace/kscience/dataforge/meta/Meta;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,8 @@ public interface Meta : MetaRepr, ItemProvider {
|
||||
*/
|
||||
public const val VALUE_KEY: String = "@value"
|
||||
|
||||
public fun equals(meta1: Meta, meta2: Meta): Boolean = meta1.items == meta2.items
|
||||
|
||||
public val EMPTY: Meta = object : MetaBase() {
|
||||
override val items: Map<NameToken, MetaItem> = emptyMap()
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public operator fun <M : TypedMeta<M>> M.get(key: NameToken): TypedMetaItem<M>?
|
||||
public abstract class MetaBase : Meta {
|
||||
|
||||
override fun equals(other: Any?): Boolean = if (other is Meta) {
|
||||
this.items == other.items
|
||||
Meta.equals(this, other)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import space.kscience.dataforge.context.Global
|
||||
import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.int
|
||||
import space.kscience.dataforge.workspace.WorkspaceBuilder
|
||||
|
||||
import space.kscience.dataforge.workspace.target
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
@ -12,13 +11,13 @@ import kotlin.test.assertEquals
|
||||
|
||||
class BuildersKtTest {
|
||||
@Test
|
||||
fun checkBuilder(){
|
||||
fun checkBuilder() {
|
||||
val workspace = WorkspaceBuilder(Global).apply {
|
||||
println("I am working")
|
||||
|
||||
context("test")
|
||||
context { name("test") }
|
||||
|
||||
target("testTarget"){
|
||||
target("testTarget") {
|
||||
"a" put 12
|
||||
}
|
||||
}
|
||||
@ -29,7 +28,7 @@ class BuildersKtTest {
|
||||
val script = """
|
||||
println("I am working")
|
||||
|
||||
context("test")
|
||||
context{ name("test") }
|
||||
|
||||
target("testTarget"){
|
||||
"a" put 12
|
||||
|
@ -50,8 +50,8 @@ public class WorkspaceBuilder(private val parentContext: Context = Global) : Tas
|
||||
/**
|
||||
* Define a context for the workspace
|
||||
*/
|
||||
public fun context(name: String = "workspace", block: ContextBuilder.() -> Unit = {}) {
|
||||
this.context = ContextBuilder(parentContext, name).apply(block).build()
|
||||
public fun context(block: ContextBuilder.() -> Unit = {}) {
|
||||
this.context = parentContext.buildContext(block)
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user