package org.shininet.bukkit.itemrenamer.serialization; import java.util.Map; import java.util.Map.Entry; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import org.shininet.bukkit.itemrenamer.configuration.ExactLookup; import org.shininet.bukkit.itemrenamer.configuration.RenameRule; import org.shininet.bukkit.itemrenamer.utils.ConfigurationUtils; import com.google.common.collect.Sets; /** * Serializes and deserializes rules pertaining to specific item stacks. * @author Kristian */ public class ExactSerializer { private static final String KEYS = "keys"; private static final String VALUES = "values"; private ConfigurationSection section; /** * Initialize a new exact lookup from a configuration section. * @param section - the configuration section. */ public ExactSerializer(ConfigurationSection section) { setSection(section); } /** * Retrieve the associated configuration section. * @return The associated configuration section. */ public ConfigurationSection getSection() { return section; } /** * Set the associated configuration section. * @param section - the associated configuration section. */ private void setSection(ConfigurationSection section) { this.section = section; } /** * Deserialize the content of the configuration section to the given exact lookup. * @param destination - the output lookup. */ public void readLookup(ExactLookup destination) { int oldModCount = destination.getModificationCount(); String currentPath = section.getCurrentPath(); ConfigurationSection keys = ConfigurationUtils.getSection(section, KEYS); ConfigurationSection values = ConfigurationUtils.getSection(section, VALUES); // Don't permit nulls if (keys == null || values == null) { // Unless they both are (initial value) if (keys != values) throw new IllegalStateException( "Section " + section + " must have both a keys and a values sub-section."); else return; } RuleSerializer serializer = new RuleSerializer(values); // First, parse all the keys and associate with values for (String key : keys.getKeys(false)) { ItemStack parsed = ItemStack.deserialize( ConfigurationUtils.getSection(keys, key).getValues(false)); // Ensure that we succeeded if (parsed != null) { RenameRule rule = serializer.readRule(key); destination.setRule(parsed, rule); } } // This is probably wrong for (String missing : Sets.symmetricDifference(keys.getKeys(false), values.getKeys(false))) { Bukkit.getLogger().warning("[ItemRenamer] [" + currentPath + "] Missing key or value: " + missing); } destination.setModificationCount(oldModCount); } /** * Write the content of the given lookup to the configuration file. * @param source - the exact lookup to write. */ public void writeLookup(ExactLookup source) { // Reset section section = ConfigurationUtils.resetSection(section); ConfigurationSection keys = section.createSection(KEYS); ConfigurationSection values = section.createSection(VALUES); RuleSerializer serializer = new RuleSerializer(values); // The index is the common key used in the one-to-one relation Map<ItemStack, RenameRule> lookup = source.toLookup(); int index = 0; for (Entry<ItemStack, RenameRule> entry : lookup.entrySet()) { String key = Integer.toString(index++); // Save this mapping keys.createSection(key, entry.getKey().serialize()); serializer.writeRule(key, entry.getValue()); } } }