update dependencies, add IllegalArgumentException for missing dependency, add settings-common
Some checks are pending
CodeQL / Analyze (push) Waiting to run

This commit is contained in:
Jörg Prante 2025-03-11 21:58:53 +01:00
parent 95c03b8bfa
commit 8cd9fb2461
24 changed files with 772 additions and 87 deletions

View file

@ -2,7 +2,7 @@
plugins {
id 'maven-publish'
id 'signing'
id "io.github.gradle-nexus.publish-plugin" version "2.0.0-rc-1"
id "io.github.gradle-nexus.publish-plugin" version "2.0.0"
}
wrapper {

View file

@ -10,7 +10,6 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -124,15 +123,6 @@ public class ConfigLoader {
}
}
}
if (!params.jdbcLookups.isEmpty()) {
for (ConfigParams.JdbcLookup jdbcLookup : params.jdbcLookups) {
try {
settings.fromJdbc(jdbcLookup.connection, jdbcLookup.statement, jdbcLookup.params);
} catch (SQLException sqlException) {
throw new ConfigException(sqlException);
}
}
}
if (params.includeAll) {
return overrideFromProperties(params, settings);
}

View file

@ -2,7 +2,6 @@ package org.xbib.config;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@ -32,8 +31,6 @@ public class ConfigParams implements Comparable<ConfigParams> {
final List<SuffixedReader> reader = new ArrayList<>();
final List<JdbcLookup> jdbcLookups = new ArrayList<>();
final List<DatastructureSettings> settings = new ArrayList<>();
List<String> args = null;
@ -121,15 +118,6 @@ public class ConfigParams implements Comparable<ConfigParams> {
return this;
}
public ConfigParams withJdbc(Connection connection, String statement, String[] params) {
JdbcLookup jdbcLookup = new JdbcLookup();
jdbcLookup.connection = connection;
jdbcLookup.statement = statement;
jdbcLookup.params = params;
jdbcLookups.add(jdbcLookup);
return this;
}
@Override
public int hashCode() {
return toString().hashCode();
@ -152,7 +140,6 @@ public class ConfigParams implements Comparable<ConfigParams> {
withSystemPropertiesOverride == that.withSystemPropertiesOverride &&
Objects.equals(classLoaders, that.classLoaders) &&
Objects.equals(reader, that.reader) &&
Objects.equals(jdbcLookups, that.jdbcLookups) &&
Objects.equals(settings, that.settings) &&
Objects.equals(args, that.args) &&
Objects.equals(directoryName, that.directoryName) &&
@ -183,10 +170,4 @@ public class ConfigParams implements Comparable<ConfigParams> {
Reader reader;
String suffix;
}
static class JdbcLookup {
Connection connection;
String statement;
String[] params;
}
}

View file

@ -1,3 +1,3 @@
org.xbib.settings.datastructures.PropertiesSettingsLoader
org.xbib.settings.datastructures.DatastructurePropertiesSettingsLoader
org.xbib.settings.datastructures.json.JsonSettingsLoader
org.xbib.settings.datastructures.yaml.YamlSettingsLoader

View file

@ -46,7 +46,7 @@ public class GeneratorTest {
gen.write("hey look a line seperator \n");
}
gen.close();
assertEquals("a,b,c,\nval0,\"\"\"Hello, World\"\"\",\"hey look a line seperator \n\"\n", writer.toString());
assertEquals("a,b,c\nval0,\"\"\"Hello, World\"\"\",\"hey look a line seperator \n\"\n", writer.toString());
}
@Test

View file

@ -1,3 +1,3 @@
group = org.xbib
name = datastructures
version = 5.2.2
version = 5.2.3

View file

@ -5,6 +5,5 @@ module org.xbib.settings.api {
exports org.xbib.settings;
uses SettingsBuilder;
uses SettingsLoader;
requires transitive org.xbib.datastructures.api;
requires transitive java.sql;
requires org.xbib.datastructures.api;
}

View file

@ -1,6 +1,5 @@
package org.xbib.settings.datastructures;
package org.xbib.settings;
import org.xbib.settings.SettingsLoader;
import org.xbib.datastructures.api.Builder;
import org.xbib.datastructures.api.DataStructure;
import org.xbib.datastructures.api.ListNode;
@ -8,12 +7,10 @@ import org.xbib.datastructures.api.MapNode;
import org.xbib.datastructures.api.Node;
import org.xbib.datastructures.api.Parser;
import org.xbib.datastructures.api.ValueNode;
import org.xbib.datastructures.tiny.TinyMap;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -37,20 +34,13 @@ public abstract class AbstractSettingsLoader implements SettingsLoader {
return load(parser, new StringReader(source));
}
private Map<String, String> load(Parser parser, Reader reader) throws IOException {
List<CharSequence> path = new ArrayList<>();
TinyMap.Builder<String, String> map = TinyMap.builder();
Node<?> node = parser.parse(reader);
parseObject(node, map, path, null);
return map.build();
}
protected abstract Map<String, String> load(Parser parser, Reader reader) throws IOException;
private void parseObject(Node<?> node,
TinyMap.Builder<String, String> map,
protected void parseObject(Node<?> node,
Map<String, String> map,
List<CharSequence> path,
CharSequence name) {
if (node instanceof ValueNode) {
ValueNode valueNode = (ValueNode) node;
if (node instanceof ValueNode valueNode) {
StringBuilder sb = new StringBuilder();
for (CharSequence s : path) {
sb.append(s).append('.');
@ -58,22 +48,20 @@ public abstract class AbstractSettingsLoader implements SettingsLoader {
sb.append(name);
Object object = valueNode.get();
map.put(sb.toString(), object != null ? object.toString() : null);
} else if (node instanceof ListNode) {
ListNode listNode = (ListNode) node;
} else if (node instanceof ListNode listNode) {
int counter = 0;
for (Node<?> nn : listNode.get()) {
parseObject(nn, map, path, name + "." + (counter++));
}
} else if (node instanceof MapNode) {
} else if (node instanceof MapNode mapNode) {
if (name != null) {
path.add(name);
}
MapNode mapNode = (MapNode) node;
for (Map.Entry<CharSequence, Node<?>> me : mapNode.get().entrySet()) {
parseObject(me.getValue(), map, path, me.getKey());
}
if (name != null) {
path.remove(path.size() - 1);
path.removeLast();
}
}
}

View file

@ -3,9 +3,6 @@ package org.xbib.settings;
import java.util.HashSet;
import java.util.Set;
/**
*
*/
public class PropertyPlaceholder {
private final String placeholderPrefix;

View file

@ -17,7 +17,10 @@ public interface Settings extends AutoCloseable {
private static SettingsBuilder createBuilder() {
ServiceLoader<SettingsBuilder> serviceLoader = ServiceLoader.load(SettingsBuilder.class);
Optional<SettingsBuilder> optionalSettingsBuilder = serviceLoader.findFirst();
return optionalSettingsBuilder.orElse(null);
if (optionalSettingsBuilder.isPresent()) {
return optionalSettingsBuilder.get();
}
throw new IllegalArgumentException("no settings-datastructures included for Settings API");
}
private static final Settings emptySettings = createBuilder().build();

View file

@ -1,12 +1,7 @@
package org.xbib.settings;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@ -41,18 +36,6 @@ public interface SettingsBuilder {
SettingsBuilder loadFromResource(String resourceName, InputStream inputStream);
default SettingsBuilder fromJdbc(Connection connection, String statement, String[] params) throws SQLException {
try (PreparedStatement preparedStatement = connection.prepareStatement(statement, params);
ResultSet resultSet = preparedStatement.executeQuery()) {
while (resultSet.next()) {
String key = resultSet.getString("key");
String value = resultSet.getString("value");
put(key, value);
}
}
return this;
}
SettingsBuilder loadFromSystemProperties();
SettingsBuilder loadFromSystemEnvironment();

View file

@ -0,0 +1,3 @@
dependencies {
api project(':settings-api')
}

View file

@ -0,0 +1,10 @@
import org.xbib.settings.SettingsBuilder;
import org.xbib.settings.common.BaseSettingsBuilder;
module org.xbib.settings.common {
uses SettingsBuilder;
provides SettingsBuilder with BaseSettingsBuilder;
exports org.xbib.settings.common;
requires org.xbib.settings.api;
requires org.xbib.datastructures.api;
}

View file

@ -0,0 +1,367 @@
package org.xbib.settings.common;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.xbib.datastructures.api.ByteSizeValue;
import org.xbib.datastructures.api.TimeValue;
import org.xbib.settings.Settings;
import org.xbib.settings.SettingsException;
public class BaseSettings implements Settings {
private static final String[] EMPTY_ARRAY = new String[0];
private final Map<String, String> map;
BaseSettings(Map<String, String> map) {
this.map = map;
}
public static BaseSettingsBuilder builder() {
return new BaseSettingsBuilder();
}
public static Settings fromMap(Map<String, Object> map) {
BaseSettingsBuilder builder = new BaseSettingsBuilder();
for (Map.Entry<String, Object> entry : map.entrySet()) {
builder.put(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : null);
}
return builder.build();
}
public static void toMap(Settings settings, Map<String, Object> map) {
for (String key : settings.getAsMap().keySet()) {
map.put(key, settings.get(key));
}
}
public static String[] splitStringByCommaToArray(String s) {
return splitStringToArray(s, ',');
}
public static String[] splitStringToArray(String s, char c) {
if (s.isEmpty()) {
return EMPTY_ARRAY;
}
final char[] chars = s.toCharArray();
int count = 1;
for (final char x : chars) {
if (x == c) {
count++;
}
}
final String[] result = new String[count];
final int len = chars.length;
int start = 0;
int pos = 0;
int i = 0;
for (; pos < len; pos++) {
if (chars[pos] == c) {
int size = pos - start;
if (size > 0) {
result[i++] = new String(chars, start, size);
}
start = pos + 1;
}
}
int size = pos - start;
if (size > 0) {
result[i++] = new String(chars, start, size);
}
if (i != count) {
String[] result1 = new String[i];
System.arraycopy(result, 0, result1, 0, i);
return result1;
}
return result;
}
@Override
public Map<String, String> getAsMap() {
return this.map;
}
@Override
public Map<String, Object> getAsStructuredMap() {
Map<String, Object> stringObjectMap = new LinkedHashMap<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
processSetting(stringObjectMap, "", key, value);
}
for (Map.Entry<String, Object> entry : stringObjectMap.entrySet()) {
String key = entry.getKey();
Object object = entry.getValue();
if (object instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> valMap = (Map<String, Object>) object;
stringObjectMap.put(key, convertMapsToArrays(valMap));
}
}
return stringObjectMap;
}
@Override
public Settings getByPrefix(String prefix) {
BaseSettingsBuilder builder = new BaseSettingsBuilder();
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (key.startsWith(prefix)) {
if (key.length() < prefix.length()) {
continue;
}
builder.put(key.substring(prefix.length()), value);
}
}
return builder.build();
}
@Override
public Settings getAsSettings(String setting) {
return getByPrefix(setting + ".");
}
@Override
public boolean containsSetting(String setting) {
if (map.containsKey(setting)) {
return true;
}
for (String key : map.keySet()) {
if (key.startsWith(setting)) {
return true;
}
}
return false;
}
@Override
public String get(String setting) {
return map.get(setting);
}
@Override
public String get(String setting, String defaultValue) {
String s = map.get(setting);
return s == null ? defaultValue : s;
}
@Override
public float getAsFloat(String setting, float defaultValue) {
String s = get(setting);
try {
return s == null ? defaultValue : Float.parseFloat(s);
} catch (NumberFormatException e) {
throw new SettingsException("Failed to parse float setting [" + setting + "] with value [" + s + "]", e);
}
}
@Override
public double getAsDouble(String setting, double defaultValue) {
String s = get(setting);
try {
return s == null ? defaultValue : Double.parseDouble(s);
} catch (NumberFormatException e) {
throw new SettingsException("Failed to parse double setting [" + setting + "] with value [" + s + "]", e);
}
}
@Override
public int getAsInt(String setting, int defaultValue) {
String s = get(setting);
try {
return s == null ? defaultValue : Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new SettingsException("Failed to parse int setting [" + setting + "] with value [" + s + "]", e);
}
}
@Override
public long getAsLong(String setting, long defaultValue) {
String s = get(setting);
try {
return s == null ? defaultValue : Long.parseLong(s);
} catch (NumberFormatException e) {
throw new SettingsException("Failed to parse long setting [" + setting + "] with value [" + s + "]", e);
}
}
@Override
public boolean getAsBoolean(String setting, boolean defaultValue) {
String value = get(setting);
if (value == null) {
return defaultValue;
}
return !("false".equals(value) || "0".equals(value) || "off".equals(value) || "no".equals(value));
}
@Override
public TimeValue getAsTime(String setting, TimeValue defaultValue) {
return TimeValue.parseTimeValue(get(setting), defaultValue);
}
@Override
public ByteSizeValue getAsBytesSize(String setting, ByteSizeValue defaultValue) {
return ByteSizeValue.parseBytesSizeValue(get(setting), defaultValue);
}
@Override
public String[] getAsArray(String settingPrefix) {
return getAsArray(settingPrefix, EMPTY_ARRAY);
}
@Override
public String[] getAsArray(String settingPrefix, String[] defaultArray) {
List<String> result = new ArrayList<>();
if (get(settingPrefix) != null) {
String[] strings = splitStringByCommaToArray(get(settingPrefix));
if (strings.length > 0) {
for (String string : strings) {
result.add(string.trim());
}
}
}
int counter = 0;
while (true) {
String value = get(settingPrefix + '.' + (counter++));
if (value == null) {
break;
}
result.add(value.trim());
}
if (result.isEmpty()) {
return defaultArray;
}
return result.toArray(new String[0]);
}
@Override
public Map<String, Settings> getGroups(String prefix) {
String settingPrefix = prefix;
if (settingPrefix.charAt(settingPrefix.length() - 1) != '.') {
settingPrefix = settingPrefix + ".";
}
// we don't really care that it might happen twice
Map<String, Map<String, String>> hashMap = new LinkedHashMap<>();
for (String o : this.map.keySet()) {
if (o.startsWith(settingPrefix)) {
String nameValue = o.substring(settingPrefix.length());
int dotIndex = nameValue.indexOf('.');
if (dotIndex == -1) {
throw new SettingsException("failed to get setting group for ["
+ settingPrefix
+ "] setting prefix and setting [" + o + "] because of a missing '.'");
}
String name = nameValue.substring(0, dotIndex);
String value = nameValue.substring(dotIndex + 1);
Map<String, String> groupSettings = hashMap.computeIfAbsent(name, k -> new LinkedHashMap<>());
groupSettings.put(value, get(o));
}
}
Map<String, Settings> retVal = new LinkedHashMap<>();
for (Map.Entry<String, Map<String, String>> entry : hashMap.entrySet()) {
String key = entry.getKey();
Map<String, String> value = entry.getValue();
retVal.put(key, new BaseSettings(value));
}
return retVal;
}
@Override
public boolean equals(Object o) {
return this == o || !(o == null || getClass() != o.getClass()) && map.equals(((BaseSettings) o).map);
}
@Override
public int hashCode() {
return map.hashCode();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public void close() throws IOException {
// do nothing
}
private void processSetting(Map<String, Object> map, String prefix, String setting, String value) {
int prefixLength = setting.indexOf('.');
if (prefixLength == -1) {
@SuppressWarnings("unchecked")
Map<String, Object> innerMap = (Map<String, Object>) map.get(prefix + setting);
if (innerMap != null) {
for (Map.Entry<String, Object> e : innerMap.entrySet()) {
String k = e.getKey();
Object v = e.getValue();
map.put(prefix + setting + "." + k, v);
}
}
map.put(prefix + setting, value);
} else {
String key = setting.substring(0, prefixLength);
String rest = setting.substring(prefixLength + 1);
Object existingValue = map.get(prefix + key);
if (existingValue == null) {
Map<String, Object> newMap = new LinkedHashMap<>();
processSetting(newMap, "", rest, value);
map.put(key, newMap);
} else {
if (existingValue instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> innerMap = (Map<String, Object>) existingValue;
processSetting(innerMap, "", rest, value);
map.put(key, innerMap);
} else {
processSetting(map, prefix + key + ".", rest, value);
}
}
}
}
private Object convertMapsToArrays(Map<String, Object> map) {
if (map.isEmpty()) {
return map;
}
boolean isArray = true;
int maxIndex = -1;
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (isArray) {
try {
int index = Integer.parseInt(key);
if (index >= 0) {
maxIndex = Math.max(maxIndex, index);
} else {
isArray = false;
}
} catch (NumberFormatException ex) {
isArray = false;
}
}
if (value instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> valMap = (Map<String, Object>) value;
map.put(key, convertMapsToArrays(valMap));
}
}
if (isArray && (maxIndex + 1) == map.size()) {
ArrayList<Object> newValue = new ArrayList<>(maxIndex + 1);
for (int i = 0; i <= maxIndex; i++) {
Object obj = map.get(Integer.toString(i));
if (obj == null) {
return map;
}
newValue.add(obj);
}
return newValue;
}
return map;
}
}

View file

@ -0,0 +1,328 @@
package org.xbib.settings.common;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.xbib.settings.PlaceholderResolver;
import org.xbib.settings.PropertyPlaceholder;
import org.xbib.settings.Settings;
import org.xbib.settings.SettingsBuilder;
import org.xbib.settings.SettingsException;
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.SettingsLoaderService;
public class BaseSettingsBuilder implements SettingsBuilder {
private final SettingsLoaderService settingsLoaderService;
private final Map<String, String> map;
public BaseSettingsBuilder() {
this.settingsLoaderService = SettingsLoaderService.getInstance();
this.map = new LinkedHashMap<>();
}
public String remove(String key) {
return map.remove(key);
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
/**
* Sets a setting with the provided setting key and value.
*
* @param key The setting key
* @param value The setting value
* @return The builder
*/
@Override
public BaseSettingsBuilder put(String key, String value) {
map.put(key, value);
return this;
}
/**
* Sets the setting with the provided setting key and the boolean value.
*
* @param setting The setting key
* @param value The boolean value
* @return The builder
*/
@Override
public BaseSettingsBuilder put(String setting, boolean value) {
put(setting, String.valueOf(value));
return this;
}
/**
* Sets the setting with the provided setting key and the int value.
*
* @param setting The setting key
* @param value The int value
* @return The builder
*/
@Override
public BaseSettingsBuilder put(String setting, int value) {
put(setting, String.valueOf(value));
return this;
}
/**
* Sets the setting with the provided setting key and the long value.
*
* @param setting The setting key
* @param value The long value
* @return The builder
*/
@Override
public BaseSettingsBuilder put(String setting, long value) {
put(setting, String.valueOf(value));
return this;
}
/**
* Sets the setting with the provided setting key and the float value.
*
* @param setting The setting key
* @param value The float value
* @return The builder
*/
@Override
public BaseSettingsBuilder put(String setting, float value) {
put(setting, String.valueOf(value));
return this;
}
/**
* Sets the setting with the provided setting key and the double value.
*
* @param setting The setting key
* @param value The double value
* @return The builder
*/
@Override
public BaseSettingsBuilder put(String setting, double value) {
put(setting, String.valueOf(value));
return this;
}
/**
* Sets the setting with the provided setting key and an array of values.
*
* @param setting The setting key
* @param values The values
* @return The builder
*/
@Override
public BaseSettingsBuilder putArray(String setting, String... values) {
remove(setting);
int counter = 0;
while (true) {
String value = map.remove(setting + '.' + (counter++));
if (value == null) {
break;
}
}
for (int i = 0; i < values.length; i++) {
put(setting + '.' + i, values[i]);
}
return this;
}
/**
* Sets the setting with the provided setting key and an array of values.
*
* @param setting The setting key
* @param values The values
* @return The builder
*/
@Override
public BaseSettingsBuilder putArray(String setting, List<String> values) {
remove(setting);
int counter = 0;
while (true) {
String value = map.remove(setting + '.' + (counter++));
if (value == null) {
break;
}
}
for (int i = 0; i < values.size(); i++) {
put(setting + '.' + i, values.get(i));
}
return this;
}
/**
* Sets the setting group.
*
* @param settingPrefix setting prefix
* @param groupName group name
* @param settings settings
* @param values values
* @return a builder
* @throws SettingsException if setting fails
*/
@Override
public BaseSettingsBuilder put(String settingPrefix, String groupName, String[] settings, String[] values)
throws SettingsException {
if (settings.length != values.length) {
throw new SettingsException("the settings length must match the value length");
}
for (int i = 0; i < settings.length; i++) {
if (values[i] == null) {
continue;
}
put(settingPrefix + "" + groupName + "." + settings[i], values[i]);
}
return this;
}
/**
* Sets all the provided settings.
*
* @param settings settings
* @return builder
*/
@Override
public BaseSettingsBuilder put(Settings settings) {
map.putAll(settings.getAsMap());
return this;
}
/**
* Sets all the provided settings.
*
* @param settings settings
* @return a builder
*/
@Override
public BaseSettingsBuilder put(Map<String, String> settings) {
map.putAll(settings);
return this;
}
/**
* Loads settings from a resource.
*
* @param resourceName resource name
* @param inputStream input stream
* @return builder
*/
@Override
public BaseSettingsBuilder loadFromResource(String resourceName, InputStream inputStream) {
SettingsLoader settingsLoader = settingsLoaderService.loaderFromResource(resourceName);
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
Map<String, String> loadedSettings = settingsLoader.load(bufferedReader.lines().collect(Collectors.joining()));
put(loadedSettings);
} catch (Exception e) {
throw new SettingsException("failed to load settings from [" + resourceName + "]", e);
}
return this;
}
/**
* Loads settings from the actual string content that represents them using the
* {@link SettingsLoaderService#loaderFromResource(String)} (String)}.
*
* @param resourceName the resource name
* @param source the source
* @return builder
*/
@Override
public BaseSettingsBuilder loadFromString(String resourceName, String source) {
SettingsLoader settingsLoader = settingsLoaderService.loaderFromResource(resourceName);
try {
put(settingsLoader.load(source));
} catch (Exception e) {
throw new SettingsException("failed to load settings from [" + source + "]", e);
}
return this;
}
/**
* Load system properties to this settings.
*
* @return builder
*/
@Override
public BaseSettingsBuilder loadFromSystemProperties() {
for (Map.Entry<Object, Object> entry : System.getProperties().entrySet()) {
put((String) entry.getKey(), (String) entry.getValue());
}
return this;
}
/**
* Load system environment to this settings.
*
* @return builder
*/
@Override
public BaseSettingsBuilder loadFromSystemEnvironment() {
for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
put(entry.getKey(), entry.getValue());
}
return this;
}
@Override
public BaseSettingsBuilder replacePropertyPlaceholders(PropertyPlaceholder propertyPlaceholder,
PlaceholderResolver placeholderResolver) {
map.replaceAll((k, v) -> propertyPlaceholder.replacePlaceholders(v, placeholderResolver));
return this;
}
@Override
public BaseSettingsBuilder replacePropertyPlaceholders() {
return replacePropertyPlaceholders(new PropertyPlaceholder("${", "}", false),
placeholderName -> {
// system property
String value = System.getProperty(placeholderName);
if (value != null) {
return value;
}
// environment
value = System.getenv(placeholderName);
if (value != null) {
return value;
}
// current date
try {
return DateTimeFormatter.ofPattern(placeholderName).format(LocalDate.now());
} catch (IllegalArgumentException | DateTimeException e) {
return map.get(placeholderName);
}
}
);
}
@Override
public BaseSettingsBuilder setRefresh(Path path, long initialDelay, long period, TimeUnit timeUnit) {
return this;
}
@Override
public SettingsBuilder map(Function<Map.Entry<String, String>, Map.Entry<String, String>> function) {
map.entrySet().stream().map(function).forEach(e -> put(e.getKey(), e.getValue()));
return this;
}
@Override
public Settings build() {
return new BaseSettings(map);
}
}

View file

@ -0,0 +1 @@
org.xbib.settings.common.BaseSettingsBuilder

View file

@ -5,6 +5,7 @@ module org.xbib.settings.datastructures.json {
exports org.xbib.settings.datastructures.json;
requires transitive org.xbib.settings.datastructures;
requires org.xbib.datastructures.json.tiny;
requires org.xbib.datastructures.tiny;
uses SettingsLoader;
provides SettingsLoader with JsonSettingsLoader;
}

View file

@ -1,6 +1,14 @@
package org.xbib.settings.datastructures.json;
import org.xbib.settings.datastructures.AbstractSettingsLoader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.xbib.datastructures.api.Node;
import org.xbib.datastructures.api.Parser;
import org.xbib.datastructures.tiny.TinyMap;
import org.xbib.settings.AbstractSettingsLoader;
import org.xbib.datastructures.api.DataStructure;
import org.xbib.datastructures.json.tiny.Json;
import java.util.Set;
@ -19,4 +27,13 @@ public class JsonSettingsLoader extends AbstractSettingsLoader {
public Set<String> suffixes() {
return Set.of("json");
}
@Override
protected Map<String, String> load(Parser parser, Reader reader) throws IOException {
List<CharSequence> path = new ArrayList<>();
TinyMap.Builder<String, String> map = TinyMap.builder();
Node<?> node = parser.parse(reader);
parseObject(node, map, path, null);
return map.build();
}
}

View file

@ -5,6 +5,7 @@ module org.xbib.settings.datastructures.yaml {
exports org.xbib.settings.datastructures.yaml;
requires transitive org.xbib.settings.datastructures;
requires org.xbib.datastructures.yaml.tiny;
requires org.xbib.datastructures.tiny;
uses SettingsLoader;
provides SettingsLoader with YamlSettingsLoader;
}

View file

@ -1,6 +1,12 @@
package org.xbib.settings.datastructures.yaml;
import org.xbib.settings.datastructures.AbstractSettingsLoader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import org.xbib.datastructures.api.Node;
import org.xbib.datastructures.api.Parser;
import org.xbib.datastructures.tiny.TinyMap;
import org.xbib.settings.AbstractSettingsLoader;
import org.xbib.datastructures.api.DataStructure;
import org.xbib.datastructures.yaml.tiny.Yaml;
@ -28,4 +34,13 @@ public class YamlSettingsLoader extends AbstractSettingsLoader {
// replace tabs with two whitespace (yaml does not accept tabs, but many users might use it still...)
return super.load(source.replace("\t", " "));
}
@Override
protected Map<String, String> load(Parser parser, Reader reader) throws IOException {
List<CharSequence> path = new ArrayList<>();
TinyMap.Builder<String, String> map = TinyMap.builder();
Node<?> node = parser.parse(reader);
parseObject(node, map, path, null);
return map.build();
}
}

View file

@ -1,11 +1,11 @@
import org.xbib.settings.SettingsBuilder;
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.datastructures.DatastructureSettingsBuilder;
import org.xbib.settings.datastructures.PropertiesSettingsLoader;
import org.xbib.settings.datastructures.DatastructurePropertiesSettingsLoader;
module org.xbib.settings.datastructures {
uses SettingsLoader;
provides SettingsLoader with PropertiesSettingsLoader;
provides SettingsLoader with DatastructurePropertiesSettingsLoader;
uses SettingsBuilder;
provides SettingsBuilder with DatastructureSettingsBuilder;
exports org.xbib.settings.datastructures;

View file

@ -11,9 +11,9 @@ import java.util.Set;
/**
* Settings loader that loads (parses) the settings in a properties format.
*/
public class PropertiesSettingsLoader implements SettingsLoader {
public class DatastructurePropertiesSettingsLoader implements SettingsLoader {
public PropertiesSettingsLoader() {
public DatastructurePropertiesSettingsLoader() {
}
@Override

View file

@ -1 +1 @@
org.xbib.settings.datastructures.PropertiesSettingsLoader
org.xbib.settings.datastructures.DatastructurePropertiesSettingsLoader

View file

@ -22,14 +22,14 @@ dependencyResolutionManagement {
library('orgjson', 'org.json', 'json').version('20210307')
}
testLibs {
version('junit', '5.10.2')
version('jackson', '2.17.3')
version('junit', '5.12.0')
version('jackson', '2.18.3')
library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit')
library('junit-jupiter-params', 'org.junit.jupiter', 'junit-jupiter-params').versionRef('junit')
library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')
library('junit-vintage-engine', 'org.junit.vintage', 'junit-vintage-engine').versionRef('junit')
library('junit-jupiter-platform-launcher', 'org.junit.platform', 'junit-platform-launcher').version('1.10.0')
library('hamcrest', 'org.hamcrest', 'hamcrest-library').version('2.2')
library('junit-jupiter-platform-launcher', 'org.junit.platform', 'junit-platform-launcher').version('1.12.0')
library('hamcrest', 'org.hamcrest', 'hamcrest-library').version('3.0')
library('junit4', 'junit', 'junit').version('4.13.2')
library('burst-junit4', 'com.squareup.burst', 'burst-junit4').version('1.1.1')
library('mockito-core', 'org.mockito', 'mockito-core').version('3.12.4')
@ -71,6 +71,7 @@ include 'datastructures-xml'
include 'datastructures-xslx'
include 'datastructures-yaml-tiny'
include 'settings-api'
include 'settings-common'
include 'settings-datastructures'
include 'settings-datastructures-json'
include 'settings-datastructures-yaml'