From b0e933fb28b6180a084656bf48ddb502b6bb25c9 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Tue, 16 Dec 2014 00:37:20 +0200
Subject: [PATCH 01/12] Prepared README for release
---
README.md | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 7a5bcb4..68c18d5 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# toml4j
-toml4j is a [TOML 0.3.1](https://github.com/toml-lang/toml/tree/v0.3.1) parser for Java that uses the [Parboiled](http://www.parboiled.org) PEG parser.
+toml4j is a [TOML 0.3.1](https://github.com/toml-lang/toml/tree/v0.3.1) parser for Java.
-[![Build Status](https://travis-ci.org/mwanji/toml4j.svg?branch=wip)](https://travis-ci.org/mwanji/toml4j) [![Coverage Status](https://img.shields.io/coveralls/mwanji/toml4j.svg)](https://coveralls.io/r/mwanji/toml4j?branch=wip)
+[![Build Status](https://travis-ci.org/mwanji/toml4j.svg)](https://travis-ci.org/mwanji/toml4j) [![Coverage Status](https://img.shields.io/coveralls/mwanji/toml4j.svg)](https://coveralls.io/r/mwanji/toml4j)
For the bleeding-edge version integrating the latest specs, see the [work-in-progress branch](https://github.com/mwanji/toml4j/tree/wip).
@@ -14,10 +14,12 @@ Add the following dependency to your POM (or equivalent for other dependency man
com.moandjiezana.tomltoml4j
- 0.2.0
+ 0.3.1
````
+Requires Java 1.6.
+
## Quick start
````java
From 3cec32eb8ec22a2861207916a42be20c922deb80 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Tue, 16 Dec 2014 00:47:10 +0200
Subject: [PATCH 02/12] Added Maven Central to badges
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 68c18d5..1aee02c 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
toml4j is a [TOML 0.3.1](https://github.com/toml-lang/toml/tree/v0.3.1) parser for Java.
-[![Build Status](https://travis-ci.org/mwanji/toml4j.svg)](https://travis-ci.org/mwanji/toml4j) [![Coverage Status](https://img.shields.io/coveralls/mwanji/toml4j.svg)](https://coveralls.io/r/mwanji/toml4j)
+[![Maven Central](https://img.shields.io/maven-central/v/com.moandjiezana.toml/toml4j.svg)](https://search.maven.org/#search|gav|1|g%3A%22com.moandjiezana.toml%22%20AND%20a%3A%22toml4j%22) [![Build Status](https://shields.io/travis/mwanji/toml4j.svg)](https://travis-ci.org/mwanji/toml4j) [![Coverage Status](https://img.shields.io/coveralls/mwanji/toml4j.svg)](https://coveralls.io/r/mwanji/toml4j)
For the bleeding-edge version integrating the latest specs, see the [work-in-progress branch](https://github.com/mwanji/toml4j/tree/wip).
From 8a16f487f5320bc1ce671149c630845c337ad85e Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Tue, 16 Dec 2014 00:49:00 +0200
Subject: [PATCH 03/12] Fixed Travis CI badge
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 1aee02c..6138335 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
toml4j is a [TOML 0.3.1](https://github.com/toml-lang/toml/tree/v0.3.1) parser for Java.
-[![Maven Central](https://img.shields.io/maven-central/v/com.moandjiezana.toml/toml4j.svg)](https://search.maven.org/#search|gav|1|g%3A%22com.moandjiezana.toml%22%20AND%20a%3A%22toml4j%22) [![Build Status](https://shields.io/travis/mwanji/toml4j.svg)](https://travis-ci.org/mwanji/toml4j) [![Coverage Status](https://img.shields.io/coveralls/mwanji/toml4j.svg)](https://coveralls.io/r/mwanji/toml4j)
+[![Maven Central](https://img.shields.io/maven-central/v/com.moandjiezana.toml/toml4j.svg)](https://search.maven.org/#search|gav|1|g%3A%22com.moandjiezana.toml%22%20AND%20a%3A%22toml4j%22) [![Build Status](https://img.shields.io/travis/mwanji/toml4j.svg)](https://travis-ci.org/mwanji/toml4j) [![Coverage Status](https://img.shields.io/coveralls/mwanji/toml4j.svg)](https://coveralls.io/r/mwanji/toml4j)
For the bleeding-edge version integrating the latest specs, see the [work-in-progress branch](https://github.com/mwanji/toml4j/tree/wip).
From 7805561133cc2ec235d5611baab77418d03503b0 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Tue, 16 Dec 2014 01:06:37 +0200
Subject: [PATCH 04/12] [maven-release-plugin] prepare release toml4j-0.3.1
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index b399907..637eb10 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.moandjiezana.tomltoml4j
- 1.0.0-SNAPSHOT
+ 0.3.1toml4jA parser for TOMLhttp://moandjiezana.com/toml/toml4j
From e425f81011285aa22c54dc4b711b4af655a2ec13 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Tue, 16 Dec 2014 01:06:46 +0200
Subject: [PATCH 05/12] [maven-release-plugin] prepare for next development
iteration
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 637eb10..c3e60bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.moandjiezana.tomltoml4j
- 0.3.1
+ 0.3.2-SNAPSHOTtoml4jA parser for TOMLhttp://moandjiezana.com/toml/toml4j
From 28c57069c631ea15a39216e6064b38a84cb99c78 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Tue, 16 Dec 2014 01:07:59 +0200
Subject: [PATCH 06/12] Fixed Javadoc for Java 8
---
src/main/java/com/moandjiezana/toml/Toml.java | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/src/main/java/com/moandjiezana/toml/Toml.java b/src/main/java/com/moandjiezana/toml/Toml.java
index 740e40f..91b00a4 100644
--- a/src/main/java/com/moandjiezana/toml/Toml.java
+++ b/src/main/java/com/moandjiezana/toml/Toml.java
@@ -33,13 +33,13 @@ import com.google.gson.JsonElement;
* {@link #getList(String, Class)}, {@link #getTable(String)} and {@link #getTables(String)} return empty values if there is no matching key.
*
*
Example usage:
- *
+ *
* Toml toml = new Toml().parse(getTomlFile());
* String name = toml.getString("name");
* Long port = toml.getLong("server.ip"); // compound key. Is equivalent to:
* Long port2 = toml.getTable("server").getLong("ip");
* MyConfig config = toml.to(MyConfig.class);
- *
+ *
*
*/
public class Toml {
@@ -67,7 +67,7 @@ public class Toml {
/**
* Populates the current Toml instance with values from file.
*
- * @param file
+ * @param file The File to be read
* @return this instance
* @throws IllegalStateException If file contains invalid TOML
*/
@@ -82,7 +82,7 @@ public class Toml {
/**
* Populates the current Toml instance with values from inputStream.
*
- * @param inputStream
+ * @param inputStream Closed after it has been read.
* @return this instance
* @throws IllegalStateException If file contains invalid TOML
*/
@@ -93,7 +93,7 @@ public class Toml {
/**
* Populates the current Toml instance with values from reader.
*
- * @param reader
+ * @param reader Closed after it has been read.
* @return this instance
* @throws IllegalStateException If file contains invalid TOML
*/
@@ -122,7 +122,7 @@ public class Toml {
/**
* Populates the current Toml instance with values from tomlString.
*
- * @param tomlString
+ * @param tomlString String to be read.
* @return this instance
* @throws IllegalStateException If tomlString is not valid TOML
*/
@@ -169,9 +169,8 @@ public class Toml {
}
/**
- * If no value is found for key, an empty Toml instance is returned.
- *
- * @param key
+ * @param key A table name, not including square brackets.
+ * @return A new Toml instance. Empty if no value is found for key.
*/
@SuppressWarnings("unchecked")
public Toml getTable(String key) {
@@ -179,8 +178,8 @@ public class Toml {
}
/**
- * If no value is found for key, an empty list is returned.
- * @param key
+ * @param key Name of array of tables, not including square brackets.
+ * @return An empty List if no value is found for key.
*/
@SuppressWarnings("unchecked")
public List getTables(String key) {
@@ -214,7 +213,9 @@ public class Toml {
*
TOML array to {@link Set}
*
*
- * @param targetClass
+ * @param targetClass Class to deserialize TOML to.
+ * @param type of targetClass.
+ * @return A new instance of targetClass.
*/
public T to(Class targetClass) {
return to(targetClass, DEFAULT_GSON);
From 51fcf76e4e75c95f62ec738efedf870483cc0347 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Tue, 16 Dec 2014 01:14:07 +0200
Subject: [PATCH 07/12] [maven-release-plugin] prepare release toml4j-0.3.1
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index c3e60bf..637eb10 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.moandjiezana.tomltoml4j
- 0.3.2-SNAPSHOT
+ 0.3.1toml4jA parser for TOMLhttp://moandjiezana.com/toml/toml4j
From 98701694c430a084b7de8708b396ed1784511356 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Tue, 16 Dec 2014 01:14:16 +0200
Subject: [PATCH 08/12] [maven-release-plugin] prepare for next development
iteration
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 637eb10..c3e60bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.moandjiezana.tomltoml4j
- 0.3.1
+ 0.3.2-SNAPSHOTtoml4jA parser for TOMLhttp://moandjiezana.com/toml/toml4j
From db950ab05410768d4c6e2b0f5781efef4c9d11d6 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Wed, 14 Jan 2015 09:46:36 +0200
Subject: [PATCH 09/12] Added support for quoted keys
https://github.com/toml-lang/toml/pull/283
---
README.md | 11 +++
src/main/java/com/moandjiezana/toml/Keys.java | 33 +++++++++
.../java/com/moandjiezana/toml/Results.java | 2 +-
src/main/java/com/moandjiezana/toml/Toml.java | 9 +--
.../com/moandjiezana/toml/QuotedKeysTest.java | 67 +++++++++++++++++++
5 files changed, 117 insertions(+), 5 deletions(-)
create mode 100644 src/main/java/com/moandjiezana/toml/Keys.java
create mode 100644 src/test/java/com/moandjiezana/toml/QuotedKeysTest.java
diff --git a/README.md b/README.md
index 6138335..df15357 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,9 @@ name = "Mwanji Ezana"
[address]
street = "123 A Street"
city = "AnyVille"
+
+[contacts]
+ "email address" = me@example.com
````
````java
@@ -62,6 +65,7 @@ class Address {
class User {
String name;
Address address;
+ Map contacts;
}
````
@@ -70,10 +74,13 @@ User user = new Toml().parse(tomlFile).to(User.class);
assert user.name.equals("Mwanji Ezana");
assert user.address.street.equals("123 A Street");
+assert user.contacts.get("\"email address\"").equals("me@example.com");
````
Any keys not found in both the TOML and the class are ignored. Fields may be private.
+Quoted keys cannot be mapped directly to a Java object, but they can be used as keys within a `Map`.
+
All TOML primitives can be mapped, as well as a number of Java-specific types:
* A TOML Number can be converted to any primitive type (or the wrapper equivalent), `BigInteger` or `BigDecimal`
@@ -102,8 +109,11 @@ You can also navigate values within a table with a compound key of the form `tab
Non-existent keys return null.
+When retrieving quoted keys, the quotes must be used and the key must be spelled exactly the same way, including whitespace.
+
````
title = "TOML Example"
+"sub title" = "Now with quoted keys"
[database]
ports = [ 8001, 8001, 8002 ]
@@ -136,6 +146,7 @@ title = "TOML Example"
Toml toml = new Toml().parse(getTomlFile());
String title = toml.getString("title");
+String subTitle = toml.getString("\"sub title\"");
Boolean enabled = toml.getBoolean("database.enabled");
List ports = toml.getList("database.ports", Long.class);
String password = toml.getString("database.credentials.password");
diff --git a/src/main/java/com/moandjiezana/toml/Keys.java b/src/main/java/com/moandjiezana/toml/Keys.java
new file mode 100644
index 0000000..7478b8f
--- /dev/null
+++ b/src/main/java/com/moandjiezana/toml/Keys.java
@@ -0,0 +1,33 @@
+package com.moandjiezana.toml;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class Keys {
+
+ static String[] split(String key) {
+ List splitKey = new ArrayList();
+ StringBuilder current = new StringBuilder();
+ char[] chars = key.toCharArray();
+ boolean quoted = false;
+
+ for (char c : chars) {
+ if (c == '"') {
+ quoted = !quoted;
+ }
+ if (c != '.' || quoted) {
+ current.append(c);
+ } else {
+ splitKey.add(current.toString());
+ current = new StringBuilder();
+ }
+ }
+
+ splitKey.add(current.toString());
+
+ return splitKey.toArray(new String[0]);
+ }
+
+ private Keys() {}
+
+}
diff --git a/src/main/java/com/moandjiezana/toml/Results.java b/src/main/java/com/moandjiezana/toml/Results.java
index 84e5a53..73ad666 100644
--- a/src/main/java/com/moandjiezana/toml/Results.java
+++ b/src/main/java/com/moandjiezana/toml/Results.java
@@ -75,7 +75,7 @@ class Results {
stack.pop();
}
- String[] tableParts = tableName.split("\\.");
+ String[] tableParts = Keys.split(tableName);
for (int i = 0; i < tableParts.length; i++) {
String tablePart = tableParts[i];
Container currentContainer = stack.peek();
diff --git a/src/main/java/com/moandjiezana/toml/Toml.java b/src/main/java/com/moandjiezana/toml/Toml.java
index 91b00a4..a95b443 100644
--- a/src/main/java/com/moandjiezana/toml/Toml.java
+++ b/src/main/java/com/moandjiezana/toml/Toml.java
@@ -246,13 +246,14 @@ public class Toml {
@SuppressWarnings("unchecked")
private Object get(String key) {
- String[] split = key.split("\\.");
+ if (values.containsKey(key)) {
+ return values.get(key);
+ }
+
+ String[] split = Keys.split(key);
Object current = new HashMap(values);
for (int i = 0; i < split.length; i++) {
- if (i == 0 && values.containsKey(key)) {
- return values.get(key);
- }
String keyWithDot = join(Arrays.copyOfRange(split, i, split.length));
if (current instanceof Map && ((Map) current).containsKey(keyWithDot)) {
diff --git a/src/test/java/com/moandjiezana/toml/QuotedKeysTest.java b/src/test/java/com/moandjiezana/toml/QuotedKeysTest.java
new file mode 100644
index 0000000..4be4d80
--- /dev/null
+++ b/src/test/java/com/moandjiezana/toml/QuotedKeysTest.java
@@ -0,0 +1,67 @@
+package com.moandjiezana.toml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Map;
+
+import org.junit.Test;
+
+public class QuotedKeysTest {
+
+ @Test
+ public void should_accept_quoted_key_for_value() throws Exception {
+ Toml toml = new Toml().parse("\"127.0.0.1\" = \"localhost\" \n \"character encoding\" = \"UTF-8\" \n \"ʎǝʞ\" = \"value\"");
+
+ assertEquals("localhost", toml.getString("\"127.0.0.1\""));
+ assertEquals("UTF-8", toml.getString("\"character encoding\""));
+ assertEquals("value", toml.getString("\"ʎǝʞ\""));
+ }
+
+ @Test
+ public void should_accept_quoted_key_for_table_name() throws Exception {
+ Toml toml = new Toml().parse("[\"abc def\"]\n val = 1");
+
+ assertEquals(1L, toml.getTable("\"abc def\"").getLong("val").longValue());
+ }
+
+ @Test
+ public void should_accept_partially_quoted_table_name() throws Exception {
+ Toml toml = new Toml().parse("[dog.\"tater.man\"] \n type = \"pug0\" \n[dog.tater] \n type = \"pug1\"\n[dog.tater.man] \n type = \"pug2\"");
+ Toml dogs = toml.getTable("dog");
+
+ assertEquals("pug0", dogs.getTable("\"tater.man\"").getString("type"));
+ assertEquals("pug1", dogs.getTable("tater").getString("type"));
+ assertEquals("pug2", dogs.getTable("tater").getTable("man").getString("type"));
+ assertEquals("pug0", toml.getString("dog.\"tater.man\".type"));
+ assertEquals("pug2", toml.getString("dog.tater.man.type"));
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void should_conserve_quoted_key_in_map() throws Exception {
+ Toml toml = new Toml().parse("[dog.\"tater.man\"] \n type = \"pug0\" \n[dog.tater] \n type = \"pug1\"\n[dog.tater.man] \n type = \"pug2\"");
+ Toml dogs = toml.getTable("dog");
+
+ Map> map = dogs.to(Map.class);
+
+ assertEquals("pug0", map.get("\"tater.man\"").get("type"));
+ assertEquals("pug1", map.get("tater").get("type"));
+ assertEquals("pug2", ((Map) map.get("tater").get("man")).get("type"));
+ }
+
+ @Test
+ public void should_convert() throws Exception {
+ Quoted quoted = new Toml().parse("\"ʎǝʞ\" = \"value\" \n[map] \n \"ʎǝʞ\" = \"value\"").to(Quoted.class);
+
+ assertNull(quoted.ʎǝʞ);
+ assertEquals("value", quoted.map.get("\"ʎǝʞ\""));
+ }
+
+ private static class Quoted {
+
+ String ʎǝʞ;
+
+ Map map;
+ }
+}
From 8fd7e6691ccff3ea3cf412195aecfc287f88592f Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Wed, 14 Jan 2015 10:07:26 +0200
Subject: [PATCH 10/12] Changed badges to match wip branch
[ci skip]
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index df15357..13fc33a 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
toml4j is a [TOML 0.3.1](https://github.com/toml-lang/toml/tree/v0.3.1) parser for Java.
-[![Maven Central](https://img.shields.io/maven-central/v/com.moandjiezana.toml/toml4j.svg)](https://search.maven.org/#search|gav|1|g%3A%22com.moandjiezana.toml%22%20AND%20a%3A%22toml4j%22) [![Build Status](https://img.shields.io/travis/mwanji/toml4j.svg)](https://travis-ci.org/mwanji/toml4j) [![Coverage Status](https://img.shields.io/coveralls/mwanji/toml4j.svg)](https://coveralls.io/r/mwanji/toml4j)
+[![Maven Central](https://img.shields.io/maven-central/v/com.moandjiezana.toml/toml4j.svg)](https://search.maven.org/#search|gav|1|g%3A%22com.moandjiezana.toml%22%20AND%20a%3A%22toml4j%22) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Build Status](https://img.shields.io/travis/mwanji/toml4j/wip.svg)](https://travis-ci.org/mwanji/toml4j) [![Coverage Status](https://img.shields.io/coveralls/mwanji/toml4j.svg)](https://coveralls.io/r/mwanji/toml4j?branch=wip)
For the bleeding-edge version integrating the latest specs, see the [work-in-progress branch](https://github.com/mwanji/toml4j/tree/wip).
From 62b2718a170d4f7eea858996ffbc24930897c3e6 Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Thu, 15 Jan 2015 11:02:22 +0200
Subject: [PATCH 11/12] Matched README to wip branch
---
README.md | 63 +++++++++++++++++++++++++++++--------------------------
1 file changed, 33 insertions(+), 30 deletions(-)
diff --git a/README.md b/README.md
index 13fc33a..f3a69a8 100644
--- a/README.md
+++ b/README.md
@@ -10,32 +10,32 @@ For the bleeding-edge version integrating the latest specs, see the [work-in-pro
Add the following dependency to your POM (or equivalent for other dependency managers):
-````xml
+```xml
com.moandjiezana.tomltoml4j0.3.1
-````
+```
Requires Java 1.6.
## Quick start
-````java
+```java
Toml toml = new Toml().parse(getTomlFile());
String someValue = toml.getString("someKey");
Date someDate = toml.getDate("someTable.someDate");
MyClass myClass = toml.to(MyClass.class);
-````
+```
## Usage
A `com.moandjiezana.toml.Toml` instance is populated by calling one of `parse(File)`, `parse(InputStream)`, `parse(Reader)` or `parse(String)`.
-````java
+```java
Toml toml = new Toml().parse("a=1");
-````
+```
An exception is thrown if the source is not valid TOML.
@@ -45,7 +45,7 @@ The data can then be accessed either by converting the Toml instance to your own
`Toml#to(Class)` maps a Toml instance to the given class.
-````
+```toml
name = "Mwanji Ezana"
[address]
@@ -54,9 +54,9 @@ name = "Mwanji Ezana"
[contacts]
"email address" = me@example.com
-````
+```
-````java
+```java
class Address {
String street;
String city;
@@ -67,28 +67,31 @@ class User {
Address address;
Map contacts;
}
-````
+```
-````java
+```java
User user = new Toml().parse(tomlFile).to(User.class);
assert user.name.equals("Mwanji Ezana");
assert user.address.street.equals("123 A Street");
assert user.contacts.get("\"email address\"").equals("me@example.com");
-````
+```
Any keys not found in both the TOML and the class are ignored. Fields may be private.
Quoted keys cannot be mapped directly to a Java object, but they can be used as keys within a `Map`.
-All TOML primitives can be mapped, as well as a number of Java-specific types:
+TOML primitives can be mapped to a number of Java types:
-* A TOML Number can be converted to any primitive type (or the wrapper equivalent), `BigInteger` or `BigDecimal`
-* A TOML string can be converted to a `String`, enum, `java.net.URI` or `java.net.URL`
-* A single-letter TOML string can be converted to a `char` or `Character`
-* Multiline and literal TOML strings can be converted to `String`
-* A TOML array can be converted to a `List`, `Set` or array. The generic type can be anything that can be converted.
-* A TOML table can be converted to a custom class or to a `Map`. The generic type of the value can be anything that can be converted.
+TOML | Java
+---- | ----
+Integer | `int`, `long` (or wrapper), `java.math.BigInteger`
+Float | `float`, `double` (or wrapper), `java.math.BigDecimal`
+String | `String`, enum, `java.net.URI`, `java.net.URL`
+One-letter String | `char`, `Character`
+Multiline and Literal Strings | `String`
+Array | `List`, `Set`, array. The generic type can be anything that can be converted.
+Table | Custom class, `Map`
Custom classes, Maps and collections thereof can be nested to any level. See [TomlToClassTest#should_convert_fruit_table_array()](src/test/java/com/moandjiezana/toml/TomlToClassTest.java) for an example.
@@ -109,9 +112,9 @@ You can also navigate values within a table with a compound key of the form `tab
Non-existent keys return null.
-When retrieving quoted keys, the quotes must be used and the key must be spelled exactly the same way, including whitespace.
+When retrieving quoted keys, the quotes must be used and the key must be spelled exactly the same way, including quotes and whitespace.
-````
+```toml
title = "TOML Example"
"sub title" = "Now with quoted keys"
@@ -140,9 +143,9 @@ title = "TOML Example"
location = "Geneva"
[[networks.operators]]
location = "Paris"
-````
+```
-````java
+```java
Toml toml = new Toml().parse(getTomlFile());
String title = toml.getString("title");
@@ -159,13 +162,13 @@ Toml network1 = toml.getTable("networks[0]");
String network2Name = toml.getString("networks[1].name"); // "Level 2"
List network3Operators = toml.getTables("networks[2].operators");
String network3Operator2Location = toml.getString("networks[2].operators[1].location"); // "Paris"
-````
+```
### Defaults
The constructor can be given a set of default values that will be used as fallbacks. For tables and table arrays, a shallow merge is performed.
-````
+```toml
# defaults
a = 2
b = 3
@@ -173,9 +176,9 @@ b = 3
[table]
c = 4
d = 5
-````
+```
-````
+```toml
a = 1
[table]
@@ -183,9 +186,9 @@ a = 1
[[array]]
d = 3
-````
+```
-````java
+```java
Toml defaults = new Toml().parse(getDefaultsFile());
Toml toml = new Toml(defaults).parse(getTomlFile());
@@ -195,7 +198,7 @@ Long c = toml.getLong("c"); // returns null
Long tableC = toml.getLong("table.c"); // returns 2, not 4
Long tableD = toml.getLong("table.d"); // returns null, not 5
Long arrayD = toml.getLong("array[0].d"); // returns 3
-````
+```
### Limitations
From df235e5a292d96e985b0f77b497402ee52a19f8d Mon Sep 17 00:00:00 2001
From: "moandji.ezana"
Date: Thu, 15 Jan 2015 11:44:14 +0200
Subject: [PATCH 12/12] Added support for quoted keys with index arrays
---
src/main/java/com/moandjiezana/toml/Keys.java | 87 +++++++++++++++++--
.../java/com/moandjiezana/toml/Results.java | 4 +-
.../moandjiezana/toml/StringConverter.java | 33 +++----
src/main/java/com/moandjiezana/toml/Toml.java | 44 ++--------
.../com/moandjiezana/toml/TomlParser.java | 7 +-
.../com/moandjiezana/toml/QuotedKeysTest.java | 25 +++++-
6 files changed, 132 insertions(+), 68 deletions(-)
diff --git a/src/main/java/com/moandjiezana/toml/Keys.java b/src/main/java/com/moandjiezana/toml/Keys.java
index 7478b8f..bffb319 100644
--- a/src/main/java/com/moandjiezana/toml/Keys.java
+++ b/src/main/java/com/moandjiezana/toml/Keys.java
@@ -1,33 +1,102 @@
package com.moandjiezana.toml;
+import static com.moandjiezana.toml.ValueConverterUtils.isComment;
+
import java.util.ArrayList;
import java.util.List;
class Keys {
- static String[] split(String key) {
- List splitKey = new ArrayList();
+ static class Key {
+ final String name;
+ final int index;
+ final String path;
+
+ Key(String name, int index, Key next) {
+ this.name = name;
+ this.index = index;
+ if (next != null) {
+ this.path = name + "." + next.path;
+ } else {
+ this.path = name;
+ }
+ }
+ }
+
+ static Keys.Key[] split(String key) {
+ List splitKey = new ArrayList();
StringBuilder current = new StringBuilder();
char[] chars = key.toCharArray();
boolean quoted = false;
+ boolean indexable = true;
+ boolean inIndex = false;
+ int index = -1;
- for (char c : chars) {
- if (c == '"') {
+ for (int i = chars.length - 1; i > -1; i--) {
+ char c = chars[i];
+ if (c == ']' && indexable) {
+ inIndex = true;
+ continue;
+ }
+ indexable = false;
+ if (c == '[' && inIndex) {
+ inIndex = false;
+ index = Integer.parseInt(current.toString());
+ current = new StringBuilder();
+ continue;
+ }
+ if (c == '"' && (i == 0 || chars[i - 1] != '\\')) {
quoted = !quoted;
+ indexable = false;
}
if (c != '.' || quoted) {
- current.append(c);
+ current.insert(0, c);
} else {
- splitKey.add(current.toString());
+ splitKey.add(0, new Key(current.toString(), index, !splitKey.isEmpty() ? splitKey.get(0) : null));
+ indexable = true;
+ index = -1;
current = new StringBuilder();
}
}
- splitKey.add(current.toString());
+ splitKey.add(0, new Key(current.toString(), index, !splitKey.isEmpty() ? splitKey.get(0) : null));
- return splitKey.toArray(new String[0]);
+ return splitKey.toArray(new Key[0]);
+ }
+
+ /**
+ * @param line raw TOML iine to parse
+ * @return null if line is not a valid table identifier
+ */
+ static String getTableName(String line) {
+ StringBuilder sb = new StringBuilder();
+ char[] chars = line.toCharArray();
+ boolean quoted = false;
+ boolean terminated = false;
+
+ for (int i = 1; i < chars.length; i++) {
+ char c = chars[i];
+ if (c == '"' && chars[i - 1] != '\\') {
+ quoted = !quoted;
+ } else if (!quoted && c == ']') {
+ terminated = true;
+ break;
+ } else if (!quoted && c == '[') {
+ break;
+ }
+
+ sb.append(c);
+ }
+
+ String tableName = sb.toString();
+
+ if (!terminated || !isComment(line.substring(tableName.length() + 2))) {
+ return null;
+ }
+
+ tableName = StringConverter.STRING_PARSER.replaceUnicodeCharacters(tableName);
+ return tableName;
}
private Keys() {}
-
}
diff --git a/src/main/java/com/moandjiezana/toml/Results.java b/src/main/java/com/moandjiezana/toml/Results.java
index 73ad666..1a3ae9b 100644
--- a/src/main/java/com/moandjiezana/toml/Results.java
+++ b/src/main/java/com/moandjiezana/toml/Results.java
@@ -75,9 +75,9 @@ class Results {
stack.pop();
}
- String[] tableParts = Keys.split(tableName);
+ Keys.Key[] tableParts = Keys.split(tableName);
for (int i = 0; i < tableParts.length; i++) {
- String tablePart = tableParts[i];
+ String tablePart = tableParts[i].name;
Container currentContainer = stack.peek();
if (tablePart.isEmpty()) {
errors.append("Empty implicit table: " + tableName + "!\n");
diff --git a/src/main/java/com/moandjiezana/toml/StringConverter.java b/src/main/java/com/moandjiezana/toml/StringConverter.java
index 05acfe7..2971e27 100644
--- a/src/main/java/com/moandjiezana/toml/StringConverter.java
+++ b/src/main/java/com/moandjiezana/toml/StringConverter.java
@@ -35,25 +35,16 @@ class StringConverter implements ValueConverter {
value = value.substring(1, stringTerminator);
value = replaceUnicodeCharacters(value);
-
- chars = value.toCharArray();
- for (int i = 0; i < chars.length - 1; i++) {
- char ch = chars[i];
- char next = chars[i + 1];
-
- if (ch == '\\' && next == '\\') {
- i++;
- } else if (ch == '\\' && !(next == 'b' || next == 'f' || next == 'n' || next == 't' || next == 'r' || next == '"' || next == '/' || next == '\\')) {
- return INVALID;
- }
- }
-
value = replaceSpecialCharacters(value);
+
+ if (value == null) {
+ return INVALID;
+ }
return value;
}
- private String replaceUnicodeCharacters(String value) {
+ String replaceUnicodeCharacters(String value) {
Matcher unicodeMatcher = UNICODE_REGEX.matcher(value);
while (unicodeMatcher.find()) {
@@ -62,7 +53,19 @@ class StringConverter implements ValueConverter {
return value;
}
- private String replaceSpecialCharacters(String value) {
+ String replaceSpecialCharacters(String value) {
+ char[] chars = value.toCharArray();
+ for (int i = 0; i < chars.length - 1; i++) {
+ char ch = chars[i];
+ char next = chars[i + 1];
+
+ if (ch == '\\' && next == '\\') {
+ i++;
+ } else if (ch == '\\' && !(next == 'b' || next == 'f' || next == 'n' || next == 't' || next == 'r' || next == '"' || next == '/' || next == '\\')) {
+ return null;
+ }
+ }
+
return value.replace("\\n", "\n")
.replace("\\\"", "\"")
.replace("\\t", "\t")
diff --git a/src/main/java/com/moandjiezana/toml/Toml.java b/src/main/java/com/moandjiezana/toml/Toml.java
index a95b443..f79b5b9 100644
--- a/src/main/java/com/moandjiezana/toml/Toml.java
+++ b/src/main/java/com/moandjiezana/toml/Toml.java
@@ -12,14 +12,12 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
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 com.google.gson.Gson;
@@ -250,52 +248,28 @@ public class Toml {
return values.get(key);
}
- String[] split = Keys.split(key);
Object current = new HashMap(values);
- for (int i = 0; i < split.length; i++) {
-
- String keyWithDot = join(Arrays.copyOfRange(split, i, split.length));
- if (current instanceof Map && ((Map) current).containsKey(keyWithDot)) {
- return ((Map) current).get(keyWithDot);
- }
-
- String splitKey = split[i];
- Matcher matcher = ARRAY_INDEX_PATTERN.matcher(splitKey);
- int index = -1;
-
- if (matcher.find()) {
- splitKey = matcher.group(1);
- index = Integer.parseInt(matcher.group(2), 10);
+ Keys.Key[] keys = Keys.split(key);
+
+ for (Keys.Key k : keys) {
+ if (k.index == -1 && current instanceof Map && ((Map) current).containsKey(k.path)) {
+ return ((Map) current).get(k.path);
}
- current = ((Map) current).get(splitKey);
+ current = ((Map) current).get(k.name);
- if (index > -1 && current != null) {
- current = ((List>) current).get(index);
+ if (k.index > -1 && current != null) {
+ current = ((List>) current).get(k.index);
}
if (current == null) {
return defaults != null ? defaults.get(key) : null;
}
}
-
+
return current;
}
-
- private String join(String[] strings) {
- StringBuilder sb = new StringBuilder();
-
- for (String string : strings) {
- sb.append(string).append('.');
- }
-
- if (sb.length() > 0) {
- sb.deleteCharAt(sb.length() - 1);
- }
-
- return sb.toString();
- }
private Toml(Toml defaults, Map values) {
this.values = values != null ? values : Collections.emptyMap();
diff --git a/src/main/java/com/moandjiezana/toml/TomlParser.java b/src/main/java/com/moandjiezana/toml/TomlParser.java
index d514c86..8e3594b 100644
--- a/src/main/java/com/moandjiezana/toml/TomlParser.java
+++ b/src/main/java/com/moandjiezana/toml/TomlParser.java
@@ -186,12 +186,7 @@ class TomlParser {
}
private String getTableName(String line) {
- List