de.static_interface.sinklibrary.api.command.SinkCommand.java Source code

Java tutorial

Introduction

Here is the source code for de.static_interface.sinklibrary.api.command.SinkCommand.java

Source

/*
 * Copyright (c) 2013 - 2014 http://static-interface.de and contributors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.static_interface.sinklibrary.api.command;

import static de.static_interface.sinklibrary.configuration.LanguageConfiguration.m;

import de.static_interface.sinklibrary.SinkLibrary;
import de.static_interface.sinklibrary.api.exception.NotEnoughArgumentsException;
import de.static_interface.sinklibrary.api.exception.UnauthorizedAccessException;
import de.static_interface.sinklibrary.api.exception.UserNotFoundException;
import de.static_interface.sinklibrary.api.sender.IrcCommandSender;
import de.static_interface.sinklibrary.util.Debug;
import de.static_interface.sinklibrary.util.SinkIrcReflection;
import de.static_interface.sinklibrary.util.StringUtil;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;

import java.io.StringWriter;

import javax.annotation.Nullable;

public abstract class SinkCommand implements CommandExecutor {

    protected CommandSender sender;
    protected Plugin plugin;
    private SinkTabCompleterOptions defaultTabOptions = new SinkTabCompleterOptions(true, false, false);
    private SinkCommandOptions defaultCommandOptions = new SinkCommandOptions(this);
    private String usage = null;
    private String permission;
    private boolean onPreExecuteCalled = false;
    private CommandLineParser parser = getCommandOptions().getCliParser();
    private CommandLine cmdLine = null;
    private String cmd = null;

    public SinkCommand(Plugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public final boolean onCommand(CommandSender sender, @Nullable Command command, String label, String[] args) {
        cmd = label.trim().replaceFirst(StringUtil.stripRegex(getCommandPrefix()), "").split(" ")[0];
        this.sender = sender;
        boolean result = onPreExecute(sender, label, args);
        if (!onPreExecuteCalled) {
            throw new IllegalStateException(getClass().getName() + " did not call super.onPreExecute()");
        }
        return result;
    }

    public SinkTabCompleterOptions getTabCompleterOptions() {
        return defaultTabOptions;
    }

    public SinkCommandOptions getCommandOptions() {
        return defaultCommandOptions;
    }

    protected boolean onPreExecute(final CommandSender sender, final String label, final String[] args) {
        onPreExecuteCalled = true;
        if (getCommandOptions().isIrcOpOnly() && sender instanceof IrcCommandSender && !sender.isOp()) {
            throw new UnauthorizedAccessException();
        }

        if (!(sender instanceof IrcCommandSender) && getCommandOptions().isIrcOnly()) {
            Debug.log("isIrcOnly check failed: sender: " + sender.getClass().getSimpleName() + ", isIrcOnly: "
                    + getCommandOptions().isIrcOnly());
            return false;
        }

        if (!(sender instanceof Player) && getCommandOptions().isPlayerOnly()) {
            Debug.log("isPlayerOnly check failed: sender: " + sender.getClass().getSimpleName() + ", isPlayerOnly: "
                    + getCommandOptions().isPlayerOnly());
            return false;
        }

        boolean defaultNotices = false;
        if (getCommandOptions().useNotices() && sender instanceof IrcCommandSender) {
            defaultNotices = ((IrcCommandSender) sender).getUseNotice();
            ((IrcCommandSender) sender).setUseNotice(true);
        }
        Bukkit.getScheduler().runTask(plugin, new Runnable() {
            @Override
            public void run() {
                Exception exception = null;
                boolean success = false;
                try {
                    Debug.log("onExecute(" + sender.getName() + ", " + label + " ["
                            + StringUtil.formatArrayToString(args, ", ") + "])");
                    String[] parsedCmdArgs = args;
                    String parsedLabel = label;
                    Options options = getCommandOptions().getCliOptions();
                    if (options != null) {
                        cmdLine = parser.parse(getCommandOptions().getCliOptions(), args);
                        if (getCommandOptions().isDefaultHelpEnabled() && cmdLine.hasOption('h')) {
                            sendUsage(sender);
                            return;
                        }
                        parsedCmdArgs = cmdLine.getArgs();
                        parsedLabel = StringUtil.formatArrayToString(parsedCmdArgs, " ");
                    }
                    success = onExecute(sender, parsedLabel, parsedCmdArgs);
                } catch (Exception e) {
                    exception = e;
                }

                onPostExecute(sender, label, args, exception, success);
            }
        });

        if (getCommandOptions().useNotices() && sender instanceof IrcCommandSender) {
            ((IrcCommandSender) sender).setUseNotice(defaultNotices);
        }

        return true;
    }

    protected abstract boolean onExecute(CommandSender sender, String label, String[] args) throws ParseException;

    protected void onPostExecute(CommandSender sender, String label, String[] args, Exception exception,
            boolean success) {
        boolean reportException = true;
        boolean exceptionReported = false;

        if (exception instanceof UnauthorizedAccessException) {
            sender.sendMessage(m("Permissions.General"));
            reportException = false;
        } else if (exception instanceof NotEnoughArgumentsException) {
            sender.sendMessage(m("General.TooFewArguments"));
            reportException = false;
        } else if (exception instanceof UserNotFoundException) {
            sender.sendMessage(exception.getMessage());
            reportException = false;
        } else if (exception instanceof ParseException) {
            sendUsage(sender);
            sender.sendMessage(ChatColor.DARK_RED + "Error: " + ChatColor.RED + exception.getMessage());
            return;
        }

        if (Debug.isEnabled() && exception != null) {
            exception.printStackTrace();
            exceptionReported = true;
        }

        if (exception != null && reportException) {
            if (!exceptionReported) {
                SinkLibrary.getInstance().getLogger().severe("Unexpected exception occurred: ");
                exception.printStackTrace();
            }

            if (SinkLibrary.getInstance().getSettings().isDebugEnabled()) {
                sender.sendMessage(exception.getMessage());
            } else {
                sender.sendMessage(ChatColor.DARK_RED + "An internal error occured.");
            }
        } else if (!success && !StringUtil.isEmptyOrNull(getUsage()) && reportException) {
            sendUsage(sender);
        }
    }

    private void sendUsage(CommandSender sender) {
        sender.sendMessage(getUsage().split(System.lineSeparator()));
    }

    protected String getCommandPrefix() {
        if (sender instanceof IrcCommandSender) {
            return SinkIrcReflection.getIrcCommandPrefix();
        }
        return "/";
    }

    public String getUsage() {
        Options options = getCommandOptions().getCliOptions();
        if (StringUtil.isEmptyOrNull(usage) && options != null) {
            StringWriter writer = new StringWriter();
            getCommandOptions().getCliHelpFormatter(writer);
            usage = writer.toString();
        }
        return usage;
    }

    public void setUsage(String usage) {
        this.usage = usage;
    }

    public String getPermission() {
        return permission;
    }

    public void setPermission(String permission) {
        this.permission = permission;
    }

    public Plugin getPlugin() {
        return plugin;
    }

    public void setPlugin(Plugin plugin) {
        this.plugin = plugin;
    }

    public CommandLine getCommandLine() {
        return cmdLine;
    }

    public CommandLineParser getCommandParser() {
        return parser;
    }

    public String getCmdAlias() {
        return cmd;
    }

    public void setCmdAlias(String cmd) {
        this.cmd = cmd;
    }
}