X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;ds=sidebyside;f=org.argeo.init%2Fsrc%2Forg%2Fargeo%2Fapi%2Finit%2FRuntimeManager.java;h=2344a86884fee44978dd2bc03aca3bd00db0223f;hb=2067f02c749114ea49d23a443ff4fa8cd3e6d30f;hp=113aa46c45189f714f56438ba62038b50509fcbb;hpb=6bfcb81dd21d8fdd9094610c00f5f8ad9c6a36a7;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.init/src/org/argeo/api/init/RuntimeManager.java b/org.argeo.init/src/org/argeo/api/init/RuntimeManager.java index 113aa46c4..2344a8688 100644 --- a/org.argeo.init/src/org/argeo/api/init/RuntimeManager.java +++ b/org.argeo.init/src/org/argeo/api/init/RuntimeManager.java @@ -1,11 +1,114 @@ package org.argeo.api.init; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Map; +import java.util.Properties; import java.util.function.Consumer; /** Dynamically manages multiple runtimes within a single JVM. */ public interface RuntimeManager { + String JVM_ARGS = "jvm.args"; + String STATE = "state"; + String OSGI_STORAGE_DIRNAME = "osgi"; + String DATA = "data"; + String SHARED = "shared"; + public void startRuntime(String relPath, Consumer> configCallback); public void closeRuntime(String relPath, boolean async); + + default void startRuntime(String relPath, String props) { + startRuntime(relPath, (config) -> { + loadProperties(config, props); + }); + } + + static void loadProperties(Map config, Properties properties) { + for (Object key : properties.keySet()) { + config.put(key.toString(), properties.getProperty(key.toString())); + } + } + + static void loadProperties(Map config, String props) { + Properties properties = new Properties(); + try (Reader reader = new StringReader(props)) { + properties.load(reader); + } catch (IOException e) { + throw new IllegalArgumentException("Cannot load properties", e); + } + loadProperties(config, properties); + } + + static void loadProperties(Map config, InputStream in) throws IOException { + Properties properties = new Properties(); + properties.load(in); + loadProperties(config, properties); + } + + static void loadDefaults(Map config) { + try (InputStream in = RuntimeManager.class.getResourceAsStream("defaults.ini")) { + loadProperties(config, in); + } catch (IOException e) { + throw new IllegalStateException("Could not load runtime defaults", e); + } + } + + /** + * Load configs recursively starting with the parent directories, until a + * jvm.args file is found. + */ + @Deprecated + static void loadConfig(Path dir, Map config) { + try { + Path jvmArgsPath = dir.resolve(RuntimeManager.JVM_ARGS); + if (!Files.exists(jvmArgsPath)) { + // load from parent directory + loadConfig(dir.getParent(), config); + } + + if (Files.exists(dir)) + for (Path p : Files.newDirectoryStream(dir, "*.ini")) { + try (InputStream in = Files.newInputStream(p)) { + loadConfig(in, config); + } + } + } catch (IOException e) { + throw new UncheckedIOException("Cannot load configuration from " + dir, e); + } + } + + /** + * Load config from a {@link Properties} formatted stream. If a property value + * starts with a '+' character, itis expected that the last character is a + * separator and it will be prepended to the existing value. + */ + @Deprecated + static void loadConfig(InputStream in, Map config) throws IOException { + Properties props = new Properties(); + props.load(in); + for (Object k : props.keySet()) { + String key = k.toString(); + String value = props.getProperty(key); + if (value.length() > 1 && '+' == value.charAt(0)) { + String currentValue = config.get(key); + if (currentValue == null || "".equals(currentValue)) { + // remove the + and the trailing separator + value = value.substring(1, value.length() - 1); + config.put(key, value); + } else { + // remove the + but keep the trailing separator + value = value.substring(1); + config.put(key, value + currentValue); + } + } else { + config.put(key, value); + } + } + } }