Skip to contentMethod: querySpec(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.rdf4j.query;
19:
20: import cz.cvut.kbss.ontodriver.ResultSet;
21: import cz.cvut.kbss.ontodriver.Statement;
22: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
23: import cz.cvut.kbss.ontodriver.rdf4j.connector.StatementExecutor;
24: import cz.cvut.kbss.ontodriver.rdf4j.exception.Rdf4jDriverException;
25: import org.eclipse.rdf4j.query.MalformedQueryException;
26: import org.eclipse.rdf4j.query.QueryEvaluationException;
27: import org.eclipse.rdf4j.query.QueryLanguage;
28: import org.eclipse.rdf4j.query.TupleQueryResult;
29: import org.eclipse.rdf4j.query.parser.ParsedBooleanQuery;
30: import org.eclipse.rdf4j.query.parser.QueryParserUtil;
31: import org.slf4j.Logger;
32: import org.slf4j.LoggerFactory;
33:
34: import java.util.Objects;
35:
36: public class Rdf4jStatement implements Statement {
37:
38: private static final Logger LOG = LoggerFactory.getLogger(Rdf4jStatement.class);
39:
40: private boolean inferenceDisabled = false;
41: private final StatementExecutor queryExecutor;
42: private ResultSet resultSet;
43:
44: private boolean open;
45:
46: public Rdf4jStatement(StatementExecutor queryExecutor) {
47: this.queryExecutor = queryExecutor;
48: this.open = true;
49: }
50:
51: @Override
52: public ResultSet executeQuery(String sparql) throws OntoDriverException {
53: ensureOpen();
54: validateQueryParams(sparql);
55: closeCurrentResultSet();
56: this.resultSet = determineResult(sparql);
57: return resultSet;
58: }
59:
60: private ResultSet determineResult(String sparql) throws Rdf4jDriverException {
61: if (isAskQuery(sparql)) {
62: return new AskResultSet(queryExecutor.executeBooleanQuery(querySpec(sparql)), this);
63: } else {
64: final TupleQueryResult tqr = queryExecutor.executeSelectQuery(querySpec(sparql));
65: try {
66: return new SelectResultSet(tqr, this);
67: } catch (QueryEvaluationException e) {
68: throw new Rdf4jDriverException(e);
69: }
70: }
71: }
72:
73: QuerySpecification querySpec(String sparql) {
74:• return QuerySpecification.query(sparql).includeInference(!inferenceDisabled);
75: }
76:
77: private static boolean isAskQuery(String query) throws Rdf4jDriverException {
78: try {
79: return QueryParserUtil.parseOperation(QueryLanguage.SPARQL, query, null) instanceof ParsedBooleanQuery;
80: } catch (MalformedQueryException e) {
81: throw new Rdf4jDriverException("Invalid query \"" + query + "\".", e);
82: }
83: }
84:
85: @Override
86: public void executeUpdate(String sparql) throws OntoDriverException {
87: ensureOpen();
88: validateQueryParams(sparql);
89: closeCurrentResultSet();
90: queryExecutor.executeUpdate(querySpec(sparql));
91: }
92:
93: @Override
94: public void useOntology(StatementOntology ontology) {
95: LOG.warn("RDF4J driver does not support changing the target ontology because it does not use transactional data snapshots.");
96: }
97:
98: @Override
99: public StatementOntology getStatementOntology() {
100: return StatementOntology.SHARED;
101: }
102:
103: private static void validateQueryParams(String sparql) {
104: Objects.requireNonNull(sparql);
105: if (sparql.isEmpty()) {
106: throw new IllegalArgumentException("Query string cannot be empty.");
107: }
108: }
109:
110: @Override
111: public boolean isOpen() {
112: return open;
113: }
114:
115: @Override
116: public void close() throws OntoDriverException {
117: if (!open) {
118: return;
119: }
120: this.open = false;
121: closeCurrentResultSet();
122: }
123:
124: private void closeCurrentResultSet() throws OntoDriverException {
125: if (resultSet != null) {
126: resultSet.close();
127: this.resultSet = null;
128: }
129: }
130:
131: @Override
132: public void disableInference() {
133: this.inferenceDisabled = true;
134: }
135:
136: @Override
137: public boolean isInferenceDisabled() {
138: return inferenceDisabled;
139: }
140:
141: void ensureOpen() {
142: if (!open) {
143: throw new IllegalStateException("This statement is closed.");
144: }
145: }
146: }