mirror of
https://github.com/plexusorg/toml4j.git
synced 2025-02-11 03:30:00 +00:00
Add writer indentation policy controls.
Set the default indentation to 0.
This commit is contained in:
parent
24a6503d19
commit
72941c146d
7 changed files with 185 additions and 37 deletions
|
@ -56,7 +56,7 @@ class MapValueWriter implements ValueWriter {
|
|||
|
||||
ValueWriter valueWriter = WRITERS.findWriterFor(fromValue);
|
||||
if (valueWriter.isTable() || valueWriter == TABLE_ARRAY_VALUE_WRITER) {
|
||||
valueWriter.write(fromValue, context.extend(quoteKey(key)));
|
||||
valueWriter.write(fromValue, context.pushTable(quoteKey(key)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class TableArrayValueWriter extends ArrayValueWriter {
|
|||
public void write(Object value, WriterContext context) {
|
||||
Collection values = normalize(value);
|
||||
|
||||
WriterContext subContext = context.extend().setIsArrayOfTable(true);
|
||||
WriterContext subContext = context.pushTableFromArray();
|
||||
|
||||
for (Object elem : values) {
|
||||
WRITERS.write(elem, subContext);
|
||||
|
|
|
@ -24,6 +24,9 @@ import static com.moandjiezana.toml.ValueWriters.WRITERS;
|
|||
* </code></pre>
|
||||
*/
|
||||
public class TomlWriter {
|
||||
|
||||
private WriterIndentationPolicy indentationPolicy = new WriterIndentationPolicy();
|
||||
|
||||
/**
|
||||
* Creates a TomlWriter instance.
|
||||
*/
|
||||
|
@ -36,7 +39,7 @@ public class TomlWriter {
|
|||
* @return a string containing the TOML representation of the given Object
|
||||
*/
|
||||
public String write(Object from) {
|
||||
return WRITERS.write(from);
|
||||
return WRITERS.write(from, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,4 +76,21 @@ public class TomlWriter {
|
|||
writer.write(write(from));
|
||||
writer.close();
|
||||
}
|
||||
|
||||
public WriterIndentationPolicy getIndentationPolicy() {
|
||||
return indentationPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link WriterIndentationPolicy} for this writer.
|
||||
*
|
||||
* If unset, the default policy (no indentation) is used.
|
||||
*
|
||||
* @param indentationPolicy the new policy
|
||||
* @return this TomlWriter instance
|
||||
*/
|
||||
public TomlWriter setIndentationPolicy(WriterIndentationPolicy indentationPolicy) {
|
||||
this.indentationPolicy = indentationPolicy;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ class ValueWriters {
|
|||
return OBJECT_VALUE_WRITER;
|
||||
}
|
||||
|
||||
String write(Object value) {
|
||||
WriterContext context = new WriterContext();
|
||||
String write(Object value, TomlWriter tomlWriter) {
|
||||
WriterContext context = new WriterContext(tomlWriter);
|
||||
write(value, context);
|
||||
|
||||
return context.output.toString();
|
||||
|
|
|
@ -1,26 +1,43 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class WriterContext {
|
||||
private String key = "";
|
||||
private String currentTableIndent = "";
|
||||
private String currentFieldIndent = "";
|
||||
private boolean isArrayOfTable = false;
|
||||
private final TomlWriter tomlWriter;
|
||||
StringBuilder output = new StringBuilder();
|
||||
|
||||
WriterContext(String key, StringBuilder output) {
|
||||
WriterContext(String key, String tableIndent, StringBuilder output, TomlWriter tomlWriter) {
|
||||
this.key = key;
|
||||
this.currentTableIndent = tableIndent;
|
||||
this.currentFieldIndent = tableIndent + fillStringWithSpaces(tomlWriter.getIndentationPolicy().getKeyValueIndent());
|
||||
this.output = output;
|
||||
this.tomlWriter = tomlWriter;
|
||||
}
|
||||
|
||||
WriterContext() {
|
||||
WriterContext(TomlWriter tomlWriter) {
|
||||
this.tomlWriter = tomlWriter;
|
||||
}
|
||||
|
||||
WriterContext extend(String newKey) {
|
||||
WriterContext pushTable(String newKey) {
|
||||
String newIndent = "";
|
||||
if (!key.isEmpty()) {
|
||||
newIndent = growIndent(tomlWriter.getIndentationPolicy());
|
||||
}
|
||||
|
||||
String fullKey = key + (key.isEmpty() ? newKey : "." + newKey);
|
||||
|
||||
return new WriterContext(fullKey, output);
|
||||
return new WriterContext(fullKey, newIndent, output, tomlWriter);
|
||||
}
|
||||
|
||||
WriterContext extend() {
|
||||
return new WriterContext(key, output);
|
||||
WriterContext pushTableFromArray() {
|
||||
WriterContext subContext = new WriterContext(key, currentTableIndent, output, tomlWriter);
|
||||
subContext.setIsArrayOfTable(true);
|
||||
|
||||
return subContext;
|
||||
}
|
||||
|
||||
void writeKey() {
|
||||
|
@ -32,6 +49,8 @@ class WriterContext {
|
|||
output.append('\n');
|
||||
}
|
||||
|
||||
output.append(currentTableIndent);
|
||||
|
||||
if (isArrayOfTable) {
|
||||
output.append("[[").append(key).append("]]\n");
|
||||
} else {
|
||||
|
@ -40,11 +59,24 @@ class WriterContext {
|
|||
}
|
||||
|
||||
void indent() {
|
||||
output.append(key.isEmpty() ? "" : " ");
|
||||
if (!key.isEmpty()) {
|
||||
output.append(currentFieldIndent);
|
||||
}
|
||||
}
|
||||
|
||||
WriterContext setIsArrayOfTable(boolean isArrayOfTable) {
|
||||
this.isArrayOfTable = isArrayOfTable;
|
||||
return this;
|
||||
}
|
||||
|
||||
private String growIndent(WriterIndentationPolicy indentationPolicy) {
|
||||
return currentTableIndent + fillStringWithSpaces(indentationPolicy.getTableIndent());
|
||||
}
|
||||
|
||||
private String fillStringWithSpaces(int count) {
|
||||
char[] chars = new char[count];
|
||||
Arrays.fill(chars, ' ');
|
||||
|
||||
return new String(chars);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
/**
|
||||
* Controls how a {@link TomlWriter} indents tables and key/value pairs.
|
||||
*
|
||||
* The default policy is to not indent.
|
||||
*/
|
||||
public class WriterIndentationPolicy {
|
||||
private int tableIndent = 0;
|
||||
private int keyValueIndent = 0;
|
||||
|
||||
public int getTableIndent() {
|
||||
return tableIndent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of spaces a nested table name is indented.
|
||||
*
|
||||
* @param tableIndent number of spaces to indent
|
||||
* @return this WriterIndentationPolicy instance
|
||||
*/
|
||||
public WriterIndentationPolicy setTableIndent(int tableIndent) {
|
||||
this.tableIndent = tableIndent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getKeyValueIndent() {
|
||||
return keyValueIndent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of spaces key/value pairs within a table are indented.
|
||||
*
|
||||
* @param keyValueIndent number of spaces to indent
|
||||
* @return this WriterIndentationPolicy instance
|
||||
*/
|
||||
public WriterIndentationPolicy setKeyValueIndent(int keyValueIndent) {
|
||||
this.keyValueIndent = keyValueIndent;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -60,21 +60,20 @@ public class ValueWriterTest {
|
|||
return dateString;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_write_nested_map() {
|
||||
class SubChild {
|
||||
int anInt;
|
||||
}
|
||||
class Child {
|
||||
SubChild subChild;
|
||||
int anInt;
|
||||
}
|
||||
class Parent {
|
||||
Map<String, Object> aMap;
|
||||
Child child;
|
||||
boolean aBoolean;
|
||||
}
|
||||
class SubChild {
|
||||
int anInt;
|
||||
}
|
||||
class Child {
|
||||
SubChild subChild;
|
||||
int anInt;
|
||||
}
|
||||
class Parent {
|
||||
Map<String, Object> aMap;
|
||||
Child child;
|
||||
boolean aBoolean;
|
||||
}
|
||||
|
||||
private Parent buildNestedMap() {
|
||||
Parent parent = new Parent();
|
||||
parent.aMap = new LinkedHashMap<String, Object>();
|
||||
parent.aMap.put("foo", 1);
|
||||
|
@ -86,7 +85,29 @@ public class ValueWriterTest {
|
|||
parent.child.subChild.anInt = 4;
|
||||
parent.aBoolean = true;
|
||||
|
||||
String output = new TomlWriter().write(parent);
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_write_nested_map() {
|
||||
String output = new TomlWriter().write(buildNestedMap());
|
||||
String expected = "aBoolean = true\n\n" +
|
||||
"[aMap]\n" +
|
||||
"foo = 1\n" +
|
||||
"bar = \"value1\"\n" +
|
||||
"\"baz.x\" = true\n\n" +
|
||||
"[child]\n" +
|
||||
"anInt = 2\n\n" +
|
||||
"[child.subChild]\n" +
|
||||
"anInt = 4\n";
|
||||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_follow_indentation_policy_of_indented_values() {
|
||||
String output = new TomlWriter().
|
||||
setIndentationPolicy(new WriterIndentationPolicy().setKeyValueIndent(2)).
|
||||
write(buildNestedMap());
|
||||
String expected = "aBoolean = true\n\n" +
|
||||
"[aMap]\n" +
|
||||
" foo = 1\n" +
|
||||
|
@ -99,6 +120,40 @@ public class ValueWriterTest {
|
|||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_follow_indentation_policy_of_indented_tables() {
|
||||
String output = new TomlWriter().
|
||||
setIndentationPolicy(new WriterIndentationPolicy().setTableIndent(2)).
|
||||
write(buildNestedMap());
|
||||
String expected = "aBoolean = true\n\n" +
|
||||
"[aMap]\n" +
|
||||
"foo = 1\n" +
|
||||
"bar = \"value1\"\n" +
|
||||
"\"baz.x\" = true\n\n" +
|
||||
"[child]\n" +
|
||||
"anInt = 2\n\n" +
|
||||
" [child.subChild]\n" +
|
||||
" anInt = 4\n";
|
||||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_follow_indentation_policy_of_indented_tables_and_values() {
|
||||
String output = new TomlWriter().
|
||||
setIndentationPolicy(new WriterIndentationPolicy().setTableIndent(2).setKeyValueIndent(2)).
|
||||
write(buildNestedMap());
|
||||
String expected = "aBoolean = true\n\n" +
|
||||
"[aMap]\n" +
|
||||
" foo = 1\n" +
|
||||
" bar = \"value1\"\n" +
|
||||
" \"baz.x\" = true\n\n" +
|
||||
"[child]\n" +
|
||||
" anInt = 2\n\n" +
|
||||
" [child.subChild]\n" +
|
||||
" anInt = 4\n";
|
||||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_write_array_of_primitive() {
|
||||
class ArrayTest {
|
||||
|
@ -128,9 +183,9 @@ public class ValueWriterTest {
|
|||
|
||||
String output = new TomlWriter().write(config);
|
||||
String expected = "[[table]]\n" +
|
||||
" anInt = 1\n\n" +
|
||||
"anInt = 1\n\n" +
|
||||
"[[table]]\n" +
|
||||
" anInt = 2\n";
|
||||
"anInt = 2\n";
|
||||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
|
@ -179,7 +234,7 @@ public class ValueWriterTest {
|
|||
B b = new B();
|
||||
}
|
||||
|
||||
assertEquals("[b.c]\n anInt = 1\n", new TomlWriter().write(new A()));
|
||||
assertEquals("[b.c]\nanInt = 1\n", new TomlWriter().write(new A()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -221,23 +276,23 @@ public class ValueWriterTest {
|
|||
basket.fruit[1].variety[0].name = "plantain";
|
||||
|
||||
String expected = "[[fruit]]\n" +
|
||||
" name = \"apple\"\n" +
|
||||
"name = \"apple\"\n" +
|
||||
"\n" +
|
||||
"[fruit.physical]\n" +
|
||||
" color = \"red\"\n" +
|
||||
" shape = \"round\"\n" +
|
||||
"color = \"red\"\n" +
|
||||
"shape = \"round\"\n" +
|
||||
"\n" +
|
||||
"[[fruit.variety]]\n" +
|
||||
" name = \"red delicious\"\n" +
|
||||
"name = \"red delicious\"\n" +
|
||||
"\n" +
|
||||
"[[fruit.variety]]\n" +
|
||||
" name = \"granny smith\"\n" +
|
||||
"name = \"granny smith\"\n" +
|
||||
"\n" +
|
||||
"[[fruit]]\n" +
|
||||
" name = \"banana\"\n" +
|
||||
"name = \"banana\"\n" +
|
||||
"\n" +
|
||||
"[[fruit.variety]]\n" +
|
||||
" name = \"plantain\"" +
|
||||
"name = \"plantain\"" +
|
||||
"\n";
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue