mirror of
https://github.com/lightbend/config.git
synced 2025-02-22 01:00:31 +08:00
Add path to ConfigNodeComplexValue if nonexistent
Add the desired path passed into the setValueOnPath method in ConfigNodeComplexValue if that path does not exist in the node.
This commit is contained in:
parent
faf8d42a6c
commit
fa0aaeabbf
@ -1,7 +0,0 @@
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
final class BasicConfigNode extends AbstractConfigNode{
|
||||
BasicConfigNode(Token t) {
|
||||
super(t);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.typesafe.config.impl;
|
||||
|
||||
final class ConfigNodeBasic extends AbstractConfigNode{
|
||||
ConfigNodeBasic(Token t) {
|
||||
super(t);
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ final class ConfigNodeComplexValue implements ConfigNode, ConfigNodeValue {
|
||||
return renderedText.toString();
|
||||
}
|
||||
|
||||
private ConfigNodeComplexValue changeValueOnPath(Path desiredPath, ConfigNodeValue value) {
|
||||
protected ConfigNodeComplexValue changeValueOnPath(Path desiredPath, ConfigNodeValue value) {
|
||||
ArrayList<ConfigNode> childrenCopy = (ArrayList<ConfigNode>)(children.clone());
|
||||
boolean replaced = value == null;
|
||||
ConfigNodeKeyValue node;
|
||||
@ -54,7 +54,7 @@ final class ConfigNodeComplexValue implements ConfigNode, ConfigNodeValue {
|
||||
if (node.value() instanceof ConfigNodeComplexValue) {
|
||||
Path remainingPath = desiredPath.subPath(key.length());
|
||||
if (!replaced) {
|
||||
node = node.replaceValue(((ConfigNodeComplexValue) node.value()).setValueOnPath(remainingPath, value));
|
||||
node = node.replaceValue(((ConfigNodeComplexValue) node.value()).changeValueOnPath(remainingPath, value));
|
||||
if (node.render() != children.get(keyValIndex.intValue()).render())
|
||||
replaced = true;
|
||||
childrenCopy.set(keyValIndex.intValue(), node);
|
||||
@ -69,7 +69,23 @@ final class ConfigNodeComplexValue implements ConfigNode, ConfigNodeValue {
|
||||
}
|
||||
|
||||
public ConfigNodeComplexValue setValueOnPath(Path desiredPath, ConfigNodeValue value) {
|
||||
return changeValueOnPath(desiredPath, value);
|
||||
ConfigNodeComplexValue node = changeValueOnPath(desiredPath, value);
|
||||
|
||||
// If the desired Path did not exist, add it
|
||||
if (node.render().equals(render())) {
|
||||
ArrayList<ConfigNode> childrenCopy = (ArrayList<ConfigNode>)children.clone();
|
||||
ArrayList<ConfigNode> newNodes = new ArrayList<ConfigNode>();
|
||||
newNodes.add(new ConfigNodeBasic(Tokens.newLine(null)));
|
||||
newNodes.add(new ConfigNodeKey(Tokens.newUnquotedText(null, desiredPath.render())));
|
||||
newNodes.add(new ConfigNodeBasic(Tokens.newIgnoredWhitespace(null, " ")));
|
||||
newNodes.add(new ConfigNodeBasic(Tokens.COLON));
|
||||
newNodes.add(new ConfigNodeBasic(Tokens.newIgnoredWhitespace(null, " ")));
|
||||
newNodes.add(value);
|
||||
newNodes.add(new ConfigNodeBasic(Tokens.newLine(null)));
|
||||
childrenCopy.add(new ConfigNodeKeyValue(newNodes));
|
||||
node = new ConfigNodeComplexValue(childrenCopy);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public ConfigNodeComplexValue removeValueOnPath(Path desiredPath) {
|
||||
|
@ -21,7 +21,7 @@ class ConfigNodeTest extends TestUtils {
|
||||
assertEquals(node.render(), token.tokenText())
|
||||
}
|
||||
|
||||
private def keyValueNodeTest(key: ConfigNodeKey, value: ConfigNodeValue, trailingWhitespace: BasicConfigNode, newValue: ConfigNodeValue) {
|
||||
private def keyValueNodeTest(key: ConfigNodeKey, value: ConfigNodeValue, trailingWhitespace: ConfigNodeBasic, newValue: ConfigNodeValue) {
|
||||
val keyValNode = nodeKeyValuePair(key, value, trailingWhitespace)
|
||||
assertEquals(key.render() + " : " + value.render() + trailingWhitespace.render(), keyValNode.render())
|
||||
assertEquals(key.render, keyValNode.key().render())
|
||||
@ -135,27 +135,26 @@ class ConfigNodeTest extends TestUtils {
|
||||
|
||||
@Test
|
||||
def replaceInNestedMapComplexValue() {
|
||||
val origText = "{\n\tfoo : bar\n\tbaz : {\n\t\t\"abc.def\" : 123\n\t\t//This is a comment about the below setting\n\n\t\tabc : {\n\t\t\t" +
|
||||
"def : \"this is a string\"\n\t\t\tghi : ${\"a.b\"}\n\t\t}\n\t}\n\tbaz.abc.ghi : 52\n\tbaz.abc.ghi : 53\n}"
|
||||
val lowestLevelMap = configNodeComplexValue(List(nodeOpenBrace, nodeLine(7),
|
||||
nodeKeyValuePair(nodeWhitespace("\t\t\t"), nodeUnquotedKey("def"), configNodeSimpleValue(tokenString("this is a string")), nodeLine(8)),
|
||||
nodeKeyValuePair(nodeWhitespace("\t\t\t"), nodeUnquotedKey("ghi"), configNodeSimpleValue(tokenKeySubstitution("a.b")), nodeLine(9)),
|
||||
nodeWhitespace("\t\t"), nodeCloseBrace))
|
||||
val higherLevelMap = configNodeComplexValue(List(nodeOpenBrace, nodeLine(3),
|
||||
nodeKeyValuePair(nodeWhitespace("\t\t"), configNodeKey(tokenString("abc.def")), configNodeSimpleValue(tokenInt(123)), nodeLine(4)),
|
||||
nodeWhitespace("\t\t"), configNodeBasic(tokenCommentDoubleSlash("This is a comment about the below setting")),
|
||||
nodeLine(5), nodeLine(6),
|
||||
nodeKeyValuePair(nodeWhitespace("\t\t"), nodeUnquotedKey("abc"), lowestLevelMap, nodeLine(10)), nodeWhitespace("\t"),
|
||||
val origText = "foo : bar\nbaz : {\n\t\"abc.def\" : 123\n\t//This is a comment about the below setting\n\n\tabc : {\n\t\t" +
|
||||
"def : \"this is a string\"\n\t\tghi : ${\"a.b\"}\n\t}\n}\nbaz.abc.ghi : 52\nbaz.abc.ghi : 53\n}"
|
||||
val lowestLevelMap = configNodeComplexValue(List(nodeOpenBrace, nodeLine(6),
|
||||
nodeKeyValuePair(nodeWhitespace("\t\t"), nodeUnquotedKey("def"), configNodeSimpleValue(tokenString("this is a string")), nodeLine(7)),
|
||||
nodeKeyValuePair(nodeWhitespace("\t\t"), nodeUnquotedKey("ghi"), configNodeSimpleValue(tokenKeySubstitution("a.b")), nodeLine(8)),
|
||||
nodeWhitespace("\t"), nodeCloseBrace))
|
||||
val higherLevelMap = configNodeComplexValue(List(nodeOpenBrace, nodeLine(2),
|
||||
nodeKeyValuePair(nodeWhitespace("\t"), configNodeKey(tokenString("abc.def")), configNodeSimpleValue(tokenInt(123)), nodeLine(3)),
|
||||
nodeWhitespace("\t"), configNodeBasic(tokenCommentDoubleSlash("This is a comment about the below setting")),
|
||||
nodeLine(4), nodeLine(5),
|
||||
nodeKeyValuePair(nodeWhitespace("\t"), nodeUnquotedKey("abc"), lowestLevelMap, nodeLine(9)), nodeWhitespace(""),
|
||||
nodeCloseBrace))
|
||||
val origNode = configNodeComplexValue(List(nodeOpenBrace, nodeLine(1),
|
||||
nodeKeyValuePair(nodeWhitespace("\t"), nodeUnquotedKey("foo"), configNodeSimpleValue(tokenUnquoted("bar")), nodeLine(2)),
|
||||
nodeKeyValuePair(nodeWhitespace("\t"), nodeUnquotedKey("baz"), higherLevelMap, nodeLine(11)),
|
||||
nodeKeyValuePair(nodeWhitespace("\t"), nodeUnquotedKey("baz.abc.ghi"), configNodeSimpleValue(tokenInt(52)), nodeLine(12)),
|
||||
nodeKeyValuePair(nodeWhitespace("\t"), nodeUnquotedKey("baz.abc.ghi"), configNodeSimpleValue(tokenInt(53)), nodeLine(13)),
|
||||
val origNode = configNodeComplexValue(List(nodeKeyValuePair(nodeUnquotedKey("foo"), configNodeSimpleValue(tokenUnquoted("bar")), nodeLine(1)),
|
||||
nodeKeyValuePair(nodeUnquotedKey("baz"), higherLevelMap, nodeLine(10)),
|
||||
nodeKeyValuePair(nodeUnquotedKey("baz.abc.ghi"), configNodeSimpleValue(tokenInt(52)), nodeLine(11)),
|
||||
nodeKeyValuePair(nodeUnquotedKey("baz.abc.ghi"), configNodeSimpleValue(tokenInt(53)), nodeLine(12)),
|
||||
nodeCloseBrace))
|
||||
assertEquals(origText, origNode.render())
|
||||
val finalText = "{\n\tfoo : bar\n\tbaz : {\n\t\t\"abc.def\" : true\n\t\t//This is a comment about the below setting\n\n\t\tabc : {\n\t\t\t" +
|
||||
"def : false\n\t\t}\n\t}\n\tbaz.abc.ghi : randomunquotedString\n}"
|
||||
val finalText = "foo : bar\nbaz : {\n\t\"abc.def\" : true\n\t//This is a comment about the below setting\n\n\tabc : {\n\t\t" +
|
||||
"def : false\n\t}\n}\nbaz.abc.ghi : randomunquotedString\n}\nbaz.abc.this.does.not.exist : doesnotexist\n"
|
||||
|
||||
//Can replace settings in nested maps
|
||||
// Paths with quotes in the name are treated as a single Path, rather than multiple sub-paths
|
||||
@ -165,6 +164,9 @@ class ConfigNodeTest extends TestUtils {
|
||||
// Repeats are removed
|
||||
newNode = newNode.setValueOnPath(Path.newPath("baz.abc.ghi"), configNodeSimpleValue(tokenUnquoted("randomunquotedString")))
|
||||
|
||||
// Missing paths are added to the top level
|
||||
newNode = newNode.setValueOnPath(Path.newPath("baz.abc.this.does.not.exist"), configNodeSimpleValue(tokenUnquoted("doesnotexist")))
|
||||
|
||||
// The above operations cause the resultant map to be rendered properly
|
||||
assertEquals(finalText, newNode.render())
|
||||
}
|
||||
|
@ -672,26 +672,26 @@ abstract trait TestUtils {
|
||||
}
|
||||
|
||||
def configNodeBasic(value: Token) = {
|
||||
new BasicConfigNode(value: Token)
|
||||
new ConfigNodeBasic(value: Token)
|
||||
}
|
||||
|
||||
def configNodeComplexValue(nodes: List[ConfigNode]) = {
|
||||
new ConfigNodeComplexValue(nodes.asJavaCollection)
|
||||
}
|
||||
|
||||
def nodeColon = new BasicConfigNode(Tokens.COLON)
|
||||
def nodeSpace = new BasicConfigNode(tokenUnquoted(" "))
|
||||
def nodeOpenBrace = new BasicConfigNode(Tokens.OPEN_CURLY)
|
||||
def nodeCloseBrace = new BasicConfigNode(Tokens.CLOSE_CURLY)
|
||||
def nodeLine(line: Integer) = new BasicConfigNode(tokenLine(line))
|
||||
def nodeWhitespace(whitespace: String) = new BasicConfigNode(tokenWhitespace(whitespace))
|
||||
def nodeColon = new ConfigNodeBasic(Tokens.COLON)
|
||||
def nodeSpace = new ConfigNodeBasic(tokenUnquoted(" "))
|
||||
def nodeOpenBrace = new ConfigNodeBasic(Tokens.OPEN_CURLY)
|
||||
def nodeCloseBrace = new ConfigNodeBasic(Tokens.CLOSE_CURLY)
|
||||
def nodeLine(line: Integer) = new ConfigNodeBasic(tokenLine(line))
|
||||
def nodeWhitespace(whitespace: String) = new ConfigNodeBasic(tokenWhitespace(whitespace))
|
||||
def nodeQuotedKey(key: String) = configNodeKey(tokenString(key))
|
||||
def nodeUnquotedKey(key: String) = configNodeKey(tokenUnquoted(key))
|
||||
def nodeKeyValuePair(key: ConfigNodeKey, value: ConfigNodeValue, trailingWhitespace: BasicConfigNode) = {
|
||||
def nodeKeyValuePair(key: ConfigNodeKey, value: ConfigNodeValue, trailingWhitespace: ConfigNodeBasic) = {
|
||||
val nodes = List(key, nodeSpace, nodeColon, nodeSpace, value, trailingWhitespace)
|
||||
new ConfigNodeKeyValue(nodes.asJavaCollection)
|
||||
}
|
||||
def nodeKeyValuePair(leadingWhitespace: BasicConfigNode, key: ConfigNodeKey, value: ConfigNodeValue, trailingWhitespace: BasicConfigNode) = {
|
||||
def nodeKeyValuePair(leadingWhitespace: ConfigNodeBasic, key: ConfigNodeKey, value: ConfigNodeValue, trailingWhitespace: ConfigNodeBasic) = {
|
||||
val nodes = List(leadingWhitespace, key, nodeSpace, nodeColon, nodeSpace, value, trailingWhitespace)
|
||||
new ConfigNodeKeyValue(nodes.asJavaCollection);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user