package net.knarcraft.paidsigns.utility; import java.util.ArrayList; import java.util.List; /** * A tokenizer for being able to support quotes in commands */ public final class Tokenizer { private Tokenizer() { } /** * Tokenizes a string * * @param input

A string

* @return

A list of tokens

*/ public static List tokenize(String input) { return tokenize(input, true); } /** * Tokenizes a string * * @param input

A string

* @param allowEmptyQuotes

Whether to treat "" as a token

* @return

A list of tokens

*/ public static List tokenize(String input, boolean allowEmptyQuotes) { List tokens = new ArrayList<>(); boolean startedQuote = false; StringBuilder currentToken = new StringBuilder(); for (int index = 0; index < input.length(); index++) { char character = input.charAt(index); switch (character) { case ' ': if (tokenizeSpace(startedQuote, currentToken, tokens)) { currentToken = new StringBuilder(); } break; case '"': if (startedQuote) { //This quote signifies the end of the argument if (allowEmptyQuotes || isNotEmpty(currentToken)) { tokens.add(currentToken.toString()); currentToken = new StringBuilder(); } startedQuote = false; } else { //This quote signifies the start of the argument startedQuote = true; currentToken = new StringBuilder(); } break; default: tokenizeNormalCharacter(currentToken, character, input.length(), index, tokens); break; } } return tokens; } /** * Adds a normal character to the token. Adds the current token to tokens if at the end of the input * * @param currentToken

The string builder containing the current token.

* @param character

The character found in the input.

* @param inputLength

The length of the given input

* @param index

The index of the read character.

* @param tokens

The list of processed tokens.

*/ private static void tokenizeNormalCharacter(StringBuilder currentToken, char character, int inputLength, int index, List tokens) { currentToken.append(character); if (index == inputLength - 1) { tokens.add(currentToken.toString()); } } /** * Tokenizes a space character * * @param startedQuote

Whether this space is inside a pair of quotes.

* @param currentToken

The string builder containing the current token.

* @param tokens

The list of processed tokens.

* @return

True if the token is finished.

*/ private static boolean tokenizeSpace(boolean startedQuote, StringBuilder currentToken, List tokens) { if (!startedQuote) { //If not inside "", a space marks the end of a parameter if (isNotEmpty(currentToken)) { tokens.add(currentToken.toString()); } return true; } else { currentToken.append(' '); return false; } } /** * Checks whether a string builder is empty * * @param builder

The string builder to check.

* @return

True if the string builder is non empty.

*/ private static boolean isNotEmpty(StringBuilder builder) { return !builder.toString().trim().equals(""); } }