001    package org.bukkit.configuration.file;
002    
003    import java.util.LinkedHashMap;
004    import java.util.Map;
005    
006    import org.yaml.snakeyaml.nodes.Node;
007    import org.yaml.snakeyaml.constructor.SafeConstructor;
008    import org.yaml.snakeyaml.error.YAMLException;
009    import org.yaml.snakeyaml.nodes.Tag;
010    
011    import org.bukkit.configuration.serialization.ConfigurationSerialization;
012    
013    public class YamlConstructor extends SafeConstructor {
014    
015        public YamlConstructor() {
016            this.yamlConstructors.put(Tag.MAP, new ConstructCustomObject());
017        }
018    
019        private class ConstructCustomObject extends ConstructYamlMap {
020            @Override
021            public Object construct(Node node) {
022                if (node.isTwoStepsConstruction()) {
023                    throw new YAMLException("Unexpected referential mapping structure. Node: " + node);
024                }
025    
026                Map<?, ?> raw = (Map<?, ?>) super.construct(node);
027    
028                if (raw.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) {
029                    Map<String, Object> typed = new LinkedHashMap<String, Object>(raw.size());
030                    for (Map.Entry<?, ?> entry : raw.entrySet()) {
031                        typed.put(entry.getKey().toString(), entry.getValue());
032                    }
033    
034                    try {
035                        return ConfigurationSerialization.deserializeObject(typed);
036                    } catch (IllegalArgumentException ex) {
037                        throw new YAMLException("Could not deserialize object", ex);
038                    }
039                }
040    
041                return raw;
042            }
043    
044            @Override
045            public void construct2ndStep(Node node, Object object) {
046                throw new YAMLException("Unexpected referential mapping structure. Node: " + node);
047            }
048        }
049    }