* class is known.
*/
protected class ConstructSequence implements Construct {
@SuppressWarnings("unchecked")
public Object construct(Node node) {
SequenceNode snode = (SequenceNode) node;
if (Set.class.isAssignableFrom(node.getType())) {
if (node.isTwoStepsConstruction()) {
throw new YAMLException("Set cannot be recursive.");
} else {
return constructSet(snode);
}
} else if (Collection.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<?>>(
snode.getValue().size());
for (java.lang.reflect.Constructor<?> constructor : node.getType()
.getConstructors()) {
if (snode.getValue().size() == constructor.getParameterTypes().length) {
possibleConstructors.add(constructor);
}
}
if (!possibleConstructors.isEmpty()) {
if (possibleConstructors.size() == 1) {
Object[] argumentList = new Object[snode.getValue().size()];
java.lang.reflect.Constructor<?> c = possibleConstructors.get(0);
int index = 0;
for (Node argumentNode : snode.getValue()) {
Class<?> type = c.getParameterTypes()[index];
// set runtime classes for arguments
argumentNode.setType(type);
argumentList[index++] = constructObject(argumentNode);
}
try {
return c.newInstance(argumentList);
} catch (Exception e) {
throw new YAMLException(e);
}
}
// use BaseConstructor
List<Object> argumentList = (List<Object>) constructSequence(snode);
Class<?>[] parameterTypes = new Class[argumentList.size()];
int index = 0;
for (Object parameter : argumentList) {
parameterTypes[index] = parameter.getClass();
index++;
}
for (java.lang.reflect.Constructor<?> c : possibleConstructors) {
Class<?>[] argTypes = c.getParameterTypes();
boolean foundConstructor = true;
for (int i = 0; i < argTypes.length; i++) {
if (!wrapIfPrimitive(argTypes[i]).isAssignableFrom(parameterTypes[i])) {
foundConstructor = false;
break;
}
}
if (foundConstructor) {
try {
return c.newInstance(argumentList.toArray());
} catch (Exception e) {
throw new YAMLException(e);
}
}
}
}
throw new YAMLException("No suitable constructor with "
+ String.valueOf(snode.getValue().size()) + " arguments found for "
+ node.getType());
}
}