mirror of
https://github.com/plexusorg/toml4j.git
synced 2024-12-28 19:24:15 +00:00
Added support for simple table array
This commit is contained in:
parent
5c3c868682
commit
095e33a03b
8 changed files with 177 additions and 38 deletions
24
README.md
24
README.md
|
@ -85,6 +85,30 @@ Long c = toml.getLong("c"); // returns null
|
|||
|
||||
* Fail on invalid definitions
|
||||
|
||||
## Coming in 0.2.0
|
||||
|
||||
### Table arrays
|
||||
|
||||
Table arrays are mapped to `List`s with `Toml#getTables(String)`. Custom classes are also supported.
|
||||
|
||||
````
|
||||
[[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
|
||||
[[products]]
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
color = "gray"
|
||||
````
|
||||
|
||||
````java
|
||||
Toml toml = new Toml().parse(getTomlFile());
|
||||
|
||||
List<Toml> tables = toml.getTables("products");
|
||||
tables.get(1).getLong("sku"); // returns 284758393
|
||||
````
|
||||
|
||||
## License
|
||||
|
||||
toml4j is copyright of Moandji Ezana and is licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php)
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -14,6 +13,8 @@ import org.parboiled.Parboiled;
|
|||
import org.parboiled.parserunners.RecoveringParseRunner;
|
||||
import org.parboiled.support.ParsingResult;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
*
|
||||
* All getters can fall back to default values if they have been provided and will return null if no matching key exists.
|
||||
|
@ -86,6 +87,16 @@ public class Toml {
|
|||
return new Toml((Map<String, Object>) get(key));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Toml> getTables(String key) {
|
||||
ArrayList<Toml> tables = new ArrayList<Toml>();
|
||||
for (Map<String, Object> table : (List<Map<String, Object>>) get(key)) {
|
||||
tables.add(new Toml(table));
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object get(String key) {
|
||||
String[] split = key.split("\\.");
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -23,15 +24,19 @@ class TomlParser extends BaseParser<Object> {
|
|||
}
|
||||
|
||||
public Rule Toml() {
|
||||
return Sequence(push(new TomlParser.Results()), push(((TomlParser.Results) peek()).values), OneOrMore(FirstOf(Table(), '\n', Comment(), Key())));
|
||||
return Sequence(push(new TomlParser.Results()), push(((TomlParser.Results) peek()).values), OneOrMore(FirstOf(TableArray(), Table(), '\n', Comment(), Key())));
|
||||
}
|
||||
|
||||
Rule Table() {
|
||||
return Sequence(Sequence(TableDelimiter(), TableName(), addTable((String) pop()), TableDelimiter(), Spacing()), checkTable(match()));
|
||||
}
|
||||
|
||||
Rule TableArray() {
|
||||
return Sequence(Sequence(TableDelimiter(), TableDelimiter(), TableName(), addTableArray((String) pop()), TableDelimiter(), TableDelimiter(), Spacing()), checkTable(match()));
|
||||
}
|
||||
|
||||
boolean checkTable(String definition) {
|
||||
String afterBracket = definition.substring(definition.indexOf(']') + 1);
|
||||
String afterBracket = definition.substring(definition.lastIndexOf(']') + 1);
|
||||
for (char character : afterBracket.toCharArray()) {
|
||||
if (character == '#') {
|
||||
return true;
|
||||
|
@ -129,7 +134,6 @@ class TomlParser extends BaseParser<Object> {
|
|||
|
||||
Rule IllegalCharacters() {
|
||||
return Sequence(ZeroOrMore(Whitespace()), OneOrMore(TestNot('#', NewLine()), ANY));
|
||||
//return Sequence(ZeroOrMore(Whitespace()), TestNot('#', NewLine()), OneOrMore(ANY));
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
|
@ -152,38 +156,12 @@ class TomlParser extends BaseParser<Object> {
|
|||
return Sequence('#', ZeroOrMore(TestNot(NewLine()), ANY), FirstOf(NewLine(), EOI));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
boolean addTableArray(String name) {
|
||||
return addTable(name, true);
|
||||
}
|
||||
|
||||
boolean addTable(String name) {
|
||||
String[] split = name.split("\\.");
|
||||
|
||||
while (getContext().getValueStack().size() > 2) {
|
||||
drop();
|
||||
}
|
||||
|
||||
Map<String, Object> newTable = (Map<String, Object>) getContext().getValueStack().peek();
|
||||
|
||||
if (!results().tables.add(name)) {
|
||||
results().errors.append("Could not create key group ").append(name).append(": key group already exists!\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String splitKey : split) {
|
||||
if (!newTable.containsKey(splitKey)) {
|
||||
newTable.put(splitKey, new HashMap<String, Object>());
|
||||
}
|
||||
Object currentValue = newTable.get(splitKey);
|
||||
if (!(currentValue instanceof Map)) {
|
||||
results().errors.append("Could not create key group ").append(name).append(": key already has a value!\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
newTable = (Map<String, Object>) currentValue;
|
||||
}
|
||||
|
||||
push(newTable);
|
||||
|
||||
return true;
|
||||
return addTable(name, false);
|
||||
}
|
||||
|
||||
boolean addKey(String key, Object value) {
|
||||
|
@ -273,8 +251,59 @@ class TomlParser extends BaseParser<Object> {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void putValue(String name, Object value) {
|
||||
private boolean addTable(String name, boolean array) {
|
||||
String[] split = name.split("\\.");
|
||||
|
||||
while (getContext().getValueStack().size() > 2) {
|
||||
drop();
|
||||
}
|
||||
|
||||
Map<String, Object> newTable = (Map<String, Object>) getContext().getValueStack().peek();
|
||||
|
||||
boolean addedToTables = results().tables.add(name);
|
||||
if (!addedToTables && !array) {
|
||||
results().errors.append("Could not create table ").append(name).append(": table already exists!\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String splitKey : split) {
|
||||
if (!newTable.containsKey(splitKey)) {
|
||||
if (array) {
|
||||
ArrayList<Map<String, Object>> newTableList = new ArrayList<Map<String, Object>>();
|
||||
newTable.put(splitKey, newTableList);
|
||||
} else {
|
||||
newTable.put(splitKey, new HashMap<String, Object>());
|
||||
}
|
||||
}
|
||||
Object currentValue = newTable.get(splitKey);
|
||||
if ((array && !(currentValue instanceof List)) || (!array && !(currentValue instanceof Map))) {
|
||||
results().errors.append("Could not create table ").append(name).append(": key already has a value!\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentValue instanceof List) {
|
||||
Map<String, Object> newTableListItem = new HashMap<String,Object>();
|
||||
currentValue = ((List<Map<String, Object>>) currentValue).add(newTableListItem);
|
||||
currentValue = newTableListItem;
|
||||
}
|
||||
|
||||
newTable = (Map<String, Object>) currentValue;
|
||||
}
|
||||
|
||||
push(newTable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void putValue(String name, Object value) {
|
||||
Map<String, Object> values = (Map<String, Object>) peek();
|
||||
Object top = peek();
|
||||
if (top instanceof List) {
|
||||
values = ((List<Map<String, Object>>) top).get(((List<Map<String, Object>>) top).size() - 1);
|
||||
}
|
||||
if (values.containsKey(name)) {
|
||||
results().errors.append("Key ").append(name).append(" already exists!\n");
|
||||
return;
|
||||
|
@ -282,7 +311,7 @@ class TomlParser extends BaseParser<Object> {
|
|||
values.put(name, value);
|
||||
}
|
||||
|
||||
TomlParser.Results results() {
|
||||
private TomlParser.Results results() {
|
||||
return (Results) peek(getContext().getValueStack().size() - 1);
|
||||
}
|
||||
}
|
||||
|
|
32
src/test/java/com/moandjiezana/toml/TableArrayTest.java
Normal file
32
src/test/java/com/moandjiezana/toml/TableArrayTest.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
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()));
|
||||
|
||||
List<Toml> products = toml.getTables("products");
|
||||
|
||||
assertEquals(3, products.size());
|
||||
|
||||
assertEquals("Hammer", products.get(0).getString("name"));
|
||||
assertEquals(738594937L, products.get(0).getLong("sku").longValue());
|
||||
|
||||
Assert.assertNull(products.get(1).getString("name"));
|
||||
assertNull(products.get(1).getLong("sku"));
|
||||
|
||||
assertEquals("Nail", products.get(2).getString("name"));
|
||||
assertEquals(284758393L, products.get(2).getLong("sku").longValue());
|
||||
assertEquals("gray", products.get(2).getString("color"));
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import org.junit.Test;
|
|||
|
||||
import com.moandjiezana.toml.testutils.TableAsMap;
|
||||
import com.moandjiezana.toml.testutils.TomlPrimitives;
|
||||
import com.moandjiezana.toml.testutils.TomlTableArrays;
|
||||
import com.moandjiezana.toml.testutils.TomlTables;
|
||||
|
||||
public class TomlToClassTest {
|
||||
|
@ -69,6 +70,18 @@ public class TomlToClassTest {
|
|||
assertEquals("value", tableAsMap.group.get("key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_convert_table_array() throws Exception {
|
||||
TomlTableArrays toml = new Toml().parse(file("should_convert_table_array_to_class.toml")).to(TomlTableArrays.class);
|
||||
|
||||
assertEquals(2, toml.groupers.size());
|
||||
assertEquals("grouper 1", toml.groupers.get(0).string);
|
||||
assertEquals("grouper 2", toml.groupers.get(1).string);
|
||||
|
||||
assertEquals("My Name", toml.name);
|
||||
assertEquals(12, toml.primitives.number.intValue());
|
||||
}
|
||||
|
||||
private File file(String fileName) {
|
||||
return new File(getClass().getResource(fileName).getFile());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package com.moandjiezana.toml.testutils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TomlTableArrays {
|
||||
|
||||
public List<TomlPrimitives> groupers;
|
||||
public String name;
|
||||
public TomlPrimitives primitives;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
[[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
|
||||
[[products]]
|
||||
|
||||
[[products]]
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
color = "gray"
|
|
@ -0,0 +1,10 @@
|
|||
name="My Name"
|
||||
|
||||
[primitives]
|
||||
number=12
|
||||
|
||||
[[groupers]]
|
||||
string="grouper 1"
|
||||
|
||||
[[groupers]]
|
||||
string="grouper 2"
|
Loading…
Reference in a new issue