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

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

Go to download

Provides common core classes and the microkernel powering all Sirius applications

There is a newer version: 12.9.1
Show newest version
/*
 * 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 java.util.LinkedHashMap;
import java.util.Map;

/**
 * Provides functionality to build a config and generate formatted HOCON text.
 * 

* If scopes contain more than one variable, they will be unfolded and formatted as a block. Example: *

 * scopeA.foo = true
 * scopeA.bar = false
 * scopeB.foo = false
 * 
* will become *
 * scopeB.foo = false
 *
 * scopeA {
 *     foo = true
 *     bar = false
 * }
 * 
*/ public class ConfigBuilder { private static final String INDENTATION = " "; /** * Contains the root scope */ private Scope config = new Scope(); /** * Adds a variable to the config. *

* Note: a string value needs to be surrounded by quotes * * @param name the full name of the variable, e.g. "scopeA.scope1.variable" * @param value the value of the variable */ public void addVariable(String name, String value) { String[] parts = name.split("\\."); Scope currentScope = config; for (int i = 0; i < parts.length - 1; i++) { currentScope = currentScope.getScope(parts[i]); } if (currentScope.hasVariable(parts[parts.length - 1])) { throw new IllegalArgumentException("Variable '" + name + "' already exists"); } currentScope.addVariable(parts[parts.length - 1], value); } @Override public String toString() { return config.toString(); } /** * Provides a base class for the elements of the config. */ private abstract static class Node { private String name; Node() { } Node(String name) { this.name = name; } public String getName() { return name; } } /** * Provides the scope */ private static class Scope extends Node { private boolean isRoot = false; private Map variables = new LinkedHashMap<>(); private Map scopes = new LinkedHashMap<>(); /** * Creates a new root scope. */ Scope() { isRoot = true; } /** * Creates a new named scope. * * @param name the name of the scope */ Scope(String name) { super(name); } /** * Returns a scope with the given name or creates one, if none exists with that name. * * @param name the name of the scope to return or create * @return the scope with the given name */ private Scope getScope(String name) { return scopes.computeIfAbsent(name, Scope::new); } /** * Determines if a variable with the given name exists. * * @param name the name of the variable * @return true if the variable exists, false otherwise */ private boolean hasVariable(String name) { return variables.containsKey(name); } /** * Creates a variable with the given name and value. * * @param name the name of the variable * @param value the value of the variable */ private void addVariable(String name, String value) { variables.put(name, new Variable(name, value)); } /** * Determines if the scope and sub scopes contain only one variable * * @return true if the scope only contains one variable, false otherwise */ private boolean hasOnlyOneVariable() { // If there are only variables, simply check the count if (scopes.isEmpty()) { return variables.size() == 1; } // No need to check all sub scopes, because multiple scopes means multiple variables. Only check if there is // one scope and no variables return scopes.size() == 1 && variables.isEmpty() && scopes.values().iterator().next().hasOnlyOneVariable(); } /** * Renders the config into a nicely formatted HOCON text and returns it * * @return the config as a formatted string */ @Override public String toString() { StringBuilder variablesStringBuilder = new StringBuilder(); StringBuilder scopeStringBuilder = new StringBuilder(); for (Variable variable : variables.values()) { if (variablesStringBuilder.length() > 0) { variablesStringBuilder.append("\n"); } variablesStringBuilder.append(variable.toString()); } for (Scope scope : scopes.values()) { // If the scope has only one variable, the scope will be collapsed and can reside with the variables if (scope.hasOnlyOneVariable()) { if (variablesStringBuilder.length() > 0) { variablesStringBuilder.append("\n"); } variablesStringBuilder.append(scope.toString()); } else { if (scopeStringBuilder.length() > 0) { scopeStringBuilder.append("\n\n"); } scopeStringBuilder.append(scope.toString()); } } return mergeVariablesAndScopes(variablesStringBuilder.toString(), scopeStringBuilder.toString()); } /** * Merges the variable and scope blocks, indents them and returns the resulting scope. * * @param variablesString the variables of the scope * @param scopesString the sub scopes of the scope * @return the resulting formatted text */ private String mergeVariablesAndScopes(String variablesString, String scopesString) { String mergedString; // Put an empty line between variables and the first scope block if (!variablesString.isEmpty() && !scopesString.isEmpty()) { mergedString = variablesString + "\n\n" + scopesString; } else { mergedString = variablesString + scopesString; } if (!isRoot) { StringBuilder stringBuilder = new StringBuilder(); if (hasOnlyOneVariable()) { // Prepend the variable with the scope name stringBuilder.append(getName()).append(".").append(variablesString); } else { // Wrap the block inside the scope stringBuilder.append(getName()).append(" {\n"); stringBuilder.append(mergedString.replaceAll("(?m)^", INDENTATION)); stringBuilder.append("\n}"); } // Remove indentation in empty lines return stringBuilder.toString().replaceAll("(?m)^\\s+$", ""); } return mergedString; } } /** * Provides the variables */ private static class Variable extends Node { private String value; /** * Create a new variable with the given name and value. * * @param name the name of the variable * @param value the value of the variable */ Variable(String name, String value) { super(name); this.value = value; } @Override public String toString() { return getName() + " = " + value; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy