
tech.harmonysoft.oss.common.template.factory.KeyValueConfigurerFactory.kt Maven / Gradle / Ivy
package tech.harmonysoft.oss.common.template.factory
import tech.harmonysoft.oss.common.template.service.KeyValueConfigurer
import tech.harmonysoft.oss.common.template.service.KeyValueConfigurationContext
import tech.harmonysoft.oss.common.data.DataModificationStrategy
import tech.harmonysoft.oss.common.data.TypedKeyManager
import tech.harmonysoft.oss.common.type.TypeManagerContext
import tech.harmonysoft.oss.common.type.TypeManager
/**
* Defines contract for building [KeyValueConfigurer] instances. The main idea is that it receives `Map`
* which holds configuration rules and builds [KeyValueConfigurer] based on that.
*
* **DSL:**
* For simplicity all examples below show YAML config, however, there is no restriction on where it comes from.
*
* ------------------------------------------------------------------------------------------------------------
*
* *Unconditional static configuration*
*
* ```
* rules:
* key1: value1
* key2: value2
* ```
*
* This is the simplest possible configuration - target values are defined for the target keys.
*
* ------------------------------------------------------------------------------------------------------------
*
* *Conditional static configuration with leaf static rules*
*
* ```
* rules:
* key1:
* - When:
* key2: some-value
* Then: value1
* - When:
* key3: some-other-value
* Then: value2
* - Then: value3
* ```
*
* 1. If [key2 = some-value][KeyValueConfigurationContext.getByStaticKey] then [key1 is set to value1][DataModificationStrategy.setValue]
* 2. Else if [key3 = some-other-value][KeyValueConfigurationContext.getByStaticKey] then [key1 is set to value1][DataModificationStrategy.setValue]
* 3. Else [key1 is set to value3][DataModificationStrategy.setValue]
*
* *Note: if there is no final unconditional `'Then'` clause, then `key1` value is not set*
*
* ------------------------------------------------------------------------------------------------------------
*
* *Composite AND filter*
*
* ```
* rules:
* key1:
* - When:
* key2: some-value
* Then: value1
* - When:
* And:
* - key3: some-other-value
* - key4: one-more-value
* Then: value2
* ```
*
* ------------------------------------------------------------------------------------------------------------
*
* *Composite OR filter*
*
* ```
* rules:
* key1:
* - When:
* Or:
* - key2: some-value
* - And:
* key3: some-other-value
* key4: one-more-value
* Then: value
* ```
*
* 1. If `key2 = some-value` or (`key3 = some-other-value` and `key4 = one-more-value`) then `key1` is set to `value`
* 2. Else `key1` value is not set/changed
*
* *Note: any other filter might be used in AND/OR filters*
*
* ------------------------------------------------------------------------------------------------------------
*
* *Dynamic value with static key*
*
* ```
* rules:
* key1:
* - When:
* key2: 3
* Then:
* ```
*
* 1. If [key2 dynamic value = 3][KeyValueConfigurationContext.getByStaticKey] then `key` is set to [key3 dynamic value][KeyValueConfigurationContext.getByStaticKey]
* 2. Else `key1` value is not set/changed
*
* *Note: here and below all elements in angle brackets (<>) mean something dynamic. Here we use a dedicated
* `original-` prefix as an indication that dynamic value should be retrieved via target static key*
*
* ------------------------------------------------------------------------------------------------------------
*
* *Dynamic value with static key shorthand*
*
* ```
* rules:
* key1:
* - When:
* key2: 3
* Then: 4
* - Then:
* ```
*
* 1. If `key2 = 3` then `key1` is set to `4`
* 2. Else `key1` is set to `key1 dynamic value`
*
* *Note: `key1: ` is the same as `key1: `*
*
* ------------------------------------------------------------------------------------------------------------
*
* *Dynamic value with dynamic key*
*
* ```
* rules:
* key1:
* - When:
* key2:
* Then:
* ```
*
* 1. If `key2 = `[dynamic value for dynamic key 'flavor1'][KeyValueConfigurationContext.getByDynamicKey] then `key1` is set to [dynamic value for dynamic key 'flavor2'][KeyValueConfigurationContext.getByDynamicKey]
* 2. Else `key1` value is not set/changed
*
* ------------------------------------------------------------------------------------------------------------
*
* *Dynamic key*
*
* ```
* rules:
* key1:
* - When:
* : flow1
* Then: value1
* - When:
* key2: value2
* Then: value3
* ```
*
* 1. If [dynamic value for dynamic key 'flow'][KeyValueConfigurationContext.getByDynamicKey] is equal to `flow`
* then `key1` is set to `value1`
* 2. Else if `key2 = value2` then `key1` is set to `value3`
* 3. Else `key1` value is not set/changed
*
* ------------------------------------------------------------------------------------------------------------
*
* *Rich string value with dynamic value by static key*
*
* ```
* rules:
* key1:
* - When:
* key2: 1
* Then: "prefix suffix"
* ```
*
* 1. If [key1 type is string][TypedKeyManager.getValueType] and `key2 = 1` then set `key1` value as string
* `prefix 'dynamic key3 value' suffix`
* 2. Else `key1` value is not set/changed
*
* ------------------------------------------------------------------------------------------------------------
*
* *Rich string value with dynamic value by dynamic key*
*
* ```
* rules:
* key1:
* - When:
* key2: 1
* Then: "prefix suffix"
* ```
*
* 1. If [key1 type is string][TypedKeyManager.getValueType] and `key2 = 1` then set `key1` value as string
* `prefix 'dynamic flow value' suffix`
* 2. Else `key1` value is not set/changed
*/
interface KeyValueConfigurerFactory {
/**
* @param rawRules raw configuration rules
* @param keyManager key manager to use
* @param contexts contexts to use for selecting target [TypeManager], see [TypeManagerContext] for
* more details
*/
fun build(
rawRules: Map,
keyManager: TypedKeyManager,
contexts: Set
): KeyValueConfigurer
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy