Command and Command bank.

keep-around/d31701866686f66088b78de2e29736ae36e55a68
Pingex aka Raphaël 9 years ago
parent cb9767f8bd
commit 2b0238dff1

@ -0,0 +1,191 @@
package net.pingex.dcf.commands;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Represents a single command.
*/
public abstract class Command implements ICommandExecutor
{
/**
* Main name of the command
*/
private String name;
/**
* Command can also be called using the following list of aliases
*/
private List<String> aliases;
/**
* Description of the command.
*/
private String description;
/**
* Is the command enabled ? Can it be invoked ?
*/
private boolean isEnabled;
/**
* Command usage help
*/
private String usage;
/**
* Basic constructor.
* @param name Name of the command
* @param aliases Aliases, if any
* @param description Description of the command
* @param isEnabled Is the command enabled ?
* @param usage Command usage help
*/
public Command(String name, List<String> aliases, String description, boolean isEnabled, String usage)
{
this.name = name;
this.aliases = aliases;
this.description = description;
this.isEnabled = isEnabled;
this.usage = usage;
}
/**
* Contains Command default values
*/
public static class Defaults
{
public static final List<String> ALIASES = Collections.emptyList();
public static final String DESCRIPTION = "No command description provided.";
public static final boolean IS_ENABLED = true;
public static final String USAGE = "No command usage provided.";
}
/**
* Builder for a command
*/
public static class Builder
{
/**
* Main name of the command
*/
private String name;
/**
* Command can also be called using the following list of aliases
*/
private List<String> aliases = Defaults.ALIASES;
/**
* Description of the command.
*/
private String description = Defaults.DESCRIPTION;
/**
* Is the command enabled ? Can it be invoked ?
*/
private boolean isEnabled = Defaults.IS_ENABLED;
/**
* Command usage help
*/
private String usage = Defaults.USAGE;
public Builder(String name)
{
this.name = name;
}
public Builder aliases(List<String> aliases)
{
this.aliases = aliases;
return this;
}
/**
* Set aliases using varargs
* @param aliases Aliases varargs
*/
public Builder aliases(String... aliases)
{
this.aliases = Arrays.asList(aliases);
return this;
}
public Builder description(String description)
{
this.description = description;
return this;
}
public Builder enabled(boolean enabled)
{
isEnabled = enabled;
return this;
}
public Builder usage(String usage)
{
this.usage = usage;
return this;
}
/**
* Build a new Command using a supplied executor.
* @param toExecute The body of the command.
* @return Built command.
*/
public Command build(ICommandExecutor toExecute)
{
return new Command(name, aliases, description, isEnabled, usage)
{
@Override
public void execute(List<String> arguments)
{
toExecute.execute(arguments);
}
};
}
}
/**
* Get a builder for a new command.
* @param name The name of the future command
* @return A new manipulable builder to build the command.
*/
public static Builder builder(String name)
{
return new Builder(name);
}
public String getName()
{
return name;
}
public List<String> getAliases()
{
return aliases;
}
public String getDescription()
{
return description;
}
public boolean isEnabled()
{
return isEnabled;
}
public String getUsage()
{
return usage;
}
public void setEnabled(boolean enabled)
{
isEnabled = enabled;
}
}

@ -0,0 +1,140 @@
package net.pingex.dcf.commands;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.*;
/**
* Command bank
*/
public class CommandRegistry
{
/**
* Command main store
*/
private static Set<Command> commandSet = new HashSet<>();
/**
* Logger
*/
private static final Logger LOGGER = LogManager.getLogger(CommandRegistry.class);
/**
* Register a command and its aliases to the bank
* @param toRegister Command to register
*/
public static void registerCommand(Command toRegister)
{
LOGGER.debug("Attempting to register command {}.", toRegister.getName());
if(commandExists(toRegister.getName()))
{
LOGGER.warn("Fail to add command: {} is already registered as a command.", toRegister.getName());
return;
}
if(aliasExists(toRegister.getName())) LOGGER.info("Overriding registered alias {} for a new command with the same name.", toRegister.getName());
LOGGER.info("Registering command {}.", toRegister.getName());
commandSet.add(toRegister);
// Check for conflicting aliases
toRegister.getAliases().stream().filter(CommandRegistry::aliasExists).forEach(i ->
{
LOGGER.warn("Conflicting alias {} for command {}, removing. (original command: {})", i, toRegister.getName(), getAliasByName(i).get().getName());
toRegister.getAliases().remove(i);
});
}
/**
* Remove a command from the bank.
* A command cannot be removed using one of its alias.
* @param commandName Target command
*/
public static void unregisterCommandByName(String commandName)
{
LOGGER.debug("Resolving command {}.", commandName);
Optional<Command> target = getCommandByName(commandName);
if(target.isPresent()) unregisterCommand(target.get());
else LOGGER.warn("Attempting to remove a command which is unknown to DCF.");
}
/**
* Remove a command from the bank.
* @param toUnregister Target command
*/
public static void unregisterCommand(Command toUnregister)
{
LOGGER.debug("Attempting to remove command {} from the bank.", toUnregister.getName());
if(!commandSet.contains(toUnregister))
{
LOGGER.warn("Attempting to remove a command which is unknown to DCF.");
return;
}
commandSet.remove(toUnregister);
LOGGER.info("Removed command {}.", toUnregister.getName());
}
/**
* Tells if the command is registered (excluding aliases).
* @param commandName Target command
* @return `true` if the command is registered, `false` otherwise
*/
public static boolean commandExists(String commandName)
{
return commandSet.stream().anyMatch(e -> e.getName().equals(commandName));
}
/**
* Tells if the alias is registered.
* @param aliasName Target alias
* @return `true` if the alias is registered, `false` otherwise
*/
public static boolean aliasExists(String aliasName)
{
return commandSet.stream().anyMatch(e -> e.getAliases().contains(aliasName));
}
/**
* Tells if the command exists (including aliases).
* Command have precedence over aliases.
* @param commandName Target command
* @return `true` if the command exists, `false` otherwise
*/
public static boolean exists(String commandName)
{
return commandExists(commandName) || aliasExists(commandName);
}
/**
* Get a command or an alias designed by its name. Commands have precedence over aliases.
* @param commandName Target command
* @return {@code Optional.empty()} if no command was found, {@code Optional.of(Command)} otherwise
*/
public static Optional<Command> getCommandOrAliasByName(String commandName)
{
return commandExists(commandName) ? getCommandByName(commandName) : getAliasByName(commandName);
}
/**
* Get a command by one of its aliases.
* @param aliasName Target command with this alias.
* @return {@code Optional.empty()} if no command was found, {@code Optional.of(Command)} otherwise
*/
public static Optional<Command> getAliasByName(String aliasName)
{
return commandSet.stream().filter(e -> e.getAliases().contains(aliasName)).findFirst();
}
/**
* Get a command designed by its name, excluding aliases.
* @param commandName Target command
* @return {@code Optional.empty()} if no command was found, {@code Optional.of(Command)} otherwise
*/
public static Optional<Command> getCommandByName(String commandName)
{
return commandSet.stream().filter(e -> e.getName().equals(commandName)).findFirst();
}
}

@ -0,0 +1,12 @@
package net.pingex.dcf.commands;
import java.util.List;
/**
* The body of a command.
*/
@FunctionalInterface
public interface ICommandExecutor
{
void execute(List<String> arguments);
}