package com.comphenix.xp.parser.sections; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.NullArgumentException; import org.bukkit.configuration.ConfigurationSection; import com.comphenix.xp.Action; import com.comphenix.xp.ActionTypes; import com.comphenix.xp.expressions.ParameterProviderSet; import com.comphenix.xp.lookup.ItemTree; import com.comphenix.xp.lookup.PotionTree; import com.comphenix.xp.lookup.Query; import com.comphenix.xp.lookup.SearchTree; import com.comphenix.xp.lookup.Query.Types; import com.comphenix.xp.parser.ActionParser; import com.comphenix.xp.parser.ParsingException; import com.comphenix.xp.parser.text.ItemParser; public class ItemsSectionParser extends SectionParser<ItemsSectionResult> { protected ItemParser itemParser; protected ActionParser actionParser; protected ActionTypes actionTypes; protected ParameterProviderSet parameterProviders; protected double multiplier; public ItemsSectionParser(ItemParser itemParser, ActionParser actionParser, ActionTypes types, ParameterProviderSet parameterProviders, double multiplier) { this.itemParser = itemParser; this.actionParser = actionParser; this.actionTypes = types; this.parameterProviders = parameterProviders; this.multiplier = multiplier; } @Override public ItemsSectionResult parse(ConfigurationSection input, String sectionName) throws ParsingException { if (input == null) throw new NullArgumentException("input"); // Create parsers with the given named parameters String[] blockNames = parameterProviders.getBlockParameters().getParameterNames(); String[] itemNames = parameterProviders.getItemParameters().getParameterNames(); ActionParser actionBlockParser = actionParser.createView(blockNames); ActionParser actionItemParser = actionParser.createView(itemNames); Map<Integer, ItemTree> actionRewards = new HashMap<Integer, ItemTree>(); Map<Integer, PotionTree> complexRewards = new HashMap<Integer, PotionTree>(); ItemsSectionResult result = new ItemsSectionResult(actionRewards, complexRewards); // Initialize all the default rewards for (Integer types : actionTypes.getTypes()) { actionRewards.put(types, new ItemTree(multiplier)); complexRewards.put(types, new PotionTree(multiplier)); } // Null is handled as the root if (sectionName != null) { input = input.getConfigurationSection(sectionName); // No rewards found if (input == null) return result; } // Load keys for (String key : input.getKeys(false)) { try { Query item = itemParser.parse(key); ConfigurationSection itemSection = input.getConfigurationSection(key); Types queryType = item.getQueryType(); // Read the different rewards for (String action : itemSection.getKeys(false)) { Integer type = actionTypes.getType(action); if (type == null) { // Catch some misunderstanding here if (action.equalsIgnoreCase("message") || action.equalsIgnoreCase("channels")) { throw ParsingException.fromFormat( "Message and channel list must be inside an action (block, smelting, ect.)."); } else { throw ParsingException.fromFormat( "Unrecogized action %s.", action); } } // Select the correct parser for the job ActionParser parser = actionTypes.isItemAction(action) ? actionItemParser : actionBlockParser; // Handle the special case of potion queries switch (queryType) { case ITEMS: loadActionOnItem(parser, itemSection, action, item, result.getActionReward(type), queryType); break; case POTIONS: loadActionOnItem(parser, itemSection, action, item, result.getComplexReward(type), queryType); break; default: throw ParsingException.fromFormat("The query type %s cannot be used on items.", queryType); } } } catch (ParsingException ex) { if (isCollectExceptions()) { // For now, record it debugger.printWarning(this, "Cannot parse item %s - %s", key, ex.getMessage()); } else { // Just invoke the error throw ex; } } } return result; } // I just wanted handle SearchTree<ItemQuery, Range> and SearchTree<PotionQuery, Range> with the same method, but // apparently you can't simply use SearchTree<Query, Range> or some derivation to match them both. Too bad. @SuppressWarnings({ "unchecked", "rawtypes" }) private void loadActionOnItem(ActionParser parser, ConfigurationSection config, String key, Query item, SearchTree destination, Query.Types checkType) throws ParsingException { Action range = parser.parse(config, key); // Check the query type if (item.getQueryType() != checkType) throw new IllegalArgumentException("Cannot load action " + key + " on this item matcher."); // Ignore this type if (range != null) { destination.put(item, range); } else { throw ParsingException.fromFormat("Unable to read range on %s.", key); } } }