Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2017-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.uchuhimo.konf.source
import com.uchuhimo.konf.Config
import com.uchuhimo.konf.Feature
import com.uchuhimo.konf.source.base.FlatSource
import com.uchuhimo.konf.source.base.KVSource
import com.uchuhimo.konf.source.base.MapSource
import com.uchuhimo.konf.source.env.EnvProvider
import com.uchuhimo.konf.source.json.JsonProvider
import com.uchuhimo.konf.source.properties.PropertiesProvider
import java.io.File
import java.net.URL
import java.util.concurrent.TimeUnit
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.Dispatchers
/**
* Default loaders for config.
*
* If [transform] is provided, source will be applied the given [transform] function when loaded.
*
* @param config parent config for loader
* @param transform the given transformation function
*/
class DefaultLoaders(
/**
* Parent config for loader.
*/
val config: Config,
/**
* The given transformation function.
*/
private val transform: ((Source) -> Source)? = null
) {
val optional = config.isEnabled(Feature.OPTIONAL_SOURCE_BY_DEFAULT)
fun Provider.orMapped(): Provider =
if (transform != null) this.map(transform) else this
fun Source.orMapped(): Source = transform?.invoke(this) ?: this
/**
* Returns default loaders applied the given [transform] function.
*
* @param transform the given transformation function
* @return the default loaders applied the given [transform] function
*/
fun mapped(transform: (Source) -> Source): DefaultLoaders = DefaultLoaders(config) {
transform(it.orMapped())
}
/**
* Returns default loaders where sources have specified additional prefix.
*
* @param prefix additional prefix
* @return the default loaders where sources have specified additional prefix
*/
fun prefixed(prefix: String): DefaultLoaders = mapped { it.withPrefix(prefix) }
/**
* Returns default loaders where sources are scoped in specified path.
*
* @param path path that is the scope of sources
* @return the default loaders where sources are scoped in specified path
*/
fun scoped(path: String): DefaultLoaders = mapped { it[path] }
fun enabled(feature: Feature): DefaultLoaders = mapped { it.enabled(feature) }
fun disabled(feature: Feature): DefaultLoaders = mapped { it.disabled(feature) }
/**
* Loader for JSON source.
*/
@JvmField
val json = Loader(config, JsonProvider.orMapped())
/**
* Loader for properties source.
*/
@JvmField
val properties = Loader(config, PropertiesProvider.orMapped())
/**
* Loader for map source.
*/
@JvmField
val map = MapLoader(config, transform)
/**
* Loader for a source from the specified provider.
*
* @param provider the specified provider
* @return a loader for a source from the specified provider
*/
fun source(provider: Provider) = Loader(config, provider.orMapped())
/**
* Returns a child config containing values from system environment.
*
* @param nested whether to treat "AA_BB_CC" as nested format "AA.BB.CC" or not. True by default.
* @return a child config containing values from system environment
*/
@JvmOverloads
fun env(nested: Boolean = true): Config = config.withSource(EnvProvider.env(nested).orMapped())
/**
* Returns a child config containing values from system properties.
*
* @return a child config containing values from system properties
*/
fun systemProperties(): Config = config.withSource(PropertiesProvider.system().orMapped())
/**
* Returns corresponding loader based on extension.
*
* @param extension the file extension
* @param source the source description for error message
* @return the corresponding loader based on extension
*/
fun dispatchExtension(extension: String, source: String = ""): Loader =
Loader(config, Provider.of(extension)?.orMapped()
?: throw UnsupportedExtensionException(source))
/**
* Returns a child config containing values from specified file.
*
* Format of the file is auto-detected from the file extension.
* Supported file formats and the corresponding extensions:
* - HOCON: conf
* - JSON: json
* - Properties: properties
* - TOML: toml
* - XML: xml
* - YAML: yml, yaml
*
* Throws [UnsupportedExtensionException] if the file extension is unsupported.
*
* @param file specified file
* @param optional whether the source is optional
* @return a child config containing values from specified file
* @throws UnsupportedExtensionException
*/
fun file(file: File, optional: Boolean = this.optional): Config = dispatchExtension(file.extension, file.name).file(file, optional)
/**
* Returns a child config containing values from specified file path.
*
* Format of the file is auto-detected from the file extension.
* Supported file formats and the corresponding extensions:
* - HOCON: conf
* - JSON: json
* - Properties: properties
* - TOML: toml
* - XML: xml
* - YAML: yml, yaml
*
* Throws [UnsupportedExtensionException] if the file extension is unsupported.
*
* @param file specified file path
* @param optional whether the source is optional
* @return a child config containing values from specified file path
* @throws UnsupportedExtensionException
*/
fun file(file: String, optional: Boolean = this.optional): Config = file(File(file), optional)
/**
* Returns a child config containing values from specified file,
* and reloads values when file content has been changed.
*
* Format of the file is auto-detected from the file extension.
* Supported file formats and the corresponding extensions:
* - HOCON: conf
* - JSON: json
* - Properties: properties
* - TOML: toml
* - XML: xml
* - YAML: yml, yaml
*
* Throws [UnsupportedExtensionException] if the file extension is unsupported.
*
* @param file specified file
* @param delayTime delay to observe between every check. The default value is 5.
* @param unit time unit of delay. The default value is [TimeUnit.SECONDS].
* @param context context of the coroutine. The default value is [Dispatchers.Default].
* @param optional whether the source is optional
* @return a child config containing values from watched file
* @throws UnsupportedExtensionException
*/
fun watchFile(
file: File,
delayTime: Long = 5,
unit: TimeUnit = TimeUnit.SECONDS,
context: CoroutineContext = Dispatchers.Default,
optional: Boolean = this.optional
): Config = dispatchExtension(file.extension, file.name)
.watchFile(file, delayTime, unit, context, optional)
/**
* Returns a child config containing values from specified file path,
* and reloads values when file content has been changed.
*
* Format of the file is auto-detected from the file extension.
* Supported file formats and the corresponding extensions:
* - HOCON: conf
* - JSON: json
* - Properties: properties
* - TOML: toml
* - XML: xml
* - YAML: yml, yaml
*
* Throws [UnsupportedExtensionException] if the file extension is unsupported.
*
* @param file specified file path
* @param delayTime delay to observe between every check. The default value is 5.
* @param unit time unit of delay. The default value is [TimeUnit.SECONDS].
* @param context context of the coroutine. The default value is [Dispatchers.Default].
* @param optional whether the source is optional
* @return a child config containing values from watched file
* @throws UnsupportedExtensionException
*/
fun watchFile(
file: String,
delayTime: Long = 5,
unit: TimeUnit = TimeUnit.SECONDS,
context: CoroutineContext = Dispatchers.Default,
optional: Boolean = this.optional
): Config = watchFile(File(file), delayTime, unit, context, optional)
/**
* Returns a child config containing values from specified url.
*
* Format of the url is auto-detected from the url extension.
* Supported url formats and the corresponding extensions:
* - HOCON: conf
* - JSON: json
* - Properties: properties
* - TOML: toml
* - XML: xml
* - YAML: yml, yaml
*
* Throws [UnsupportedExtensionException] if the url extension is unsupported.
*
* @param url specified url
* @param optional whether the source is optional
* @return a child config containing values from specified url
* @throws UnsupportedExtensionException
*/
fun url(url: URL, optional: Boolean = this.optional): Config = dispatchExtension(File(url.path).extension, url.toString()).url(url, optional)
/**
* Returns a child config containing values from specified url string.
*
* Format of the url is auto-detected from the url extension.
* Supported url formats and the corresponding extensions:
* - HOCON: conf
* - JSON: json
* - Properties: properties
* - TOML: toml
* - XML: xml
* - YAML: yml, yaml
*
* Throws [UnsupportedExtensionException] if the url extension is unsupported.
*
* @param url specified url string
* @param optional whether the source is optional
* @return a child config containing values from specified url string
* @throws UnsupportedExtensionException
*/
fun url(url: String, optional: Boolean = this.optional): Config = url(URL(url), optional)
/**
* Returns a child config containing values from specified url,
* and reloads values periodically.
*
* Format of the url is auto-detected from the url extension.
* Supported url formats and the corresponding extensions:
* - HOCON: conf
* - JSON: json
* - Properties: properties
* - TOML: toml
* - XML: xml
* - YAML: yml, yaml
*
* Throws [UnsupportedExtensionException] if the url extension is unsupported.
*
* @param url specified url
* @param period reload period. The default value is 5.
* @param unit time unit of delay. The default value is [TimeUnit.SECONDS].
* @param context context of the coroutine. The default value is [Dispatchers.Default].
* @param optional whether the source is optional
* @return a child config containing values from specified url
* @throws UnsupportedExtensionException
*/
fun watchUrl(
url: URL,
period: Long = 5,
unit: TimeUnit = TimeUnit.SECONDS,
context: CoroutineContext = Dispatchers.Default,
optional: Boolean = this.optional
): Config = dispatchExtension(File(url.path).extension, url.toString())
.watchUrl(url, period, unit, context, optional)
/**
* Returns a child config containing values from specified url string,
* and reloads values periodically.
*
* Format of the url is auto-detected from the url extension.
* Supported url formats and the corresponding extensions:
* - HOCON: conf
* - JSON: json
* - Properties: properties
* - TOML: toml
* - XML: xml
* - YAML: yml, yaml
*
* Throws [UnsupportedExtensionException] if the url extension is unsupported.
*
* @param url specified url string
* @param period reload period. The default value is 5.
* @param unit time unit of delay. The default value is [TimeUnit.SECONDS].
* @param context context of the coroutine. The default value is [Dispatchers.Default].
* @param optional whether the source is optional
* @return a child config containing values from specified url string
* @throws UnsupportedExtensionException
*/
fun watchUrl(
url: String,
period: Long = 5,
unit: TimeUnit = TimeUnit.SECONDS,
context: CoroutineContext = Dispatchers.Default,
optional: Boolean = this.optional
): Config = watchUrl(URL(url), period, unit, context, optional)
}
/**
* Loader to load source from map of variant formats.
*
* If [transform] is provided, source will be applied the given [transform] function when loaded.
*
* @param config parent config
*/
class MapLoader(
/**
* Parent config for all child configs loading source in this loader.
*/
val config: Config,
/**
* The given transformation function.
*/
private val transform: ((Source) -> Source)? = null
) {
fun Source.orMapped(): Source = transform?.invoke(this) ?: this
/**
* Returns a child config containing values from specified hierarchical map.
*
* @param map a hierarchical map
* @return a child config containing values from specified hierarchical map
*/
fun hierarchical(map: Map): Config = config.withSource(MapSource(map).orMapped())
/**
* Returns a child config containing values from specified map in key-value format.
*
* @param map a map in key-value format
* @return a child config containing values from specified map in key-value format
*/
fun kv(map: Map): Config = config.withSource(KVSource(map).orMapped())
/**
* Returns a child config containing values from specified map in flat format.
*
* @param map a map in flat format
* @return a child config containing values from specified map in flat format
*/
fun flat(map: Map): Config = config.withSource(FlatSource(map).orMapped())
}