toml4j/README.md

341 lines
9.0 KiB
Markdown
Raw Permalink Normal View History

2022-05-06 03:29:02 +00:00
# toml4j [![Build Status](https://ci.plex.us.org/job/toml4j/badge/icon)](https://ci.plex.us.org/job/toml4j/)
2013-02-26 07:57:26 +00:00
toml4j is a [TOML 0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md) parser for Java.
2014-04-07 13:41:14 +00:00
2013-02-26 19:49:57 +00:00
## Installation
2014-04-07 13:41:14 +00:00
Add the following dependency to your POM (or equivalent for other dependency managers):
2013-02-26 19:49:57 +00:00
2015-01-15 09:02:22 +00:00
```xml
2013-02-26 19:49:57 +00:00
<dependency>
<groupId>dev.plex</groupId>
2013-02-26 19:49:57 +00:00
<artifactId>toml4j</artifactId>
<version>0.7.3</version>
2013-02-26 19:49:57 +00:00
</dependency>
2015-01-15 09:02:22 +00:00
```
2013-02-26 19:49:57 +00:00
2022-05-06 02:04:31 +00:00
If you use Gradle, you can use the following code:
2021-07-17 11:35:17 +00:00
```gradle
repositories {
mavenCentral()
2022-05-06 02:04:31 +00:00
maven {
url = uri("https://nexus.telesphoreo.me/repository/totalfreedom/")
}
2021-07-17 11:35:17 +00:00
}
dependencies {
...
2022-05-06 02:04:31 +00:00
implementation("dev.plex:toml4j:0.7.3")
2021-07-17 11:35:17 +00:00
}
```
Requires Java 17 above.
2014-12-15 22:37:20 +00:00
2014-04-07 13:41:14 +00:00
## Quick start
2015-01-15 09:02:22 +00:00
```java
2016-01-14 16:23:11 +00:00
Toml toml = new Toml().read(getTomlFile());
2014-04-07 13:41:14 +00:00
String someValue = toml.getString("someKey");
2014-04-10 13:21:40 +00:00
Date someDate = toml.getDate("someTable.someDate");
2014-04-07 13:41:14 +00:00
MyClass myClass = toml.to(MyClass.class);
2015-01-15 09:02:22 +00:00
```
2014-04-07 13:41:14 +00:00
2013-02-26 07:57:26 +00:00
## Usage
A `dev.plex.Toml` instance is populated by calling one of `read(File)`, `read(InputStream)`, `read(Reader)`, `read(String)` or `read(Toml)`.
2014-04-07 13:41:14 +00:00
2015-01-15 09:02:22 +00:00
```java
2016-01-14 16:23:11 +00:00
Toml toml = new Toml().read("a=1");
2015-01-15 09:02:22 +00:00
```
2014-04-07 13:41:14 +00:00
2014-04-10 13:21:40 +00:00
An exception is thrown if the source is not valid TOML.
2014-04-07 13:41:14 +00:00
The data can then be accessed either by converting the Toml instance to your own class or by accessing tables and keys by name.
2016-05-10 02:58:46 +00:00
### Maps
`Toml#toMap()` is a quick way to turn a Toml instance into a `Map<String, Object>`.
```java
Map<String, Object> map = new Toml().read("a=1").toMap();
```
### Custom classes
2014-04-07 13:41:14 +00:00
`Toml#to(Class<T>)` maps a Toml instance to the given class.
2015-01-15 09:02:22 +00:00
```toml
name = "Mwanji Ezana"
[address]
street = "123 A Street"
city = "AnyVille"
[contacts]
2015-03-11 21:06:55 +00:00
"email address" = "me@example.com"
2015-01-15 09:02:22 +00:00
```
2015-01-15 09:02:22 +00:00
```java
2014-04-07 13:41:14 +00:00
class Address {
String street;
String city;
}
class User {
String name;
Address address;
Map<String, Object> contacts;
2014-04-07 13:41:14 +00:00
}
2015-01-15 09:02:22 +00:00
```
2015-01-15 09:02:22 +00:00
```java
2016-01-14 16:23:11 +00:00
User user = new Toml().read(tomlFile).to(User.class);
2014-04-06 19:56:14 +00:00
assert user.name.equals("Mwanji Ezana");
assert user.address.street.equals("123 A Street");
assert user.contacts.get("\"email address\"").equals("me@example.com");
2015-01-15 09:02:22 +00:00
```
2014-04-10 13:21:40 +00:00
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`.
2015-01-15 09:02:22 +00:00
TOML primitives can be mapped to a number of Java types:
2014-04-10 13:21:40 +00:00
2015-01-15 09:02:22 +00:00
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<String, Object>`
2014-04-10 13:21:40 +00:00
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.
2014-04-06 19:56:14 +00:00
### Key names
2014-04-07 13:41:14 +00:00
Use the getters to retrieve the data:
* `getString(String)`
* `getDate(String)`
* `getBoolean(String)`
* `getLong(String)`
* `getDouble(String)`
2015-02-08 21:16:06 +00:00
* `getList(String)`
2014-04-10 13:21:40 +00:00
* `getTable(String)` returns a new Toml instance containing only the keys in that table.
* `getTables(String)`, for table arrays, returns `List<Toml>`.
2014-04-07 13:41:14 +00:00
2014-04-10 13:21:40 +00:00
You can also navigate values within a table with a compound key of the form `table.key`. Use a zero-based index such as `tableArray[0].key` to navigate table arrays.
2014-04-07 13:41:14 +00:00
2014-12-15 22:31:26 +00:00
Non-existent keys return null.
2014-04-07 13:41:14 +00:00
When retrieving quoted keys, the quotes must be used and the key must be spelled exactly the same way, including quotes and whitespace. The only exceptions are Unicode escapes: `"\u00B1" = "value"` would be retrieved with `toml.getString("\"±\"")`.
2015-01-15 09:02:22 +00:00
```toml
2014-04-07 13:41:14 +00:00
title = "TOML Example"
"sub title" = "Now with quoted keys"
2014-04-07 13:41:14 +00:00
[database]
ports = [ 8001, 8001, 8002 ]
enabled = true
2014-04-10 13:21:40 +00:00
[database.credentials]
password = "password"
2014-04-07 13:41:14 +00:00
[servers]
cluster = "hyades"
[servers.alpha]
ip = "10.0.0.1"
2014-04-10 13:21:40 +00:00
[[networks]]
name = "Level 1"
[networks.status]
bandwidth = 10
[[networks]]
name = "Level 2"
[[networks]]
name = "Level 3"
[[networks.operators]]
location = "Geneva"
[[networks.operators]]
location = "Paris"
2015-01-15 09:02:22 +00:00
```
2014-04-07 13:41:14 +00:00
2015-01-15 09:02:22 +00:00
```java
2016-01-14 16:23:11 +00:00
Toml toml = new Toml().read(getTomlFile());
2014-04-07 13:41:14 +00:00
String title = toml.getString("title");
String subTitle = toml.getString("\"sub title\"");
2014-04-07 13:41:14 +00:00
Boolean enabled = toml.getBoolean("database.enabled");
2015-02-08 21:16:06 +00:00
List<Long> ports = toml.getList("database.ports");
2014-04-10 13:21:40 +00:00
String password = toml.getString("database.credentials.password");
Toml servers = toml.getTable("servers");
String cluster = servers.getString("cluster"); // navigation is relative to current Toml instance
2014-04-07 13:41:14 +00:00
String ip = servers.getString("alpha.ip");
2014-04-06 19:56:14 +00:00
2014-04-10 13:21:40 +00:00
Toml network1 = toml.getTable("networks[0]");
String network2Name = toml.getString("networks[1].name"); // "Level 2"
List<Toml> network3Operators = toml.getTables("networks[2].operators");
String network3Operator2Location = toml.getString("networks[2].operators[1].location"); // "Paris"
2015-01-15 09:02:22 +00:00
```
2014-04-06 19:56:14 +00:00
### Defaults
2014-04-10 13:21:40 +00:00
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.
2016-07-12 11:10:10 +00:00
`Toml#read(Toml)` is used to merge two Toml instances:
```java
Toml toml1 = new Toml().read("a=1");
Toml toml2 = new Toml().read(getTomlFile());
Toml mergedToml = new Toml(toml1).read(toml2);
```
2015-03-30 20:57:14 +00:00
You can also call an overloaded version of the getters that take a default value. Note that the default value provided in the constructor take precedence over the one provided by the getter.
2015-01-15 09:02:22 +00:00
```toml
2014-04-10 13:21:40 +00:00
# defaults
a = 2
b = 3
[table]
c = 4
d = 5
2015-01-15 09:02:22 +00:00
```
2014-04-10 13:21:40 +00:00
2015-01-15 09:02:22 +00:00
```toml
2014-04-10 13:21:40 +00:00
a = 1
[table]
c = 2
[[array]]
d = 3
2015-01-15 09:02:22 +00:00
```
2014-04-06 19:56:14 +00:00
2015-01-15 09:02:22 +00:00
```java
2016-01-14 16:23:11 +00:00
Toml defaults = new Toml().read(getDefaultsFile());
Toml toml = new Toml(defaults).read(getTomlFile());
2014-04-06 19:56:14 +00:00
Long a = toml.getLong("a"); // returns 1, not 2
2015-03-30 20:57:14 +00:00
Long b = toml.getLong("b"); // returns 3, taken from defaults provided to constructor
Long bPrefersConstructor = toml.getLong("b", 5); // returns 3, not 5
2014-04-06 19:56:14 +00:00
Long c = toml.getLong("c"); // returns null
2015-03-30 20:57:14 +00:00
Long cWithDefault = toml.getLong("c", 5); // returns 5
2014-04-10 13:21:40 +00:00
Long tableC = toml.getLong("table.c"); // returns 2, not 4
2015-03-30 20:57:14 +00:00
Long tableD = toml.getLong("table.d"); // returns null, not 5, because of shallow merge
2014-04-10 13:21:40 +00:00
Long arrayD = toml.getLong("array[0].d"); // returns 3
2015-01-15 09:02:22 +00:00
```
2014-04-06 19:56:14 +00:00
2015-04-28 10:07:34 +00:00
### Reflection
2015-06-12 13:25:23 +00:00
`Toml#entrySet()` returns a Set of [Map.Entry](http://docs.oracle.com/javase/6/docs/api/java/util/Map.Entry.html) instances. Modifications to the returned Set are not reflected in the Toml instance. Note that Map.Entry#setValue() will throw an UnsupportedOperationException.
```java
for (Map.Entry<String, Object> entry : myToml.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
```
2015-04-28 10:07:34 +00:00
`Toml#contains(String)` verifies that the instance contains a key of any type (primitive, table or array of tables) of the given name. `Toml#containsPrimitive(String)`, `Toml#containsTable(String)` and `Toml#containsTableArray(String)` return true only if a key exists and is a primitive, table or array of tables, respectively. Compound keys can be used to check existence at any depth.
```java
2016-01-14 16:23:11 +00:00
Toml toml = new Toml().read("a = 1");
toml.contains("a"); // true
toml.conatinsKey("a"); // true
toml.containsTable("a"); // false
toml.containsTableArray("a"); // false
```
### Converting Objects To TOML
You can write `Map`s and custom objects to a TOML `String`, `File`, `Writer`, or `OutputStream` with a `TomlWriter`. Each TomlWriter instance is customisable, immutable and threadsafe, so it can be reused and passed around. Constants and transient fields are ignored.
To write a `List` of objects as a table array, put the list in a `Map` or in a custom object.
```java
class AClass {
int anInt = 1;
int[] anArray = { 2, 3 };
}
TomlWriter tomlWriter = new TomlWriter();
AClass obj = new AClass();
2016-05-10 02:58:46 +00:00
Map<String, Object> map = new HashMap<String, Object>();
int[] intArray = { 2, 3 };
map.put("anInt", 1);
map.put("anArray", intArray);
String tomlString = tomlWriter.write(obj);
2016-05-10 02:58:46 +00:00
tomlString = tomlWriter.write(map);
tomlWriter.write(obj, new File("path/to/file"));
tomlWriter.write(obj, new ByteArrayOutputStream());
tomlWriter.write(obj, new OutputStreamWriter(anOutputStream));
/*
2015-07-01 07:32:16 +00:00
All methods output:
anInt = 1
2015-07-01 07:32:16 +00:00
anArray = [2, 3]
*/
```
2015-07-01 07:32:16 +00:00
You can customise formatting with a TomlWriter.Builder:
2015-06-28 21:15:38 +00:00
```java
2015-07-01 07:32:16 +00:00
class BClass {
Map<String, ?> aMap = new HashMap<String, Object>();
}
BClass obj = new BClass();
obj.aMap.put("item", 1);
TomlWriter tomlWriter = new TomlWriter.Builder()
.indentValuesBy(2)
.indentTablesBy(4)
.padArrayDelimitersBy(3)
.build();
2015-07-01 07:32:16 +00:00
String tomlString = tomlWriter.write(obj);
2015-06-28 21:15:38 +00:00
2015-07-01 07:32:16 +00:00
/*
Output:
[aMap]
item = 1
[aMap.a]
anInt = 1
anArray = [ 2, 3 ]
*/
```
### Threadsafety
`TomlWriter` is threadsafe, however the JDK's streams and `Writer` are not. Take care not to write to the same stream in parallel.
2014-12-15 13:44:03 +00:00
### Limitations
Date precision is limited to milliseconds.
2016-06-15 00:01:22 +00:00
## Changelog
Please see the [changelog](CHANGELOG.md).
## Contributing
2015-12-10 15:47:46 +00:00
Please see the [contribution guidelines](CONTRIBUTING.md).
2013-02-26 19:49:57 +00:00
## License
2022-05-06 03:29:02 +00:00
toml4j is copyright (c) 2013-2015 Moandji Ezana and is licensed under the [MIT License](LICENSE)