com.comphenix.xp.parser.text.ItemParser.java Source code

Java tutorial

Introduction

Here is the source code for com.comphenix.xp.parser.text.ItemParser.java

Source

/*
 *  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);
    }
}