Package net.lahwran.bukkit.jython

Source Code of net.lahwran.bukkit.jython.PythonCommandHandler

package net.lahwran.bukkit.jython;

import java.util.ArrayList;
import java.util.List;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
import org.python.antlr.ast.alias;
import org.python.core.*;


/**
* Class to wrap python functions so that they can be used to handle commands
* @author lahwran
*/
public class PythonCommandHandler implements CommandExecutor, TabCompleter {

    private final PyObject func;
    private final String name;
    private final PyObject tabComplete;
    private int argcount = -1;
    private int tabArgcount = -1;

    /**
     * @param func function to handle
     * @param name name of command to use when registering
     */
    public PythonCommandHandler(PyObject func, String name, PyObject tabComplete) {
        this.func = func;
        this.name = name;
        this.tabComplete = tabComplete;
    }

    /**
     * @param pythonPlugin plugin to register command to
     */
    void register(PythonPlugin pythonPlugin) {
        PluginCommand command = pythonPlugin.getCommand(name);
        if (command == null)
            throw new IllegalArgumentException("Command '"+name+"' not found in plugin " + pythonPlugin.getDescription().getName());
        command.setExecutor(this);
    }

    private boolean call(int argcount, CommandSender sender, Command command, String label, String[] args) {
        PyObject[] handlerargs;
        if (argcount == 4) {
            handlerargs = new PyObject[] { Py.java2py(sender), Py.java2py(command), Py.java2py(label), Py.java2py(args)};
        } else if (argcount == 3) {
            handlerargs = new PyObject[] { Py.java2py(sender), Py.java2py(label), Py.java2py(args)};
        } else if (argcount == 2) {
            handlerargs = new PyObject[] { Py.java2py(sender), Py.java2py(args)};
        } else
            throw new IllegalArgumentException("this can't happen unless you stick your fingers in my code, which obviously you did, so howabout you undo it?");
        return func.__call__(handlerargs).__nonzero__();
    }

    private PyObject[] pyArgs(Object... args) {
        PyObject[] converted = new PyObject[args.length];

        for(int i = 0; i < args.length; i++) {
            converted[i] = Py.java2py(args[i]);
        }

        return converted;
    }

    private ArrayList<String> toJavaStringList(PyObject pyList) {
        if(pyList.getType().equals(PyString.TYPE)) {
            ArrayList<String> result = new ArrayList<String>(1);
            result.add(pyList.asString());
            return result;
        } else if(pyList.isSequenceType()) {
            ArrayList<String> result = new ArrayList<String>();
            for(PyObject o : pyList.asIterable()) {
                result.add(o.asString());
            }
            return result;
        } else if(pyList.equals(Py.None) || pyList.equals(null)) {
            return null;
        }
        else throw new IllegalArgumentException("Tab Completer function must return a list of strings a string or null");
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        boolean result;
        if (argcount == -1) {
            try {
                result = call(4, sender, command, label, args);
                argcount = 4;
            } catch (PyException e) {
                //this could goof up someone ... they'll probably yell at us and eventually read this code ... fuck them
                if (e.type == Py.TypeError && (e.value.toString().endsWith("takes exactly 3 arguments (4 given)") || e.value.toString().endsWith("takes exactly 4 arguments (5 given)"))) {
                    result = call(3, sender, command, label, args);
                    argcount = 3;
                } else if (e.type == Py.TypeError && (e.value.toString().endsWith("takes exactly 2 arguments (4 given)") || e.value.toString().endsWith("takes exactly 3 arguments (5 given)"))) {
                    result = call(2, sender, command, label, args);
                    argcount = 2;
                } else {
                    throw e;
                }
            }
        } else {
            result = call(argcount, sender, command, label, args);
        }
        return result;
    }

    @Override
    public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
        if (tabComplete == null) {
            return null;
        }

        PyObject result = null;
        if (tabArgcount == -1) {
            try {
                result = tabComplete.__call__(pyArgs(sender, command, label, args));
                tabArgcount = 4;
            } catch (PyException e) {
                //this could goof up someone ... they'll probably yell at us and eventually read this code ... fuck them
                if (e.type == Py.TypeError && (e.value.toString().endsWith("takes exactly 3 arguments (4 given)") || e.value.toString().endsWith("takes exactly 4 arguments (5 given)"))) {
                    result = tabComplete.__call__(pyArgs(sender, label, args));
                    tabArgcount = 3;
                } else if (e.type == Py.TypeError && (e.value.toString().endsWith("takes exactly 2 arguments (4 given)") || e.value.toString().endsWith("takes exactly 3 arguments (5 given)"))) {
                    result = tabComplete.__call__(pyArgs(sender, args));
                    tabArgcount = 2;
                } else {
                    throw e;
                }
            }
        } else {
            switch (tabArgcount) {
            case 2: result = tabComplete.__call__(pyArgs(sender, args)); break;
            case 3: result = tabComplete.__call__(pyArgs(sender,  label, args)); break;
            case 4: result = tabComplete.__call__(pyArgs(sender, command, label, args)); break;
            default: throw new IllegalArgumentException("Python Tab Completer needs an invalid number of arguments. This case should be impossible.");
            }
        }

        return toJavaStringList(result);
    }

}
TOP

Related Classes of net.lahwran.bukkit.jython.PythonCommandHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.