Search for a large string to see if an invalid "parameter" exists
I have a big line like this:
BREW pot HTCPCP / 1.0
Accept additions: #milk; 3 # whiskey; splash
Content-Length: 5
Content-Type: message / coffeepot
I also have a multi-padded array (#whiskey, #espresso, etc.). I need to send an error if this big string contains an add-on that is NOT in the array of available add-ons. For example, if the "Accept-Additionaldition" part in the line contained "#bricks; 3", an error was generated because it is not in the array.
How can I do this in Java? I am having trouble implementing this part, even though I have coded the rest of the program (which many of you might recognize). How would I code the following issue with an emphasis on adding not available?
a source to share
This code makes several input assumptions. It looks like you can split each token by another #; Components. Using a list for the acceptable liquids parameter will clean up the code a bit (just use liquidids.contains (String s))
static String[] liquids = {"#milk;3", "#whiskey;splash"};
public static void parseString(String input)
{
// Break the String down into line-by-line.
String[] lines = input.split("" + '\n');
for (int line_index = 0; line_index < lines.length; line_index++)
{
if (lines[line_index].length() > 16)
{
// Assume you're delimiting by '#'
String[] tokens = lines[line_index].split("#");
if (tokens.length > 1)
{
// Start at index = 1 to kill "Accept-Additions:"
for (int token_index = 1; token_index < tokens.length; token_index++)
{
boolean valid = false;
for (int liquids_index = 0; liquids_index < liquids.length; liquids_index++)
{
if (liquids[liquids_index].equals("#" + tokens[token_index]))
{
valid = true;
// break to save some time if liquids is very long
break;
}
}
if (!valid)
{
throwError("#" + tokens[token_index]);
}
}
}
}
}
}
public static void throwError(String error)
{
System.out.println(error + " is not in the Array!");
}
a source to share
You will parse the string. Looking at this gives you one set of options per line, so you can search for all lines starting with ACCEPT-ADDITIONS. Then you need to extract the additions that appear to be separate with semi-colonies by specifying String.split (). Then go through the resuling array to find the additions.
Or you can create a grammar and use a tool like ANTLR to generate your parser.
a source to share
Here is a possible solution using regular expressions. It extracts the Accept-Append string from the payload, then validates each key-value pair of the form #foo;bar
.
final String[] VALID_ADDITIONS = {
"milk", "whiskey"
};
final Pattern LINE = Pattern.compile("Accept-Additions:(.+)$", Pattern.MULTILINE);
final Pattern ADDITIONS = Pattern.compile("#(.+?);([^#]+)");
void checkValidAdditions(String request) {
Matcher lineMatcher = LINE.matcher(request);
if (!lineMatcher.find()) {
// no additions - do whatever is appropriate here
throw new IllegalArgumentException("Additions line not found");
}
String line = lineMatcher.group(1);
Matcher additions = ADDITIONS.matcher(line);
while (additions.find()) {
String key = additions.group(1);
//String value = additions.group(2);
boolean validKey = false;
for (String validAddition : VALID_ADDITIONS) {
if (key.equals(validAddition)) {
validKey = true;
}
}
if (!validKey) {
// ...
}
}
}
The first regular expression retrieves the matching string from the query. The second one extracts key-value pairs. Please note the following caveats:
-
This method will not correctly display invalid queries - only invalid "keys".
-
If you allow different capitalizations (for example, "ACCEPT-ADDITIONS", "accept-additions") add the Pattern.CASE_INSENSITIVE flag, i.e.
Pattern.MULTILINE & Pattern.CASE_INSENSITIVE
...
a source to share