我正在寻找一种说法:
val c: Config = ConfigFactory.parseString("a=fox,b=dog")
val s: String = """This is a "quick" brown ${a}.\nThat is a lazy, lazy ${b}."""
println(c.resolveString(s))
// Should print:
// > This is a "quick" brown fox.
// > That is a lazy lazy dog.
我的两个想法:
s
转换为具有单一值的配置并使用resolveWith
- 但似乎引用可能非常棘手也许有一种更简单的方法?
答案 0 :(得分:1)
天真的解决方案:
class Resolver(vars: Config) {
private lazy val placeholderRegex = "(?<=\\$\\{).*?(?=\\})".r
def resolveString(s: String): String = {
placeholderRegex.findAllIn(s).foldLeft(s) { (str, v) =>
if (vars.hasPath(v)) str.replaceAll("\\Q${" + v + "}\\E", vars.getString(v)) else str
}
}
如果字符串不是很大并且没有疯狂数量的不同占位符,那应该没问题。
答案 1 :(得分:0)
我有类似的情况,我之前会自动推送弹性搜索索引定义 我启动了使用这些索引定义的作业。
在我的例子中,包含变量引用的字符串是 JSON索引/模板定义,它也来自typesafe配置。 (参见下面的es.template_or_index.json。)
我使用我在上面写的实用程序方法解析这些引用 apache.commons StrSubstitutor。
(参见:下面的VariableReferenceResolver.resolveReferences(字符串模板))
以下是我的配置示例。请注意该属性&#39; es.animal&#39;被注入到索引/模板json中。 这不能通过类型安全配置库的开箱即用功能来完成(但我想这会 是他们添加的一个很棒的功能!)
es {
// user and password credentials should not be checked in to git. deployer is expected to
// set these parameters into the their environment in whatever way is convenient -- .bashrc or whatever.
user = dummy
user = ${?ES_USER}
password = dummy.passwd
password = ${?ES_PASSWORD}
hostPort = "localhost:9200"
hostPort = ${?ES_HOST_PORT}
protocol = http
protocol = ${?ES_PROTOCOL}
animal = horse // This gets injected into the configuration property es.template_or_index.json
// Note: for template json there is a second round of interpolation performed so the json can reference any defined
// property of this configuration file (or anything it includes)
template_or_index {
name = test_template
json = """
{
"template": "${es.animal}_sql-*",
"settings": {
"number_of_shards": 50,
"number_of_replicas": 2
},
"mappings": {
"test_results" : {
"date_detection": false,
"properties" : {
"timestamp" : { "type" : "date"},
"yyyymmdd" : { "type" : "string", "index" : "not_analyzed"}
}
}
}
}
"""
}
}
package com.foo
import com.typesafe.config.Config;
import org.apache.commons.lang.text.StrLookup;
import org.apache.commons.lang.text.StrSubstitutor;
public class VariableReferenceResolver {
final StrSubstitutor substitutor;
static class ConfigStrLookup extends StrLookup {
private final Config config;
ConfigStrLookup(Config config) {
this.config = config;
}
public String lookup(String key) {
return config.getString(key);
}
}
public VariableReferenceResolver (Config config) {
substitutor=new StrSubstitutor(new ConfigStrLookup(config));
}
public String resolveReferences(String template) {
return substitutor.replace(template);
}
}
public class OtherClass {
private static void getIndexConfiguration(String path) throws IOException {
System.setProperty("config.file", path);
Config config = ConfigFactory.load();
String user = config.getString("es.user");
String password = config.getString("es.password");
String protocol = config.getString("es.protocol");
String hostPort = config.getString("es.hostPort");
String indexOrTemplateJson = config.getString("es.template_or_index.json");
String indexOrTemplateName = config.getString("es.template_or_index.name");
VariableReferenceResolver resolver = new VariableReferenceResolver(config);
String resolvedIndexOrTemplateJson = resolver.resolveReferences(indexOrTemplateJson);
File jsonFile = File.createTempFile("index-or-template-json", indexOrTemplateName);
Files.write(Paths.get(jsonFile.getAbsolutePath()), resolvedIndexOrTemplateJson.getBytes());
curlIndexOrTemplateCreateCommand =
String.format(
"curl -XPUT -k -u %s:%s %s://%s/_template/%s -d @%s",
user, password, protocol, hostPort, indexOrTemplateName, jsonFile.getAbsolutePath());
}
....
}