package pluginbase.command; import org.jetbrains.annotations.NotNull; import pluginbase.messages.Theme; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; class CommandBuilder { private static final Pattern OPTIONAL_ARGS_PATTERN = Pattern.compile("\\[.+?\\]"); private static final Pattern REQUIRED_ARGS_PATTERN = Pattern.compile("\\{.+?\\}"); private CommandProvider commandProvider; private CommandInfo commandInfo; private Command command; List<String> aliases; String[] permissions; String usageString; CommandBuilder(@NotNull CommandProvider commandProvider, @NotNull Class<? extends Command> commandClass) { this.commandProvider = commandProvider; commandInfo = gatherCommandInfo(commandClass); command = CommandLoader.loadCommand(commandProvider, commandClass); aliases = gatherAliases(commandProvider, command, commandInfo); permissions = gatherPermissions(command); usageString = gatherUsageString(); } @NotNull private CommandInfo gatherCommandInfo(Class<? extends Command> commandClass) { CommandInfo commandInfo = commandClass.getAnnotation(CommandInfo.class); if (commandInfo == null) { throw new IllegalArgumentException("Command must be annotated with @CommandInfo"); } return commandInfo; } private List<String> gatherAliases(CommandProvider commandProvider, Command command, CommandInfo cmdInfo) { CommandAliases aliases = new CommandAliases(commandProvider, cmdInfo, command); return aliases.gatherAliases(); } private String[] gatherPermissions(Command command) { String[] permissions; if (command.getPerm() != null) { permissions = new String[1]; permissions[0] = command.getPerm().getName(); } else { permissions = new String[0]; } return permissions; } private String gatherUsageString() { final String flags = commandInfo.flags(); final StringBuilder command2 = new StringBuilder(); command2.append(parseUsage(commandInfo.usage())); for (int i = 0; i < flags.length(); ++i) { command2.append(" "); command2.append(Theme.OPT_ARG).append("[").append(Theme.CMD_FLAG).append("-"); command2.append(flags.charAt(i)); if (flags.length() > (i + 1) && flags.charAt(i + 1) == ':') { command2.append(Theme.REQ_ARG).append(" {VALUE}"); i++; } command2.append(Theme.OPT_ARG).append("]"); } return command2.toString(); } private CharSequence parseUsage(@NotNull String usageString) { if (usageString.isEmpty()) { return usageString; } // Add required arg theme before required args StringBuilder usage = new StringBuilder(usageString.length() + 10); Matcher matcher = REQUIRED_ARGS_PATTERN.matcher(usageString); int lastIndex = 0; while (matcher.find()) { if (matcher.start() > lastIndex) { // Add the initial part of the string if the required arg isn't first position usage.append(usageString.subSequence(lastIndex, matcher.start())); } usage.append(Theme.REQ_ARG); usage.append(matcher.group()); lastIndex = matcher.end(); } // Add what is left over in the string usage.append(usageString.subSequence(lastIndex, usageString.length())); // Replace initial string with builder that contains colored required args usageString = usage.toString(); // Add optional arg theme before optional args usage = new StringBuilder(usageString.length() + 10); matcher = OPTIONAL_ARGS_PATTERN.matcher(usageString); lastIndex = 0; while (matcher.find()) { if (matcher.start() > lastIndex) { // Add the initial part of the string if the optional arg isn't first position usage.append(usageString.subSequence(lastIndex, matcher.start())); } usage.append(Theme.OPT_ARG); usage.append(matcher.group()); lastIndex = matcher.end(); } // Add what is left over in the string usage.append(usageString.subSequence(lastIndex, usageString.length())); return usage; } public String getPrimaryAlias() { return aliases.get(0); } public CommandInfo getCommandInfo() { return commandInfo; } public CommandHandler.CommandRegistration createCommandRegistration() { return new CommandHandler.CommandRegistration(getCommandUsageString(), commandInfo.desc(), aliases.toArray(new String[aliases.size()]), commandProvider, permissions); } public String getCommandUsageString() { return usageString; } public Command getCommand() { return command; } private static class CommandAliases { private final CommandProvider commandProvider; private final CommandInfo cmdInfo; private final Command command; private CommandAliases(final CommandProvider commandProvider, final CommandInfo cmdInfo, final Command command) { this.commandProvider = commandProvider; this.cmdInfo = cmdInfo; this.command = command; } private List<String> aliases; public List<String> gatherAliases() { return buildUpAliasList(); } private List<String> buildUpAliasList() { int totalAliasCount = getTotalAliasCount(); aliases = new ArrayList<String>(totalAliasCount); addPrimaryAlias(); addRegularAliases(); addPrefixedAliases(); addDirectlyPrefixedAliases(); addAdditionalAliases(); return aliases; } private int getTotalAliasCount() { return cmdInfo.aliases().length + cmdInfo.prefixedAliases().length + cmdInfo.directlyPrefixedAliases().length + commandProvider.getAdditionalCommandAliases(command.getClass()).length + 1; } private void addPrimaryAlias() { if (cmdInfo.directlyPrefixPrimary()) { aliases.add(commandProvider.getCommandPrefix() + cmdInfo.primaryAlias()); } else if (cmdInfo.prefixPrimary()) { aliases.add(commandProvider.getCommandPrefix() + " " + cmdInfo.primaryAlias()); } else { aliases.add(cmdInfo.primaryAlias()); } } private void addRegularAliases() { for (final String alias : cmdInfo.aliases()) { if (!alias.isEmpty()) { aliases.add(alias); } } } private void addPrefixedAliases() { for (final String alias : cmdInfo.prefixedAliases()) { if (!alias.isEmpty()) { aliases.add(commandProvider.getCommandPrefix() + " " + alias); } } } private void addDirectlyPrefixedAliases() { for (final String alias : cmdInfo.directlyPrefixedAliases()) { if (!alias.isEmpty()) { aliases.add(commandProvider.getCommandPrefix() + alias); } } } private void addAdditionalAliases() { for (final String alias : commandProvider.getAdditionalCommandAliases(command.getClass())) { if (!alias.isEmpty()) { aliases.add(alias); } } } } }