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