From 1a0a742daa67a5f702cb6edfc813811ad81a63ad Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Fri, 20 Mar 2015 03:56:03 +0500 Subject: [PATCH] Clean up encapsulating values in quotes significantly Added hopefully the first of many unit tests to make maintaining the project easier --- pom.xml | 8 ++- .../java/de/diddiz/LogBlock/QueryParams.java | 52 +++++-------------- src/main/java/de/diddiz/util/Utils.java | 23 ++++++++ .../de/diddiz/LogBlock/QueryParsingTest.java | 21 ++++++++ 4 files changed, 64 insertions(+), 40 deletions(-) create mode 100644 src/test/java/de/diddiz/LogBlock/QueryParsingTest.java diff --git a/pom.xml b/pom.xml index 865f1c2..3167735 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,13 @@ worldedit 6.0.0-SNAPSHOT - + + junit + junit + 4.11 + test + + diff --git a/src/main/java/de/diddiz/LogBlock/QueryParams.java b/src/main/java/de/diddiz/LogBlock/QueryParams.java index 0c2cb29..47f22bd 100644 --- a/src/main/java/de/diddiz/LogBlock/QueryParams.java +++ b/src/main/java/de/diddiz/LogBlock/QueryParams.java @@ -1,6 +1,7 @@ package de.diddiz.LogBlock; import de.diddiz.util.Block; +import de.diddiz.util.Utils; import de.diddiz.worldedit.RegionContainer; import org.bukkit.Location; import org.bukkit.Material; @@ -476,6 +477,7 @@ public final class QueryParams implements Cloneable public void parseArgs(CommandSender sender, List args) throws IllegalArgumentException { if (args == null || args.isEmpty()) throw new IllegalArgumentException("No parameters specified."); + args = Utils.parseQuotes(args); final Player player = sender instanceof Player ? (Player)sender : null; final Session session = prepareToolQuery ? null : getSession(sender); if (player != null && world == null) @@ -744,51 +746,23 @@ public final class QueryParams implements Cloneable break; } } - // If the offset equals to the last value index, return an empty string array + // If there are no values, i.e there is a keyword immediately after the offset + // return an empty string array if (i == offset) { return new String[0]; } - // Instantiate a new string array with the total indexes required - final List values = new ArrayList(); - // Buffer for the value - String value = ""; - // Iterate over the offset up till the last index value + + final String[] values = new String[i - offset]; for (int j = offset; j < i; j++) { - // If the value starts with a double quote or we're already dealing with a quoted value - if (args.get(j).startsWith("\"") || !value.equals("")) { - // If the value doesn't end with a double quote - if (!args.get(j).endsWith("\"")) { - // Add the argument to the value buffer after stripping out the initial quote - - // If the argument starts with a quote we wanna strip that out otherwise add it normally - if (args.get(j).startsWith("\"")) { - value += args.get(j).substring(1) + " "; - } else { - value += args.get(j) + " "; - } - - } else { - // The value ends with a double quote - - // If the argument starts with a double quote we wanna strip that out too along with the end quote - if (args.get(j).startsWith("\"")) { - value += args.get(j).substring(0, args.get(j).length() - 1).substring(1); - } else { - // Looks like its just the end quote here, just need to strip that out - value += args.get(j).substring(0, args.get(j).length() - 1); - } - // Add the value to the main values list - values.add(value); - // Reset the buffer - value = ""; - } - } else { - // Set the value in the array to be returned to the one from the main arguments list - values.add(args.get(j)); + String value = args.get(j); + + // If the value is encapsulated in quotes, strip them + if (value.startsWith("\"") && value.endsWith("\"")) { + value = value.substring(1, value.length() - 1); } + values[j - offset] = value; } - // Return the values array - return values.toArray(new String[values.size()]); + return values; } public void merge(QueryParams p) { diff --git a/src/main/java/de/diddiz/util/Utils.java b/src/main/java/de/diddiz/util/Utils.java index 7959b63..2cd7edc 100644 --- a/src/main/java/de/diddiz/util/Utils.java +++ b/src/main/java/de/diddiz/util/Utils.java @@ -4,7 +4,10 @@ import java.io.File; import java.io.FilenameFilter; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class Utils { @@ -135,6 +138,26 @@ public class Utils return builder.toString(); } + /*** + * Converts a list of arguments e.g ['lb', 'clearlog', 'world', '"my', 'world', 'of', 'swag"'] + * into a list of arguments with any text encapsulated by quotes treated as one word + * For this particular example: ['lb', 'clearlog', 'world', '"my world of swag"'] + * @param args The list of arguments + * @return A new list with the quoted arguments parsed to single values + */ + public static List parseQuotes(List args) { + List newArguments = new ArrayList(); + String subjectString = join(args.toArray(new String[args.size()]), " "); + + Pattern regex = Pattern.compile("[^\\s\"']+|\"[^\"]*\"|'[^']*'"); + Matcher regexMatcher = regex.matcher(subjectString); + while (regexMatcher.find()) { + newArguments.add(regexMatcher.group()); + } + + return newArguments; + } + public static class ExtensionFilenameFilter implements FilenameFilter { private final String ext; diff --git a/src/test/java/de/diddiz/LogBlock/QueryParsingTest.java b/src/test/java/de/diddiz/LogBlock/QueryParsingTest.java new file mode 100644 index 0000000..ebb729c --- /dev/null +++ b/src/test/java/de/diddiz/LogBlock/QueryParsingTest.java @@ -0,0 +1,21 @@ +package de.diddiz.LogBlock; + + +import de.diddiz.util.Utils; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +public class QueryParsingTest { + + @Test + public void testParseQuotes() { + // input = /lb clearlog world "my world of swag" player "player" + List input = Arrays.asList("lb", "clearlog", "world", "\"my", "world", "of", "swag\"", "player", "\"player\""); + List expectedOut = Arrays.asList("lb", "clearlog", "world", "\"my world of swag\"", "player", "\"player\""); + Assert.assertEquals(Utils.parseQuotes(input), expectedOut); + } + +}