net.citizensnpcs.api.command.CommandContext.java Source code

Java tutorial

Introduction

Here is the source code for net.citizensnpcs.api.command.CommandContext.java

Source

// $Id$
/*
 * Copyright (C) 2010 sk89q <http://www.sk89q.com>
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */

package net.citizensnpcs.api.command;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import net.citizensnpcs.api.command.exception.CommandException;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class CommandContext {
    protected String[] args;
    protected final Set<Character> flags = new HashSet<Character>();
    private Location location = null;
    private final CommandSender sender;
    protected final Map<String, String> valueFlags = Maps.newHashMap();

    public CommandContext(CommandSender sender, String[] args) {
        this.sender = sender;
        int i = 1;
        for (; i < args.length; i++) {
            // initial pass for quotes
            args[i] = args[i].trim();
            if (args[i].length() == 0) {
                // Ignore this
                continue;
            } else if (args[i].charAt(0) == '\'' || args[i].charAt(0) == '"') {
                char quote = args[i].charAt(0);
                String quoted = args[i].substring(1); // remove initial quote
                if (quoted.length() > 0 && quoted.charAt(quoted.length() - 1) == quote) {
                    args[i] = quoted.substring(0, quoted.length() - 1);
                    continue;
                }
                for (int inner = i + 1; inner < args.length; inner++) {
                    if (args[inner].isEmpty())
                        continue;
                    String test = args[inner].trim();
                    quoted += " " + test;
                    if (test.charAt(test.length() - 1) == quote) {
                        args[i] = quoted.substring(0, quoted.length() - 1);
                        // remove ending quote
                        for (int j = i + 1; j <= inner; ++j) {
                            args[j] = ""; // collapse previous
                        }
                        break;
                    }
                }
            }
        }
        for (i = 1; i < args.length; ++i) {
            // second pass for flags
            int length = args[i].length();
            if (length == 0)
                continue;
            if (i + 1 < args.length && length > 2 && VALUE_FLAG.matcher(args[i]).matches()) {
                int inner = i + 1;
                while (args[inner].length() == 0) {
                    // later args may have been quoted
                    if (++inner >= args.length) {
                        inner = -1;
                        break;
                    }
                }

                if (inner != -1) {
                    valueFlags.put(args[i].toLowerCase().substring(2), args[inner]);
                    args[i] = "";
                    args[inner] = "";
                }
            } else if (FLAG.matcher(args[i]).matches()) {
                for (int k = 1; k < args[i].length(); k++)
                    flags.add(args[i].charAt(k));
                args[i] = "";
            }
        }
        List<String> copied = Lists.newArrayList();
        for (String arg : args) {
            arg = arg.trim();
            if (arg == null || arg.isEmpty())
                continue;
            copied.add(arg.trim());
        }
        this.args = copied.toArray(new String[copied.size()]);
    }

    public CommandContext(String[] args) {
        this(null, args);
    }

    public int argsLength() {
        return args.length - 1;
    }

    public String getCommand() {
        return args[0];
    }

    public double getDouble(int index) throws NumberFormatException {
        return Double.parseDouble(args[index + 1]);
    }

    public double getDouble(int index, double def) throws NumberFormatException {
        return index + 1 < args.length ? Double.parseDouble(args[index + 1]) : def;
    }

    public String getFlag(String ch) {
        return valueFlags.get(ch);
    }

    public String getFlag(String ch, String def) {
        final String value = valueFlags.get(ch);
        if (value == null) {
            return def;
        }

        return value;
    }

    public double getFlagDouble(String ch) throws NumberFormatException {
        return Double.parseDouble(valueFlags.get(ch));
    }

    public double getFlagDouble(String ch, double def) throws NumberFormatException {
        final String value = valueFlags.get(ch);
        if (value == null) {
            return def;
        }

        return Double.parseDouble(value);
    }

    public int getFlagInteger(String ch) throws NumberFormatException {
        return Integer.parseInt(valueFlags.get(ch));
    }

    public int getFlagInteger(String ch, int def) throws NumberFormatException {
        final String value = valueFlags.get(ch);
        if (value == null) {
            return def;
        }

        return Integer.parseInt(value);
    }

    public Set<Character> getFlags() {
        return flags;
    }

    public int getInteger(int index) throws NumberFormatException {
        return Integer.parseInt(args[index + 1]);
    }

    public int getInteger(int index, int def) throws NumberFormatException {
        if (index + 1 < args.length) {
            try {
                return Integer.parseInt(args[index + 1]);
            } catch (NumberFormatException ex) {
            }
        }
        return def;
    }

    public String getJoinedStrings(int initialIndex) {
        return getJoinedStrings(initialIndex, ' ');
    }

    public String getJoinedStrings(int initialIndex, char delimiter) {
        initialIndex = initialIndex + 1;
        StringBuilder buffer = new StringBuilder(args[initialIndex]);
        for (int i = initialIndex + 1; i < args.length; i++)
            buffer.append(delimiter).append(args[i]);
        return buffer.toString().trim();
    }

    public String[] getPaddedSlice(int index, int padding) {
        String[] slice = new String[args.length - index + padding];
        System.arraycopy(args, index, slice, padding, args.length - index);
        return slice;
    }

    public Location getSenderLocation() throws CommandException {
        if (location != null || sender == null)
            return location;
        if (sender instanceof Player)
            location = ((Player) sender).getLocation();
        else if (sender instanceof BlockCommandSender)
            location = ((BlockCommandSender) sender).getBlock().getLocation();
        if (hasValueFlag("location")) {
            location = parseLocation(location, getFlag("location"));
        }
        return location;
    }

    public Location getSenderTargetBlockLocation() {
        if (sender == null)
            return location;
        if (sender instanceof Player)
            location = ((Player) sender).getTargetBlock(null, 50).getLocation();
        else if (sender instanceof BlockCommandSender)
            location = ((BlockCommandSender) sender).getBlock().getLocation();
        return location;
    }

    public String[] getSlice(int index) {
        String[] slice = new String[args.length - index];
        System.arraycopy(args, index, slice, 0, args.length - index);
        return slice;
    }

    public String getString(int index) {
        return args[index + 1];
    }

    public String getString(int index, String def) {
        return index + 1 < args.length ? args[index + 1] : def;
    }

    public Map<String, String> getValueFlags() {
        return valueFlags;
    }

    public boolean hasFlag(char ch) {
        return flags.contains(ch);
    }

    public boolean hasValueFlag(String ch) {
        return valueFlags.containsKey(ch);
    }

    public int length() {
        return args.length;
    }

    public boolean matches(String command) {
        return args[0].equalsIgnoreCase(command);
    }

    public static Location parseLocation(Location currentLocation, String flag) throws CommandException {
        boolean denizen = flag.startsWith("l@");
        String[] parts = Iterables.toArray(LOCATION_SPLITTER.split(flag.replaceFirst("l@", "")), String.class);
        if (parts.length > 0) {
            String worldName = currentLocation != null ? currentLocation.getWorld().getName() : "";
            double x = 0, y = 0, z = 0;
            float yaw = 0F, pitch = 0F;
            switch (parts.length) {
            case 6:
                if (denizen) {
                    worldName = parts[5].replaceFirst("w@", "");
                } else
                    pitch = Float.parseFloat(parts[5]);
            case 5:
                if (denizen) {
                    pitch = Float.parseFloat(parts[4]);
                } else
                    yaw = Float.parseFloat(parts[4]);
            case 4:
                if (denizen && parts.length > 4) {
                    yaw = Float.parseFloat(parts[3]);
                } else
                    worldName = parts[3].replaceFirst("w@", "");
            case 3:
                x = Double.parseDouble(parts[0]);
                y = Double.parseDouble(parts[1]);
                z = Double.parseDouble(parts[2]);
                break;
            default:
                throw new CommandException(CommandMessages.INVALID_SPAWN_LOCATION);
            }
            World world = Bukkit.getWorld(worldName);
            if (world == null)
                throw new CommandException(CommandMessages.INVALID_SPAWN_LOCATION);
            return new Location(world, x, y, z, yaw, pitch);
        } else {
            Player search = Bukkit.getPlayerExact(flag);
            if (search == null)
                throw new CommandException(CommandMessages.PLAYER_NOT_FOUND_FOR_SPAWN);
            return search.getLocation();
        }
    }

    private static final Pattern FLAG = Pattern.compile("^-[a-zA-Z]+$");
    private static final Splitter LOCATION_SPLITTER = Splitter.on(Pattern.compile("[,]|[:]")).omitEmptyStrings();
    private static final Pattern VALUE_FLAG = Pattern.compile("^--[a-zA-Z0-9]+$");
}