refactoring into the settings subprojects, each content/datastructure

This commit is contained in:
Jörg Prante 2021-10-13 17:32:29 +02:00
parent 9411e901be
commit bd2eb07591
80 changed files with 330 additions and 228 deletions

View file

@ -1,8 +1,3 @@
import org.xbib.content.SettingsBuilder;
module org.xbib.content.api { module org.xbib.content.api {
exports org.xbib.content; exports org.xbib.content;
requires transitive org.xbib.datastructures.api;
requires java.sql;
uses SettingsBuilder;
} }

View file

@ -1,5 +1,5 @@
dependencies { dependencies {
api project(':content-settings-datastructures') api project(':settings-datastructures')
testImplementation project(':content-settings-datastructures-json') testImplementation project(':settings-datastructures-json')
testImplementation project(':content-settings-datastructures-yaml') testImplementation project(':settings-datastructures-yaml')
} }

View file

@ -1,11 +1,11 @@
import org.xbib.content.config.ConfigLogger; import org.xbib.content.config.ConfigLogger;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
module org.xbib.content.config { module org.xbib.content.config {
exports org.xbib.content.config; exports org.xbib.content.config;
uses ConfigLogger; uses ConfigLogger;
uses SettingsLoader; uses SettingsLoader;
provides ConfigLogger with org.xbib.content.config.SystemConfigLogger; provides ConfigLogger with org.xbib.content.config.SystemConfigLogger;
requires org.xbib.content.api; requires org.xbib.settings.api;
requires transitive org.xbib.content.settings.datastructures; requires transitive org.xbib.settings.datastructures;
} }

View file

