115 lines
3.9 KiB
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("");
|
|
}
|
|
|
|
}
|