Java tutorial
/* * ExperienceMod - Bukkit server plugin for modifying the experience system in Minecraft. * Copyright (C) 2012 Kristian S. Stangeland * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA */ package com.comphenix.xp.parser.text; import java.util.List; import java.util.Set; import java.util.Queue; import org.apache.commons.lang.StringUtils; import org.bukkit.Material; import com.comphenix.xp.lookup.ItemQuery; import com.comphenix.xp.lookup.PotionQuery; import com.comphenix.xp.lookup.Query; import com.comphenix.xp.parser.TextParser; import com.comphenix.xp.parser.ParsingException; import com.comphenix.xp.parser.Utility; import com.comphenix.xp.parser.primitives.BooleanParser; public class ItemParser extends TextParser<Query> { private ParameterParser<Set<Integer>> itemNameParser; private ItemDurabilityParser elementDurability = new ItemDurabilityParser(); private ParameterParser<Integer> durabilityParser = new ParameterParser<Integer>(elementDurability); // Parse options private BooleanParser playerParser = new BooleanParser("player"); // Our potion parser private PotionParser potionParser; public ItemParser(ItemNameParser nameParser) { potionParser = new PotionParser(nameParser, new PotionTypeParser()); itemNameParser = new ParameterParser<Set<Integer>>(nameParser); } @Override public Query parse(String text) throws ParsingException { if (text.length() == 0) // Empty names are not legal in YAML, so this shouldn't be possible throw new IllegalArgumentException("Key must have some characters."); Queue<String> tokens = getParameterQueue(text); List<Integer> itemIDs = Utility.getElementList((Integer) null); ; List<Integer> durabilities = Utility.getElementList((Integer) null); ; ParsingException errorReason = null; Integer first = null; boolean isPotion = false; boolean sameCategory = false; try { // Get item IDs itemIDs = Utility.flatten(itemNameParser.parse(tokens)); first = null; // Get the first element if (!itemIDs.isEmpty()) { first = itemIDs.get(0); isPotion = itemIDs.contains(Material.POTION.getId()); } /* We may have a slight problem here. Durabilities may require the item ID to properly decode the name, * but if we have multiple item IDs that may conflict with each other. * * Therefore, only items of the same category may have multiple durabilities. */ sameCategory = ItemDurabilityParser.inSameCategory(itemIDs); // Set the first item or null elementDurability.setItemID(first); elementDurability.setUsedName(false); // Get list of durabilities durabilities = durabilityParser.parse(tokens); // Check for multiple items and named durabilities if (!sameCategory && elementDurability.isUsedName()) throw ParsingException.fromFormat( "Cannot use named durabilities (%s) with items of different data categories.", StringUtils.join(durabilities, ", ")); // Negative items or durabilities are not legal if (hasNegativeIntegers(itemIDs) || hasNegativeIntegers(durabilities)) throw new ParsingException("Item ID or durability cannot contain negative numbers"); } catch (ParsingException ex) { // Potion? Try again. if (isPotion) return parseAsPotion(text); // Check for named categories if (!sameCategory && elementDurability.isUsedName()) throw new ParsingException("Named durabilities with different data categories."); else // Try more errorReason = ex; } // Scan for the "player creation" option List<Boolean> playerCreation = playerParser.parseAny(tokens); // Still more tokens? Something is wrong. if (!tokens.isEmpty()) { if (isPotion) return parseAsPotion(text); else if (errorReason == null) throw ParsingException.fromFormat("Unknown item tokens: ", StringUtils.join(tokens, ", ")); else throw errorReason; } // Return universal potion query if (isPotion && durabilities.isEmpty()) { return PotionQuery.fromAny(); } // At this point we have all we need to know return new ItemQuery(itemIDs, durabilities, playerCreation); } public ParameterParser<Set<Integer>> getItemNameParser() { return itemNameParser; } public void setItemNameParser(ParameterParser<Set<Integer>> itemNameParser) { this.itemNameParser = itemNameParser; } public ItemDurabilityParser getElementDurability() { return elementDurability; } public void setElementDurability(ItemDurabilityParser elementDurability) { this.elementDurability = elementDurability; } public ParameterParser<Integer> getDurabilityParser() { return durabilityParser; } public void setDurabilityParser(ParameterParser<Integer> durabilityParser) { this.durabilityParser = durabilityParser; } public PotionParser getPotionParser() { return potionParser; } public void setPotionParser(PotionParser potionParser) { this.potionParser = potionParser; } private boolean hasNegativeIntegers(List<Integer> values) { // See if any of the values are negative for (Integer value : values) { if (value != null && value < 0) { return true; } } return false; } private PotionQuery parseAsPotion(String text) throws ParsingException { // Delegate this task to the potion parser return potionParser.parse(text); } }