Skip to content

Package: SparqlQueryParser

SparqlQueryParser

nameinstructionbranchcomplexitylinemethod
SparqlQueryParser()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getQueryParameter(Integer)
M: 0 C: 35
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getQueryParameter(String)
M: 0 C: 20
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
parameterEnd(int)
M: 0 C: 21
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
parameterStart(int, SparqlQueryParser.ParamType)
M: 0 C: 28
100%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 0 C: 6
100%
M: 0 C: 1
100%
parseQuery(String)
M: 0 C: 113
100%
M: 0 C: 16
100%
M: 0 C: 11
100%
M: 0 C: 28
100%
M: 0 C: 1
100%
resolveParamIdentification(String)
M: 0 C: 86
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 13
100%
M: 0 C: 1
100%

Coverage

1: /**
2: * Copyright (C) 2016 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: * <p>
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.jopa.query.sparql;
16:
17: import cz.cvut.kbss.jopa.exception.QueryParserException;
18: import cz.cvut.kbss.jopa.query.QueryParameter;
19: import cz.cvut.kbss.jopa.query.QueryParser;
20:
21: import java.util.ArrayList;
22: import java.util.HashMap;
23: import java.util.List;
24: import java.util.Map;
25:
26: public class SparqlQueryParser implements QueryParser {
27:
28: private String query;
29:
30: private Map<Object, QueryParameter<?>> uniqueParams;
31: private Integer positionalCounter;
32:
33: private List<String> queryParts;
34: private List<QueryParameter<?>> parameters;
35: private boolean inParam;
36: private boolean inSQString; // In apostrophe string (')
37: private boolean inDQString; // In double-quoted string (")
38: private int lastParamEndIndex;
39: private int paramStartIndex;
40: private ParamType currentParamType;
41:
42: private enum ParamType {
43: POSITIONAL, NAMED
44: }
45:
46: @Override
47: public SparqlQueryHolder parseQuery(String query) {
48: this.query = query;
49: this.queryParts = new ArrayList<>();
50: this.uniqueParams = new HashMap<>();
51: this.positionalCounter = 1;
52: this.parameters = new ArrayList<>();
53: this.inSQString = false;
54: // In double-quoted string
55: this.inDQString = false;
56: this.inParam = false;
57: this.lastParamEndIndex = 0;
58: this.paramStartIndex = 0;
59: this.currentParamType = null;
60: int i;
61:• for (i = 0; i < query.length(); i++) {
62: final char c = query.charAt(i);
63:• switch (c) {
64: case '\'':
65:• inSQString = !inSQString;
66: break;
67: case '"':
68:• inDQString = !inDQString;
69: break;
70: case '$':
71: parameterStart(i, ParamType.POSITIONAL);
72: break;
73: case '?':
74: parameterStart(i, ParamType.NAMED);
75: break;
76: // TODO Use an algebra and AST to parse queries
77: case '<':
78: case '>':
79: case ',':
80: case '\n':
81: case ')':
82: case ' ':
83: case '.':
84: case ';':
85: case '{':
86: case '}':
87: case '[':
88: case ']':
89:• if (inParam) {
90: parameterEnd(i);
91: }
92: break;
93: default:
94: break;
95: }
96: }
97:• if (inParam) {
98: parameterEnd(i);
99: } else {
100: queryParts.add(query.substring(lastParamEndIndex));
101: }
102: return new SparqlQueryHolder(query, queryParts, parameters);
103: }
104:
105: private void parameterStart(int index, ParamType paramType) {
106:• if (!inSQString && !inDQString) {
107: queryParts.add(query.substring(lastParamEndIndex, index));
108: paramStartIndex = index + 1;
109: inParam = true;
110: this.currentParamType = paramType;
111: }
112: }
113:
114: private void parameterEnd(int index) {
115: this.lastParamEndIndex = index;
116: this.inParam = false;
117: final String param = query.substring(paramStartIndex, index);
118: parameters.add(resolveParamIdentification(param));
119: }
120:
121: private QueryParameter<?> resolveParamIdentification(String identification) {
122: final QueryParameter<?> queryParameter;
123:• if (identification.isEmpty()) {
124:• if (currentParamType == ParamType.POSITIONAL) {
125: queryParameter = getQueryParameter(positionalCounter++);
126: } else {
127: throw new QueryParserException("Missing parameter name in query " + query);
128: }
129: } else {
130:• if (currentParamType == ParamType.POSITIONAL) {
131: try {
132: Integer position = Integer.parseInt(identification);
133: positionalCounter++;
134: queryParameter = getQueryParameter(position);
135: } catch (NumberFormatException e) {
136: throw new QueryParserException(identification + " is not a valid parameter position.", e);
137: }
138: } else {
139: queryParameter = getQueryParameter(identification);
140: }
141: }
142: return queryParameter;
143: }
144:
145: private QueryParameter<?> getQueryParameter(String name) {
146: // We want to reuse the param instances, so that changes to them apply throughout the whole query
147:• if (!uniqueParams.containsKey(name)) {
148: uniqueParams.put(name, new QueryParameter<>(name));
149: }
150: return uniqueParams.get(name);
151: }
152:
153: private QueryParameter<?> getQueryParameter(Integer position) {
154: // We want to reuse the param instances, so that changes to them apply throughout the whole query
155:• if (uniqueParams.containsKey(position)) {
156: throw new QueryParserException("Parameter with position " + position + " already found in query " + query);
157: }
158: final QueryParameter<?> qp = new QueryParameter<>(position);
159: uniqueParams.put(position, qp);
160: return qp;
161: }
162: }