package org.shininet.bukkit.itemrenamer.configuration; import java.util.Map; import java.util.Map.Entry; import org.bukkit.configuration.ConfigurationSection; import org.shininet.bukkit.itemrenamer.serialization.DamageSerializer; import org.shininet.bukkit.itemrenamer.serialization.ExactSerializer; import org.shininet.bukkit.itemrenamer.utils.ConfigurationUtils; import com.google.common.collect.Maps; /** * Represents a rule pack in memory. * * @author Kristian */ class RulePack { public static final String EXACT = "exact"; private final String name; // The two different lookups private Map<Integer, DamageLookup> rangeLookup; private ExactLookup exactLookup; // Number of extra modifications private int modCount; public RulePack(String name) { this.name = name; this.rangeLookup = Maps.newHashMap(); this.exactLookup = new MemoryExactLookup(); } /** * Construct a rule pack from a given configuration section. * @param name - the name of the pack. * @param parent - the parent configuration. */ public RulePack(String name, ConfigurationSection parent) { this.name = name; load(parent); } /** * Load the content of a serialized configuration. * @param parent - the parent configuration. */ public void load(ConfigurationSection parent) { ConfigurationSection items = ConfigurationUtils.getSection(parent, name); // Reset current values rangeLookup.clear(); exactLookup.clear(); if (items != null) { for (String key : items.getKeys(false)) { if (EXACT.equals(key)) { ExactSerializer serializer = new ExactSerializer( ConfigurationUtils.getSection(items, EXACT)); serializer.readLookup(exactLookup); } else { parseRange(items, key); } } } } /** * Parse the given item section. * @param items - the item section. * @param key - the item ID. */ private void parseRange(ConfigurationSection items, String key) { Integer id = Integer.parseInt(key); DamageSerializer serializer = new DamageSerializer(ConfigurationUtils.getSection(items, key)); DamageLookup damage = new MemoryDamageLookup(); // Load and save serializer.readLookup(damage); rangeLookup.put(id, damage); } /** * Save the content of this rule pack to the given configuration section. * @param section - the section to save to. */ public void save(ConfigurationSection section) { // Write all the stored damage lookups for (Entry<Integer, DamageLookup> entry : rangeLookup.entrySet()) { DamageSerializer serializer = new DamageSerializer(section.createSection(name + "." + entry.getKey())); serializer.writeLookup(entry.getValue()); } // Save the exact item stacks ExactSerializer serializer = new ExactSerializer( section.createSection(name + "." + EXACT)); serializer.writeLookup(exactLookup); } /** * Retrieve or create the range damage lookup associated with a given item ID. * @param id - the item ID to search for. * @return A damage lookup. */ public DamageLookup getOrCreateLookup(int id) { DamageLookup lookup = rangeLookup.get(id); // Create it if it doesn't exist yet if (lookup == null) { modCount++; rangeLookup.put(id, lookup = new MemoryDamageLookup()); } return lookup; } /** * Retrieve the current range (for both item ID and damage value) lookup. * @return The range lookup. */ public Map<Integer, DamageLookup> getRangeLookup() { return rangeLookup; } /** * Retrieve the exact lookup. * @return The exact lookup. */ public ExactLookup getExactLookup() { return exactLookup; } /** * Retrieve the name of this rule pack. * @return The name of the rule pack. */ public String getName() { return name; } /** * Retrieve the total modification count used to track changes across saves and loads. * @return The total modification count. */ public int getModificationCount() { int totalCount = modCount; for (DamageLookup lookup : rangeLookup.values()) { if (lookup.getModificationCount() > 0) { totalCount += lookup.getModificationCount(); } } return exactLookup.getModificationCount() + totalCount; } }