Fix: dump omits JavaBean class name when used with an alias
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 60aab41..2a6c80c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -7,6 +7,9 @@
</properties>
<body>
<release version="1.4-SNAPSHOT" date="in Mercurial" description="development">
+ <action dev="py4fun" type="fix" issue="10" due-to="derrick.rice">
+ Fix: dump omits JavaBean class name when used with an alias (2009-07-28)
+ </action>
<action dev="py4fun" type="add">
Generate sources and Javadoc (2009-07-27)
</action>
diff --git a/src/main/java/org/yaml/snakeyaml/nodes/NodeTuple.java b/src/main/java/org/yaml/snakeyaml/nodes/NodeTuple.java
index 4fcb03a..84163b0 100644
--- a/src/main/java/org/yaml/snakeyaml/nodes/NodeTuple.java
+++ b/src/main/java/org/yaml/snakeyaml/nodes/NodeTuple.java
@@ -9,6 +9,9 @@
private final Node valueNode;
public NodeTuple(Node keyNode, Node valueNode) {
+ if (keyNode == null || valueNode == null) {
+ throw new NullPointerException("Nodes must be provided.");
+ }
this.keyNode = keyNode;
this.valueNode = valueNode;
}
@@ -20,4 +23,10 @@
public Node getValueNode() {
return valueNode;
}
+
+ @Override
+ public String toString() {
+ return "<NodeTuple keyNode=" + keyNode.toString() + "; valueNode=" + valueNode.toString()
+ + ">";
+ }
}
diff --git a/src/main/java/org/yaml/snakeyaml/representer/Representer.java b/src/main/java/org/yaml/snakeyaml/representer/Representer.java
index 6adf9f3..ef4285f 100644
--- a/src/main/java/org/yaml/snakeyaml/representer/Representer.java
+++ b/src/main/java/org/yaml/snakeyaml/representer/Representer.java
@@ -91,20 +91,22 @@
for (Property property : properties) {
ScalarNode nodeKey = (ScalarNode) representData(property.getName());
Object memberValue = property.get(javaBean);
+ boolean hasAlias = false;
+ if (this.representedObjects.containsKey(memberValue)) {
+ // the first occurrence of the node must keep the tag
+ hasAlias = true;
+ }
Node nodeValue = representData(memberValue);
- if (nodeValue instanceof MappingNode) {
+ // if possible try to avoid a global tag with a class name
+ if (nodeValue instanceof MappingNode && !hasAlias) {
// the node is a map, set or JavaBean
if (!Map.class.isAssignableFrom(memberValue.getClass())) {
// the node is set or JavaBean
if (property.getType() == memberValue.getClass()) {
// we do not need global tag because the property
// Class is the same as the runtime class
- if (node != nodeValue) {
- String memberTag = "tag:yaml.org,2002:map";
- nodeValue.setTag(memberTag);
- } else {
- // recursive node, keep the tag
- }
+ String memberTag = "tag:yaml.org,2002:map";
+ nodeValue.setTag(memberTag);
}
}
} else if (memberValue != null && Enum.class.isAssignableFrom(memberValue.getClass())) {
diff --git a/src/test/java/org/yaml/snakeyaml/issues/issue10/BasicDumpTest.java b/src/test/java/org/yaml/snakeyaml/issues/issue10/BasicDumpTest.java
new file mode 100644
index 0000000..dd4f077
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/issues/issue10/BasicDumpTest.java
@@ -0,0 +1,81 @@
+/*
+ * See LICENSE file in distribution for copyright and licensing information.
+ */
+package org.yaml.snakeyaml.issues.issue10;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import org.yaml.snakeyaml.JavaBeanDumper;
+import org.yaml.snakeyaml.Util;
+import org.yaml.snakeyaml.Yaml;
+
+public class BasicDumpTest extends TestCase {
+
+ public void testTag() {
+ DataSource base = new DataSource();
+ JDBCDataSource baseJDBC = new JDBCDataSource();
+ baseJDBC.setParent(base);
+
+ ArrayList<DataSource> dataSources = new ArrayList<DataSource>();
+ // trying expected order first
+ dataSources.add(base);
+ dataSources.add(baseJDBC);
+
+ DataSources ds = new DataSources();
+ ds.setDataSources(dataSources);
+
+ Yaml yaml = new Yaml();
+ String output = yaml.dump(ds);
+
+ String etalon = Util.getLocalResource("javabeans/issue10-1.yaml");
+ assertEquals(etalon.trim(), output.trim());
+ Object obj = yaml.load(output);
+ DataSources dsOut = (DataSources) obj;
+ Iterator<DataSource> iter = dsOut.getDataSources().iterator();
+ assertFalse("Must be DataSource.", iter.next() instanceof JDBCDataSource);
+ assertTrue(iter.next() instanceof JDBCDataSource);
+ }
+
+ public void testTag2() {
+ DataSource base = new DataSource();
+ JDBCDataSource baseJDBC = new JDBCDataSource();
+ baseJDBC.setParent(base);
+
+ ArrayList<DataSource> dataSources = new ArrayList<DataSource>();
+ // trying expected order first
+ dataSources.add(base);
+ dataSources.add(baseJDBC);
+
+ DataSources ds = new DataSources();
+ ds.setDataSources(dataSources);
+
+ JavaBeanDumper yaml = new JavaBeanDumper();
+ String output = yaml.dump(ds);
+
+ String etalon = Util.getLocalResource("javabeans/issue10-2.yaml");
+ assertEquals(etalon.trim(), output.trim());
+ }
+
+ public void testTag3() {
+ DataSource base = new DataSource();
+ JDBCDataSource baseJDBC = new JDBCDataSource();
+ baseJDBC.setParent(base);
+
+ ArrayList<DataSource> dataSources = new ArrayList<DataSource>();
+ // trying expected order first
+ dataSources.add(baseJDBC);
+ dataSources.add(base);
+
+ DataSources ds = new DataSources();
+ ds.setDataSources(dataSources);
+
+ JavaBeanDumper yaml = new JavaBeanDumper();
+ String output = yaml.dump(ds);
+
+ String etalon = Util.getLocalResource("javabeans/issue10-3.yaml");
+ assertEquals(etalon.trim(), output.trim());
+ }
+}
diff --git a/src/test/java/org/yaml/snakeyaml/issues/issue10/DataSource.java b/src/test/java/org/yaml/snakeyaml/issues/issue10/DataSource.java
new file mode 100644
index 0000000..8d7d7cf
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/issues/issue10/DataSource.java
@@ -0,0 +1,16 @@
+/*
+ * See LICENSE file in distribution for copyright and licensing information.
+ */
+package org.yaml.snakeyaml.issues.issue10;
+
+public class DataSource {
+ String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/test/java/org/yaml/snakeyaml/issues/issue10/DataSources.java b/src/test/java/org/yaml/snakeyaml/issues/issue10/DataSources.java
new file mode 100644
index 0000000..5cfe77f
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/issues/issue10/DataSources.java
@@ -0,0 +1,18 @@
+/*
+ * See LICENSE file in distribution for copyright and licensing information.
+ */
+package org.yaml.snakeyaml.issues.issue10;
+
+import java.util.List;
+
+public class DataSources {
+ List<DataSource> dataSources;
+
+ public List<DataSource> getDataSources() {
+ return dataSources;
+ }
+
+ public void setDataSources(List<DataSource> dataSources) {
+ this.dataSources = dataSources;
+ }
+}
diff --git a/src/test/java/org/yaml/snakeyaml/issues/issue10/JDBCDataSource.java b/src/test/java/org/yaml/snakeyaml/issues/issue10/JDBCDataSource.java
new file mode 100644
index 0000000..129bdd4
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/issues/issue10/JDBCDataSource.java
@@ -0,0 +1,44 @@
+/*
+ * See LICENSE file in distribution for copyright and licensing information.
+ */
+package org.yaml.snakeyaml.issues.issue10;
+
+public class JDBCDataSource extends DataSource {
+ String username;
+ String password;
+ String url;
+
+ DataSource parent;
+
+ public DataSource getParent() {
+ return parent;
+ }
+
+ public void setParent(DataSource parent) {
+ this.parent = parent;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+}
diff --git a/src/test/java/org/yaml/snakeyaml/nodes/NodeTupleTest.java b/src/test/java/org/yaml/snakeyaml/nodes/NodeTupleTest.java
new file mode 100644
index 0000000..94ce1c7
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/nodes/NodeTupleTest.java
@@ -0,0 +1,36 @@
+package org.yaml.snakeyaml.nodes;
+
+import junit.framework.TestCase;
+
+public class NodeTupleTest extends TestCase {
+
+ public void testNodeTuple1() {
+ Node node = new ScalarNode("!tag", "value1", null, null, null);
+ try {
+ new NodeTuple(null, node);
+ fail("Node must be provided.");
+ } catch (Exception e) {
+ assertEquals("Nodes must be provided.", e.getMessage());
+ }
+ }
+
+ public void testNodeTuple2() {
+ Node node = new ScalarNode("!tag", "value1", null, null, null);
+ try {
+ new NodeTuple(node, null);
+ fail("Node must be provided.");
+ } catch (Exception e) {
+ assertEquals("Nodes must be provided.", e.getMessage());
+ }
+ }
+
+ public void testToString() {
+ Node key = new ScalarNode("tag:yaml.org,2002:str", "key1", null, null, null);
+ Node value = new ScalarNode("tag:yaml.org,2002:str", "value1", null, null, null);
+ NodeTuple tuple = new NodeTuple(key, value);
+ assertEquals(
+ "<NodeTuple keyNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=key1)>; valueNode=<org.yaml.snakeyaml.nodes.ScalarNode (tag=tag:yaml.org,2002:str, value=value1)>>",
+ tuple.toString());
+ }
+
+}
diff --git a/src/test/resources/javabeans/issue10-1.yaml b/src/test/resources/javabeans/issue10-1.yaml
new file mode 100644
index 0000000..0c8786e
--- /dev/null
+++ b/src/test/resources/javabeans/issue10-1.yaml
@@ -0,0 +1,9 @@
+!!org.yaml.snakeyaml.issues.issue10.DataSources
+dataSources:
+- &id001 !!org.yaml.snakeyaml.issues.issue10.DataSource {name: null}
+- !!org.yaml.snakeyaml.issues.issue10.JDBCDataSource
+ name: null
+ parent: *id001
+ password: null
+ url: null
+ username: null
\ No newline at end of file
diff --git a/src/test/resources/javabeans/issue10-2.yaml b/src/test/resources/javabeans/issue10-2.yaml
new file mode 100644
index 0000000..3fde97a
--- /dev/null
+++ b/src/test/resources/javabeans/issue10-2.yaml
@@ -0,0 +1,9 @@
+dataSources:
+- &id001 !!org.yaml.snakeyaml.issues.issue10.DataSource
+ name: null
+- !!org.yaml.snakeyaml.issues.issue10.JDBCDataSource
+ name: null
+ parent: *id001
+ password: null
+ url: null
+ username: null
\ No newline at end of file
diff --git a/src/test/resources/javabeans/issue10-3.yaml b/src/test/resources/javabeans/issue10-3.yaml
new file mode 100644
index 0000000..65d512e
--- /dev/null
+++ b/src/test/resources/javabeans/issue10-3.yaml
@@ -0,0 +1,9 @@
+dataSources:
+- !!org.yaml.snakeyaml.issues.issue10.JDBCDataSource
+ name: null
+ parent: &id001
+ name: null
+ password: null
+ url: null
+ username: null
+- *id001
\ No newline at end of file