@ -1,9 +1,9 @@
package org.xbib.content.config; package org.xbib.content.config;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import org.xbib.content.SettingsBuilder; import org.xbib.settings.SettingsBuilder;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import org.xbib.content.settings.datastructures.SettingsLoaderService; import org.xbib.settings.SettingsLoaderService;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -14,6 +14,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -137,6 +138,15 @@ 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) { if (params.includeAll) {
return overrideFromProperties(params, settings); return overrideFromProperties(params, settings);
} }
@ -263,15 +273,15 @@ public class ConfigLoader {
return null; return null;
} }
private SettingsBuilder overrideFromProperties(ConfigParams params, private SettingsBuilder overrideFromProperties(ConfigParams params, SettingsBuilder settingsBuilder) {
SettingsBuilder settings) { if (params.withSystemPropertiesOverride) {
for (String key : settings.map().keySet()) { settingsBuilder.map(e -> {
String key = e.getKey();
String value = System.getProperty(params.directoryName != null ? params.directoryName + '.' + key : key); String value = System.getProperty(params.directoryName != null ? params.directoryName + '.' + key : key);
if (value != null) { return value != null ? Map.entry(key, value) : Map.entry(key, e.getValue());
settings.put(key, value); });
} }
} return settingsBuilder;
return settings;
} }
private List<String> createListOfLocations(ConfigParams params, private List<String> createListOfLocations(ConfigParams params,

View file

@ -1,8 +1,9 @@
package org.xbib.content.config; package org.xbib.content.config;
import org.xbib.content.settings.datastructures.DatastructureSettings; import org.xbib.settings.datastructures.DatastructureSettings;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.sql.Connection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
@ -21,10 +22,14 @@ public class ConfigParams implements Comparable<ConfigParams> {
boolean withStdin = false; boolean withStdin = false;
boolean withSystemPropertiesOverride = false;
List<ClassLoader> classLoaders = null; List<ClassLoader> classLoaders = null;
final List<SuffixedReader> reader = new ArrayList<>(); final List<SuffixedReader> reader = new ArrayList<>();
final List<JdbcLookup> jdbcLookups = new ArrayList<>();
final List<DatastructureSettings> settings = new ArrayList<>(); final List<DatastructureSettings> settings = new ArrayList<>();
List<String> args = null; List<String> args = null;
@ -48,6 +53,11 @@ public class ConfigParams implements Comparable<ConfigParams> {
return this; return this;
} }
public ConfigParams withSystemPropertiesOverride() {
this.withSystemPropertiesOverride = true;
return this;
}
public ConfigParams includeAll() { public ConfigParams includeAll() {
this.includeAll = true; this.includeAll = true;
return this; return this;
@ -102,6 +112,15 @@ public class ConfigParams implements Comparable<ConfigParams> {
return this; 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 @Override
public int compareTo(ConfigParams o) { public int compareTo(ConfigParams o) {
return COMPARATOR.compare(this, o); return COMPARATOR.compare(this, o);
@ -125,4 +144,10 @@ public class ConfigParams implements Comparable<ConfigParams> {
Reader reader; Reader reader;
String suffix; String suffix;
} }
public static class JdbcLookup {
Connection connection;
String statement;
String[] params;
}
} }

View file

@ -2,7 +2,7 @@ package org.xbib.content.config.test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import org.xbib.content.config.ConfigLoader; import org.xbib.content.config.ConfigLoader;
import org.xbib.content.config.ConfigParams; import org.xbib.content.config.ConfigParams;
import java.io.IOException; import java.io.IOException;
@ -29,4 +29,17 @@ public class ConfigLoaderTest {
assertEquals("world2", settings.get("hello2")); assertEquals("world2", settings.get("hello2"));
} }
@Test
public void testOverride() throws IOException {
System.setProperty("hello", "override");
Settings settings = ConfigLoader.getInstance()
.load(new ConfigParams()
.withPath(null, null, "src/test/resources", "config.*"));
assertEquals("world", settings.get("hello"));
settings = ConfigLoader.getInstance()
.load(new ConfigParams()
.withSystemPropertiesOverride()
.withPath(null, null, "src/test/resources", "config.*"));
assertEquals("override", settings.get("hello"));
}
} }

View file

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

View file

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

View file

@ -1,6 +1,5 @@
dependencies { dependencies {
api project(':content-core') api project(':content-core')
api project(':content-settings')
api "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}" api "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}"
testImplementation("org.mockito:mockito-core:${project.property('mockito.version')}") { testImplementation("org.mockito:mockito-core:${project.property('mockito.version')}") {
exclude group: 'org.hamcrest' exclude group: 'org.hamcrest'

View file

@ -1,5 +1,4 @@
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.SettingsLoader;
module org.xbib.content.json { module org.xbib.content.json {
exports org.xbib.content.json; exports org.xbib.content.json;
@ -9,8 +8,6 @@ module org.xbib.content.json {
exports org.xbib.content.json.patch; exports org.xbib.content.json.patch;
exports org.xbib.content.json.pointer; exports org.xbib.content.json.pointer;
requires org.xbib.content.core; requires org.xbib.content.core;
requires org.xbib.content.settings;
requires com.fasterxml.jackson.databind; requires com.fasterxml.jackson.databind;
provides XContent with org.xbib.content.json.JsonXContent; provides XContent with org.xbib.content.json.JsonXContent;
provides SettingsLoader with org.xbib.content.json.JsonSettingsLoader;
} }

View file

@ -1 +0,0 @@
org.xbib.content.json.JsonSettingsLoader

View file

@ -1,10 +0,0 @@
import org.xbib.content.SettingsLoader;
import org.xbib.content.settings.datastructures.json.JsonSettingsLoader;
module org.xbib.content.settings.datastructures.json {
exports org.xbib.content.settings.datastructures.json;
requires transitive org.xbib.content.settings.datastructures;
requires org.xbib.datastructures.json.tiny;
uses SettingsLoader;
provides SettingsLoader with JsonSettingsLoader;
}

View file

@ -1 +0,0 @@
org.xbib.content.settings.datastructures.json.JsonSettingsLoader

View file

@ -1,10 +0,0 @@
import org.xbib.content.SettingsLoader;
import org.xbib.content.settings.datastructures.yaml.YamlSettingsLoader;
module org.xbib.content.settings.datastructures.yaml {
exports org.xbib.content.settings.datastructures.yaml;
requires transitive org.xbib.content.settings.datastructures;
requires org.xbib.datastructures.yaml.tiny;
uses SettingsLoader;
provides SettingsLoader with YamlSettingsLoader;
}

View file

@ -1 +0,0 @@
org.xbib.content.settings.datastructures.yaml.YamlSettingsLoader

View file

@ -1,15 +0,0 @@
import org.xbib.content.SettingsBuilder;
import org.xbib.content.SettingsLoader;
import org.xbib.content.settings.datastructures.DatastructureSettingsBuilder;
import org.xbib.content.settings.datastructures.PropertiesSettingsLoader;
module org.xbib.content.settings.datastructures {
uses SettingsLoader;
provides SettingsLoader with PropertiesSettingsLoader;
uses SettingsBuilder;
provides SettingsBuilder with DatastructureSettingsBuilder;
exports org.xbib.content.settings.datastructures;
requires transitive org.xbib.content.api;
requires org.xbib.datastructures.tiny;
requires transitive org.xbib.datastructures.api;
}

View file

@ -1 +0,0 @@
org.xbib.content.settings.datastructures.DatastructureSettingsBuilder

View file

@ -1 +0,0 @@
org.xbib.content.settings.datastructures.PropertiesSettingsLoader

View file

@ -1,15 +0,0 @@
import org.xbib.content.SettingsBuilder;
import org.xbib.content.SettingsLoader;
import org.xbib.content.settings.ContentSettingsBuilder;
import org.xbib.content.settings.PropertiesSettingsLoader;
module org.xbib.content.settings {
uses SettingsLoader;
provides SettingsLoader with PropertiesSettingsLoader;
uses SettingsBuilder;
provides SettingsBuilder with ContentSettingsBuilder;
exports org.xbib.content.settings;
requires org.xbib.content.core;
requires org.xbib.datastructures.api;
requires transitive org.xbib.datastructures.tiny;
}

View file

@ -1,4 +0,0 @@
/**
* Classes for settings.
*/
package org.xbib.content.settings;

View file

@ -1 +0,0 @@
org.xbib.content.settings.ContentSettingsBuilder

View file

@ -1 +0,0 @@
org.xbib.content.settings.PropertiesSettingsLoader

View file

@ -1,6 +1,5 @@
dependencies { dependencies {
api project(':content-core') api project(':content-core')
api project(':content-settings')
api "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${project.property('jackson.version')}" api "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${project.property('jackson.version')}"
implementation "org.yaml:snakeyaml:${project.property('snakeyaml.version')}" implementation "org.yaml:snakeyaml:${project.property('snakeyaml.version')}"
} }

View file

@ -1,12 +1,9 @@
import org.xbib.content.SettingsLoader;
import org.xbib.content.XContent; import org.xbib.content.XContent;
module org.xbib.content.yaml { module org.xbib.content.yaml {
exports org.xbib.content.yaml; exports org.xbib.content.yaml;
requires transitive org.xbib.content.core; requires transitive org.xbib.content.core;
requires transitive org.xbib.content.settings;
requires transitive com.fasterxml.jackson.dataformat.yaml; requires transitive com.fasterxml.jackson.dataformat.yaml;
requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.core;
provides XContent with org.xbib.content.yaml.YamlXContent; provides XContent with org.xbib.content.yaml.YamlXContent;
provides SettingsLoader with org.xbib.content.yaml.YamlSettingsLoader;
} }

View file

@ -1 +0,0 @@
org.xbib.content.yaml.YamlSettingsLoader

View file

@ -0,0 +1,10 @@
import org.xbib.settings.SettingsBuilder;
import org.xbib.settings.SettingsLoader;
module org.xbib.settings.api {
exports org.xbib.settings;
uses SettingsBuilder;
uses SettingsLoader;
requires transitive org.xbib.datastructures.api;
requires transitive java.sql;
}

View file

@ -1,4 +1,4 @@
package org.xbib.content; package org.xbib.settings;
/** /**
* Strategy interface used to resolve replacement values for placeholders contained in Strings. * Strategy interface used to resolve replacement values for placeholders contained in Strings.

View file

@ -1,4 +1,4 @@
package org.xbib.content; package org.xbib.settings;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

View file

@ -1,7 +1,8 @@
package org.xbib.content; package org.xbib.settings;
import org.xbib.datastructures.api.ByteSizeValue; import org.xbib.datastructures.api.ByteSizeValue;
import org.xbib.datastructures.api.TimeValue; import org.xbib.datastructures.api.TimeValue;
import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.ServiceLoader; import java.util.ServiceLoader;
@ -62,4 +63,6 @@ public interface Settings extends AutoCloseable {
Settings getByPrefix(String prefix); Settings getByPrefix(String prefix);
boolean containsSetting(String setting); boolean containsSetting(String setting);
void close() throws IOException;
} }

View file

@ -1,4 +1,4 @@
package org.xbib.content; package org.xbib.settings;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path; import java.nio.file.Path;
@ -9,13 +9,12 @@ import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
public interface SettingsBuilder { public interface SettingsBuilder {
SettingsBuilder put(String setting, String value); SettingsBuilder put(String setting, String value);
SettingsBuilder put(String setting, Class<?> clazz);
SettingsBuilder put(String setting, boolean value); SettingsBuilder put(String setting, boolean value);
SettingsBuilder put(String setting, int value); SettingsBuilder put(String setting, int value);
@ -41,9 +40,9 @@ public interface SettingsBuilder {
SettingsBuilder loadFromResource(String resourceName, InputStream inputStream) throws SettingsException; SettingsBuilder loadFromResource(String resourceName, InputStream inputStream) throws SettingsException;
default SettingsBuilder fromJdbcConfTable(Connection connection, String id, String type) throws SQLException { default SettingsBuilder fromJdbc(Connection connection, String statement, String[] params) throws SQLException {
try (PreparedStatement statement = connection.prepareStatement("select key, value from conf where id = ? and type = ?", try (PreparedStatement preparedStatement = connection.prepareStatement(statement, params);
new String[]{id, type}); ResultSet resultSet = statement.executeQuery()) { ResultSet resultSet = preparedStatement.executeQuery()) {
while (resultSet.next()) { while (resultSet.next()) {
String key = resultSet.getString("key"); String key = resultSet.getString("key");
String value = resultSet.getString("value"); String value = resultSet.getString("value");
@ -57,17 +56,49 @@ public interface SettingsBuilder {
SettingsBuilder loadFromSystemEnvironment(); SettingsBuilder loadFromSystemEnvironment();
/**
* Runs across all the settings set on this builder and replaces {@code ${...}} elements in the
* each setting value according to the following logic:
* First, tries to resolve it against a System property ({@link System#getProperty(String)}), next,
* tries and resolve it against an environment variable ({@link System#getenv(String)}), next,
* tries and resolve it against a date pattern to resolve the current date,
* and last, tries and replace it with another setting already set on this builder.
* @param propertyPlaceholder the property place holder
* @param placeholderResolver the place holder resolver
* @return this builder
*/
SettingsBuilder replacePropertyPlaceholders(PropertyPlaceholder propertyPlaceholder, SettingsBuilder replacePropertyPlaceholders(PropertyPlaceholder propertyPlaceholder,
PlaceholderResolver placeholderResolver); PlaceholderResolver placeholderResolver);
/**
* A default method to replace property placeholders.
* @return this builder
*/
SettingsBuilder replacePropertyPlaceholders(); SettingsBuilder replacePropertyPlaceholders();
/**
* Optional settings refresh mechanism, using reloading from a path after a give time period.
* May not be implemented at all.
*/
SettingsBuilder setRefresh(Path path, long initialDelay, long period, TimeUnit timeUnit); SettingsBuilder setRefresh(Path path, long initialDelay, long period, TimeUnit timeUnit);
/**
* Map all settings keys and values to other keys and values.
* Example usage is to override settings from another priority source.
* @return this builder
*/
SettingsBuilder map(Function<Map.Entry<String, String>, Map.Entry<String, String>> function);
/**
* Return the Settings from this SettingsBuilder.
* @return the settings
*/
Settings build(); Settings build();
/**
* Returns true if the settings builder is empty.
* @return true if empty
*/
boolean isEmpty(); boolean isEmpty();
Map<String, String> map();
} }

View file

@ -1,4 +1,4 @@
package org.xbib.content; package org.xbib.settings;
/** /**
* A generic failure to handle settings. * A generic failure to handle settings.

View file

@ -1,4 +1,4 @@
package org.xbib.content; package org.xbib.settings;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;

View file

@ -1,6 +1,4 @@
package org.xbib.content.settings.datastructures; package org.xbib.settings;
import org.xbib.content.SettingsLoader;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;

View file

@ -0,0 +1,4 @@
/**
* Settings API.
*/
package org.xbib.settings;

View file

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

View file

@ -0,0 +1,12 @@
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.content.json.JsonSettingsLoader;
module org.xbib.settings.content.json {
exports org.xbib.settings.content.json;
requires transitive org.xbib.settings.content;
requires org.xbib.content.api;
requires org.xbib.content.json;
requires org.xbib.settings.api;
uses SettingsLoader;
provides SettingsLoader with JsonSettingsLoader;
}

View file

@ -1,7 +1,8 @@
package org.xbib.content.json; package org.xbib.settings.content.json;
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.settings.AbstractSettingsLoader; import org.xbib.content.json.JsonXContent;
import org.xbib.settings.content.AbstractSettingsLoader;
import java.util.Set; import java.util.Set;
/** /**

View file

@ -0,0 +1 @@
org.xbib.settings.content.json.JsonSettingsLoader

View file

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

View file

@ -0,0 +1,12 @@
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.content.yaml.YamlSettingsLoader;
module org.xbib.settings.content.yaml {
exports org.xbib.settings.content.yaml;
requires transitive org.xbib.settings.content;
requires org.xbib.content.api;
requires org.xbib.content.yaml;
requires org.xbib.settings.api;
uses SettingsLoader;
provides SettingsLoader with YamlSettingsLoader;
}

View file

@ -1,7 +1,8 @@
package org.xbib.content.yaml; package org.xbib.settings.content.yaml;
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.settings.AbstractSettingsLoader; import org.xbib.content.yaml.YamlXContent;
import org.xbib.settings.content.AbstractSettingsLoader;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;

View file

@ -0,0 +1 @@
org.xbib.settings.content.yaml.YamlSettingsLoader

View file

@ -1,5 +1,6 @@
dependencies { dependencies {
api project(':settings-api')
api project(':content-core') api project(':content-core')
api "org.xbib:datastructures-tiny:${project.property('xbib-datastructures.version')}" api "org.xbib:datastructures-tiny:${project.property('xbib-datastructures.version')}"
testImplementation project(":content-json") testImplementation project(":settings-content-json")
} }

View file

@ -0,0 +1,16 @@
import org.xbib.settings.SettingsBuilder;
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.content.ContentSettingsBuilder;
import org.xbib.settings.content.PropertiesSettingsLoader;
module org.xbib.settings.content {
uses SettingsLoader;
provides SettingsLoader with PropertiesSettingsLoader;
uses SettingsBuilder;
provides SettingsBuilder with ContentSettingsBuilder;
exports org.xbib.settings.content;
requires org.xbib.settings.api;
requires org.xbib.content.core;
requires org.xbib.datastructures.api;
requires transitive org.xbib.datastructures.tiny;
}

View file

@ -1,6 +1,6 @@
package org.xbib.content.settings; package org.xbib.settings.content;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.core.DefaultXContentBuilder; import org.xbib.content.core.DefaultXContentBuilder;

View file

@ -1,7 +1,9 @@
package org.xbib.content.settings; package org.xbib.settings.content;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsException;
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.SettingsLoaderService;
import org.xbib.datastructures.api.ByteSizeValue; import org.xbib.datastructures.api.ByteSizeValue;
import org.xbib.datastructures.api.TimeValue; import org.xbib.datastructures.api.TimeValue;
import org.xbib.datastructures.tiny.TinyMap; import org.xbib.datastructures.tiny.TinyMap;
@ -21,8 +23,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class ContentSettings implements Settings, AutoCloseable { public class ContentSettings implements Settings, AutoCloseable {
public static final ContentSettings EMPTY_SETTINGS = new ContentSettingsBuilder().build();
public static final String[] EMPTY_ARRAY = new String[0]; public static final String[] EMPTY_ARRAY = new String[0];
public static final int BUFFER_SIZE = 1024 * 4; public static final int BUFFER_SIZE = 1024 * 4;
@ -44,6 +44,10 @@ public class ContentSettings implements Settings, AutoCloseable {
} }
} }
public static ContentSettingsBuilder builder() {
return new ContentSettingsBuilder();
}
public static ContentSettings readSettingsFromMap(Map<String, Object> map) { public static ContentSettings readSettingsFromMap(Map<String, Object> map) {
ContentSettingsBuilder builder = new ContentSettingsBuilder(); ContentSettingsBuilder builder = new ContentSettingsBuilder();
for (Map.Entry<String, Object> entry : map.entrySet()) { for (Map.Entry<String, Object> entry : map.entrySet()) {
@ -290,7 +294,7 @@ public class ContentSettings implements Settings, AutoCloseable {
} }
@Override @Override
public Map<String, org.xbib.content.Settings> getGroups(String prefix) { public Map<String, Settings> getGroups(String prefix) {
String settingPrefix = prefix; String settingPrefix = prefix;
if (settingPrefix.charAt(settingPrefix.length() - 1) != '.') { if (settingPrefix.charAt(settingPrefix.length() - 1) != '.') {
settingPrefix = settingPrefix + "."; settingPrefix = settingPrefix + ".";
@ -313,7 +317,7 @@ public class ContentSettings implements Settings, AutoCloseable {
groupSettings.put(value, get(setting)); groupSettings.put(value, get(setting));
} }
} }
TinyMap.Builder<String, org.xbib.content.Settings> retVal = TinyMap.builder(); TinyMap.Builder<String, Settings> retVal = TinyMap.builder();
for (Map.Entry<String, Map<String, String>> entry : hashMap.entrySet()) { for (Map.Entry<String, Map<String, String>> entry : hashMap.entrySet()) {
retVal.put(entry.getKey(), new ContentSettings(entry.getValue())); retVal.put(entry.getKey(), new ContentSettings(entry.getValue()));
} }
@ -416,14 +420,11 @@ public class ContentSettings implements Settings, AutoCloseable {
private final AtomicBoolean closed; private final AtomicBoolean closed;
private final SettingsLoaderService settingsLoaderService;
DefaultSettingsRefresher(Path path, long initialDelay, long period, TimeUnit timeUnit) { DefaultSettingsRefresher(Path path, long initialDelay, long period, TimeUnit timeUnit) {
this.path = path; this.path = path;
this.executorService = Executors.newSingleThreadScheduledExecutor(); this.executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(this, initialDelay, period, timeUnit); executorService.scheduleAtFixedRate(this, initialDelay, period, timeUnit);
this.closed = new AtomicBoolean(); this.closed = new AtomicBoolean();
this.settingsLoaderService = new SettingsLoaderService();
} }
@Override @Override
@ -431,7 +432,7 @@ public class ContentSettings implements Settings, AutoCloseable {
try { try {
if (!closed.get()) { if (!closed.get()) {
String settingsSource = Files.readString(path); String settingsSource = Files.readString(path);
SettingsLoader settingsLoader = settingsLoaderService.loaderFromResource(path.toString()); SettingsLoader settingsLoader = SettingsLoaderService.getInstance().loaderFromResource(path.toString());
map = settingsLoader.load(settingsSource); map = settingsLoader.load(settingsSource);
} }
} catch (IOException e) { } catch (IOException e) {

View file

@ -1,10 +1,12 @@
package org.xbib.content.settings; package org.xbib.settings.content;
import org.xbib.content.PlaceholderResolver; import org.xbib.settings.PlaceholderResolver;
import org.xbib.content.PropertyPlaceholder; import org.xbib.settings.PropertyPlaceholder;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import org.xbib.content.SettingsBuilder; import org.xbib.settings.SettingsBuilder;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsException;
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.SettingsLoaderService;
import org.xbib.datastructures.tiny.TinyMap; import org.xbib.datastructures.tiny.TinyMap;
import java.io.IOException; import java.io.IOException;
@ -19,12 +21,15 @@ import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/** /**
* *
*/ */
public class ContentSettingsBuilder implements SettingsBuilder { public class ContentSettingsBuilder implements SettingsBuilder {
private final SettingsLoaderService settingsLoaderService = SettingsLoaderService.getInstance();
private final Map<String, String> map; private final Map<String, String> map;
private Path path; private Path path;
@ -39,18 +44,10 @@ public class ContentSettingsBuilder implements SettingsBuilder {
map = TinyMap.builder(); map = TinyMap.builder();
} }
public Map<String, String> map() {
return map;
}
public String remove(String key) { public String remove(String key) {
return map.remove(key); return map.remove(key);
} }
public String get(String key) {
return map.get(key);
}
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return map.isEmpty(); return map.isEmpty();
@ -238,7 +235,6 @@ public class ContentSettingsBuilder implements SettingsBuilder {
* @return builder * @return builder
*/ */
public ContentSettingsBuilder loadFromString(String source) { public ContentSettingsBuilder loadFromString(String source) {
SettingsLoaderService settingsLoaderService = new SettingsLoaderService();
SettingsLoader settingsLoader = settingsLoaderService.loaderFromString(source); SettingsLoader settingsLoader = settingsLoaderService.loaderFromString(source);
try { try {
Map<String, String> loadedSettings = settingsLoader.load(source); Map<String, String> loadedSettings = settingsLoader.load(source);
@ -272,7 +268,6 @@ public class ContentSettingsBuilder implements SettingsBuilder {
*/ */
@Override @Override
public ContentSettingsBuilder loadFromResource(String resourceName, InputStream inputStream) throws SettingsException { public ContentSettingsBuilder loadFromResource(String resourceName, InputStream inputStream) throws SettingsException {
SettingsLoaderService settingsLoaderService = new SettingsLoaderService();
SettingsLoader settingsLoader = settingsLoaderService.loaderFromResource(resourceName); SettingsLoader settingsLoader = settingsLoaderService.loaderFromResource(resourceName);
try { try {
Map<String, String> loadedSettings = settingsLoader Map<String, String> loadedSettings = settingsLoader
@ -357,6 +352,12 @@ public class ContentSettingsBuilder implements SettingsBuilder {
return this; 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;
}
public ContentSettings build() { public ContentSettings build() {
return new ContentSettings(map, path, initialDelay, period, timeUnit); return new ContentSettings(map, path, initialDelay, period, timeUnit);
} }

View file

@ -1,7 +1,7 @@
package org.xbib.content.settings; package org.xbib.settings.content;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;

View file

@ -0,0 +1,4 @@
/**
* Classes for settings.
*/
package org.xbib.settings.content;

View file

@ -0,0 +1 @@
org.xbib.settings.content.ContentSettingsBuilder

View file

@ -0,0 +1 @@
org.xbib.settings.content.PropertiesSettingsLoader

View file

@ -1,16 +1,16 @@
package org.xbib.content.settings.test; package org.xbib.settings.content.test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import org.xbib.content.core.XContentHelper; import org.xbib.content.core.XContentHelper;
import org.xbib.content.io.BytesArray; import org.xbib.content.io.BytesArray;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
import org.xbib.content.json.JsonSettingsLoader; import org.xbib.settings.content.json.JsonSettingsLoader;
import org.xbib.content.json.JsonXContent; import org.xbib.content.json.JsonXContent;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;

View file

@ -1,4 +1,4 @@
dependencies { dependencies {
api project(':content-settings-datastructures') api project(':settings-datastructures')
api "org.xbib:datastructures-json-tiny:${project.property('xbib-datastructures.version')}" api "org.xbib:datastructures-json-tiny:${project.property('xbib-datastructures.version')}"
} }

View file

@ -0,0 +1,10 @@
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.datastructures.json.JsonSettingsLoader;
module org.xbib.settings.datastructures.json {
exports org.xbib.settings.datastructures.json;
requires transitive org.xbib.settings.datastructures;
requires org.xbib.datastructures.json.tiny;
uses SettingsLoader;
provides SettingsLoader with JsonSettingsLoader;
}

View file

@ -1,6 +1,6 @@
package org.xbib.content.settings.datastructures.json; package org.xbib.settings.datastructures.json;
import org.xbib.content.settings.datastructures.AbstractSettingsLoader; import org.xbib.settings.datastructures.AbstractSettingsLoader;
import org.xbib.datastructures.api.DataStructure; import org.xbib.datastructures.api.DataStructure;
import org.xbib.datastructures.json.tiny.Json; import org.xbib.datastructures.json.tiny.Json;
import java.util.Set; import java.util.Set;

View file

@ -1,4 +1,4 @@
/** /**
* JSON settings with the datastructures package. * JSON settings with the datastructures package.
*/ */
package org.xbib.content.settings.datastructures.json; package org.xbib.settings.datastructures.json;

View file

@ -0,0 +1 @@
org.xbib.settings.datastructures.json.JsonSettingsLoader

View file

@ -1,9 +1,9 @@
package org.xbib.content.settings.datastructures.json.test; package org.xbib.settings.datastructures.json.test;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import org.xbib.content.settings.datastructures.json.JsonSettingsLoader; import org.xbib.settings.datastructures.json.JsonSettingsLoader;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;

View file

@ -1,4 +1,4 @@
/** /**
* Testing JSON settings with the datastructures package. * Testing JSON settings with the datastructures package.
*/ */
package org.xbib.content.settings.datastructures.json.test; package org.xbib.settings.datastructures.json.test;

View file

@ -1,4 +1,4 @@
dependencies { dependencies {
api project(':content-settings-datastructures') api project(':settings-datastructures')
api "org.xbib:datastructures-yaml-tiny:${project.property('xbib-datastructures.version')}" api "org.xbib:datastructures-yaml-tiny:${project.property('xbib-datastructures.version')}"
} }

View file

@ -0,0 +1,10 @@
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.datastructures.yaml.YamlSettingsLoader;
module org.xbib.settings.datastructures.yaml {
exports org.xbib.settings.datastructures.yaml;
requires transitive org.xbib.settings.datastructures;
requires org.xbib.datastructures.yaml.tiny;
uses SettingsLoader;
provides SettingsLoader with YamlSettingsLoader;
}

View file

@ -1,6 +1,6 @@
package org.xbib.content.settings.datastructures.yaml; package org.xbib.settings.datastructures.yaml;
import org.xbib.content.settings.datastructures.AbstractSettingsLoader; import org.xbib.settings.datastructures.AbstractSettingsLoader;
import org.xbib.datastructures.api.DataStructure; import org.xbib.datastructures.api.DataStructure;
import org.xbib.datastructures.yaml.tiny.Yaml; import org.xbib.datastructures.yaml.tiny.Yaml;

View file

@ -1,4 +1,4 @@
/** /**
* YAML settings with the datastructures package. * YAML settings with the datastructures package.
*/ */
package org.xbib.content.settings.datastructures.yaml; package org.xbib.settings.datastructures.yaml;

View file

@ -0,0 +1 @@
org.xbib.settings.datastructures.yaml.YamlSettingsLoader

View file

@ -1,11 +1,11 @@
package org.xbib.content.settings.datastructures.yaml.test; package org.xbib.settings.datastructures.yaml.test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import org.xbib.content.settings.datastructures.yaml.YamlSettingsLoader; import org.xbib.settings.datastructures.yaml.YamlSettingsLoader;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;

View file

@ -1,4 +1,4 @@
/** /**
* Testing YAML settings with the datastructures package. * Testing YAML settings with the datastructures package.
*/ */
package org.xbib.content.settings.datastructures.yaml.test; package org.xbib.settings.datastructures.yaml.test;

View file

@ -1,4 +1,4 @@
dependencies { dependencies {
api project(':content-api') api project(':settings-api')
api "org.xbib:datastructures-tiny:${project.property('xbib-datastructures.version')}" api "org.xbib:datastructures-tiny:${project.property('xbib-datastructures.version')}"
} }

View file

@ -0,0 +1,15 @@
import org.xbib.settings.SettingsBuilder;
import org.xbib.settings.SettingsLoader;
import org.xbib.settings.datastructures.DatastructureSettingsBuilder;
import org.xbib.settings.datastructures.PropertiesSettingsLoader;
module org.xbib.settings.datastructures {
uses SettingsLoader;
provides SettingsLoader with PropertiesSettingsLoader;
uses SettingsBuilder;
provides SettingsBuilder with DatastructureSettingsBuilder;
exports org.xbib.settings.datastructures;
requires transitive org.xbib.settings.api;
requires org.xbib.datastructures.tiny;
requires transitive org.xbib.datastructures.api;
}

View file

@ -1,6 +1,6 @@
package org.xbib.content.settings.datastructures; package org.xbib.settings.datastructures;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import org.xbib.datastructures.api.Builder; import org.xbib.datastructures.api.Builder;
import org.xbib.datastructures.api.DataStructure; import org.xbib.datastructures.api.DataStructure;
import org.xbib.datastructures.api.ListNode; import org.xbib.datastructures.api.ListNode;

View file

@ -1,7 +1,7 @@
package org.xbib.content.settings.datastructures; package org.xbib.settings.datastructures;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import org.xbib.content.SettingsException; import org.xbib.settings.SettingsException;
import org.xbib.datastructures.api.ByteSizeValue; import org.xbib.datastructures.api.ByteSizeValue;
import org.xbib.datastructures.api.TimeValue; import org.xbib.datastructures.api.TimeValue;
import org.xbib.datastructures.tiny.TinyMap; import org.xbib.datastructures.tiny.TinyMap;
@ -21,6 +21,10 @@ public class DatastructureSettings implements Settings {
this.map = map; this.map = map;
} }
public static DatastructureSettingsBuilder builder() {
return new DatastructureSettingsBuilder();
}
public static DatastructureSettings fromMap(Map<String, Object> map) { public static DatastructureSettings fromMap(Map<String, Object> map) {
DatastructureSettingsBuilder builder = new DatastructureSettingsBuilder(); DatastructureSettingsBuilder builder = new DatastructureSettingsBuilder();
for (Map.Entry<String, Object> entry : map.entrySet()) { for (Map.Entry<String, Object> entry : map.entrySet()) {
@ -233,7 +237,7 @@ public class DatastructureSettings implements Settings {
} }
@Override @Override
public Map<String, org.xbib.content.Settings> getGroups(String prefix) { public Map<String, Settings> getGroups(String prefix) {
String settingPrefix = prefix; String settingPrefix = prefix;
if (settingPrefix.charAt(settingPrefix.length() - 1) != '.') { if (settingPrefix.charAt(settingPrefix.length() - 1) != '.') {
settingPrefix = settingPrefix + "."; settingPrefix = settingPrefix + ".";
@ -255,7 +259,7 @@ public class DatastructureSettings implements Settings {
groupSettings.put(value, get(o)); groupSettings.put(value, get(o));
} }
} }
TinyMap.Builder<String, org.xbib.content.Settings> retVal = TinyMap.builder(); TinyMap.Builder<String, Settings> retVal = TinyMap.builder();
for (String key : hashMap.keySet()) { for (String key : hashMap.keySet()) {
TinyMap.Builder<String, String> value = hashMap.get(key); TinyMap.Builder<String, String> value = hashMap.get(key);
retVal.put(key, new DatastructureSettings(value.build())); retVal.put(key, new DatastructureSettings(value.build()));

View file

@ -1,11 +1,12 @@
package org.xbib.content.settings.datastructures; package org.xbib.settings.datastructures;
import org.xbib.content.PlaceholderResolver; import org.xbib.settings.PlaceholderResolver;
import org.xbib.content.PropertyPlaceholder; import org.xbib.settings.PropertyPlaceholder;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import org.xbib.content.SettingsBuilder; import org.xbib.settings.SettingsBuilder;
import org.xbib.content.SettingsException; import org.xbib.settings.SettingsException;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import org.xbib.settings.SettingsLoaderService;
import org.xbib.datastructures.tiny.TinyMap; import org.xbib.datastructures.tiny.TinyMap;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -19,6 +20,7 @@ import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -34,18 +36,10 @@ public class DatastructureSettingsBuilder implements SettingsBuilder {
map = TinyMap.builder(); map = TinyMap.builder();
} }
public Map<String, String> map() {
return map;
}
public String remove(String key) { public String remove(String key) {
return map.remove(key); return map.remove(key);
} }
public String get(String key) {
return map.get(key);
}
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return map.isEmpty(); return map.isEmpty();
@ -64,19 +58,6 @@ public class DatastructureSettingsBuilder implements SettingsBuilder {
return this; return this;
} }
/**
* Sets a setting with the provided setting key and class as value.
*
* @param key The setting key
* @param clazz The setting class value
* @return The builder
*/
@Override
public DatastructureSettingsBuilder put(String key, Class<?> clazz) {
map.put(key, clazz.getName());
return this;
}
/** /**
* Sets the setting with the provided setting key and the boolean value. * Sets the setting with the provided setting key and the boolean value.
* *
@ -308,17 +289,6 @@ public class DatastructureSettingsBuilder implements SettingsBuilder {
return this; return this;
} }
/**
* Runs across all the settings set on this builder and replaces {@code ${...}} elements in the
* each setting value according to the following logic:
* <p>
* First, tries to resolve it against a System property ({@link System#getProperty(String)}), next,
* tries and resolve it against an environment variable ({@link System#getenv(String)}), next,
* tries and resolve it against a date pattern to resolve the current date,
* and last, tries and replace it with another setting already set on this builder.
*
* @return builder
*/
@Override @Override
public DatastructureSettingsBuilder replacePropertyPlaceholders() { public DatastructureSettingsBuilder replacePropertyPlaceholders() {
return replacePropertyPlaceholders(new PropertyPlaceholder("${", "}", false), return replacePropertyPlaceholders(new PropertyPlaceholder("${", "}", false),
@ -348,6 +318,12 @@ public class DatastructureSettingsBuilder implements SettingsBuilder {
return this; 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 @Override
public DatastructureSettings build() { public DatastructureSettings build() {
return new DatastructureSettings(map.build()); return new DatastructureSettings(map.build());

View file

@ -1,6 +1,6 @@
package org.xbib.content.settings.datastructures; package org.xbib.settings.datastructures;
import org.xbib.content.SettingsLoader; import org.xbib.settings.SettingsLoader;
import org.xbib.datastructures.tiny.TinyMap; import org.xbib.datastructures.tiny.TinyMap;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;

View file

@ -1,4 +1,4 @@
/** /**
* Classes for settings using the datastructures API. * Classes for settings using the datastructures API.
*/ */
package org.xbib.content.settings.datastructures; package org.xbib.settings.datastructures;

View file

@ -0,0 +1 @@
org.xbib.settings.datastructures.DatastructureSettingsBuilder

View file

@ -0,0 +1 @@
org.xbib.settings.datastructures.PropertiesSettingsLoader

View file

@ -1,7 +1,7 @@
package org.xbib.content.settings.datastructures.test; package org.xbib.settings.datastructures.test;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.Settings; import org.xbib.settings.Settings;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;

View file

@ -6,10 +6,13 @@ include 'content-language'
include 'content-json' include 'content-json'
include 'content-rdf' include 'content-rdf'
include 'content-resource' include 'content-resource'
include 'content-settings'
include 'content-smile' include 'content-smile'
include 'content-xml' include 'content-xml'
include 'content-yaml' include 'content-yaml'
include 'content-settings-datastructures' include 'settings-api'
include 'content-settings-datastructures-json' include 'settings-content'
include 'content-settings-datastructures-yaml' include 'settings-content-json'
include 'settings-content-yaml'
include 'settings-datastructures'
include 'settings-datastructures-json'
include 'settings-datastructures-yaml'