SnakeYaml now ignores additional mapping values in files, so it throws less errors.

This commit is contained in:
snowleo 2011-12-07 11:57:31 +01:00
parent 5c02346f85
commit e7ebc94a9e

View File

@ -1,6 +1,12 @@
package com.earth2me.essentials.storage;
import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -11,8 +17,10 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.introspector.Property;
import org.yaml.snakeyaml.nodes.*;
@ -270,6 +278,132 @@ public class BukkitConstructor extends Constructor
}
return super.construct(node);
}
protected Object constructJavaBean2ndStep(final MappingNode node, final Object object)
{
Map<Class<? extends Object>, TypeDescription> typeDefinitions;
try
{
final Field typeDefField = Constructor.class.getDeclaredField("typeDefinitions");
typeDefField.setAccessible(true);
typeDefinitions = (Map<Class<? extends Object>, TypeDescription>)typeDefField.get((Constructor)BukkitConstructor.this);
if (typeDefinitions == null) {
throw new NullPointerException();
}
}
catch (Exception ex)
{
throw new YAMLException(ex);
}
flattenMapping(node);
final Class<? extends Object> beanType = node.getType();
final List<NodeTuple> nodeValue = node.getValue();
for (NodeTuple tuple : nodeValue)
{
ScalarNode keyNode;
if (tuple.getKeyNode() instanceof ScalarNode)
{
// key must be scalar
keyNode = (ScalarNode)tuple.getKeyNode();
}
else
{
throw new YAMLException("Keys must be scalars but found: " + tuple.getKeyNode());
}
final Node valueNode = tuple.getValueNode();
// keys can only be Strings
keyNode.setType(String.class);
final String key = (String)constructObject(keyNode);
try
{
Property property;
try
{
property = getProperty(beanType, key);
}
catch (YAMLException e)
{
continue;
}
valueNode.setType(property.getType());
final TypeDescription memberDescription = typeDefinitions.get(beanType);
boolean typeDetected = false;
if (memberDescription != null)
{
switch (valueNode.getNodeId())
{
case sequence:
final SequenceNode snode = (SequenceNode)valueNode;
final Class<? extends Object> memberType = memberDescription.getListPropertyType(key);
if (memberType != null)
{
snode.setListType(memberType);
typeDetected = true;
}
else if (property.getType().isArray())
{
snode.setListType(property.getType().getComponentType());
typeDetected = true;
}
break;
case mapping:
final MappingNode mnode = (MappingNode)valueNode;
final Class<? extends Object> keyType = memberDescription.getMapKeyType(key);
if (keyType != null)
{
mnode.setTypes(keyType, memberDescription.getMapValueType(key));
typeDetected = true;
}
break;
}
}
if (!typeDetected && valueNode.getNodeId() != NodeId.scalar)
{
// only if there is no explicit TypeDescription
final Class<?>[] arguments = property.getActualTypeArguments();
if (arguments != null)
{
// type safe (generic) collection may contain the
// proper class
if (valueNode.getNodeId() == NodeId.sequence)
{
final Class<?> t = arguments[0];
final SequenceNode snode = (SequenceNode)valueNode;
snode.setListType(t);
}
else if (valueNode.getTag().equals(Tag.SET))
{
final Class<?> t = arguments[0];
final MappingNode mnode = (MappingNode)valueNode;
mnode.setOnlyKeyType(t);
mnode.setUseClassConstructor(true);
}
else if (property.getType().isAssignableFrom(Map.class))
{
final Class<?> ketType = arguments[0];
final Class<?> valueType = arguments[1];
final MappingNode mnode = (MappingNode)valueNode;
mnode.setTypes(ketType, valueType);
mnode.setUseClassConstructor(true);
}
else
{
// the type for collection entries cannot be
// detected
}
}
}
final Object value = constructObject(valueNode);
property.set(object, value);
}
catch (Exception e)
{
throw new YAMLException("Cannot create property=" + key + " for JavaBean="
+ object + "; " + e.getMessage(), e);
}
}
return object;
}
}
@Override