Enhancement for a pretty format that combines BLOCK and FLOW
diff --git a/AUTHORS b/AUTHORS
index 318769e..456a19e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -22,3 +22,4 @@
Christophe Desguez
Magne at edb
infinity0x
+obastard
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index cf2d1a6..ac3a0f5 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -7,7 +7,10 @@
</properties>
<body>
<release version="1.7" date="in Mercurial" description="development">
- <action dev="py4fun" type="fix" issue="50" due-to="sualeh.fatehi">
+ <action dev="obastard" type="fix" issue="53" due-to="obastard">
+ Enhancement for a pretty format that combines BLOCK and FLOW (2010-03-03)
+ </action>
+ <action dev="py4fun" type="fix" issue="50" due-to="sualeh.fatehi">
Unable to dump JavaBean that inherits from a protected base class (2010-03-02)
</action>
<action dev="py4fun" type="update">
diff --git a/src/main/java/org/yaml/snakeyaml/DumperOptions.java b/src/main/java/org/yaml/snakeyaml/DumperOptions.java
index ee05ad1..1cee9c4 100644
--- a/src/main/java/org/yaml/snakeyaml/DumperOptions.java
+++ b/src/main/java/org/yaml/snakeyaml/DumperOptions.java
@@ -166,6 +166,7 @@
private Tag explicitRoot = null;
private Version version = null;
private Map<String, String> tags = null;
+ private Boolean prettyFlow = false;
public boolean isAllowUnicode() {
return allowUnicode;
@@ -239,6 +240,21 @@
}
/**
+ * Force the emitter to produce a pretty YAML document when using the flow style.
+ *
+ * @param prettyFlow true produce pretty flow YAML document
+ */
+ public void setPrettyFlow(boolean prettyFlow)
+ {
+ this.prettyFlow = prettyFlow;
+ }
+
+ public boolean isPrettyFlow()
+ {
+ return this.prettyFlow;
+ }
+
+ /**
* Specify the preferred width to emit scalars. When the scalar
* representation takes more then the preferred with the scalar will be
* split into a few lines. The default is 80.
diff --git a/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java b/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java
index a62e05e..d2b9b0a 100644
--- a/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java
+++ b/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java
@@ -128,6 +128,9 @@
// Formatting details.
private Boolean canonical;
+ // pretty print flow by adding extra line breaks
+ private Boolean prettyFlow;
+
private boolean allowUnicode;
private int bestIndent;
private int bestWidth;
@@ -178,7 +181,8 @@
openEnded = false;
// Formatting details.
- this.canonical = opts.isCanonical();
+ this.canonical = opts.isCanonical();
+ this.prettyFlow = opts.isPrettyFlow();
this.allowUnicode = opts.isAllowUnicode();
this.bestIndent = 2;
if ((opts.getIndent() > MIN_INDENT) && (opts.getIndent() < MAX_INDENT)) {
@@ -423,7 +427,13 @@
writeIndicator("[", true, true, false);
flowLevel++;
increaseIndent(true, false);
- state = new ExpectFirstFlowSequenceItem();
+
+ if (prettyFlow)
+ {
+ writeIndent();
+ }
+
+ state = new ExpectFirstFlowSequenceItem();
}
private class ExpectFirstFlowSequenceItem implements EmitterState {
@@ -432,9 +442,13 @@
indent = indents.pop();
flowLevel--;
writeIndicator("]", false, false, false);
+ if (prettyFlow)
+ {
+ writeIndent();
+ }
state = states.pop();
} else {
- if (canonical || column > bestWidth) {
+ if (canonical || column > bestWidth || prettyFlow) {
writeIndent();
}
states.push(new ExpectFlowSequenceItem());
@@ -453,10 +467,14 @@
writeIndent();
}
writeIndicator("]", false, false, false);
+ if (prettyFlow)
+ {
+ writeIndent();
+ }
state = states.pop();
} else {
writeIndicator(",", false, false, false);
- if (canonical || column > bestWidth) {
+ if (canonical || column > bestWidth || prettyFlow) {
writeIndent();
}
states.push(new ExpectFlowSequenceItem());
@@ -471,6 +489,12 @@
writeIndicator("{", true, true, false);
flowLevel++;
increaseIndent(true, false);
+
+ if (prettyFlow)
+ {
+ writeIndent();
+ }
+
state = new ExpectFirstFlowMappingKey();
}
@@ -479,10 +503,14 @@
if (event instanceof MappingEndEvent) {
indent = indents.pop();
flowLevel--;
+ if (prettyFlow)
+ {
+ writeIndent();
+ }
writeIndicator("}", false, false, false);
state = states.pop();
} else {
- if (canonical || column > bestWidth) {
+ if (canonical || column > bestWidth || prettyFlow) {
writeIndent();
}
if (!canonical && checkSimpleKey()) {
@@ -506,11 +534,15 @@
writeIndicator(",", false, false, false);
writeIndent();
}
+ if (prettyFlow)
+ {
+ writeIndent();
+ }
writeIndicator("}", false, false, false);
state = states.pop();
} else {
writeIndicator(",", false, false, false);
- if (canonical || column > bestWidth) {
+ if (canonical || column > bestWidth || prettyFlow) {
writeIndent();
}
if (!canonical && checkSimpleKey()) {
@@ -535,7 +567,7 @@
private class ExpectFlowMappingValue implements EmitterState {
public void expect() throws IOException {
- if (canonical || column > bestWidth) {
+ if (canonical || column > bestWidth || prettyFlow) {
writeIndent();
}
writeIndicator(":", true, false, false);
diff --git a/src/test/java/org/yaml/snakeyaml/DumperOptionsTest.java b/src/test/java/org/yaml/snakeyaml/DumperOptionsTest.java
index f485ffa..769bcad 100644
--- a/src/test/java/org/yaml/snakeyaml/DumperOptionsTest.java
+++ b/src/test/java/org/yaml/snakeyaml/DumperOptionsTest.java
@@ -72,6 +72,12 @@
assertEquals("[1, 2, 3]\n", yaml.dump(list));
//
options = new DumperOptions();
+ options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
+ options.setPrettyFlow(true);
+ yaml = new Yaml(options);
+ assertEquals("[\n 1,\n 2,\n 3]\n", yaml.dump(list));
+ //
+ options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
yaml = new Yaml(options);
assertEquals("- 1\n- 2\n- 3\n", yaml.dump(list));
@@ -93,7 +99,8 @@
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("a", "b");
map.put("c", list);
- assertEquals("a: b\nc: [1, 2, 3]\n", yaml.dump(map));
+ String result=yaml.dump(map);
+ assertEquals("a: b\nc: [1, 2, 3]\n", result);
//
DumperOptions options = new DumperOptions();
options = new DumperOptions();
@@ -102,6 +109,13 @@
assertEquals("{a: b, c: [1, 2, 3]}\n", yaml.dump(map));
//
options = new DumperOptions();
+ options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
+ options.setPrettyFlow(true);
+ yaml = new Yaml(options);
+ result=yaml.dump(map);
+ assertEquals("{\n a: b,\n c: [\n 1,\n 2,\n 3]\n \n}\n", result);
+ //
+ options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
yaml = new Yaml(options);
assertEquals("a: b\nc:\n- 1\n- 2\n- 3\n", yaml.dump(map));
diff --git a/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java b/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java
index 802095b..b60dfd1 100644
--- a/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java
+++ b/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java
@@ -65,6 +65,24 @@
assertEquals(etalon, output);
}
+ public void testWritePlainPretty()
+ {
+ DumperOptions options = new DumperOptions();
+ options.setDefaultScalarStyle(ScalarStyle.PLAIN);
+ options.setPrettyFlow(true);
+
+ String folded = "0123456789 0123456789\n0123456789 0123456789";
+ Map<String, String> map = new LinkedHashMap<String, String>();
+ map.put("aaa", folded);
+ map.put("bbb", "\nbla-bla");
+
+ Yaml yaml = new Yaml(options);
+ String output = yaml.dump(map);
+ String etalon =
+ "{\n aaa: '0123456789 0123456789\n\n 0123456789 0123456789',\n bbb: '\n\n bla-bla'\n}\n";
+ assertEquals(etalon, output);
+ }
+
public void testWriteSingleQuoted() {
DumperOptions options = new DumperOptions();
options.setDefaultScalarStyle(ScalarStyle.SINGLE_QUOTED);
diff --git a/src/test/java/org/yaml/snakeyaml/javabeans/StringArrayTest.java b/src/test/java/org/yaml/snakeyaml/javabeans/StringArrayTest.java
index fb3280f..0947803 100644
--- a/src/test/java/org/yaml/snakeyaml/javabeans/StringArrayTest.java
+++ b/src/test/java/org/yaml/snakeyaml/javabeans/StringArrayTest.java
@@ -19,6 +19,7 @@
import junit.framework.TestCase;
+import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
public class StringArrayTest extends TestCase {
@@ -32,6 +33,19 @@
A b = (A) yaml.load(output);
assertTrue(Arrays.equals(a.getNames(), b.getNames()));
}
+
+ public void testStringsPretty() {
+ A a = new A();
+ a.setNames(new String[] { "aaa", "bbb", "ccc" });
+ DumperOptions options = new DumperOptions();
+ options.setPrettyFlow(true);
+ Yaml yaml = new Yaml(options);
+ String output = yaml.dump(a);
+ assertEquals("!!org.yaml.snakeyaml.javabeans.StringArrayTest$A\nnames: [\n aaa,\n bbb,\n ccc]\n",
+ output);
+ A b = (A) yaml.load(output);
+ assertTrue(Arrays.equals(a.getNames(), b.getNames()));
+ }
public static class A {
String[] names;
diff --git a/src/test/java/org/yaml/snakeyaml/recursive/HumanTest.java b/src/test/java/org/yaml/snakeyaml/recursive/HumanTest.java
index 886bc7e..9bca959 100644
--- a/src/test/java/org/yaml/snakeyaml/recursive/HumanTest.java
+++ b/src/test/java/org/yaml/snakeyaml/recursive/HumanTest.java
@@ -28,12 +28,14 @@
import junit.framework.TestCase;
+import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.JavaBeanDumper;
import org.yaml.snakeyaml.JavaBeanLoader;
import org.yaml.snakeyaml.Loader;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Util;
import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.constructor.Constructor;
public class HumanTest extends TestCase {
@@ -64,6 +66,35 @@
assertSame(father2, father2.getBankAccountOwner());
}
+ public void testNoChildrenPretty() throws IOException {
+ Human father = new Human();
+ father.setName("Father");
+ father.setBirthday(new Date(1000000000));
+ father.setBirthPlace("Leningrad");
+ father.setBankAccountOwner(father);
+ Human mother = new Human();
+ mother.setName("Mother");
+ mother.setBirthday(new Date(100000000000L));
+ mother.setBirthPlace("Saint-Petersburg");
+ father.setPartner(mother);
+ mother.setPartner(father);
+ mother.setBankAccountOwner(father);
+ DumperOptions options= new DumperOptions();
+ options.setPrettyFlow(true);
+ options.setDefaultFlowStyle(FlowStyle.FLOW);
+ Yaml yaml = new Yaml(options);
+ String output = yaml.dump(father);
+ String etalon = Util.getLocalResource("recursive/no-children-1-pretty.yaml");
+ assertEquals(etalon, output);
+ //
+ Human father2 = (Human) yaml.load(output);
+ assertNotNull(father2);
+ assertEquals("Father", father2.getName());
+ assertEquals("Mother", father2.getPartner().getName());
+ assertEquals("Father", father2.getBankAccountOwner().getName());
+ assertSame(father2, father2.getBankAccountOwner());
+ }
+
public void testChildren() throws IOException {
Human father = new Human();
father.setName("Father");
@@ -133,6 +164,79 @@
// check if hashCode is correct
validateSet(children2);
}
+
+ public void testChildrenPretty() throws IOException {
+ Human father = new Human();
+ father.setName("Father");
+ father.setBirthday(new Date(1000000000));
+ father.setBirthPlace("Leningrad");
+ father.setBankAccountOwner(father);
+ //
+ Human mother = new Human();
+ mother.setName("Mother");
+ mother.setBirthday(new Date(100000000000L));
+ mother.setBirthPlace("Saint-Petersburg");
+ father.setPartner(mother);
+ mother.setPartner(father);
+ mother.setBankAccountOwner(father);
+ //
+ Human son = new Human();
+ son.setName("Son");
+ son.setBirthday(new Date(310000000000L));
+ son.setBirthPlace("Munich");
+ son.setBankAccountOwner(father);
+ son.setFather(father);
+ son.setMother(mother);
+ //
+ Human daughter = new Human();
+ daughter.setName("Daughter");
+ daughter.setBirthday(new Date(420000000000L));
+ daughter.setBirthPlace("New York");
+ daughter.setBankAccountOwner(father);
+ daughter.setFather(father);
+ daughter.setMother(mother);
+ //
+ Set<Human> children = new LinkedHashSet<Human>(2);
+ children.add(son);
+ children.add(daughter);
+ father.setChildren(children);
+ mother.setChildren(children);
+ //
+ DumperOptions options=new DumperOptions();
+ options.setDefaultFlowStyle(FlowStyle.FLOW);
+ options.setPrettyFlow(true);
+ Yaml beanDumper = new Yaml(options);
+ String output = beanDumper.dump(son);
+ // System.out.println(output);
+ String etalon = Util.getLocalResource("recursive/with-children-pretty.yaml");
+ assertEquals(etalon, output);
+ TypeDescription humanDescription = new TypeDescription(Human.class);
+ humanDescription.putMapPropertyType("children", Human.class, Object.class);
+ JavaBeanLoader<Human> beanLoader = new JavaBeanLoader<Human>(humanDescription);
+ //
+ Human son2 = beanLoader.load(output);
+ assertNotNull(son2);
+ assertEquals("Son", son.getName());
+
+ Human father2 = son2.getFather();
+ assertEquals("Father", father2.getName());
+ assertEquals("Mother", son2.getMother().getName());
+ assertSame(father2, father2.getBankAccountOwner());
+ assertSame(father2.getPartner(), son2.getMother());
+ assertSame(father2, son2.getMother().getPartner());
+
+ Set<Human> children2 = father2.getChildren();
+ assertEquals(2, children2.size());
+ assertSame(father2.getPartner().getChildren(), children2);
+
+ for (Object child : children2) {
+ // check if type descriptor was correct
+ assertSame(Human.class, child.getClass());
+ }
+
+ // check if hashCode is correct
+ validateSet(children2);
+ }
public void testChildren2() throws IOException {
Human2 father = new Human2();
diff --git a/src/test/java/org/yaml/snakeyaml/representer/SafeRepresenterTest.java b/src/test/java/org/yaml/snakeyaml/representer/SafeRepresenterTest.java
index c6360f4..6935435 100644
--- a/src/test/java/org/yaml/snakeyaml/representer/SafeRepresenterTest.java
+++ b/src/test/java/org/yaml/snakeyaml/representer/SafeRepresenterTest.java
@@ -114,4 +114,21 @@
assertEquals("{'age': !!int '5', 'name': 'Ubuntu', 'list': [!!int '1', !!int '1']}\n",
output);
}
+ public void testStyle2Pretty() {
+ List<Integer> list = new ArrayList<Integer>();
+ list.add(new Integer(1));
+ list.add(new Integer(1));
+ Map<String, Object> map = new LinkedHashMap<String, Object>();
+ map.put("age", 5);
+ map.put("name", "Ubuntu");
+ map.put("list", list);
+ DumperOptions options = new DumperOptions();
+ options.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);
+ options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW);
+ options.setPrettyFlow(true);
+ Yaml yaml = new Yaml(options);
+ String output = yaml.dump(map);
+ assertEquals("{\n 'age': !!int '5',\n 'name': 'Ubuntu',\n 'list': [\n !!int '1',\n !!int '1']\n \n}\n",
+ output);
+ }
}
diff --git a/src/test/resources/recursive/no-children-1-pretty.yaml b/src/test/resources/recursive/no-children-1-pretty.yaml
new file mode 100644
index 0000000..89e9c1c
--- /dev/null
+++ b/src/test/resources/recursive/no-children-1-pretty.yaml
@@ -0,0 +1,23 @@
+&id001 !!org.yaml.snakeyaml.recursive.Human {
+ bankAccountOwner: *id001,
+ birthPlace: Leningrad,
+ birthday: !!timestamp '1970-01-12T13:46:40Z',
+ children: !!set {
+
+ },
+ father: null,
+ mother: null,
+ name: Father,
+ partner: {
+ bankAccountOwner: *id001,
+ birthPlace: Saint-Petersburg,
+ birthday: !!timestamp '1973-03-03T09:46:40Z',
+ children: !!set {
+
+ },
+ father: null,
+ mother: null,
+ name: Mother,
+ partner: *id001
+ }
+}
diff --git a/src/test/resources/recursive/with-children-pretty.yaml b/src/test/resources/recursive/with-children-pretty.yaml
new file mode 100644
index 0000000..0089c4f
--- /dev/null
+++ b/src/test/resources/recursive/with-children-pretty.yaml
@@ -0,0 +1,45 @@
+&id002 {
+ bankAccountOwner: &id001 {
+ bankAccountOwner: *id001,
+ birthPlace: Leningrad,
+ birthday: !!timestamp '1970-01-12T13:46:40Z',
+ children: &id003 !!set {
+ *id002: null,
+ ? {
+ bankAccountOwner: *id001,
+ birthPlace: New York,
+ birthday: !!timestamp '1983-04-24T02:40:00Z',
+ children: !!set {
+
+ },
+ father: *id001,
+ mother: &id004 {
+ bankAccountOwner: *id001,
+ birthPlace: Saint-Petersburg,
+ birthday: !!timestamp '1973-03-03T09:46:40Z',
+ children: *id003,
+ father: null,
+ mother: null,
+ name: Mother,
+ partner: *id001
+ },
+ name: Daughter,
+ partner: null
+ }
+ : null
+ },
+ father: null,
+ mother: null,
+ name: Father,
+ partner: *id004
+ },
+ birthPlace: Munich,
+ birthday: !!timestamp '1979-10-28T23:06:40Z',
+ children: !!set {
+
+ },
+ father: *id001,
+ mother: *id004,
+ name: Son,
+ partner: null
+}