ParamsParser { public static Map<String, String> parse(String input) { ParseState s = ParseState.expectingName; Map<String, String> parms = new LinkedHashMap<>(); StringBuilder varname = new StringBuilder(128); StringBuilder value = new StringBuilder(128); boolean isEscaped = false; for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); if (isEscaped) { switch (s) { case expectingVal: case readingDquotedVal: case readingSquotedVal: case readingRawVal: value.append(c); break; case readingName: varname.append(c); break; default: throw new RuntimeException("invalid position for escape:" + i + ", in " + input); } isEscaped = false; continue; } switch (s) { case expectingName: if (c != ' ' && c != ';') { s = ParseState.readingName; varname.append(c); } break; case readingName: if (c == '\\') { isEscaped = true; } else if (c != '=') { varname.append(c); } else { s = ParseState.expectingVal; } break; case expectingVal: if (c == '\\') { isEscaped = true; } else if (c == '\'') { s = ParseState.readingSquotedVal; } else if (c == '"') { s = ParseState.readingDquotedVal; } else if (c == ';') { parms.put(varname.toString(), null); varname.setLength(0); s = ParseState.expectingName; } else { s = ParseState.readingRawVal; value.append(c); } break; case readingRawVal: if (c == '\\') { isEscaped = true; } else if (c != ';') { value.append(c); } else { parms.put(varname.toString(), value.toString()); varname.setLength(0); value.setLength(0); s = ParseState.expectingName; } break; case readingSquotedVal: if (c == '\\') { isEscaped = true; } else if (c != '\'') { value.append(c); } else { parms.put(varname.toString(), value.toString()); varname.setLength(0); value.setLength(0); s = ParseState.expectingName; } break; case readingDquotedVal: if (c == '\\') { isEscaped = true; } else if (c != '"') { value.append(c); } else { parms.put(varname.toString(), value.toString()); varname.setLength(0); value.setLength(0); s = ParseState.expectingName; } break; default: throw new RuntimeException("Unmatched parse state. This should be impossible."); } } if (isEscaped) { throw new RuntimeException("an unfinished escape sequence at the end is not valid"); } switch (s) { case expectingVal: parms.put(varname.toString(), null); varname.setLength(0); s = ParseState.expectingName; break; case readingRawVal: parms.put(varname.toString(), value.toString()); varname.setLength(0); s = ParseState.expectingName; break; default: } if (input.length()>0 && parms.size()==0) { throw new RuntimeException("Unable to parse input:" + input); } return parms; }  static Map<String, String> parse(String input);  }
@Test public void testSingleQuotedEscape() { Map<String,String> p; p = ParamsParser.parse("a=1;b='fo\\'urfive';"); assertThat(p).hasSize(2); assertThat(p).containsKey("b"); assertThat(p.get("b")).isEqualTo("fo'urfive"); }
@Test public void testDoubleQuote() { Map<String,String> p; p = ParamsParser.parse("a=1;b=\"six\";"); assertThat(p).hasSize(2); assertThat(p).containsKey("b"); assertThat(p.get("b")).isEqualTo("six"); }
@Test public void testDoubleQuotedEscape() { Map<String,String> p; p = ParamsParser.parse("a=1;b=\"si\\'x\";"); assertThat(p).hasSize(2); assertThat(p).containsKey("b"); assertThat(p.get("b")).isEqualTo("si'x"); }
@Test public void testSQuotesInDQuotes() { Map<String,String> p; p = ParamsParser.parse("a=1;b=\"si'x\";"); assertThat(p).hasSize(2); assertThat(p).containsKey("b"); assertThat(p.get("b")).isEqualTo("si'x"); }
@Test public void testDQuotesInSquotes() { Map<String,String> p; p = ParamsParser.parse("a=1;b='Sev\"en';"); assertThat(p).hasSize(2); assertThat(p).containsKey("b"); assertThat(p.get("b")).isEqualTo("Sev\"en"); }
@Test public void testSpaces() { Map<String,String> p; p = ParamsParser.parse("a=1; b=2;"); assertThat(p).hasSize(2); assertThat(p).containsKey("a"); assertThat(p.get("a")).isEqualTo("1"); assertThat(p).containsKey("b"); assertThat(p.get("b")).isEqualTo("2"); }
@Test public void testMissingSemi() { Map<String,String> p; p = ParamsParser.parse("a=1; b=2"); assertThat(p).hasSize(2); assertThat(p).containsKey("b"); assertThat(p.get("b")).isEqualTo("2"); }
@Test public void testSimpleParams() { Map<String, String> p; p = ParamsParser.parse("a=1;"); assertThat(p).hasSize(1); assertThat(p).containsKey("a"); assertThat(p.get("a")).isEqualTo("1"); }
@Test public void testNullValueParam() { Map<String,String> p; p = ParamsParser.parse("a=1;b=;"); assertThat(p).hasSize(2); assertThat(p).containsKey("b"); assertThat(p.get("b")).isNull(); }
@Test public void testSingleQuote() { Map<String,String> p; p = ParamsParser.parse("a=1;b='fourfive';"); assertThat(p).hasSize(2); assertThat(p).containsKey("b"); assertThat(p.get("b")).isEqualTo("fourfive"); }