Skip to content

Method: addContext(URI)

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