StatementHolder { public void analyzeStatement() { this.paramNames = new ArrayList<>(); this.statementParts = new ArrayList<>(); boolean inSQString = false; boolean inDQString = false; boolean inParam = false; int lastParamEndIndex = 0; int paramStartIndex = 0; for (int i = 0; i < statement.length(); i++) { final char c = statement.charAt(i); switch (c) { case '\'': inSQString = !inSQString; break; case '"': inDQString = !inDQString; break; case '?': if (!inSQString && !inDQString) { statementParts.add(statement.substring(lastParamEndIndex, i)); paramStartIndex = i + 1; inParam = true; } break; case '<': case '>': case ',': case '\n': case ')': case ' ': case '.': case ';': case '{': case '}': case '[': case ']': if (inParam) { lastParamEndIndex = i; final String param = statement.substring(paramStartIndex, i); paramNames.add(param); inParam = false; } break; default: break; } } statementParts.add(statement.substring(lastParamEndIndex)); this.paramValues = new HashMap<>(paramNames.size()); assert statementParts.size() == paramNames.size() + 1; } StatementHolder(String statement); void analyzeStatement(); void setParameter(String parameterName, String value); String assembleStatement(); String getStatement(); void clearParameters();  }
@Test void testAnalyzeSimpleQueryWithTwoParams() throws Exception { final String query = "SELECT ?x ?y WHERE { ?x <http: final StatementHolder holder = new StatementHolder(query); holder.analyzeStatement(); final Field paramNamesField = StatementHolder.class.getDeclaredField("paramNames"); paramNamesField.setAccessible(true); final List<String> paramNames = (List<String>) paramNamesField.get(holder); assertTrue(paramNames.contains("x")); assertTrue(paramNames.contains("y")); }