Files
PaidSigns/src/main/java/net/knarcraft/paidsigns/utility/Tokenizer.java

115 lines
3.9 KiB
Java

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 <p>A string</p>
* @return <p>A list of tokens</p>
*/
public static List<String> tokenize(String input) {
return tokenize(input, true);
}
/**
* Tokenizes a string
*
* @param input <p>A string</p>
* @param allowEmptyQuotes <p>Whether to treat "" as a token</p>
* @return <p>A list of tokens</p>
*/
public static List<String> tokenize(String input, boolean allowEmptyQuotes) {
List<String> 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 <p>The string builder containing the current token.</p>
* @param character <p>The character found in the input.</p>
* @param inputLength <p>The length of the given input</p>
* @param index <p>The index of the read character.</p>
* @param tokens <p>The list of processed tokens.</p>
*/
private static void tokenizeNormalCharacter(StringBuilder currentToken, char character, int inputLength, int index,
List<String> tokens) {
currentToken.append(character);
if (index == inputLength - 1) {
tokens.add(currentToken.toString());
}
}
/**
* Tokenizes a space character
*
* @param startedQuote <p>Whether this space is inside a pair of quotes.</p>
* @param currentToken <p>The string builder containing the current token.</p>
* @param tokens <p>The list of processed tokens.</p>
* @return <p>True if the token is finished.</p>
*/
private static boolean tokenizeSpace(boolean startedQuote, StringBuilder currentToken, List<String> 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 <p>The string builder to check.</p>
* @return <p>True if the string builder is non empty.</p>
*/
private static boolean isNotEmpty(StringBuilder builder) {
return !builder.toString().trim().equals("");
}
}