Merge pull request #64 from mipt-npm/dev

0.4.0
This commit is contained in:
Alexander Nozik 2021-04-27 11:23:43 +03:00 committed by GitHub
commit 32b986fc47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 952 additions and 576 deletions

33
.github/workflows/pages.yml vendored Normal file
View File

@ -0,0 +1,33 @@
name: Dokka publication
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Cache gradle
uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ubuntu-20.04-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
ubuntu-20.04-gradle-
- name: Build
run: |
./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
mv build/dokka/htmlMultiModule/-modules.html build/dokka/htmlMultiModule/index.html
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@4.1.0
with:
branch: gh-pages
folder: build/dokka/htmlMultiModule

View File

@ -2,20 +2,41 @@
## [Unreleased]
### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security
## [0.4.0]
### Added
- LogManager plugin
- dataforge-context API dependency on SLF4j
- Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation.
- Split `ItemDescriptor` into builder and read-only part
### 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)
- Kotlin 1.5
- Added blank builders for children context.
- Refactor loggers
### Deprecated
- Direct use of PluginManager
### Removed
- Common dependency on Kotlin-logging
- Kotlinx-io fork dependency. Replaced by Ktor-io.
### Fixed
- Scheme properties properly handle children property change.
### Security

View File

@ -4,21 +4,21 @@ plugins {
allprojects {
group = "space.kscience"
version = "0.4.0-dev-2"
version = "0.4.0"
}
subprojects {
apply(plugin = "maven-publish")
repositories {
maven("https://dl.bintray.com/mipt-npm/kscience")
maven("https://dl.bintray.com/mipt-npm/dev")
}
}
readme {
readmeTemplate = file("docs/templates/README-TEMPLATE.md")
}
changelog{
version = project.version.toString()
}
ksciencePublish {
github("dataforge-core")
space("https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven")
@ -26,5 +26,8 @@ ksciencePublish {
}
apiValidation {
if(project.version.toString().contains("dev")) {
validationDisabled = true
}
nonPublicMarkers.add("space.kscience.dataforge.misc.DFExperimental")
}

View File

@ -3,17 +3,12 @@ public abstract class space/kscience/dataforge/context/AbstractPlugin : space/ks
public fun <init> (Lspace/kscience/dataforge/meta/Meta;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun attach (Lspace/kscience/dataforge/context/Context;)V
public fun content (Ljava/lang/String;)Ljava/util/Map;
public final fun dependsOn ()Ljava/util/Map;
public fun detach ()V
public fun getContext ()Lspace/kscience/dataforge/context/Context;
public fun getDefaultChainTarget ()Ljava/lang/String;
public fun getDefaultTarget ()Ljava/lang/String;
public fun getMeta ()Lspace/kscience/dataforge/meta/Meta;
public fun getName ()Lspace/kscience/dataforge/names/Name;
protected final fun require (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)Lkotlin/properties/ReadOnlyProperty;
public static synthetic fun require$default (Lspace/kscience/dataforge/context/AbstractPlugin;Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty;
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
}
public final class space/kscience/dataforge/context/AbstractPluginKt {
@ -38,15 +33,17 @@ 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 (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
public static synthetic fun buildContext$default (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)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;
public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext;
public fun getDefaultChainTarget ()Ljava/lang/String;
public fun getDefaultTarget ()Ljava/lang/String;
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,51 +55,62 @@ 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/Plugin;)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 static final fun withEnv (Lspace/kscience/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
}
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 getDefaultLogger ()Lspace/kscience/dataforge/context/Logger;
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
public fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger;
}
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 {
public abstract fun invoke (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;)Ljava/lang/Object;
}
public final class space/kscience/dataforge/context/Factory$DefaultImpls {
public static synthetic fun invoke$default (Lspace/kscience/dataforge/context/Factory;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;ILjava/lang/Object;)Ljava/lang/Object;
}
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 class space/kscience/dataforge/context/GlobalKt {
public static final fun Context (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
public static synthetic fun Context$default (Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context;
public static final fun getGlobal ()Lspace/kscience/dataforge/context/Context;
}
public abstract interface class space/kscience/dataforge/context/LogManager : space/kscience/dataforge/context/Logable, space/kscience/dataforge/context/Plugin {
public abstract interface class space/kscience/dataforge/context/LogManager : space/kscience/dataforge/context/Logger, space/kscience/dataforge/context/Plugin {
public static final field Companion Lspace/kscience/dataforge/context/LogManager$Companion;
public static final field DEBUG Ljava/lang/String;
public static final field ERROR Ljava/lang/String;
public static final field INFO Ljava/lang/String;
public static final field TRACE Ljava/lang/String;
public static final field WARNING Ljava/lang/String;
public abstract fun getDefaultLogger ()Lspace/kscience/dataforge/context/Logger;
public fun log (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
public fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
public abstract fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger;
}
public final class space/kscience/dataforge/context/LogManager$Companion {
@ -113,33 +121,19 @@ public final class space/kscience/dataforge/context/LogManager$Companion {
public static final field WARNING Ljava/lang/String;
}
public final class space/kscience/dataforge/context/LogManager$DefaultImpls {
public static fun content (Lspace/kscience/dataforge/context/LogManager;Ljava/lang/String;)Ljava/util/Map;
public static fun getDefaultChainTarget (Lspace/kscience/dataforge/context/LogManager;)Ljava/lang/String;
public static fun getDefaultTarget (Lspace/kscience/dataforge/context/LogManager;)Ljava/lang/String;
public static fun getName (Lspace/kscience/dataforge/context/LogManager;)Lspace/kscience/dataforge/names/Name;
public static fun toMeta (Lspace/kscience/dataforge/context/LogManager;)Lspace/kscience/dataforge/meta/Meta;
}
public final class space/kscience/dataforge/context/LogManagerKt {
public static final fun debug (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V
public static synthetic fun debug$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
public static final fun error (Lspace/kscience/dataforge/context/Logable;Ljava/lang/Throwable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V
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 debug (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
public static final fun error (Lspace/kscience/dataforge/context/Logger;Ljava/lang/Throwable;Lkotlin/jvm/functions/Function0;)V
public static final fun error (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)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/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
public static final fun trace (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V
public static synthetic fun trace$default (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
public static final fun warn (Lspace/kscience/dataforge/context/Logable;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)V
public static synthetic fun warn$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/ContextAware;)Lspace/kscience/dataforge/context/Logger;
public static final fun info (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
public static final fun trace (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
public static final fun warn (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
}
public abstract interface class space/kscience/dataforge/context/Logable {
public abstract fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
public abstract interface class space/kscience/dataforge/context/Logger {
public abstract fun log (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
}
public abstract interface class space/kscience/dataforge/context/Plugin : space/kscience/dataforge/context/ContextAware, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/misc/Named, space/kscience/dataforge/provider/Provider {
@ -149,23 +143,15 @@ public abstract interface class space/kscience/dataforge/context/Plugin : space/
public abstract fun dependsOn ()Ljava/util/Map;
public abstract fun detach ()V
public abstract fun getMeta ()Lspace/kscience/dataforge/meta/Meta;
public abstract fun getName ()Lspace/kscience/dataforge/names/Name;
public fun getName ()Lspace/kscience/dataforge/names/Name;
public abstract fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
public abstract fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
}
public final class space/kscience/dataforge/context/Plugin$Companion {
public static final field TARGET Ljava/lang/String;
}
public final class space/kscience/dataforge/context/Plugin$DefaultImpls {
public static fun content (Lspace/kscience/dataforge/context/Plugin;Ljava/lang/String;)Ljava/util/Map;
public static fun getDefaultChainTarget (Lspace/kscience/dataforge/context/Plugin;)Ljava/lang/String;
public static fun getDefaultTarget (Lspace/kscience/dataforge/context/Plugin;)Ljava/lang/String;
public static fun getName (Lspace/kscience/dataforge/context/Plugin;)Lspace/kscience/dataforge/names/Name;
public static fun toMeta (Lspace/kscience/dataforge/context/Plugin;)Lspace/kscience/dataforge/meta/Meta;
}
public abstract interface class space/kscience/dataforge/context/PluginFactory : space/kscience/dataforge/context/Factory {
public static final field Companion Lspace/kscience/dataforge/context/PluginFactory$Companion;
public static final field TYPE Ljava/lang/String;
@ -192,10 +178,6 @@ public final class space/kscience/dataforge/context/PluginManager : java/lang/It
public fun getContext ()Lspace/kscience/dataforge/context/Context;
public fun iterator ()Ljava/util/Iterator;
public final fun list (Z)Ljava/util/Collection;
public final fun load (Lspace/kscience/dataforge/context/Plugin;)Lspace/kscience/dataforge/context/Plugin;
public final fun load (Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Plugin;
public final fun load (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/context/Plugin;
public static synthetic fun load$default (Lspace/kscience/dataforge/context/PluginManager;Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Plugin;
public final fun remove (Lspace/kscience/dataforge/context/Plugin;)V
}
@ -234,8 +216,9 @@ public final class space/kscience/dataforge/context/ResolveKt {
public final class space/kscience/dataforge/context/SlfLogManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/dataforge/context/LogManager {
public static final field Companion Lspace/kscience/dataforge/context/SlfLogManager$Companion;
public fun <init> ()V
public fun getDefaultLogger ()Lspace/kscience/dataforge/context/Logger;
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 fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger;
}
public final class space/kscience/dataforge/context/SlfLogManager$Companion : space/kscience/dataforge/context/PluginFactory {
@ -267,12 +250,10 @@ public abstract interface annotation class space/kscience/dataforge/descriptors/
public abstract fun type ()[Lspace/kscience/dataforge/values/ValueType;
}
public final class space/kscience/dataforge/properties/Property$DefaultImpls {
public static synthetic fun onChange$default (Lspace/kscience/dataforge/properties/Property;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static synthetic fun removeChangeListener$default (Lspace/kscience/dataforge/properties/Property;Ljava/lang/Object;ILjava/lang/Object;)V
public final class space/kscience/dataforge/properties/PropertyKt {
}
public final class space/kscience/dataforge/properties/PropertyKt {
public final class space/kscience/dataforge/properties/SchemePropertyKt {
}
public final class space/kscience/dataforge/provider/DfTypeKt {
@ -334,15 +315,9 @@ public final class space/kscience/dataforge/provider/PathToken$Companion {
}
public abstract interface class space/kscience/dataforge/provider/Provider {
public abstract fun content (Ljava/lang/String;)Ljava/util/Map;
public abstract fun getDefaultChainTarget ()Ljava/lang/String;
public abstract fun getDefaultTarget ()Ljava/lang/String;
}
public final class space/kscience/dataforge/provider/Provider$DefaultImpls {
public static fun content (Lspace/kscience/dataforge/provider/Provider;Ljava/lang/String;)Ljava/util/Map;
public static fun getDefaultChainTarget (Lspace/kscience/dataforge/provider/Provider;)Ljava/lang/String;
public static fun getDefaultTarget (Lspace/kscience/dataforge/provider/Provider;)Ljava/lang/String;
public fun content (Ljava/lang/String;)Ljava/util/Map;
public fun getDefaultChainTarget ()Ljava/lang/String;
public fun getDefaultTarget ()Ljava/lang/String;
}
public final class space/kscience/dataforge/provider/ProviderKt {

View File

@ -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,27 @@ 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(name: String? = null, block: ContextBuilder.() -> Unit = {}): Context {
val newContext = ContextBuilder(this)
.apply { name?.let { name(it) } }
.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 +106,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
*

View File

@ -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)
}
@ -40,11 +55,38 @@ public class ContextBuilder(private val parent: Context = Global, public var nam
plugin(PluginTag(name, group, version), action)
}
/**
* Add de-facto existing plugin as a dependency
*/
public fun plugin(plugin: Plugin) {
plugin(DeFactoPluginFactory(plugin))
}
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) ->
@Suppress("DEPRECATION")
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
}

View File

@ -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,11 @@ 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(name: String? = null, block: ContextBuilder.() -> Unit = {}): Context =
Global.buildContext(name, block)

View File

@ -1,14 +1,23 @@
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 log(name: Name, tag: String, body: () -> String)
public fun interface Logger {
public fun log(tag: String, body: () -> String)
}
public interface LogManager : Plugin, Logable {
public interface LogManager : Plugin, Logger {
public fun logger(name: Name): Logger
public val defaultLogger: Logger
override fun log(tag: String, body: () -> String): Unit = defaultLogger.log(tag, body)
public fun log(name: Name, tag: String, body: () -> String): Unit = logger(name).log(tag, body)
public companion object {
public const val TRACE: String = "TRACE"
@ -19,11 +28,11 @@ public interface LogManager : Plugin, Logable {
}
}
public fun Logable.trace(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.TRACE, body)
public fun Logable.info(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.INFO, body)
public fun Logable.debug(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.DEBUG, body)
public fun Logable.warn(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.WARNING, body)
public fun Logable.error(name: Name = Name.EMPTY, body: () -> String): Unit = log(name, LogManager.ERROR, body)
public fun Logger.trace(body: () -> String): Unit = log(LogManager.TRACE, body)
public fun Logger.info(body: () -> String): Unit = log(LogManager.INFO, body)
public fun Logger.debug(body: () -> String): Unit = log(LogManager.DEBUG, body)
public fun Logger.warn(body: () -> String): Unit = log(LogManager.WARNING, body)
public fun Logger.error(body: () -> String): Unit = log(LogManager.ERROR, body)
internal val (() -> String).safe: String
get() = try {
@ -33,30 +42,48 @@ internal val (() -> String).safe: String
}
public fun Logable.error(throwable: Throwable?, name: Name = Name.EMPTY, body: () -> String): Unit =
log(name, LogManager.ERROR) {
buildString {
appendLine(body())
throwable?.let { appendLine(throwable.stackTraceToString()) }
}
public fun Logger.error(throwable: Throwable?, body: () -> String): Unit = log(LogManager.ERROR) {
buildString {
appendLine(body())
throwable?.let { appendLine(throwable.stackTraceToString()) }
}
}
public class DefaultLogManager : AbstractPlugin(), LogManager {
override fun logger(name: Name): Logger = Logger { tag, body ->
val message: String = body.safe
println("$tag $name: [${context.name}] $message")
}
override val defaultLogger: Logger = logger(Name.EMPTY)
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
get() = plugins.find(inherit = true) { it is LogManager } as? LogManager
?: globalLoggerFactory(context = Global).apply { attach(Global) }
/**
* The named proxy logger for a context member
*/
public val ContextAware.logger: Logable
public val ContextAware.logger: Logger
get() = if (this is Named) {
object : Logable {
val contextLog = context.logger
override fun log(name: Name, tag: String, body: () -> String) {
contextLog.log(this@logger.name + name, tag, body)
}
Logger { tag, body ->
context.logger.log(this@logger.name + name, tag, body)
}
} else {
context.logger

View File

@ -63,5 +63,4 @@ public interface Plugin : Named, ContextAware, Provider, MetaRepr {
public companion object {
public const val TARGET: String = "plugin"
}
}

View File

@ -1,5 +1,6 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.Type
import kotlin.reflect.KClass
@ -12,3 +13,12 @@ public interface PluginFactory<T : Plugin> : Factory<T> {
public const val TYPE: String = "pluginFactory"
}
}
/**
* Plugin factory created for the specific actual plugin
*/
internal class DeFactoPluginFactory<T : Plugin>(val plugin: T) : PluginFactory<T> {
override fun invoke(meta: Meta, context: Context): T = plugin
override val tag: PluginTag get() = plugin.tag
override val type: KClass<out T> get() = plugin::class
}

View File

@ -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,7 +83,8 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab
* @param plugin
* @return
*/
public fun <T : Plugin> load(plugin: T): T {
@Deprecated("Use immutable contexts instead")
private 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}")
} else {
@ -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,14 @@ public class PluginManager(override val context: Context) : ContextAware, Iterab
/**
* Load a plugin using its factory
*/
public fun <T : Plugin> load(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T =
@Deprecated("Use immutable contexts instead")
internal fun <T : Plugin> load(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T =
load(factory(meta, context))
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 +121,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 +131,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 +140,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]!!
}
}

View File

@ -8,6 +8,7 @@ import space.kscience.dataforge.meta.transformations.nullableItemToObject
import space.kscience.dataforge.meta.transformations.nullableObjectToMetaItem
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.startsWith
@DFExperimental
public class ConfigProperty<T : Any>(
@ -24,7 +25,7 @@ public class ConfigProperty<T : Any>(
override fun onChange(owner: Any?, callback: (T?) -> Unit) {
config.onChange(owner) { name, oldItem, newItem ->
if (name == this.name && oldItem != newItem) callback(converter.nullableItemToObject(newItem))
if (name.startsWith(this.name) && oldItem != newItem) callback(converter.nullableItemToObject(newItem))
}
}

View File

@ -1,6 +1,5 @@
package space.kscience.dataforge.properties
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@ -23,12 +22,12 @@ public fun <T> Property<T>.toFlow(): StateFlow<T> = MutableStateFlow(value).also
}
/**
* Reflect all changes in the [source] property onto this property
* Reflect all changes in the [source] property onto this property. Does not reflect changes back.
*
* @return a mirroring job
*/
@DFExperimental
public fun <T> Property<T>.mirror(source: Property<T>, scope: CoroutineScope) {
public fun <T> Property<T>.mirror(source: Property<T>) {
source.onChange(this) {
this.value = it
}

View File

@ -0,0 +1,30 @@
package space.kscience.dataforge.properties
import space.kscience.dataforge.meta.ItemPropertyProvider
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.startsWith
import space.kscience.dataforge.names.toName
import kotlin.reflect.KMutableProperty1
@DFExperimental
public fun <P : ItemPropertyProvider, T : Any> P.property(property: KMutableProperty1<P, T?>): Property<T?> =
object : Property<T?> {
override var value: T?
get() = property.get(this@property)
set(value) {
property.set(this@property, value)
}
override fun onChange(owner: Any?, callback: (T?) -> Unit) {
this@property.onChange(this) { name, oldItem, newItem ->
if (name.startsWith(property.name.toName()) && oldItem != newItem) {
callback(property.get(this@property))
}
}
}
override fun removeChangeListener(owner: Any?) {
this@property.removeListener(this@property)
}
}

View File

@ -17,12 +17,14 @@ package space.kscience.dataforge.provider
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.toName
import kotlin.jvm.JvmInline
/**
* Path interface.
*
*/
public inline class Path(public val tokens: List<PathToken>) : Iterable<PathToken> {
@JvmInline
public value class Path(public val tokens: List<PathToken>) : Iterable<PathToken> {
override fun iterator(): Iterator<PathToken> = tokens.iterator()

View File

@ -22,9 +22,10 @@ class ContextTest {
@Test
fun testPluginManager() {
val context = Global.context("test")
context.plugins.load(DummyPlugin())
//Global.plugins.load(DummyPlugin())
val context = Global.buildContext{
name("test")
plugin(DummyPlugin())
}
val members = context.gather<Name>("test")
assertEquals(3, members.count())
members.forEach {

View File

@ -0,0 +1,28 @@
package space.kscience.dataforge.properties
import space.kscience.dataforge.meta.Scheme
import space.kscience.dataforge.meta.SchemeSpec
import space.kscience.dataforge.meta.int
import space.kscience.dataforge.misc.DFExperimental
import kotlin.test.Test
import kotlin.test.assertEquals
internal class TestScheme : Scheme() {
var a by int()
var b by int()
companion object : SchemeSpec<TestScheme>(::TestScheme)
}
@DFExperimental
class ItemPropertiesTest {
@Test
fun testBinding() {
val scheme = TestScheme.empty()
val a = scheme.property(TestScheme::a)
val b = scheme.property(TestScheme::b)
a.bind(b)
scheme.a = 2
assertEquals(2, scheme.b)
assertEquals(2, b.value)
}
}

View File

@ -6,7 +6,7 @@ import kotlin.reflect.KClass
public class ConsoleLogManager : AbstractPlugin(), LogManager {
override fun log(name: Name, tag: String, body: () -> String) {
override fun logger(name: Name): Logger = Logger { tag, body ->
val message: String = body.safe
when (tag) {
LogManager.INFO -> console.info("[${context.name}] $name: $message")
@ -16,6 +16,9 @@ public class ConsoleLogManager : AbstractPlugin(), LogManager {
}
}
override val defaultLogger: Logger = logger(Name.EMPTY)
override val tag: PluginTag get() = Companion.tag
public companion object : PluginFactory<ConsoleLogManager> {

View File

@ -7,7 +7,7 @@ import kotlin.reflect.KClass
public class SlfLogManager : AbstractPlugin(), LogManager {
override fun log(name: Name, tag: String, body: () -> String) {
override fun logger(name: Name): Logger = Logger { tag, body ->
val logger = LoggerFactory.getLogger("[${context.name}] $name") //KotlinLogging.logger("[${context.name}] $name")
val message = body.safe
when (tag) {
@ -19,6 +19,8 @@ public class SlfLogManager : AbstractPlugin(), LogManager {
}
}
override val defaultLogger: Logger = logger(Name.EMPTY)
override val tag: PluginTag get() = Companion.tag
public companion object : PluginFactory<SlfLogManager> {

View File

@ -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

View File

@ -48,9 +48,9 @@ public val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.mo
public val Job.dependencies: Collection<Job> get() = this[Dependencies]?.values ?: emptyList()
@DFExperimental
public val Job.totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0)
public val Job.totalWork: Double get() = dependencies.sumOf { totalWork } + (monitor?.totalWork ?: 0.0)
@DFExperimental
public val Job.workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0)
public val Job.workDone: Double get() = dependencies.sumOf { workDone } + (monitor?.workDone ?: 0.0)
@DFExperimental
public val Job.status: String get() = monitor?.status ?: ""
@DFExperimental

View File

@ -28,12 +28,11 @@ public interface DataSet<out T : Any> {
public suspend fun getData(name: Name): Data<T>?
/**
* Get a snapshot of names of children of given node. Empty if node does not exist or is a leaf.
*
* By default traverses the whole tree. Could be optimized in descendants
* Get a snapshot of names of top level children of given node. Empty if node does not exist or is a leaf.
*/
public suspend fun listChildren(prefix: Name = Name.EMPTY): List<Name> =
public suspend fun listTop(prefix: Name = Name.EMPTY): List<Name> =
flow().map { it.name }.filter { it.startsWith(prefix) && (it.length == prefix.length + 1) }.toList()
// By default traverses the whole tree. Could be optimized in descendants
public companion object {
public val META_KEY: Name = "@meta".asName()

View File

@ -43,7 +43,7 @@ public interface DataTree<out T : Any> : DataSet<T> {
}
}
override suspend fun listChildren(prefix: Name): List<Name> =
override suspend fun listTop(prefix: Name): List<Name> =
getItem(prefix).tree?.items()?.keys?.map { prefix + it } ?: emptyList()
override suspend fun getData(name: Name): Data<T>? = when (name.length) {

View File

@ -20,7 +20,7 @@ public object BinaryMetaFormat : MetaFormat, MetaFormatFactory {
return (input.readMetaItem() as MetaItemNode).node
}
private fun Output.writeChar(char: Char) = writeByte(char.toByte())
private fun Output.writeChar(char: Char) = writeByte(char.code.toByte())
private fun Output.writeString(str: String) {
writeInt(str.length)
@ -101,7 +101,7 @@ public object BinaryMetaFormat : MetaFormat, MetaFormatFactory {
@Suppress("UNCHECKED_CAST")
public fun Input.readMetaItem(): TypedMetaItem<MetaBuilder> {
return when (val keyChar = readByte().toChar()) {
return when (val keyChar = readByte().toInt().toChar()) {
'S' -> MetaItemValue(StringValue(readString()))
'N' -> MetaItemValue(Null)
'+' -> MetaItemValue(True)

View File

@ -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)

View File

@ -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) }

View File

@ -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) }

View File

@ -9,10 +9,9 @@ public abstract class space/kscience/dataforge/meta/AbstractMutableMeta : space/
public abstract class space/kscience/dataforge/meta/AbstractTypedMeta : space/kscience/dataforge/meta/MetaBase, space/kscience/dataforge/meta/TypedMeta {
public fun <init> ()V
public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
}
public final class space/kscience/dataforge/meta/Config : space/kscience/dataforge/meta/AbstractMutableMeta, space/kscience/dataforge/meta/ObservableItemProvider {
public final class space/kscience/dataforge/meta/Config : space/kscience/dataforge/meta/AbstractMutableMeta, space/kscience/dataforge/meta/ItemPropertyProvider {
public static final field ConfigSerializer Lspace/kscience/dataforge/meta/Config$ConfigSerializer;
public fun <init> ()V
public synthetic fun empty$dataforge_meta ()Lspace/kscience/dataforge/meta/MutableMeta;
@ -33,6 +32,8 @@ public final class space/kscience/dataforge/meta/Config$ConfigSerializer : kotli
public final class space/kscience/dataforge/meta/ConfigKt {
public static final fun asConfig (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Config;
public static final fun copy (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/Config;
public static synthetic fun copy$default (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Config;
public static final fun get (Lspace/kscience/dataforge/meta/Config;Lspace/kscience/dataforge/names/NameToken;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public static final fun toConfig (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Config;
}
@ -94,18 +95,7 @@ public final class space/kscience/dataforge/meta/ItemDelegateKt {
public static synthetic fun value$default (Lspace/kscience/dataforge/meta/ItemProvider;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty;
}
public final class space/kscience/dataforge/meta/ItemListener {
public fun <init> (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V
public synthetic fun <init> (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/Object;
public final fun component2 ()Lkotlin/jvm/functions/Function3;
public final fun copy (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Lspace/kscience/dataforge/meta/ItemListener;
public static synthetic fun copy$default (Lspace/kscience/dataforge/meta/ItemListener;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/ItemListener;
public fun equals (Ljava/lang/Object;)Z
public final fun getAction ()Lkotlin/jvm/functions/Function3;
public final fun getOwner ()Ljava/lang/Object;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
public abstract interface class space/kscience/dataforge/meta/ItemPropertyProvider : space/kscience/dataforge/meta/MutableItemProvider, space/kscience/dataforge/meta/ObservableItemProvider {
}
public abstract interface class space/kscience/dataforge/meta/ItemProvider {
@ -183,30 +173,24 @@ public abstract interface class space/kscience/dataforge/meta/Meta : space/kscie
public static final field TYPE Ljava/lang/String;
public static final field VALUE_KEY Ljava/lang/String;
public abstract fun equals (Ljava/lang/Object;)Z
public abstract fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public abstract fun getItems ()Ljava/util/Map;
public abstract fun hashCode ()I
public abstract fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
public abstract fun toString ()Ljava/lang/String;
}
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;
}
public final class space/kscience/dataforge/meta/Meta$DefaultImpls {
public static fun getItem (Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public static fun toMeta (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Meta;
}
public abstract class space/kscience/dataforge/meta/MetaBase : space/kscience/dataforge/meta/Meta {
public fun <init> ()V
public fun equals (Ljava/lang/Object;)Z
public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public fun hashCode ()I
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
public fun toString ()Ljava/lang/String;
}
@ -408,11 +392,6 @@ public abstract interface class space/kscience/dataforge/meta/MutableMeta : spac
public abstract fun getItems ()Ljava/util/Map;
}
public final class space/kscience/dataforge/meta/MutableMeta$DefaultImpls {
public static fun getItem (Lspace/kscience/dataforge/meta/MutableMeta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public static fun toMeta (Lspace/kscience/dataforge/meta/MutableMeta;)Lspace/kscience/dataforge/meta/Meta;
}
public final class space/kscience/dataforge/meta/MutableMetaKt {
public static final fun append (Lspace/kscience/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/Object;)V
public static final fun append (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/names/Name;Ljava/lang/Object;)V
@ -423,22 +402,24 @@ public abstract interface class space/kscience/dataforge/meta/ObservableItemProv
public abstract fun removeListener (Ljava/lang/Object;)V
}
public final class space/kscience/dataforge/meta/ObservableItemProviderKt {
public static synthetic fun useProperty$default (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
}
public abstract interface class space/kscience/dataforge/meta/ReadOnlySpecification {
public abstract fun empty ()Lspace/kscience/dataforge/meta/ItemProvider;
public abstract fun invoke (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider;
public fun invoke (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider;
public abstract fun read (Lspace/kscience/dataforge/meta/ItemProvider;)Lspace/kscience/dataforge/meta/ItemProvider;
}
public final class space/kscience/dataforge/meta/ReadOnlySpecification$DefaultImpls {
public static fun invoke (Lspace/kscience/dataforge/meta/ReadOnlySpecification;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider;
}
public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/MutableItemProvider, space/kscience/dataforge/meta/descriptors/Described {
public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/ItemPropertyProvider, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/descriptors/Described {
public fun <init> ()V
public fun getDefaultLayer ()Lspace/kscience/dataforge/meta/Meta;
public synthetic fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public final fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V
public fun removeListener (Ljava/lang/Object;)V
public final fun setDescriptor (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)V
public fun setItem (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;)V
public fun toMeta ()Lspace/kscience/dataforge/meta/Laminate;
@ -479,10 +460,6 @@ public final class space/kscience/dataforge/meta/SealedMetaKt {
public abstract interface class space/kscience/dataforge/meta/Specification : space/kscience/dataforge/meta/ReadOnlySpecification {
public abstract fun write (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;)Lspace/kscience/dataforge/meta/MutableItemProvider;
}
public final class space/kscience/dataforge/meta/Specification$DefaultImpls {
public static fun invoke (Lspace/kscience/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/MutableItemProvider;
public static synthetic fun write$default (Lspace/kscience/dataforge/meta/Specification;Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/MutableItemProvider;
}
@ -495,15 +472,10 @@ public final class space/kscience/dataforge/meta/SpecificationKt {
}
public abstract interface class space/kscience/dataforge/meta/TypedMeta : space/kscience/dataforge/meta/Meta {
public abstract fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public abstract fun getItems ()Ljava/util/Map;
}
public final class space/kscience/dataforge/meta/TypedMeta$DefaultImpls {
public static fun getItem (Lspace/kscience/dataforge/meta/TypedMeta;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public static fun toMeta (Lspace/kscience/dataforge/meta/TypedMeta;)Lspace/kscience/dataforge/meta/Meta;
}
public abstract class space/kscience/dataforge/meta/TypedMetaItem {
public static final field Companion Lspace/kscience/dataforge/meta/TypedMetaItem$Companion;
public abstract fun equals (Ljava/lang/Object;)Z
@ -534,78 +506,117 @@ public final class space/kscience/dataforge/meta/descriptors/DescriptorMetaKt {
public static final fun defaultMeta (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)Lspace/kscience/dataforge/meta/Laminate;
}
public abstract class space/kscience/dataforge/meta/descriptors/ItemDescriptor : space/kscience/dataforge/meta/Configurable {
public abstract interface class space/kscience/dataforge/meta/descriptors/ItemDescriptor : space/kscience/dataforge/meta/MetaRepr {
public static final field Companion Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor$Companion;
public static final field DEFAULT_INDEX_KEY Ljava/lang/String;
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public abstract fun copy ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public final fun getAttributes ()Lspace/kscience/dataforge/meta/Config;
public final fun getConfig ()Lspace/kscience/dataforge/meta/Config;
public final fun getIndexKey ()Ljava/lang/String;
public final fun getInfo ()Ljava/lang/String;
public final fun getMultiple ()Z
public abstract fun getAttributes ()Lspace/kscience/dataforge/meta/Meta;
public abstract fun getIndexKey ()Ljava/lang/String;
public abstract fun getInfo ()Ljava/lang/String;
public abstract fun getMultiple ()Z
public abstract fun getRequired ()Z
public final fun setAttributes (Lspace/kscience/dataforge/meta/Config;)V
public final fun setIndexKey (Ljava/lang/String;)V
public final fun setInfo (Ljava/lang/String;)V
public final fun setMultiple (Z)V
public abstract fun setRequired (Z)V
}
public final class space/kscience/dataforge/meta/descriptors/ItemDescriptor$Companion {
public static final field DEFAULT_INDEX_KEY Ljava/lang/String;
}
public abstract class space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder : space/kscience/dataforge/meta/Configurable, space/kscience/dataforge/meta/descriptors/ItemDescriptor {
public static final field Companion Lspace/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder$Companion;
public static final field DEFAULT_INDEX_KEY Ljava/lang/String;
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public abstract fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public fun getAttributes ()Lspace/kscience/dataforge/meta/Config;
public synthetic fun getAttributes ()Lspace/kscience/dataforge/meta/Meta;
public final fun getConfig ()Lspace/kscience/dataforge/meta/Config;
public fun getIndexKey ()Ljava/lang/String;
public fun getInfo ()Ljava/lang/String;
public fun getMultiple ()Z
public abstract fun getRequired ()Z
public fun setAttributes (Lspace/kscience/dataforge/meta/Config;)V
public fun setIndexKey (Ljava/lang/String;)V
public fun setInfo (Ljava/lang/String;)V
public fun setMultiple (Z)V
public abstract fun setRequired (Z)V
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
}
public final class space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder$Companion {
}
public final class space/kscience/dataforge/meta/descriptors/ItemDescriptorKt {
public static final fun NodeDescriptor (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
public static final fun attributes (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;Lkotlin/jvm/functions/Function1;)V
public static final fun attributes (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder;Lkotlin/jvm/functions/Function1;)V
public static final fun get (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;Ljava/lang/String;)Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public static final fun get (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public static final fun plus (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
public static final fun validateItem (Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;Lspace/kscience/dataforge/meta/TypedMetaItem;)Z
}
public final class space/kscience/dataforge/meta/descriptors/NodeDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor {
public abstract interface class space/kscience/dataforge/meta/descriptors/NodeDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor {
public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor$Companion;
public fun <init> ()V
public fun <init> (Lspace/kscience/dataforge/meta/Config;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun copy ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public fun copy ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
public final fun getDefault ()Lspace/kscience/dataforge/meta/Config;
public final fun getItems ()Ljava/util/Map;
public final fun getNodes ()Ljava/util/Map;
public fun getRequired ()Z
public final fun getValues ()Ljava/util/Map;
public final fun item (Ljava/lang/String;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V
public final fun item (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V
public final fun node (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun node (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V
public final fun setDefault (Lspace/kscience/dataforge/meta/Config;)V
public fun setRequired (Z)V
public final fun value (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun value (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V
public abstract fun getDefault ()Lspace/kscience/dataforge/meta/Config;
public abstract fun getItems ()Ljava/util/Map;
public abstract fun getNodes ()Ljava/util/Map;
public abstract fun getRequired ()Z
public abstract fun getValues ()Ljava/util/Map;
}
public final class space/kscience/dataforge/meta/descriptors/NodeDescriptor$Companion {
}
public final class space/kscience/dataforge/meta/descriptors/ValueDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor {
public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder : space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder, space/kscience/dataforge/meta/descriptors/NodeDescriptor {
public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder$Companion;
public fun <init> ()V
public fun <init> (Lspace/kscience/dataforge/meta/Config;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public fun build ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
public fun getDefault ()Lspace/kscience/dataforge/meta/Config;
public fun getItems ()Ljava/util/Map;
public fun getNodes ()Ljava/util/Map;
public fun getRequired ()Z
public fun getValues ()Ljava/util/Map;
public final fun item (Ljava/lang/String;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V
public final fun item (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V
public final fun node (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun node (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V
public fun setDefault (Lspace/kscience/dataforge/meta/Config;)V
public fun setRequired (Z)V
public final fun value (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun value (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V
}
public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder$Companion {
}
public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorKt {
public static final fun NodeDescriptor (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
public static final fun plus (Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
}
public abstract interface class space/kscience/dataforge/meta/descriptors/ValueDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor {
public abstract fun getAllowedValues ()Ljava/util/List;
public abstract fun getDefault ()Lspace/kscience/dataforge/values/Value;
public abstract fun getRequired ()Z
public abstract fun getType ()Ljava/util/List;
public fun isAllowedValue (Lspace/kscience/dataforge/values/Value;)Z
}
public final class space/kscience/dataforge/meta/descriptors/ValueDescriptorBuilder : space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder, space/kscience/dataforge/meta/descriptors/ValueDescriptor {
public fun <init> ()V
public fun <init> (Lspace/kscience/dataforge/meta/Config;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun allow ([Ljava/lang/Object;)V
public synthetic fun copy ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public fun copy ()Lspace/kscience/dataforge/meta/descriptors/ValueDescriptor;
public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public fun build ()Lspace/kscience/dataforge/meta/descriptors/ValueDescriptor;
public final fun default (Ljava/lang/Object;)V
public final fun getAllowedValues ()Ljava/util/List;
public final fun getDefault ()Lspace/kscience/dataforge/values/Value;
public fun getAllowedValues ()Ljava/util/List;
public fun getDefault ()Lspace/kscience/dataforge/values/Value;
public fun getRequired ()Z
public final fun getType ()Ljava/util/List;
public final fun isAllowedValue (Lspace/kscience/dataforge/values/Value;)Z
public final fun setAllowedValues (Ljava/util/List;)V
public final fun setDefault (Lspace/kscience/dataforge/values/Value;)V
public fun getType ()Ljava/util/List;
public fun isAllowedValue (Lspace/kscience/dataforge/values/Value;)Z
public fun setAllowedValues (Ljava/util/List;)V
public fun setDefault (Lspace/kscience/dataforge/values/Value;)V
public fun setRequired (Z)V
public final fun setType (Ljava/util/List;)V
public fun setType (Ljava/util/List;)V
public final fun type ([Lspace/kscience/dataforge/values/ValueType;)V
}
@ -661,7 +672,6 @@ public final class space/kscience/dataforge/meta/transformations/MetaTransformat
public static fun equals-impl (Ljava/util/Collection;Ljava/lang/Object;)Z
public static final fun equals-impl0 (Ljava/util/Collection;Ljava/util/Collection;)Z
public static final fun generate-impl (Ljava/util/Collection;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Meta;
public final fun getTransformations ()Ljava/util/Collection;
public fun hashCode ()I
public static fun hashCode-impl (Ljava/util/Collection;)I
public fun toString ()Ljava/lang/String;
@ -694,7 +704,6 @@ public final class space/kscience/dataforge/meta/transformations/RegexItemTransf
public final fun getTransform ()Lkotlin/jvm/functions/Function4;
public fun hashCode ()I
public fun matches (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;)Z
public fun selectItems (Lspace/kscience/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
public fun toString ()Ljava/lang/String;
public fun transformItem (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;Lspace/kscience/dataforge/meta/MutableMeta;)V
}
@ -717,14 +726,10 @@ public final class space/kscience/dataforge/meta/transformations/SingleItemTrans
public abstract interface class space/kscience/dataforge/meta/transformations/TransformationRule {
public abstract fun matches (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;)Z
public abstract fun selectItems (Lspace/kscience/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
public fun selectItems (Lspace/kscience/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
public abstract fun transformItem (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;Lspace/kscience/dataforge/meta/MutableMeta;)V
}
public final class space/kscience/dataforge/meta/transformations/TransformationRule$DefaultImpls {
public static fun selectItems (Lspace/kscience/dataforge/meta/transformations/TransformationRule;Lspace/kscience/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
}
public abstract interface annotation class space/kscience/dataforge/misc/DFBuilder : java/lang/annotation/Annotation {
}
@ -857,7 +862,6 @@ public final class space/kscience/dataforge/values/DoubleArrayValue : java/lang/
public final class space/kscience/dataforge/values/EnumValue : space/kscience/dataforge/values/Value {
public fun <init> (Ljava/lang/Enum;)V
public fun equals (Ljava/lang/Object;)Z
public fun getList ()Ljava/util/List;
public fun getType ()Lspace/kscience/dataforge/values/ValueType;
public fun getValue ()Ljava/lang/Enum;
public synthetic fun getValue ()Ljava/lang/Object;
@ -873,7 +877,6 @@ public final class space/kscience/dataforge/values/ExoticValuesKt {
public final class space/kscience/dataforge/values/False : space/kscience/dataforge/values/Value {
public static final field INSTANCE Lspace/kscience/dataforge/values/False;
public fun equals (Ljava/lang/Object;)Z
public fun getList ()Ljava/util/List;
public fun getType ()Lspace/kscience/dataforge/values/ValueType;
public fun getValue ()Ljava/lang/Object;
public fun hashCode ()I
@ -883,7 +886,6 @@ public final class space/kscience/dataforge/values/False : space/kscience/datafo
public final class space/kscience/dataforge/values/LazyParsedValue : space/kscience/dataforge/values/Value {
public fun <init> (Ljava/lang/String;)V
public fun equals (Ljava/lang/Object;)Z
public fun getList ()Ljava/util/List;
public final fun getString ()Ljava/lang/String;
public fun getType ()Lspace/kscience/dataforge/values/ValueType;
public fun getValue ()Ljava/lang/Object;
@ -911,7 +913,6 @@ public final class space/kscience/dataforge/values/ListValue$Companion {
public final class space/kscience/dataforge/values/Null : space/kscience/dataforge/values/Value {
public static final field INSTANCE Lspace/kscience/dataforge/values/Null;
public fun equals (Ljava/lang/Object;)Z
public fun getList ()Ljava/util/List;
public fun getType ()Lspace/kscience/dataforge/values/ValueType;
public fun getValue ()Ljava/lang/Object;
public fun hashCode ()I
@ -921,7 +922,6 @@ public final class space/kscience/dataforge/values/Null : space/kscience/datafor
public final class space/kscience/dataforge/values/NumberValue : space/kscience/dataforge/values/Value {
public fun <init> (Ljava/lang/Number;)V
public fun equals (Ljava/lang/Object;)Z
public fun getList ()Ljava/util/List;
public final fun getNumber ()Ljava/lang/Number;
public fun getType ()Lspace/kscience/dataforge/values/ValueType;
public fun getValue ()Ljava/lang/Object;
@ -932,7 +932,6 @@ public final class space/kscience/dataforge/values/NumberValue : space/kscience/
public final class space/kscience/dataforge/values/StringValue : space/kscience/dataforge/values/Value {
public fun <init> (Ljava/lang/String;)V
public fun equals (Ljava/lang/Object;)Z
public fun getList ()Ljava/util/List;
public final fun getString ()Ljava/lang/String;
public fun getType ()Lspace/kscience/dataforge/values/ValueType;
public fun getValue ()Ljava/lang/Object;
@ -943,7 +942,6 @@ public final class space/kscience/dataforge/values/StringValue : space/kscience/
public final class space/kscience/dataforge/values/True : space/kscience/dataforge/values/Value {
public static final field INSTANCE Lspace/kscience/dataforge/values/True;
public fun equals (Ljava/lang/Object;)Z
public fun getList ()Ljava/util/List;
public fun getType ()Lspace/kscience/dataforge/values/ValueType;
public fun getValue ()Ljava/lang/Object;
public fun hashCode ()I
@ -954,7 +952,7 @@ public abstract interface class space/kscience/dataforge/values/Value {
public static final field Companion Lspace/kscience/dataforge/values/Value$Companion;
public static final field TYPE Ljava/lang/String;
public abstract fun equals (Ljava/lang/Object;)Z
public abstract fun getList ()Ljava/util/List;
public fun getList ()Ljava/util/List;
public abstract fun getType ()Lspace/kscience/dataforge/values/ValueType;
public abstract fun getValue ()Ljava/lang/Object;
public abstract fun hashCode ()I
@ -966,10 +964,6 @@ public final class space/kscience/dataforge/values/Value$Companion {
public final fun of (Ljava/lang/Object;)Lspace/kscience/dataforge/values/Value;
}
public final class space/kscience/dataforge/values/Value$DefaultImpls {
public static fun getList (Lspace/kscience/dataforge/values/Value;)Ljava/util/List;
}
public final class space/kscience/dataforge/values/ValueExtensionsKt {
public static final fun getBoolean (Lspace/kscience/dataforge/values/Value;)Z
public static final fun getDouble (Lspace/kscience/dataforge/values/Value;)D

View File

@ -14,21 +14,11 @@ import kotlin.jvm.Synchronized
//TODO add validator to configuration
public data class ItemListener(
val owner: Any? = null,
val action: (name: Name, oldItem: MetaItem?, newItem: MetaItem?) -> Unit
)
public interface ObservableItemProvider : ItemProvider {
public fun onChange(owner: Any?, action: (name: Name, oldItem: MetaItem?, newItem: MetaItem?) -> Unit)
public fun removeListener(owner: Any?)
}
/**
* Mutable meta representing object state
*/
@Serializable(Config.Companion::class)
public class Config() : AbstractMutableMeta<Config>(), ObservableItemProvider {
public class Config : AbstractMutableMeta<Config>(), ItemPropertyProvider {
private val listeners = HashSet<ItemListener>()
@ -108,6 +98,12 @@ public fun Meta.toConfig(): Config = Config().also { builder ->
}
}
/**
* Create a copy of this config, optionally applying the given [block].
* The listeners of the original Config are not retained.
*/
public inline fun Config.copy(block: Config.() -> Unit = {}): Config = toConfig().apply(block)
/**
* Return this [Meta] as [Config] if it is [Config] and create a new copy otherwise
*/

View File

@ -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()
}

View File

@ -0,0 +1,42 @@
package space.kscience.dataforge.meta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.startsWith
import space.kscience.dataforge.names.toName
import kotlin.reflect.KProperty1
internal data class ItemListener(
val owner: Any? = null,
val action: (name: Name, oldItem: MetaItem?, newItem: MetaItem?) -> Unit,
)
public interface ObservableItemProvider : ItemProvider {
public fun onChange(owner: Any?, action: (name: Name, oldItem: MetaItem?, newItem: MetaItem?) -> Unit)
public fun removeListener(owner: Any?)
}
public interface ItemPropertyProvider: ObservableItemProvider, MutableItemProvider
/**
* Use the value of the property in a [callBack].
* The callback is called once immediately after subscription to pass the initial value.
*
* Optional [owner] property is used for
*/
@DFExperimental
public fun <O : ObservableItemProvider, T> O.useProperty(
property: KProperty1<O, T>,
owner: Any? = null,
callBack: O.(T) -> Unit,
) {
//Pass initial value.
callBack(property.get(this))
onChange(owner) { name, oldItem, newItem ->
if (name.startsWith(property.name.toName()) && oldItem != newItem) {
callBack(property.get(this))
}
}
}

View File

@ -4,19 +4,42 @@ import space.kscience.dataforge.meta.descriptors.*
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.NameToken
import space.kscience.dataforge.names.asName
import kotlin.jvm.Synchronized
/**
* A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [Specification].
* Default item provider and [NodeDescriptor] are optional
*/
public open class Scheme() : MutableItemProvider, Described, MetaRepr {
public open class Scheme() : Described, MetaRepr, ItemPropertyProvider {
private var items: MutableItemProvider = Config()
private val listeners = HashSet<ItemListener>()
private var default: ItemProvider? = null
final override var descriptor: NodeDescriptor? = null
/**
* Add a listener to this scheme changes. If the inner provider is observable, then listening will be delegated to it.
* Otherwise, local listeners will be created.
*/
@Synchronized
override fun onChange(owner: Any?, action: (Name, MetaItem?, MetaItem?) -> Unit) {
(items as? ObservableItemProvider)?.onChange(owner, action)
?: run { listeners.add(ItemListener(owner, action)) }
}
/**
* Remove all listeners belonging to given owner
*/
@Synchronized
override fun removeListener(owner: Any?) {
(items as? ObservableItemProvider)?.removeListener(owner)
?: listeners.removeAll { it.owner === owner }
}
internal fun wrap(
items: MutableItemProvider,
default: ItemProvider? = null,
@ -50,13 +73,16 @@ public open class Scheme() : MutableItemProvider, Described, MetaRepr {
* Set a configurable property
*/
override fun setItem(name: Name, item: MetaItem?) {
val oldItem = items[name]
if (validateItem(name, item)) {
items[name] = item
listeners.forEach { it.action(name, oldItem, item) }
} else {
error("Validation failed for property $name with value $item")
}
}
/**
* Provide a default layer which returns items from [default] and falls back to descriptor
* values if default value is unavailable.
@ -100,7 +126,7 @@ public fun <T : Scheme, S : Specification<T>> S.wrap(
* Relocate scheme target onto given [MutableItemProvider]. Old provider does not get updates anymore.
* Current state of the scheme used as a default.
*/
public fun <T : Scheme> T.retarget(provider: MutableItemProvider) :T = apply { wrap(provider) }
public fun <T : Scheme> T.retarget(provider: MutableItemProvider): T = apply { wrap(provider) }
/**
* A shortcut to edit a [Scheme] object in-place

View File

@ -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
}

View File

@ -3,28 +3,26 @@ package space.kscience.dataforge.meta.descriptors
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.misc.DFBuilder
import space.kscience.dataforge.names.*
import space.kscience.dataforge.values.*
/**
* A common parent for [ValueDescriptor] and [NodeDescriptor]. Describes a single [TypedMetaItem] or a group of same-name-siblings.
*/
@DFBuilder
public sealed class ItemDescriptor(final override val config: Config) : Configurable {
public sealed interface ItemDescriptor: MetaRepr {
/**
* True if same name siblings with this name are allowed
*/
public var multiple: Boolean by config.boolean(false)
public val multiple: Boolean
/**
* The item description text
*/
public var info: String? by config.string()
public val info: String?
/**
* True if the item is required
*/
public abstract var required: Boolean
public val required: Boolean
/**
@ -32,14 +30,56 @@ public sealed class ItemDescriptor(final override val config: Config) : Configur
*
* @return
*/
public var attributes: Config? by config.node()
public val attributes: Meta?
/**
* An index field by which this node is identified in case of same name siblings construct
*/
public var indexKey: String by config.string(DEFAULT_INDEX_KEY)
public val indexKey: String
public abstract fun copy(): ItemDescriptor
public companion object {
public const val DEFAULT_INDEX_KEY: String = "@index"
}
}
/**
* The builder for [ItemDescriptor]
*/
@DFBuilder
public sealed class ItemDescriptorBuilder(final override val config: Config) : Configurable, ItemDescriptor {
/**
* True if same name siblings with this name are allowed
*/
override var multiple: Boolean by config.boolean(false)
/**
* The item description text
*/
override var info: String? by config.string()
/**
* True if the item is required
*/
abstract override var required: Boolean
/**
* Additional attributes of an item. For example validation and widget parameters
*
* @return
*/
override var attributes: Config? by config.node()
/**
* An index field by which this node is identified in case of same name siblings construct
*/
override var indexKey: String by config.string(DEFAULT_INDEX_KEY)
public abstract fun build(): ItemDescriptor
override fun toMeta(): Meta = config
public companion object {
public const val DEFAULT_INDEX_KEY: String = "@index"
@ -49,7 +89,7 @@ public sealed class ItemDescriptor(final override val config: Config) : Configur
/**
* Configure attributes of the descriptor, creating an attributes node if needed.
*/
public inline fun ItemDescriptor.attributes(block: Config.() -> Unit) {
public inline fun ItemDescriptorBuilder.attributes(block: Config.() -> Unit) {
(attributes ?: Config().also { this.attributes = it }).apply(block)
}
@ -66,140 +106,6 @@ public fun ItemDescriptor.validateItem(item: MetaItem?): Boolean {
}
}
/**
* Descriptor for meta node. Could contain additional information for viewing
* and editing.
*
* @author Alexander Nozik
*/
@DFBuilder
public class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) {
init {
config[IS_NODE_KEY] = true
}
/**
* True if the node is required
*
* @return
*/
override var required: Boolean by config.boolean { default == null }
/**
* The default for this node. Null if there is no default.
*
* @return
*/
public var default: Config? by config.node()
/**
* The map of children item descriptors (both nodes and values)
*/
public val items: Map<String, ItemDescriptor>
get() = config.getIndexed(ITEM_KEY).entries.associate { (name, item) ->
if (name == null) error("Child item index should not be null")
val node = item.node ?: error("Node descriptor must be a node")
if (node[IS_NODE_KEY].boolean == true) {
name to NodeDescriptor(node as Config)
} else {
name to ValueDescriptor(node as Config)
}
}
/**
* The map of children node descriptors
*/
@Suppress("UNCHECKED_CAST")
public val nodes: Map<String, NodeDescriptor>
get() = config.getIndexed(ITEM_KEY).entries.filter {
it.value.node[IS_NODE_KEY].boolean == true
}.associate { (name, item) ->
if (name == null) error("Child node index should not be null")
val node = item.node ?: error("Node descriptor must be a node")
name to NodeDescriptor(node as Config)
}
/**
* The list of children value descriptors
*/
public val values: Map<String, ValueDescriptor>
get() = config.getIndexed(ITEM_KEY).entries.filter {
it.value.node[IS_NODE_KEY].boolean != true
}.associate { (name, item) ->
if (name == null) error("Child value index should not be null")
val node = item.node ?: error("Node descriptor must be a node")
name to ValueDescriptor(node as Config)
}
private fun buildNode(name: Name): NodeDescriptor {
return when (name.length) {
0 -> this
1 -> {
val token = NameToken(ITEM_KEY.toString(), name.toString())
val config: Config = config[token].node ?: Config().also {
it[IS_NODE_KEY] = true
config[token] = it
}
NodeDescriptor(config)
}
else -> buildNode(name.firstOrNull()?.asName()!!).buildNode(name.cutFirst())
}
}
/**
* Define a child item descriptor for this node
*/
private fun newItem(key: String, descriptor: ItemDescriptor) {
if (items.keys.contains(key)) error("The key $key already exists in descriptor")
val token = ITEM_KEY.withIndex(key)
config[token] = descriptor.config
}
public fun item(name: Name, descriptor: ItemDescriptor) {
buildNode(name.cutLast()).newItem(name.lastOrNull().toString(), descriptor)
}
public fun item(name: String, descriptor: ItemDescriptor) {
item(name.toName(), descriptor)
}
/**
* Create and configure a child node descriptor
*/
public fun node(name: Name, block: NodeDescriptor.() -> Unit) {
item(name, NodeDescriptor().apply(block))
}
public fun node(name: String, block: NodeDescriptor.() -> Unit) {
node(name.toName(), block)
}
/**
* Create and configure child value descriptor
*/
public fun value(name: Name, block: ValueDescriptor.() -> Unit) {
require(name.length >= 1) { "Name length for value descriptor must be non-empty" }
item(name, ValueDescriptor().apply(block))
}
public fun value(name: String, block: ValueDescriptor.() -> Unit) {
value(name.toName(), block)
}
override fun copy(): NodeDescriptor = NodeDescriptor(config.toConfig())
public companion object {
internal val ITEM_KEY: Name = "item".asName()
internal val IS_NODE_KEY: Name = "@isNode".asName()
//TODO infer descriptor from spec
}
}
public inline fun NodeDescriptor(block: NodeDescriptor.() -> Unit): NodeDescriptor =
NodeDescriptor().apply(block)
/**
* Get a descriptor item associated with given name or null if item for given name not provided
*/
@ -213,93 +119,3 @@ public operator fun ItemDescriptor.get(name: Name): ItemDescriptor? {
public operator fun ItemDescriptor.get(name: String): ItemDescriptor? = get(name.toName())
/**
* A descriptor for meta value
*
* Descriptor can have non-atomic path. It is resolved when descriptor is added to the node
*
* @author Alexander Nozik
*/
@DFBuilder
public class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) {
/**
* True if the value is required
*
* @return
*/
override var required: Boolean by config.boolean { default == null }
/**
* The default for this value. Null if there is no default.
*
* @return
*/
public var default: Value? by config.value()
public fun default(v: Any) {
this.default = Value.of(v)
}
/**
* A list of allowed ValueTypes. Empty if any value type allowed
*
* @return
*/
public var type: List<ValueType>? by config.listValue { ValueType.valueOf(it.string) }
public fun type(vararg t: ValueType) {
this.type = listOf(*t)
}
/**
* Check if given value is allowed for here. The type should be allowed and
* if it is value should be within allowed values
*
* @param value
* @return
*/
public fun isAllowedValue(value: Value): Boolean {
return (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true)
&& (allowedValues.isEmpty() || allowedValues.contains(value))
}
/**
* A list of allowed values with descriptions. If empty than any value is
* allowed.
*
* @return
*/
public var allowedValues: List<Value> by config.item().convert(
reader = {
val value = it.value
when {
value?.list != null -> value.list
type?.let { type -> type.size == 1 && type[0] === ValueType.BOOLEAN } ?: false -> listOf(True, False)
else -> emptyList()
}
},
writer = {
MetaItemValue(it.asValue())
}
)
/**
* Allow given list of value and forbid others
*/
public fun allow(vararg v: Any) {
this.allowedValues = v.map { Value.of(it) }
}
override fun copy(): ValueDescriptor = ValueDescriptor(config.toConfig())
}
/**
* Merge two node descriptors into one using first one as primary
*/
public operator fun NodeDescriptor.plus(other: NodeDescriptor): NodeDescriptor {
return NodeDescriptor().apply {
config.update(other.config)
config.update(this@plus.config)
}
}

View File

@ -0,0 +1,191 @@
package space.kscience.dataforge.meta.descriptors
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.misc.DFBuilder
import space.kscience.dataforge.names.*
/**
* Descriptor for meta node. Could contain additional information for viewing
* and editing.
*
* @author Alexander Nozik
*/
@DFBuilder
public sealed interface NodeDescriptor: ItemDescriptor {
/**
* True if the node is required
*
* @return
*/
override val required: Boolean
/**
* The default for this node. Null if there is no default.
*
* @return
*/
public val default: Config?
/**
* The map of children item descriptors (both nodes and values)
*/
public val items: Map<String, ItemDescriptor>
/**
* The map of children node descriptors
*/
public val nodes: Map<String, NodeDescriptor>
/**
* The list of children value descriptors
*/
public val values: Map<String, ValueDescriptor>
public companion object {
internal val ITEM_KEY: Name = "item".asName()
internal val IS_NODE_KEY: Name = "@isNode".asName()
//TODO infer descriptor from spec
}
}
@DFBuilder
public class NodeDescriptorBuilder(config: Config = Config()) : ItemDescriptorBuilder(config), NodeDescriptor {
init {
config[IS_NODE_KEY] = true
}
/**
* True if the node is required
*
* @return
*/
override var required: Boolean by config.boolean { default == null }
/**
* The default for this node. Null if there is no default.
*
* @return
*/
override var default: Config? by config.node()
/**
* The map of children item descriptors (both nodes and values)
*/
override val items: Map<String, ItemDescriptor>
get() = config.getIndexed(ITEM_KEY).entries.associate { (name, item) ->
if (name == null) error("Child item index should not be null")
val node = item.node ?: error("Node descriptor must be a node")
if (node[IS_NODE_KEY].boolean == true) {
name to NodeDescriptorBuilder(node as Config)
} else {
name to ValueDescriptorBuilder(node as Config)
}
}
/**
* The map of children node descriptors
*/
@Suppress("UNCHECKED_CAST")
override val nodes: Map<String, NodeDescriptor>
get() = config.getIndexed(ITEM_KEY).entries.filter {
it.value.node[IS_NODE_KEY].boolean == true
}.associate { (name, item) ->
if (name == null) error("Child node index should not be null")
val node = item.node ?: error("Node descriptor must be a node")
name to NodeDescriptorBuilder(node as Config)
}
/**
* The list of children value descriptors
*/
override val values: Map<String, ValueDescriptor>
get() = config.getIndexed(ITEM_KEY).entries.filter {
it.value.node[IS_NODE_KEY].boolean != true
}.associate { (name, item) ->
if (name == null) error("Child value index should not be null")
val node = item.node ?: error("Node descriptor must be a node")
name to ValueDescriptorBuilder(node as Config)
}
private fun buildNode(name: Name): NodeDescriptorBuilder {
return when (name.length) {
0 -> this
1 -> {
val token = NameToken(ITEM_KEY.toString(), name.toString())
val config: Config = config[token].node ?: Config().also {
it[IS_NODE_KEY] = true
config[token] = it
}
NodeDescriptorBuilder(config)
}
else -> buildNode(name.firstOrNull()?.asName()!!).buildNode(name.cutFirst())
}
}
/**
* Define a child item descriptor for this node
*/
private fun newItem(key: String, descriptor: ItemDescriptor) {
if (items.keys.contains(key)) error("The key $key already exists in descriptor")
val token = ITEM_KEY.withIndex(key)
config[token] = descriptor.toMeta()
}
public fun item(name: Name, descriptor: ItemDescriptor) {
buildNode(name.cutLast()).newItem(name.lastOrNull().toString(), descriptor)
}
public fun item(name: String, descriptor: ItemDescriptor) {
item(name.toName(), descriptor)
}
/**
* Create and configure a child node descriptor
*/
public fun node(name: Name, block: NodeDescriptorBuilder.() -> Unit) {
item(name, NodeDescriptorBuilder().apply(block))
}
public fun node(name: String, block: NodeDescriptorBuilder.() -> Unit) {
node(name.toName(), block)
}
/**
* Create and configure child value descriptor
*/
public fun value(name: Name, block: ValueDescriptorBuilder.() -> Unit) {
require(name.length >= 1) { "Name length for value descriptor must be non-empty" }
item(name, ValueDescriptorBuilder().apply(block))
}
public fun value(name: String, block: ValueDescriptorBuilder.() -> Unit) {
value(name.toName(), block)
}
override fun build(): NodeDescriptor = NodeDescriptorBuilder(config.copy())
public companion object {
internal val ITEM_KEY: Name = "item".asName()
internal val IS_NODE_KEY: Name = "@isNode".asName()
//TODO infer descriptor from spec
}
}
public inline fun NodeDescriptor(block: NodeDescriptorBuilder.() -> Unit): NodeDescriptor =
NodeDescriptorBuilder().apply(block)
/**
* Merge two node descriptors into one using first one as primary
*/
public operator fun NodeDescriptor.plus(other: NodeDescriptor): NodeDescriptor {
return NodeDescriptorBuilder().apply {
config.update(other.toMeta())
config.update(this@plus.toMeta())
}
}

View File

@ -0,0 +1,135 @@
package space.kscience.dataforge.meta.descriptors
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.misc.DFBuilder
import space.kscience.dataforge.values.*
/**
* A descriptor for meta value
*
* Descriptor can have non-atomic path. It is resolved when descriptor is added to the node
*
* @author Alexander Nozik
*/
@DFBuilder
public sealed interface ValueDescriptor: ItemDescriptor{
/**
* True if the value is required
*
* @return
*/
override val required: Boolean
/**
* The default for this value. Null if there is no default.
*
* @return
*/
public val default: Value?
/**
* A list of allowed ValueTypes. Empty if any value type allowed
*
* @return
*/
public val type: List<ValueType>?
/**
* Check if given value is allowed for here. The type should be allowed and
* if it is value should be within allowed values
*
* @param value
* @return
*/
public fun isAllowedValue(value: Value): Boolean =
(type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true)
&& (allowedValues.isEmpty() || allowedValues.contains(value))
/**
* A list of allowed values with descriptions. If empty than any value is
* allowed.
*
* @return
*/
public val allowedValues: List<Value>
}
/**
* A builder fir [ValueDescriptor]
*/
@DFBuilder
public class ValueDescriptorBuilder(config: Config = Config()) : ItemDescriptorBuilder(config), ValueDescriptor {
/**
* True if the value is required
*
* @return
*/
override var required: Boolean by config.boolean { default == null }
/**
* The default for this value. Null if there is no default.
*
* @return
*/
override var default: Value? by config.value()
public fun default(v: Any) {
this.default = Value.of(v)
}
/**
* A list of allowed ValueTypes. Empty if any value type allowed
*
* @return
*/
override var type: List<ValueType>? by config.listValue { ValueType.valueOf(it.string) }
public fun type(vararg t: ValueType) {
this.type = listOf(*t)
}
/**
* Check if given value is allowed for here. The type should be allowed and
* if it is value should be within allowed values
*
* @param value
* @return
*/
override fun isAllowedValue(value: Value): Boolean {
return (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true)
&& (allowedValues.isEmpty() || allowedValues.contains(value))
}
/**
* A list of allowed values with descriptions. If empty than any value is
* allowed.
*
* @return
*/
override var allowedValues: List<Value> by config.item().convert(
reader = {
val value = it.value
when {
value?.list != null -> value.list
type?.let { type -> type.size == 1 && type[0] === ValueType.BOOLEAN } ?: false -> listOf(True, False)
else -> emptyList()
}
},
writer = {
MetaItemValue(it.asValue())
}
)
/**
* Allow given list of value and forbid others
*/
public fun allow(vararg v: Any) {
this.allowedValues = v.map { Value.of(it) }
}
override fun build(): ValueDescriptor = ValueDescriptorBuilder(config.copy())
}

View File

@ -4,7 +4,7 @@ import space.kscience.dataforge.names.Name
import space.kscience.dataforge.values.ValueType
import space.kscience.dataforge.values.asValue
public inline fun <reified E : Enum<E>> NodeDescriptor.enum(
public inline fun <reified E : Enum<E>> NodeDescriptorBuilder.enum(
key: Name,
default: E?,
crossinline modifier: ValueDescriptor.() -> Unit = {},

View File

@ -3,6 +3,7 @@ package space.kscience.dataforge.meta.transformations
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import kotlin.jvm.JvmInline
/**
* A transformation for meta item or a group of items
@ -85,7 +86,8 @@ public data class RegexItemTransformationRule(
/**
* A set of [TransformationRule] to either transform static meta or create dynamically updated [MutableMeta]
*/
public inline class MetaTransformation(public val transformations: Collection<TransformationRule>) {
@JvmInline
public value class MetaTransformation(private val transformations: Collection<TransformationRule>) {
/**
* Produce new meta using only those items that match transformation rules

View File

@ -1,8 +1,10 @@
package space.kscience.dataforge.meta
import space.kscience.dataforge.misc.DFExperimental
import kotlin.test.Test
import kotlin.test.assertEquals
@DFExperimental
class SchemeTest {
@Test
fun testSchemeWrappingBeforeEdit(){
@ -20,4 +22,15 @@ class SchemeTest {
scheme.retarget(config)
assertEquals(29, scheme.a)
}
@Test
fun testSchemeSubscription(){
val scheme = TestScheme.empty()
var flag: Int? = null
scheme.useProperty(TestScheme::a){a->
flag = a
}
scheme.a = 2
assertEquals(2, flag)
}
}

View File

@ -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

View File

@ -2,9 +2,11 @@ package space.kscience.dataforge.tables
import kotlinx.coroutines.flow.toList
import space.kscience.dataforge.meta.Meta
import kotlin.jvm.JvmInline
import kotlin.reflect.KType
public inline class MapRow<C : Any>(private val values: Map<String, C?>) : Row<C> {
@JvmInline
public value class MapRow<C : Any>(private val values: Map<String, C?>) : Row<C> {
override fun get(column: String): C? = values[column]
}

View File

@ -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("workspace", block)
}
/**

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -2,13 +2,11 @@ pluginManagement {
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
jcenter()
gradlePluginPortal()
maven("https://dl.bintray.com/kotlin/kotlin-eap")
}
val toolsVersion = "0.9.1"
val kotlinVersion = "1.4.31"
val toolsVersion = "0.9.5"
val kotlinVersion = "1.5.0"
plugins {
id("ru.mipt.npm.gradle.project") version toolsVersion