mirror of
https://github.com/plexusorg/toml4j.git
synced 2024-12-28 19:24:15 +00:00
Indexed navigation in compound keys and shallow merging of defaults
This commit is contained in:
parent
2f355b47f3
commit
0af30b90ac
6 changed files with 76 additions and 27 deletions
6
pom.xml
6
pom.xml
|
@ -47,6 +47,12 @@
|
|||
<version>1.4.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
@ -18,6 +18,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.parboiled.Parboiled;
|
||||
import org.parboiled.parserunners.RecoveringParseRunner;
|
||||
|
@ -44,21 +46,23 @@ import com.google.gson.Gson;
|
|||
*/
|
||||
public class Toml {
|
||||
|
||||
private static Pattern ARRAY_INDEX_PATTERN = Pattern.compile("(.*)\\[(\\d+)\\]");
|
||||
private Map<String, Object> values = new HashMap<String, Object>();
|
||||
private final Toml defaults;
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* Creates Toml instance with no defaults.
|
||||
*/
|
||||
public Toml() {
|
||||
this((Toml) null);
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param defaults fallback values used when the requested key or table is not present.
|
||||
*/
|
||||
public Toml(Toml defaults) {
|
||||
this.defaults = defaults;
|
||||
this(defaults, new HashMap<String, Object>());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,7 +181,7 @@ public class Toml {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Toml getTable(String key) {
|
||||
return new Toml((Map<String, Object>) get(key));
|
||||
return new Toml(null, (Map<String, Object>) get(key));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,8 +197,9 @@ public class Toml {
|
|||
}
|
||||
|
||||
ArrayList<Toml> tables = new ArrayList<Toml>();
|
||||
|
||||
for (Map<String, Object> table : tableArray) {
|
||||
tables.add(new Toml(table));
|
||||
tables.add(new Toml(null, table));
|
||||
}
|
||||
|
||||
return tables;
|
||||
|
@ -219,6 +224,7 @@ public class Toml {
|
|||
*/
|
||||
public <T> T to(Class<T> targetClass) {
|
||||
HashMap<String, Object> valuesCopy = new HashMap<String, Object>(values);
|
||||
|
||||
if (defaults != null) {
|
||||
for (Map.Entry<String, Object> entry : defaults.values.entrySet()) {
|
||||
if (!valuesCopy.containsKey(entry.getKey())) {
|
||||
|
@ -226,7 +232,7 @@ public class Toml {
|
|||
}
|
||||
}
|
||||
}
|
||||
Gson gson = new Gson();
|
||||
|
||||
String json = gson.toJson(valuesCopy);
|
||||
return gson.fromJson(json, targetClass);
|
||||
}
|
||||
|
@ -235,32 +241,32 @@ public class Toml {
|
|||
private Object get(String key) {
|
||||
String[] split = key.split("\\.");
|
||||
Object current = new HashMap<String, Object>(values);
|
||||
Object currentDefaults = defaults != null ? defaults.values : null;
|
||||
|
||||
for (String splitKey : split) {
|
||||
Matcher matcher = ARRAY_INDEX_PATTERN.matcher(splitKey);
|
||||
int index = -1;
|
||||
|
||||
if (matcher.find()) {
|
||||
splitKey = matcher.group(1);
|
||||
index = Integer.parseInt(matcher.group(2), 10);
|
||||
}
|
||||
|
||||
current = ((Map<String, Object>) current).get(splitKey);
|
||||
if (currentDefaults != null) {
|
||||
currentDefaults = ((Map<String, Object>) currentDefaults).get(splitKey);
|
||||
if (current instanceof Map && currentDefaults instanceof Map) {
|
||||
for (Map.Entry<String, Object> entry : ((Map<String, Object>) currentDefaults).entrySet()) {
|
||||
if (!((Map<String, Object>) current).containsKey(entry.getKey())) {
|
||||
((Map<String, Object>) current).put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current == null && currentDefaults != null) {
|
||||
current = currentDefaults;
|
||||
|
||||
if (index > -1 && current != null) {
|
||||
current = ((List<?>) current).get(index);
|
||||
}
|
||||
|
||||
if (current == null) {
|
||||
return null;
|
||||
return defaults != null ? defaults.get(key) : null;
|
||||
}
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
private Toml(Map<String, Object> values) {
|
||||
private Toml(Toml defaults, Map<String, Object> values) {
|
||||
this.values = values != null ? values : Collections.<String, Object>emptyMap();
|
||||
this.defaults = null;
|
||||
this.defaults = defaults;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ public class TableArrayTest {
|
|||
|
||||
@Test
|
||||
public void should_parse_table_array() throws Exception {
|
||||
Toml toml = new Toml().parse(new File(getClass().getResource("products_table_array.toml").getFile()));
|
||||
Toml toml = new Toml().parse(file("products_table_array"));
|
||||
|
||||
List<Toml> products = toml.getTables("products");
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class TableArrayTest {
|
|||
|
||||
@Test
|
||||
public void should_parse_nested_table_arrays() throws Exception {
|
||||
Toml toml = new Toml().parse(new File(getClass().getResource("fruit_table_array.toml").getFile()));
|
||||
Toml toml = new Toml().parse(file("fruit_table_array"));
|
||||
|
||||
List<Toml> fruits = toml.getTables("fruit");
|
||||
|
||||
|
@ -56,4 +56,23 @@ public class TableArrayTest {
|
|||
|
||||
assertEquals(3, toml.getTable("a").getTable("b").getTables("c").get(0).getLong("id").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_navigate_array_with_compound_key() throws Exception {
|
||||
Toml toml = new Toml().parse(file("fruit_table_array"));
|
||||
|
||||
List<Toml> appleVarieties = toml.getTables("fruit[0].variety");
|
||||
Toml appleVariety = toml.getTable("fruit[0].variety[1]");
|
||||
String bananaVariety = toml.getString("fruit[1].variety[0].name");
|
||||
|
||||
assertEquals(2, appleVarieties.size());
|
||||
assertEquals("red delicious", appleVarieties.get(0).getString("name"));
|
||||
assertEquals("granny smith", appleVariety.getString("name"));
|
||||
assertEquals("plantain", bananaVariety);
|
||||
}
|
||||
|
||||
private File file(String fileName) {
|
||||
return new File(getClass().getResource(fileName + ".toml").getFile());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -13,7 +16,7 @@ public class TomlDefaultsTest {
|
|||
|
||||
@Before
|
||||
public void before() {
|
||||
defaultToml = new Toml().parse("a = \"a\"\n[group]\na=\"a\"");
|
||||
defaultToml = new Toml().parse("a = \"a\"\n [group]\n a=\"a\"\n [[array]]\n b=1 [[array]]\n b=2");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -52,10 +55,22 @@ public class TomlDefaultsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void should_fall_back_to_key_within_table() throws Exception {
|
||||
Toml toml = new Toml(defaultToml).parse("[group]\nb=1");
|
||||
public void should_fall_back_to_table_array() throws Exception {
|
||||
Toml toml = new Toml(defaultToml).parse("");
|
||||
|
||||
assertThat(toml.getTables("array"), hasSize(2));
|
||||
assertThat(toml.getLong("array[1].b"), Matchers.equalTo(2L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_perform_shallow_merge() throws Exception {
|
||||
Toml toml = new Toml(defaultToml).parse("[group]\nb=1\n [[array]]\n b=0");
|
||||
Toml toml2 = new Toml(defaultToml).parse("[[array]]\n b=1 [[array]]\n b=2 [[array]]\n b=3");
|
||||
|
||||
assertEquals(1, toml.getTable("group").getLong("b").intValue());
|
||||
assertEquals("a", toml.getTable("group").getString("a"));
|
||||
assertNull(toml.getTable("group").getString("a"));
|
||||
assertThat(toml.getTables("array"), hasSize(1));
|
||||
assertEquals(0, toml.getLong("array[0].b").intValue());
|
||||
assertThat(toml2.getTables("array"), hasSize(3));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.moandjiezana.toml.testutils;
|
|||
import java.lang.annotation.ElementType;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -17,5 +18,6 @@ public class ExtraPrimitives {
|
|||
public Character character;
|
||||
public ElementType elementType;
|
||||
public URL url;
|
||||
public URI uri;
|
||||
public Set<String> set;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ anInteger=7
|
|||
character="u"
|
||||
elementType="CONSTRUCTOR"
|
||||
url="http://www.example.com"
|
||||
uri="http://www.test.com"
|
||||
set=["a", "b"]
|
||||
[group]
|
||||
key="value"
|
||||
|
|
Loading…
Reference in a new issue