All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jitsi.metaconfig.Delegates.kt Maven / Gradle / Ivy

Go to download

jitsi-metaconfig helps solve the problems around the evolution of configuration properties

The newest version!
/*
 * Copyright @ 2018 - present 8x8, Inc.
 *
 * 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 org.jitsi.metaconfig

import org.jitsi.metaconfig.supplier.ConfigSourceSupplier
import org.jitsi.metaconfig.supplier.ConfigValueSupplier
import org.jitsi.metaconfig.supplier.FallbackSupplier
import kotlin.reflect.KProperty
import kotlin.reflect.typeOf

/**
 * A delegate for a configuration property which takes a [ConfigValueSupplier]
 */
open class ConfigDelegate(private val supplier: ConfigValueSupplier) {
    open operator fun getValue(thisRef: Any, property: KProperty<*>): T {
        return supplier.get()
    }
}

/**
 * A config property delegate which will return null if the property isn't found
 */
class OptionalConfigDelegate(private val supplier: ConfigValueSupplier) {
    operator fun getValue(thisRef: Any, property: KProperty<*>): T? {
        return try {
            supplier.get()
        } catch (e: ConfigException.UnableToRetrieve.ConditionNotMet) {
            throw e
        } catch (t: ConfigException.UnableToRetrieve) {
            null
        }
    }
}

/**
 * Create a [ConfigDelegate] for a single property (no fallback) from only a key and source and fill in
 * the type automatically, enables doing:
 *   val port: Int by config("app.server.port".from(configSource))
 * Instead of:
 *   val port: Int by config("app.server.port".from(configSource).asType())
 * Since the inline function can fill in the type on its own.
 *
 * throws [ConfigException.UnableToRetrieve] if the property couldn't be retrieved
 */
inline fun  config(supplier: ConfigSourceSupplier): ConfigDelegate = ConfigDelegate(supplier)

/**
 * Create a [ConfigDelegate] which will query multiple [ConfigValueSupplier]s, in order, for a
 * given property.
 *
 * throws [ConfigException.UnableToRetrieve] if the property couldn't be retrieved
 */
inline fun  config(block: SupplierBuilder.() -> Unit): ConfigDelegate {
    val supplierBuilder = SupplierBuilder(typeOf()).apply(block)
    return if (supplierBuilder.suppliers.size == 1) {
        // Avoid wrapping in a FallbackSupplier if we don't need one
        ConfigDelegate(supplierBuilder.suppliers.first())
    } else {
        ConfigDelegate(FallbackSupplier(supplierBuilder.suppliers))
    }
}

/**
 * Create a [ConfigValueSupplier] which can be used for a non-member field, e.g.:
 *
 * fun main(args: Array) {
 *     val port: ConfigValueSupplier = configSupplier {
 *         retrieve("app.port".from(configSource))
 *     }
 * }
 */
inline fun  configSupplier(block: SupplierBuilder.() -> Unit): ConfigValueSupplier {
    val supplier = SupplierBuilder(typeOf()).apply(block)
    return FallbackSupplier(supplier.suppliers)
}

/**
 * Create an [OptionalConfigDelegate] for a single property (no fallback) from only a key and source (filling in
 * the type automatically), returns null if the property couldn't be retrieved
 */
inline fun  optionalconfig(supplier: ConfigSourceSupplier): OptionalConfigDelegate =
    OptionalConfigDelegate(supplier)

/**
 * Create an [OptionalConfigDelegate] which queries multiple [ConfigValueSupplier]s for a property, returning
 * null if the property couldn't be retrieved
 */
inline fun  optionalconfig(block: SupplierBuilder.() -> Unit): OptionalConfigDelegate {
    val supplierBuilder = SupplierBuilder(typeOf()).apply(block)
    return if (supplierBuilder.suppliers.size == 1) {
        // Avoid wrapping in a FallbackSupplier if we don't need one
        OptionalConfigDelegate(supplierBuilder.suppliers.first())
    } else {
        OptionalConfigDelegate(FallbackSupplier(supplierBuilder.suppliers))
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy