mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-29 04:17:44 +01:00
SPIGOT-6949: Configuration sections that are nested within Maps or Lists are not properly serialized.
This broke with the configuration changes in
ed8a152b3a
.
This commit reverts one of the changes of this other commit so that
nested configuration sections are serialized as Maps again.
Although the types of these nested configuration sections are not
preserved when reloading a configuration (they turn into Maps), their
contents should at least be preserved, as it has been the case in
earlier Bukkit versions.
By: blablubbabc <lukas@wirsindwir.de>
This commit is contained in:
parent
212f79b449
commit
0854352e80
@ -2,6 +2,7 @@ package org.bukkit.configuration.file;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -11,12 +12,23 @@ import org.yaml.snakeyaml.representer.Representer;
|
||||
public class YamlRepresenter extends Representer {
|
||||
|
||||
public YamlRepresenter() {
|
||||
this.multiRepresenters.put(ConfigurationSection.class, new RepresentConfigurationSection());
|
||||
this.multiRepresenters.put(ConfigurationSerializable.class, new RepresentConfigurationSerializable());
|
||||
// SPIGOT-6234: We could just switch YamlConstructor to extend Constructor rather than SafeConstructor, however there is a very small risk of issues with plugins treating config as untrusted input
|
||||
// So instead we will just allow future plugins to have their enums extend ConfigurationSerializable
|
||||
this.multiRepresenters.remove(Enum.class);
|
||||
}
|
||||
|
||||
// SPIGOT-6949: Used by configuration sections that are nested within lists or maps.
|
||||
private class RepresentConfigurationSection extends RepresentMap {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Node representData(@NotNull Object data) {
|
||||
return super.representData(((ConfigurationSection) data).getValues(false));
|
||||
}
|
||||
}
|
||||
|
||||
private class RepresentConfigurationSerializable extends RepresentMap {
|
||||
|
||||
@NotNull
|
||||
|
@ -3,8 +3,14 @@ package org.bukkit.configuration.file;
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.MemoryConfiguration;
|
||||
import org.junit.Test;
|
||||
|
||||
public class YamlConfigurationTest extends FileConfigurationTest {
|
||||
@ -201,4 +207,61 @@ public class YamlConfigurationTest extends FileConfigurationTest {
|
||||
+ "'!!null': X\n";
|
||||
assertEquals(expected, config.saveToString());
|
||||
}
|
||||
|
||||
// SPIGOT-6949
|
||||
@Test
|
||||
public void testNestedConfigSections() throws InvalidConfigurationException {
|
||||
YamlConfiguration config = getConfig();
|
||||
List<Object> configList = new ArrayList<>();
|
||||
|
||||
MemoryConfiguration nestedSection = new MemoryConfiguration();
|
||||
nestedSection.set("something", "value");
|
||||
configList.add(nestedSection);
|
||||
|
||||
Map<String, Object> nestedMap = new HashMap<>();
|
||||
nestedMap.put("scalar", 10);
|
||||
nestedMap.put("string", "something");
|
||||
|
||||
MemoryConfiguration nestedSection2 = new MemoryConfiguration();
|
||||
nestedSection2.set("embedded", "value");
|
||||
nestedMap.put("section", nestedSection2);
|
||||
configList.add(nestedMap);
|
||||
|
||||
config.set("list", configList);
|
||||
|
||||
String serialized = config.saveToString();
|
||||
YamlConfiguration deserialized = new YamlConfiguration();
|
||||
deserialized.loadFromString(serialized);
|
||||
|
||||
// The types of nested maps or configuration sections or configs might not be preserved, but
|
||||
// their contents should be preserved:
|
||||
assertEquals(convertSectionsToMaps(config), convertSectionsToMaps(deserialized));
|
||||
}
|
||||
|
||||
// Recursively converts all configuration sections to Maps, including within any nested data
|
||||
// structures such as Maps and Lists.
|
||||
private Object convertSectionsToMaps(Object object) {
|
||||
if (object instanceof ConfigurationSection) {
|
||||
ConfigurationSection section = (ConfigurationSection) object;
|
||||
Map<String, Object> values = section.getValues(false);
|
||||
return convertSectionsToMaps(values);
|
||||
} else if (object instanceof Map) {
|
||||
Map<?, ?> map = (Map<?, ?>) object; // Might be immutable
|
||||
Map<Object, Object> newMap = new LinkedHashMap<>();
|
||||
for (Entry<?, ?> entry : map.entrySet()) {
|
||||
newMap.put(entry.getKey(), convertSectionsToMaps(entry.getValue()));
|
||||
}
|
||||
return newMap;
|
||||
} else if (object instanceof Iterable) {
|
||||
// Any other type of Collection is converted to a list:
|
||||
Iterable<?> iterable = (Iterable<?>) object; // Might be immutable
|
||||
List<Object> newList = new ArrayList<>();
|
||||
for (Object element : iterable) {
|
||||
newList.add(convertSectionsToMaps(element));
|
||||
}
|
||||
return newList;
|
||||
} else {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user