001 package org.bukkit.command;
002
003 import java.util.List;
004
005 import org.apache.commons.lang.Validate;
006 import org.bukkit.plugin.Plugin;
007
008 /**
009 * Represents a {@link Command} belonging to a plugin
010 */
011 public final class PluginCommand extends Command implements PluginIdentifiableCommand {
012 private final Plugin owningPlugin;
013 private CommandExecutor executor;
014 private TabCompleter completer;
015
016 protected PluginCommand(String name, Plugin owner) {
017 super(name);
018 this.executor = owner;
019 this.owningPlugin = owner;
020 this.usageMessage = "";
021 }
022
023 /**
024 * Executes the command, returning its success
025 *
026 * @param sender Source object which is executing this command
027 * @param commandLabel The alias of the command used
028 * @param args All arguments passed to the command, split via ' '
029 * @return true if the command was successful, otherwise false
030 */
031 @Override
032 public boolean execute(CommandSender sender, String commandLabel, String[] args) {
033 boolean success = false;
034
035 if (!owningPlugin.isEnabled()) {
036 return false;
037 }
038
039 if (!testPermission(sender)) {
040 return true;
041 }
042
043 try {
044 success = executor.onCommand(sender, this, commandLabel, args);
045 } catch (Throwable ex) {
046 throw new CommandException("Unhandled exception executing command '" + commandLabel + "' in plugin " + owningPlugin.getDescription().getFullName(), ex);
047 }
048
049 if (!success && usageMessage.length() > 0) {
050 for (String line : usageMessage.replace("<command>", commandLabel).split("\n")) {
051 sender.sendMessage(line);
052 }
053 }
054
055 return success;
056 }
057
058 /**
059 * Sets the {@link CommandExecutor} to run when parsing this command
060 *
061 * @param executor New executor to run
062 */
063 public void setExecutor(CommandExecutor executor) {
064 this.executor = executor == null ? owningPlugin : executor;
065 }
066
067 /**
068 * Gets the {@link CommandExecutor} associated with this command
069 *
070 * @return CommandExecutor object linked to this command
071 */
072 public CommandExecutor getExecutor() {
073 return executor;
074 }
075
076 /**
077 * Sets the {@link TabCompleter} to run when tab-completing this command.
078 * <p>
079 * If no TabCompleter is specified, and the command's executor implements
080 * TabCompleter, then the executor will be used for tab completion.
081 *
082 * @param completer New tab completer
083 */
084 public void setTabCompleter(TabCompleter completer) {
085 this.completer = completer;
086 }
087
088 /**
089 * Gets the {@link TabCompleter} associated with this command.
090 *
091 * @return TabCompleter object linked to this command
092 */
093 public TabCompleter getTabCompleter() {
094 return completer;
095 }
096
097 /**
098 * Gets the owner of this PluginCommand
099 *
100 * @return Plugin that owns this command
101 */
102 public Plugin getPlugin() {
103 return owningPlugin;
104 }
105
106 /**
107 * {@inheritDoc}
108 * <p>
109 * Delegates to the tab completer if present.
110 * <p>
111 * If it is not present or returns null, will delegate to the current
112 * command executor if it implements {@link TabCompleter}. If a non-null
113 * list has not been found, will default to standard player name
114 * completion in {@link
115 * Command#tabComplete(CommandSender, String, String[])}.
116 * <p>
117 * This method does not consider permissions.
118 *
119 * @throws CommandException if the completer or executor throw an
120 * exception during the process of tab-completing.
121 * @throws IllegalArgumentException if sender, alias, or args is null
122 */
123 @Override
124 public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws CommandException, IllegalArgumentException {
125 Validate.notNull(sender, "Sender cannot be null");
126 Validate.notNull(args, "Arguments cannot be null");
127 Validate.notNull(alias, "Alias cannot be null");
128
129 List<String> completions = null;
130 try {
131 if (completer != null) {
132 completions = completer.onTabComplete(sender, this, alias, args);
133 }
134 if (completions == null && executor instanceof TabCompleter) {
135 completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args);
136 }
137 } catch (Throwable ex) {
138 StringBuilder message = new StringBuilder();
139 message.append("Unhandled exception during tab completion for command '/").append(alias).append(' ');
140 for (String arg : args) {
141 message.append(arg).append(' ');
142 }
143 message.deleteCharAt(message.length() - 1).append("' in plugin ").append(owningPlugin.getDescription().getFullName());
144 throw new CommandException(message.toString(), ex);
145 }
146
147 if (completions == null) {
148 return super.tabComplete(sender, alias, args);
149 }
150 return completions;
151 }
152
153 @Override
154 public String toString() {
155 StringBuilder stringBuilder = new StringBuilder(super.toString());
156 stringBuilder.deleteCharAt(stringBuilder.length() - 1);
157 stringBuilder.append(", ").append(owningPlugin.getDescription().getFullName()).append(')');
158 return stringBuilder.toString();
159 }
160 }