Documentation adjustment for Context
This commit is contained in:
parent
139a78beca
commit
abf222434f
@ -10,6 +10,18 @@ import mu.KLogger
|
|||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
|
||||||
|
* Context has [properties] - equivalent for system environment values, but grouped into a tree and inherited from parent context.
|
||||||
|
*
|
||||||
|
* The main function of the Context is to provide [PluginManager] which stores the loaded plugins and works as a dependency injection point.
|
||||||
|
* The normal behaviour of the [PluginManager] is to search for a plugin in parent context if it is not found in a current one. It is possible to have
|
||||||
|
* different plugins with the same interface in different contexts in the hierarchy. The usual behaviour is to use nearest one, but it could
|
||||||
|
* be overridden by plugin implementation.
|
||||||
|
*
|
||||||
|
* Since plugins could contain mutable state, context has two states: active and inactive. No changes are allowed to active context.
|
||||||
|
* @author Alexander Nozik
|
||||||
|
*/
|
||||||
interface Context : Named, MetaRepr, Provider {
|
interface Context : Named, MetaRepr, Provider {
|
||||||
|
|
||||||
val parent: Context?
|
val parent: Context?
|
||||||
@ -24,6 +36,9 @@ interface Context : Named, MetaRepr, Provider {
|
|||||||
*/
|
*/
|
||||||
val logger: KLogger
|
val logger: KLogger
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [PluginManager] for current context
|
||||||
|
*/
|
||||||
val plugins: PluginManager
|
val plugins: PluginManager
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,9 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
*/
|
*/
|
||||||
private val plugins = HashSet<Plugin>()
|
private val plugins = HashSet<Plugin>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [PluginManager] of parent context if it is present
|
||||||
|
*/
|
||||||
private val parent: PluginManager? = context.parent?.plugins
|
private val parent: PluginManager? = context.parent?.plugins
|
||||||
|
|
||||||
|
|
||||||
@ -31,7 +34,9 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get for existing plugin
|
* Get existing plugin or return null if not present. Only first matching plugin is returned.
|
||||||
|
* @param recursive search for parent [PluginManager] plugins
|
||||||
|
* @param predicate condition for the plugin
|
||||||
*/
|
*/
|
||||||
fun get(recursive: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = sequence(recursive).find(predicate)
|
fun get(recursive: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = sequence(recursive).find(predicate)
|
||||||
|
|
||||||
@ -87,6 +92,9 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a plugin from [PluginManager]
|
||||||
|
*/
|
||||||
fun remove(plugin: Plugin) {
|
fun remove(plugin: Plugin) {
|
||||||
if (context.isActive) error("Can't remove plugin from active context")
|
if (context.isActive) error("Can't remove plugin from active context")
|
||||||
|
|
||||||
@ -98,7 +106,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get plugin instance via plugin reolver and load it.
|
* Get plugin instance via plugin resolver and load it.
|
||||||
*
|
*
|
||||||
* @param tag
|
* @param tag
|
||||||
* @return
|
* @return
|
||||||
@ -114,6 +122,7 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Load plugin by its class and meta. Ignore if plugin with this meta is already loaded.
|
* Load plugin by its class and meta. Ignore if plugin with this meta is already loaded.
|
||||||
|
* Throw an exception if there exists plugin with the same type, but different meta
|
||||||
*/
|
*/
|
||||||
fun <T : Plugin> load(type: KClass<T>, meta: Meta = EmptyMeta): T {
|
fun <T : Plugin> load(type: KClass<T>, meta: Meta = EmptyMeta): T {
|
||||||
val loaded = get(type, false)
|
val loaded = get(type, false)
|
||||||
@ -142,4 +151,11 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
|
|
||||||
override fun iterator(): Iterator<Plugin> = plugins.iterator()
|
override fun iterator(): Iterator<Plugin> = plugins.iterator()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a plugin if it exists or load it with given meta if it is not.
|
||||||
|
*/
|
||||||
|
inline fun <reified T : Plugin> getOrLoad(noinline metaBuilder: MetaBuilder.() -> Unit = {}): T {
|
||||||
|
return get(true) ?: load(metaBuilder)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -26,13 +26,6 @@ import kotlin.collections.HashSet
|
|||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.full.cast
|
import kotlin.reflect.full.cast
|
||||||
|
|
||||||
/**
|
|
||||||
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
|
|
||||||
* Each context has a set of named [Value] properties which are taken from parent context in case they are not found in local context.
|
|
||||||
* Context implements [ValueProvider] interface and therefore could be uses as a value source for substitutions etc.
|
|
||||||
* Context contains [PluginManager] which could be used any number of configurable named plugins.
|
|
||||||
* @author Alexander Nozik
|
|
||||||
*/
|
|
||||||
open class JVMContext(
|
open class JVMContext(
|
||||||
final override val name: String,
|
final override val name: String,
|
||||||
final override val parent: JVMContext? = Global,
|
final override val parent: JVMContext? = Global,
|
||||||
|
Loading…
Reference in New Issue
Block a user