package pluginbase.command; import ninja.leaping.configurate.loader.ConfigurationLoader; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import pluginbase.logging.PluginLogger; import pluginbase.messages.messaging.Messager; import pluginbase.messages.messaging.MessagerFactory; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; public abstract class AbstractCommandProvider<P> implements CommandProvider<P> { private final P plugin; private final String commandPrefix; private final boolean useQueuedCommands; private final Map<Class<? extends Command>, List<String>> additionalAliases; private PluginLogger pluginLogger; @Nullable private Messager messager; protected AbstractCommandProvider(P plugin, String commandPrefix, boolean useQueuedCommands) { this.plugin = plugin; this.commandPrefix = commandPrefix; this.useQueuedCommands = useQueuedCommands; this.additionalAliases = new HashMap<>(); } /** * Gets the prefix for commands used by this CommandProvider. * <p/> * This prefix will be use on all command primary aliases but is optional on alternate aliases. * * @return the prefix for commands used by this CommandProvider. */ @NotNull public String getCommandPrefix() { return commandPrefix; } /** * Gets the handler object for commands provided by this CommandProvider. * * @return the handler object for commands provided by this CommandProvider. */ @NotNull public abstract CommandHandler getCommandHandler(); /** * Schedules a queued command to be run later in order to deal with it's expiration when left unconfirmed. * <p/> * This method should simply run the QueuedCommand (which implements {@link Runnable}) an amount of seconds later. * The amount is specified with {@link pluginbase.command.QueuedCommand#getExpirationDuration()}. * <p/> * This will automatically be called by the command handler when the queued command is used initially in order to * schedule its expiration. * </p> * If {@link #useQueuedCommands()} returns false this method can happily do nothing. * * @param queuedCommand the queued command to schedule expiration for. */ public abstract void scheduleQueuedCommandExpiration(@NotNull final QueuedCommand queuedCommand); /** * Whether or not the command provider offers queued commands. * <p/> * This is important to note as it determines whether or not the provider should have a built in confirm command. * <p/> * Simply implement this method to return true to offer queued commands. * * @return true means this provider offers queued commands and has a built in confirm command. */ public boolean useQueuedCommands() { return useQueuedCommands; } /** * Provides additional aliases that commands should use. * <p/> * This is useful for when the CommandProvider does not have access to the Command class in order to add them normally. * * @return an array of additional command aliases. */ @NotNull public String[] getAdditionalCommandAliases(@NotNull Class<? extends Command> commandClass) { List<String> aliases = additionalAliases.get(commandClass); return aliases != null ? aliases.toArray(new String[aliases.size()]) : new String[0]; } /** * Adds an additional alias to a command. Any amount may be added by calling this method multiple times. * <p/> * This must be called before command registration occurs! * * @param commandClass the command class to add aliases for. * @param alias the alias to add. */ public void addCommandAlias(@NotNull Class<? extends Command> commandClass, @NotNull String alias) { List<String> aliases = additionalAliases.get(commandClass); if (aliases == null) { aliases = new ArrayList<String>(); additionalAliases.put(commandClass, aliases); } aliases.add(alias); } /** * Gets the plugin that this command provider belongs to. * * @return the plugin that this command provider belongs to. */ public P getPlugin() { return plugin; } /** {@inheritDoc} */ @NotNull @Override public PluginLogger getLog() { if (pluginLogger == null) { pluginLogger = PluginLogger.getLogger(this); } return pluginLogger; } /** {@inheritDoc} */ @Override public void loadMessages(@NotNull ConfigurationLoader loader, @NotNull Locale locale) { messager = MessagerFactory.createMessager(this, loader, locale); } /** {@inheritDoc} */ @NotNull @Override public Messager getMessager() { if (messager == null) { throw new IllegalStateException("No Messager has been loaded for this command provider!"); } return messager; } }