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

sirius.kernel.settings.ExtendedSettings Maven / Gradle / Ivy

/*
 * Made with all the love in the world
 * by scireum in Remshalden, Germany
 *
 * Copyright by scireum GmbH
 * http://www.scireum.de - [email protected]
 */

package sirius.kernel.settings;

import com.google.common.collect.Maps;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigObject;
import com.typesafe.config.ConfigValue;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

/**
 * Provides an advanced wrapper for a {@link Config} object, which supports to represent inner maps as {@link Extension
 * extensions}.
 * 

* Using the typesafe config library, * several several sources can be loaded into a single config object. These sources will be merged together, so that * extensions like the following will be put into one extension list reachable as "examples": *

 * {@code
 *     File A:
 *
 *      examples {
 *          A = {
 *              key = "string"
 *              otherKey = true
 *          }
 *      }
 *
 *     File B:
 *
 *      examples {
 *          B = {
 *              key = "string"
 *              otherKey = true
 *          }
 *      }
 * }
 * 
*

* This permits frameworks to provide extension hooks which can be extended by sub modules, without having the * framework to "know" those modules. Using a loose coupled approach like this simplifies the task of building * modular and extensible systems. *

* The extensions defined above can be obtained calling {@code settings.getExtension("examples")}. Each * of those extensions can be read out calling {@code ext.getValue("key").asString()} or * {@code ext.getValue("otherKey").asBoolean()} * * @see Extension */ public class ExtendedSettings extends Settings { /** * Provides a regular expression which verifies if an extension name is well formed. */ public static final Pattern VALID_EXTENSION_ID = Pattern.compile("[a-z0-9\\-]+"); /** * Used as cache for already loaded extension lists */ private Map> cache = new ConcurrentHashMap<>(); /** * Used as cache for the default values of a given extension type */ private Map defaultsCache = new ConcurrentHashMap<>(); /** * Creates a new settings object based on the given config. * * @param config the config to wrap */ public ExtendedSettings(Config config) { super(config); } /** * Returns the Extension for the given id of the given type * * @param type the type of the extension to be returned * @param id the unique id of the extension to be returned * @return the specified extension or null, if no such extension exists */ @Nullable public Extension getExtension(String type, String id) { if (!VALID_EXTENSION_ID.matcher(id).matches()) { Extension.LOG.WARN("Bad extension id detected: '%s' (for type: %s). Names should only consist of" + " lowercase letters, digits or '-'", id, type); } Extension result = getExtensionMap(type).get(id); if (result == null) { return getDefault(type); } return result; } /** * Returns all extensions available for the given type *

* The order of the extensions can be defined, setting a property named priority. If no value is * present {@link sirius.kernel.commons.PriorityCollector#DEFAULT_PRIORITY} is assumed. * * @param type the type of the extensions to be returned. * @return a non-null collection of extensions found for the given type */ @Nonnull public Collection getExtensions(String type) { return getExtensionMap(type).values(); } protected Extension getDefault(String type) { Extension result = defaultsCache.get(type); if (result != null) { return result; } ConfigObject cfg = getConfig().getConfig(type).root(); ConfigObject def = (ConfigObject) cfg.get(Extension.DEFAULT); if (cfg.containsKey(Extension.DEFAULT)) { result = new Extension(type, Extension.DEFAULT, def, null); defaultsCache.put(type, result); return result; } return null; } private Map getExtensionMap(String type) { Map result = cache.get(type); if (result != null) { return result; } if (!getConfig().hasPath(type)) { return Collections.emptyMap(); } ConfigObject cfg = getConfig().getConfig(type).root(); List list = new ArrayList<>(); ConfigObject defaultObject = null; if (cfg.containsKey(Extension.DEFAULT)) { defaultObject = (ConfigObject) cfg.get(Extension.DEFAULT); } for (Map.Entry entry : cfg.entrySet()) { String key = entry.getKey(); if (!Extension.DEFAULT.equals(key) && !key.contains(".")) { if (entry.getValue() instanceof ConfigObject) { list.add(new Extension(type, key, (ConfigObject) entry.getValue(), defaultObject)); } else { Extension.LOG.WARN("Malformed extension within '%s'. Expected a config object but found: %s", type, entry.getValue()); } } } Collections.sort(list); result = Maps.newLinkedHashMap(); for (Extension ex : list) { result.put(ex.getId(), ex); } cache.put(type, result); return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy