Skip to content

Method: StatementHolder(String)

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.ontodriver.util;
19:
20: import java.util.*;
21:
22: /**
23: * Used for parsing and managing SPARQL statements.
24: */
25: public class StatementHolder {
26:
27: private Map<String, String> paramValues;
28: private List<String> paramNames;
29: private List<String> statementParts;
30: private final String statement;
31:
32:
33: public StatementHolder(String statement) {
34: Objects.requireNonNull(statement);
35:
36: this.statement = statement.trim();
37: }
38:
39: public void analyzeStatement() {
40: this.paramNames = new ArrayList<>();
41: this.statementParts = new ArrayList<>();
42: // In single-quoted string
43: boolean inSQString = false;
44: // In double-quoted string
45: boolean inDQString = false;
46: boolean inParam = false;
47: int lastParamEndIndex = 0;
48: int paramStartIndex = 0;
49: for (int i = 0; i < statement.length(); i++) {
50: final char c = statement.charAt(i);
51: switch (c) {
52: case '\'':
53: inSQString = !inSQString;
54: break;
55: case '"':
56: inDQString = !inDQString;
57: break;
58: case '?':
59: if (!inSQString && !inDQString) {
60: statementParts.add(statement.substring(lastParamEndIndex, i));
61: paramStartIndex = i + 1;
62: inParam = true;
63: }
64: break;
65: case '<':
66: case '>':
67: case ',':
68: case '\n':
69: case ')':
70: case ' ':
71: case '.':
72: case ';':
73: case '{':
74: case '}':
75: case '[':
76: case ']':
77: if (inParam) {
78: lastParamEndIndex = i;
79: final String param = statement.substring(paramStartIndex, i);
80: paramNames.add(param);
81: inParam = false;
82: }
83: break;
84: default:
85: break;
86: }
87: }
88: statementParts.add(statement.substring(lastParamEndIndex));
89: this.paramValues = new HashMap<>(paramNames.size());
90:
91: assert statementParts.size() == paramNames.size() + 1;
92: }
93:
94: public void setParameter(String parameterName, String value) {
95: ensureState();
96: if (!paramNames.contains(parameterName)) {
97: throw new IllegalArgumentException("Unknown binding name " + parameterName);
98: }
99: paramValues.put(parameterName, value);
100: }
101:
102: private void ensureState() {
103: if (paramNames == null) {
104: throw new IllegalStateException("Statement has to be analyzed before working with parameters.");
105: }
106: }
107:
108: public String assembleStatement() {
109: if (isNotParametrized()) {
110: return statement;
111: }
112: final StringBuilder sb = new StringBuilder(statement.length());
113: for (int i = 0; i < paramNames.size(); i++) {
114: sb.append(statementParts.get(i));
115: final String paramValue = paramValues.get(paramNames.get(i));
116: if (paramValue == null) {
117: sb.append("?").append(paramNames.get(i));
118: } else {
119: sb.append(paramValue);
120: }
121: }
122: sb.append(statementParts.get(paramNames.size()));
123: return sb.toString();
124: }
125:
126: public String getStatement() {
127: return statement;
128: }
129:
130: private boolean isNotParametrized() {
131: return paramNames == null || paramNames.isEmpty();
132: }
133:
134: public void clearParameters() {
135: ensureState();
136: paramValues.replaceAll((p, v) -> null);
137: }
138: }