Skip to contentMethod: clearContexts()
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.model;
16:
17: import cz.cvut.kbss.jopa.exceptions.NoResultException;
18: import cz.cvut.kbss.jopa.exceptions.NoUniqueResultException;
19: import cz.cvut.kbss.jopa.exceptions.OWLPersistenceException;
20: import cz.cvut.kbss.jopa.model.query.Parameter;
21: import cz.cvut.kbss.jopa.model.query.Query;
22: import cz.cvut.kbss.jopa.query.QueryHolder;
23: import cz.cvut.kbss.jopa.sessions.ConnectionWrapper;
24: import cz.cvut.kbss.jopa.utils.ErrorUtils;
25: import cz.cvut.kbss.ontodriver.ResultSet;
26: import cz.cvut.kbss.ontodriver.Statement;
27: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
28:
29: import java.net.URI;
30: import java.util.*;
31:
32: public class QueryImpl implements Query {
33:
34: private final QueryHolder query;
35: private final Set<URI> contexts;
36: private final ConnectionWrapper connection;
37:
38: private int maxResults;
39: private boolean useBackupOntology;
40:
41: public QueryImpl(final QueryHolder query, final ConnectionWrapper connection) {
42: this.query = Objects.requireNonNull(query, ErrorUtils.constructNPXMessage("query"));
43: this.connection = Objects.requireNonNull(connection,
44: ErrorUtils.constructNPXMessage("connection"));
45: this.contexts = new HashSet<>();
46: this.useBackupOntology = false;
47: this.maxResults = Integer.MAX_VALUE;
48: }
49:
50: @Override
51: public List getResultList() {
52: try {
53: if (maxResults == 0) {
54: return Collections.emptyList();
55: }
56: return getResultListImpl(maxResults);
57: } catch (OntoDriverException e) {
58: throw queryEvaluationException(e);
59: }
60: }
61:
62: private OWLPersistenceException queryEvaluationException(OntoDriverException e) {
63: final String executedQuery = query.assembleQuery();
64: return new OWLPersistenceException("Exception caught when evaluating query " + executedQuery, e);
65: }
66:
67: @Override
68: public Object getSingleResult() {
69: try {
70: // Call it with maxResults = 2 just to see whether there are more
71: final List<?> list = getResultListImpl(2);
72: if (list.isEmpty()) {
73: throw new NoResultException("No result found for query " + query);
74: }
75: if (list.size() > 1) {
76: throw new NoUniqueResultException("Multiple results found for query " + query);
77: }
78: return list.get(0);
79: } catch (OntoDriverException e) {
80: throw queryEvaluationException(e);
81: }
82: }
83:
84: @Override
85: public int getMaxResults() {
86: return maxResults;
87: }
88:
89: @Override
90: public Parameter<?> getParameter(int position) {
91: return query.getParameter(position);
92: }
93:
94: @Override
95: public Parameter<?> getParameter(String name) {
96: return query.getParameter(name);
97: }
98:
99: @Override
100: public Set<Parameter<?>> getParameters() {
101: return query.getParameters();
102: }
103:
104: @Override
105: public boolean isBound(Parameter<?> parameter) {
106: return query.getParameterValue(parameter) != null;
107: }
108:
109: @Override
110: public Object getParameterValue(int position) {
111: final Parameter<?> param = query.getParameter(position);
112: return getParameterValue(param);
113: }
114:
115: @Override
116: public Object getParameterValue(String name) {
117: final Parameter<?> param = query.getParameter(name);
118: return getParameterValue(param);
119: }
120:
121: private static IllegalStateException unboundParam(Object param) {
122: return new IllegalStateException("Parameter " + param + " is not bound.");
123: }
124:
125: @Override
126: public <T> T getParameterValue(Parameter<T> parameter) {
127: if (!isBound(parameter)) {
128: throw unboundParam(parameter);
129: }
130: return (T) query.getParameterValue(parameter);
131: }
132:
133: @Override
134: public Query setParameter(int position, Object value) {
135: query.setParameter(query.getParameter(position), value);
136: return this;
137: }
138:
139: @Override
140: public Query setParameter(int position, String value, String language) {
141: query.setParameter(query.getParameter(position), value, language);
142: return this;
143: }
144:
145: @Override
146: public Query setParameter(String name, Object value) {
147: query.setParameter(query.getParameter(name), value);
148: return this;
149: }
150:
151: @Override
152: public Query setParameter(String name, String value, String language) {
153: query.setParameter(query.getParameter(name), value, language);
154: return this;
155: }
156:
157: @Override
158: public <T> Query setParameter(Parameter<T> parameter, T value) {
159: query.setParameter(parameter, value);
160: return this;
161: }
162:
163: @Override
164: public Query setParameter(Parameter<String> parameter, String value, String language) {
165: query.setParameter(parameter, value, language);
166: return this;
167: }
168:
169: @Override
170: public Query setMaxResults(int maxResults) {
171: if (maxResults < 0) {
172: throw new IllegalArgumentException(
173: "Cannot set maximum number of results to less than 0.");
174: }
175: this.maxResults = maxResults;
176: return this;
177: }
178:
179: /**
180: * Sets ontology used for processing of this query. </p>
181: *
182: * @param useBackupOntology If true, the backup (central) ontology is used, otherwise the transactional ontology is
183: * used (default)
184: */
185: public void setUseBackupOntology(boolean useBackupOntology) {
186: this.useBackupOntology = useBackupOntology;
187: }
188:
189: private List<?> getResultListImpl(int maxResults) throws OntoDriverException {
190: assert maxResults > 0;
191:
192: final Statement stmt = connection.createStatement();
193: setTargetOntology(stmt);
194: URI[] uris = new URI[contexts.size()];
195: uris = contexts.toArray(uris);
196: try (ResultSet rs = stmt.executeQuery(query.assembleQuery(), uris)) {
197: final int columnCount = rs.getColumnCount();
198: int cnt = 0;
199: final List<Object> res = new ArrayList<>();
200: // TODO register this as observer on the result set so that additional results can be loaded asynchronously
201: while (rs.hasNext() && cnt < maxResults) {
202: rs.next();
203: if (columnCount == 1) {
204: res.add(rs.getObject(0));
205: } else {
206: res.add(extractResultRow(rs, columnCount));
207: }
208: cnt++;
209: }
210: return res;
211: }
212: }
213:
214: private void setTargetOntology(Statement stmt) {
215: if (useBackupOntology) {
216: stmt.useOntology(Statement.StatementOntology.CENTRAL);
217: } else {
218: stmt.useOntology(Statement.StatementOntology.TRANSACTIONAL);
219: }
220: }
221:
222: private static Object[] extractResultRow(ResultSet rs, int columnCount) throws OntoDriverException {
223: final Object[] row = new Object[columnCount];
224: for (int i = 0; i < columnCount; i++) {
225: final Object ob = rs.getObject(i);
226: row[i] = ob;
227: }
228: return row;
229: }
230:
231: @Override
232: public Query addContext(URI context) {
233: Objects.requireNonNull(context, ErrorUtils.constructNPXMessage("context"));
234: contexts.add(context);
235: return this;
236: }
237:
238: @Override
239: public Query addContexts(Collection<URI> contexts) {
240: Objects.requireNonNull(contexts, ErrorUtils.constructNPXMessage("contexts"));
241: this.contexts.addAll(contexts);
242: return this;
243: }
244:
245: @Override
246: public Query clearContexts() {
247: contexts.clear();
248: return this;
249: }
250: }