Skip to content

Method: getByte(int)

1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.ontodriver.owlapi.query;
14:
15: import cz.cvut.kbss.ontodriver.Statement;
16: import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
17: import cz.cvut.kbss.ontodriver.exception.VariableNotBoundException;
18: import cz.cvut.kbss.ontodriver.owlapi.exception.BindingValueMismatchException;
19: import cz.cvut.kbss.ontodriver.owlapi.exception.OwlapiDriverException;
20: import cz.cvut.kbss.ontodriver.owlapi.util.OwlapiUtils;
21: import cz.cvut.kbss.owl2query.model.GroundTerm;
22: import cz.cvut.kbss.owl2query.model.QueryResult;
23: import cz.cvut.kbss.owl2query.model.ResultBinding;
24: import cz.cvut.kbss.owl2query.model.Variable;
25: import org.semanticweb.owlapi.model.OWLEntity;
26: import org.semanticweb.owlapi.model.OWLLiteral;
27: import org.semanticweb.owlapi.model.OWLObject;
28:
29: import java.lang.reflect.Constructor;
30: import java.lang.reflect.InvocationTargetException;
31: import java.net.URI;
32: import java.util.*;
33: import java.util.stream.Collectors;
34:
35: import static cz.cvut.kbss.ontodriver.util.ErrorUtils.getNPXMessageSupplier;
36:
37: class SelectResultSet extends AbstractResultSet {
38:
39: private final QueryResult<OWLObject> queryResult;
40: private Iterator<ResultBinding<OWLObject>> iterator;
41:
42: private final Map<String, Variable<OWLObject>> namesToVariables;
43: private final Map<Integer, Variable<OWLObject>> indexesToVariables;
44:
45: private int currentIndex;
46: private ResultBinding<OWLObject> currentRow;
47:
48: public SelectResultSet(QueryResult<OWLObject> queryResult, Statement statement) {
49: super(statement);
50: this.queryResult = queryResult;
51: this.iterator = queryResult.iterator();
52: this.currentIndex = -1;
53: final int bindingSize = queryResult.getResultVars().size();
54: this.namesToVariables = new HashMap<>(bindingSize);
55: this.indexesToVariables = new HashMap<>(bindingSize);
56: resolveVariableNamesAndIndexes();
57: }
58:
59: private void resolveVariableNamesAndIndexes() {
60: Integer i = 0;
61: for (Variable<OWLObject> v : queryResult.getResultVars()) {
62: namesToVariables.put(v.getName(), v);
63: indexesToVariables.put(i, v);
64: i++;
65: }
66: }
67:
68: @Override
69: public int findColumn(String columnLabel) {
70: ensureOpen();
71: final Variable<OWLObject> v = namesToVariables.get(columnLabel);
72: if (v == null) {
73: return -1;
74: }
75: for (Map.Entry<Integer, Variable<OWLObject>> e : indexesToVariables.entrySet()) {
76: if (e.getValue().equals(v)) {
77: return e.getKey();
78: }
79: }
80: return -1;
81: }
82:
83: @Override
84: public int getColumnCount() {
85: ensureOpen();
86: return namesToVariables.size();
87: }
88:
89: @Override
90: public boolean isBound(int variableIndex) {
91: ensureState();
92: return indexesToVariables.containsKey(variableIndex) && currentRow
93: .get(indexesToVariables.get(variableIndex)) != null;
94: }
95:
96: @Override
97: public boolean isBound(String variableName) {
98: ensureState();
99: return namesToVariables.containsKey(variableName) && currentRow.get(namesToVariables.get(variableName)) != null;
100: }
101:
102: @Override
103: public void first() {
104: ensureOpen();
105: this.currentIndex = -1;
106: this.iterator = queryResult.iterator();
107: next();
108: }
109:
110: @Override
111: public boolean getBoolean(int columnIndex) throws OntoDriverException {
112: return getPrimitiveValue(Boolean.class, columnIndex);
113: }
114:
115: private <T> T getPrimitiveValue(Class<T> cls, int columnIndex) throws OntoDriverException {
116: final Object val = OwlapiUtils.owlLiteralToValue(getLiteral(columnIndex));
117: ensureValueIsAssignableToClass(val, cls);
118: return cls.cast(val);
119: }
120:
121: private static <T> void ensureValueIsAssignableToClass(Object val, Class<T> cls) {
122: if (!cls.isAssignableFrom(val.getClass())) {
123: throw new BindingValueMismatchException("Value " + val + " cannot be returned as " + cls.getSimpleName());
124: }
125: }
126:
127: private OWLLiteral getLiteral(int columnIndex) throws OntoDriverException {
128: final OWLObject currentValue = getCurrentValue(columnIndex);
129: ensureValueIsLiteral(currentValue);
130: return (OWLLiteral) currentValue;
131: }
132:
133: private static void ensureValueIsLiteral(OWLObject currentValue) {
134: if (!(currentValue instanceof OWLLiteral)) {
135: throw new BindingValueMismatchException("Value " + currentValue + " is not an OWLLiteral.");
136: }
137: }
138:
139: private OWLObject getCurrentValue(int columnIndex) throws OwlapiDriverException {
140: ensureState();
141: if (!indexesToVariables.containsKey(columnIndex)) {
142: throw new OwlapiDriverException("No result binding found for index " + columnIndex);
143: }
144: final Variable<OWLObject> v = indexesToVariables.get(columnIndex);
145: final GroundTerm<OWLObject> gt = currentRow.get(v);
146: if (gt == null) {
147: throw new VariableNotBoundException(
148: "Variable at index " + columnIndex + " not bound in the current result row.");
149: }
150: return gt.getWrappedObject();
151: }
152:
153: private void ensureState() {
154: ensureOpen();
155: if (currentRow == null) {
156: throw new IllegalStateException("Current row is null.");
157: }
158: }
159:
160: @Override
161: public boolean getBoolean(String columnLabel) throws OntoDriverException {
162: return getPrimitiveValue(Boolean.class, columnLabel);
163: }
164:
165: private <T> T getPrimitiveValue(Class<T> cls, String columnLabel) throws OwlapiDriverException {
166: final Object val = OwlapiUtils.owlLiteralToValue(getLiteral(columnLabel));
167: ensureValueIsAssignableToClass(val, cls);
168: return cls.cast(val);
169: }
170:
171: private OWLLiteral getLiteral(String columnLabel) throws OwlapiDriverException {
172: final OWLObject currentValue = getCurrentValue(columnLabel);
173: ensureValueIsLiteral(currentValue);
174: return (OWLLiteral) currentValue;
175: }
176:
177: private OWLObject getCurrentValue(String columnLabel) throws OwlapiDriverException {
178: ensureState();
179: if (!namesToVariables.containsKey(columnLabel)) {
180: throw new OwlapiDriverException("No result binding found for label " + columnLabel);
181: }
182: final Variable<OWLObject> v = namesToVariables.get(columnLabel);
183: final GroundTerm<OWLObject> gt = currentRow.get(v);
184: if (gt == null) {
185: throw new VariableNotBoundException(
186: "Variable \"" + columnLabel + "\" not bound in the current result row.");
187: }
188: return gt.getWrappedObject();
189: }
190:
191: @Override
192: public byte getByte(int columnIndex) throws OntoDriverException {
193: final Number num = getPrimitiveValue(Number.class, columnIndex);
194: return num.byteValue();
195: }
196:
197: @Override
198: public byte getByte(String columnLabel) throws OntoDriverException {
199: final Number num = getPrimitiveValue(Number.class, columnLabel);
200: return num.byteValue();
201: }
202:
203: @Override
204: public double getDouble(int columnIndex) throws OntoDriverException {
205: final Number num = getPrimitiveValue(Number.class, columnIndex);
206: return num.doubleValue();
207: }
208:
209: @Override
210: public double getDouble(String columnLabel) throws OntoDriverException {
211: final Number num = getPrimitiveValue(Number.class, columnLabel);
212: return num.doubleValue();
213: }
214:
215: @Override
216: public float getFloat(int columnIndex) throws OntoDriverException {
217: final Number num = getPrimitiveValue(Number.class, columnIndex);
218: return num.floatValue();
219: }
220:
221: @Override
222: public float getFloat(String columnLabel) throws OntoDriverException {
223: final Number num = getPrimitiveValue(Number.class, columnLabel);
224: return num.floatValue();
225: }
226:
227: @Override
228: public int getInt(int columnIndex) throws OntoDriverException {
229: final Number num = getPrimitiveValue(Number.class, columnIndex);
230: return num.intValue();
231: }
232:
233: @Override
234: public int getInt(String columnLabel) throws OntoDriverException {
235: final Number num = getPrimitiveValue(Number.class, columnLabel);
236: return num.intValue();
237: }
238:
239: @Override
240: public long getLong(int columnIndex) throws OntoDriverException {
241: final Number num = getPrimitiveValue(Number.class, columnIndex);
242: return num.longValue();
243: }
244:
245: @Override
246: public long getLong(String columnLabel) throws OntoDriverException {
247: final Number num = getPrimitiveValue(Number.class, columnLabel);
248: return num.longValue();
249: }
250:
251: @Override
252: public Object getObject(int columnIndex) throws OntoDriverException {
253: return owlObjectToObject(getCurrentValue(columnIndex));
254: }
255:
256: private static Object owlObjectToObject(OWLObject owlValue) {
257: if (owlValue == null) {
258: return null;
259: }
260: if (owlValue instanceof OWLLiteral) {
261: return OwlapiUtils.owlLiteralToValue((OWLLiteral) owlValue);
262: }
263: final Set<OWLEntity> sig = owlValue.signature().collect(Collectors.toSet());
264: if (sig.isEmpty()) {
265: return owlValue.toString();
266: } else {
267: return URI.create(sig.iterator().next().toStringID());
268: }
269: }
270:
271: @Override
272: public Object getObject(String columnLabel) throws OntoDriverException {
273: return owlObjectToObject(getCurrentValue(columnLabel));
274: }
275:
276: @Override
277: public <T> T getObject(int columnIndex, Class<T> cls) throws OntoDriverException {
278: Objects.requireNonNull(cls);
279: return owlObjectToType(getCurrentValue(columnIndex), cls);
280: }
281:
282: private static <T> T owlObjectToType(OWLObject owlValue, Class<T> cls) throws OntoDriverException {
283: if (cls.isAssignableFrom(owlValue.getClass())) {
284: return cls.cast(owlValue);
285: }
286: if (owlValue instanceof OWLLiteral) {
287: final Object ob = OwlapiUtils.owlLiteralToValue((OWLLiteral) owlValue);
288: if (cls.isAssignableFrom(ob.getClass())) {
289: return cls.cast(ob);
290: } else if (String.class.equals(cls)) {
291: return cls.cast(((OWLLiteral) owlValue).getLiteral());
292: }
293: } else {
294: final Set<OWLEntity> sig = owlValue.signature().collect(Collectors.toSet());
295: if (!sig.isEmpty()) {
296: final URI uri = URI.create(sig.iterator().next().toStringID());
297: if (cls.isAssignableFrom(uri.getClass())) {
298: return cls.cast(uri);
299: }
300: return tryInstantiatingClassUsingConstructor(cls, uri);
301: }
302: }
303: throw new OwlapiDriverException("Conversion to type " + cls + " is not supported.");
304: }
305:
306: private static <T> T tryInstantiatingClassUsingConstructor(Class<T> cls, URI uri) throws OwlapiDriverException {
307: try {
308: final Constructor<T> constructor = cls.getDeclaredConstructor(uri.getClass());
309: if (!constructor.isAccessible()) {
310: constructor.setAccessible(true);
311: }
312: return constructor.newInstance(uri);
313: } catch (NoSuchMethodException e) {
314: throw new OwlapiDriverException(
315: "No constructor taking parameter of type " + uri.getClass().getName() + " found in class " + cls,
316: e);
317: } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
318: throw new OwlapiDriverException(
319: "Unable to create instance of class " + cls + " using constructor with argument " + uri, e);
320: }
321: }
322:
323: @Override
324: public <T> T getObject(String columnLabel, Class<T> cls) throws OntoDriverException {
325: Objects.requireNonNull(cls, getNPXMessageSupplier("cls"));
326: return owlObjectToType(getCurrentValue(columnLabel), cls);
327: }
328:
329: @Override
330: public int getRowIndex() {
331: return currentIndex;
332: }
333:
334: @Override
335: public short getShort(int columnIndex) throws OntoDriverException {
336: final Number num = getPrimitiveValue(Number.class, columnIndex);
337: return num.shortValue();
338: }
339:
340: @Override
341: public short getShort(String columnLabel) throws OntoDriverException {
342: final Number num = getPrimitiveValue(Number.class, columnLabel);
343: return num.shortValue();
344: }
345:
346: @Override
347: public String getString(int columnIndex) throws OntoDriverException {
348: return owlValueToString(getCurrentValue(columnIndex));
349: }
350:
351: private static String owlValueToString(OWLObject owlValue) {
352: if (owlValue instanceof OWLLiteral) {
353: return ((OWLLiteral) owlValue).getLiteral();
354: }
355: final Set<OWLEntity> sig = owlValue.signature().collect(Collectors.toSet());
356: if (sig.isEmpty()) {
357: return owlValue.toString();
358: } else {
359: return sig.iterator().next().toStringID();
360: }
361: }
362:
363: @Override
364: public String getString(String columnLabel) throws OntoDriverException {
365: return owlValueToString(getCurrentValue(columnLabel));
366: }
367:
368: @Override
369: public boolean isFirst() {
370: ensureOpen();
371: return currentIndex == 0;
372: }
373:
374: @Override
375: public boolean hasNext() {
376: ensureOpen();
377: return iterator.hasNext();
378: }
379:
380: @Override
381: public void last() {
382: ensureOpen();
383: while (hasNext()) {
384: next();
385: }
386: }
387:
388: @Override
389: public void next() {
390: ensureOpen();
391: if (!hasNext()) {
392: throw new NoSuchElementException("The result set has no more rows.");
393: }
394: this.currentRow = iterator.next();
395: currentIndex++;
396: }
397:
398: @Override
399: public void previous() {
400: ensureOpen();
401: relative(-1);
402: }
403:
404: @Override
405: public void relative(int rows) {
406: ensureOpen();
407: setRowIndex(currentIndex + rows);
408: }
409:
410: @Override
411: public void setRowIndex(int rowIndex) {
412: ensureOpen();
413: if (rowIndex == currentIndex) {
414: return;
415: }
416: if (rowIndex < 0) {
417: throw new IllegalArgumentException("Cannot set row index to a number less than 0.");
418: }
419: if (rowIndex < currentIndex) {
420: first();
421: }
422: while (rowIndex > currentIndex && hasNext()) {
423: next();
424: }
425: }
426: }