create arrays like arrays straightaway, not like List->Array
diff --git a/src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java b/src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java
index 8f98574..fecb2c3 100644
--- a/src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java
+++ b/src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java
@@ -15,7 +15,9 @@
*/
package org.yaml.snakeyaml.constructor;
+import java.lang.reflect.Array;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
@@ -61,7 +63,7 @@
protected final Map<String, Construct> yamlMultiConstructors = new HashMap<String, Construct>();
private Composer composer;
- private final Map<Node, Object> constructedObjects;
+ protected final Map<Node, Object> constructedObjects;
private final Set<Node> recursiveObjects;
private final ArrayList<RecursiveTuple<Map<Object, Object>, RecursiveTuple<Object, Object>>> maps2fill;
private final ArrayList<RecursiveTuple<Set<Object>, Object>> sets2fill;
@@ -218,6 +220,11 @@
}
@SuppressWarnings("unchecked")
+ protected <T> T[] createArray(Class<T> type, int size) {
+ return (T[]) Array.newInstance(type.getComponentType(), size);
+ }
+
+ @SuppressWarnings("unchecked")
protected List<? extends Object> constructSequence(SequenceNode node) {
List<Object> result;
if (List.class.isAssignableFrom(node.getType()) && !node.getType().isInterface()) {
@@ -232,6 +239,12 @@
}
constructSequenceStep2(node, result);
return result;
+
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Object constructArray(SequenceNode node) {
+ return constructArrayStep2(node, createArray(node.getType(), node.getValue().size()));
}
protected void constructSequenceStep2(SequenceNode node, List<Object> list) {
@@ -240,6 +253,14 @@
}
}
+ protected Object constructArrayStep2(SequenceNode node, Object array) {
+ int index = 0;
+ for (Node child : node.getValue()) {
+ Array.set(array, index++, constructObject(child));
+ }
+ return array;
+ }
+
protected Map<Object, Object> createDefaultMap() {
// respect order from YAML document
return new LinkedHashMap<Object, Object>();
diff --git a/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java b/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
index 90d02a6..f55558a 100644
--- a/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
+++ b/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
@@ -236,13 +236,9 @@
// keys can only be Strings
keyNode.setType(String.class);
String key = (String) constructObject(keyNode);
- boolean isArray = false;
try {
Property property = getProperty(beanType, key);
valueNode.setType(property.getType());
- if (property.getType().isArray()) {
- isArray = true;
- }
TypeDescription memberDescription = typeDefinitions.get(beanType);
boolean typeDetected = false;
if (memberDescription != null) {
@@ -255,7 +251,6 @@
snode.setListType(memberType);
typeDetected = true;
} else if (property.getType().isArray()) {
- isArray = true;
snode.setListType(property.getType().getComponentType());
typeDetected = true;
}
@@ -298,10 +293,6 @@
}
}
Object value = constructObject(valueNode);
- if (isArray && value instanceof List) {
- List<Object> list = (List<Object>) value;
- value = list.toArray(createArray(property.getType()));
- }
property.set(object, value);
} catch (Exception e) {
throw new YAMLException("Cannot create property=" + key + " for JavaBean="
@@ -311,11 +302,6 @@
return object;
}
- @SuppressWarnings("unchecked")
- private <T> T[] createArray(Class<T> type) {
- return (T[]) Array.newInstance(type.getComponentType(), 0);
- }
-
private Property getProperty(Class<? extends Object> type, String name)
throws IntrospectionException {
// check cache
@@ -535,15 +521,22 @@
* class is known. TODO make protected
*/
private class ConstructSequence implements Construct {
+
@SuppressWarnings("unchecked")
public Object construct(Node node) {
SequenceNode snode = (SequenceNode) node;
- if (List.class.isAssignableFrom(node.getType()) || node.getType().isArray()) {
+ if (List.class.isAssignableFrom(node.getType())) {
if (node.isTwoStepsConstruction()) {
return createDefaultList(snode.getValue().size());
} else {
return constructSequence(snode);
}
+ } else if (node.getType().isArray()) {
+ if (node.isTwoStepsConstruction()) {
+ return createArray(node.getType(), snode.getValue().size());
+ } else {
+ return constructArray(snode);
+ }
} else {
// create immutable object
List<java.lang.reflect.Constructor> possibleConstructors = new ArrayList<java.lang.reflect.Constructor>(
@@ -596,13 +589,16 @@
@SuppressWarnings("unchecked")
public void construct2ndStep(Node node, Object object) {
SequenceNode snode = (SequenceNode) node;
- List<Object> list = (List<Object>) object;
- if (List.class.isAssignableFrom(node.getType()) || node.getType().isArray()) {
+ if (List.class.isAssignableFrom(node.getType())) {
+ List<Object> list = (List<Object>) object;
constructSequenceStep2(snode, list);
+ } else if (node.getType().isArray()) {
+ constructArrayStep2(snode, object);
} else {
throw new YAMLException("Immutable objects cannot be recursive.");
}
}
+
}
protected Class<?> getClassForNode(Node node) {
diff --git a/src/test/java/org/yaml/snakeyaml/recursive/Human_WithArrayOfChildrenTest.java b/src/test/java/org/yaml/snakeyaml/recursive/Human_WithArrayOfChildrenTest.java
index a4695a8..84475f3 100644
--- a/src/test/java/org/yaml/snakeyaml/recursive/Human_WithArrayOfChildrenTest.java
+++ b/src/test/java/org/yaml/snakeyaml/recursive/Human_WithArrayOfChildrenTest.java
@@ -142,13 +142,13 @@
assertSame(father2.getPartner(), son2.getMother());
assertSame(father2, son2.getMother().getPartner());
- Human_WithArrayOfChildren[] children2 = father2.getChildren();
- assertEquals(2, children2.length);
- Human_WithArrayOfChildren[] fathersChildren = father2.getPartner().getChildren();
- // TODO Daughter is lost assertEquals(2, fathersChildren.length);
- // assertSame(father2.getPartner().getChildren(), children2);
+ Human_WithArrayOfChildren[] fathersChildren = father2.getChildren();
+ assertEquals(2, fathersChildren.length);
+ Human_WithArrayOfChildren[] mothersChildren = father2.getPartner().getChildren();
+ assertEquals(2, mothersChildren.length);
+ assertSame(mothersChildren, fathersChildren);
- for (Object child : children2) {
+ for (Object child : fathersChildren) {
// check if type descriptor was correct
assertSame(Human_WithArrayOfChildren.class, child.getClass());
}